一、 Stable Diffusion能做什么
通过前面几篇文章关于 Stable Diffusion 整合包的安装、ControlNet插件的介绍使、sd模型的安装和使用以及文生图功能的介绍后,相信看过的朋友应该都清楚的知道 Stable Diffusion 是做什么的吧?
对于新朋友,想详细了解的话,请前往:
AI 绘画Stable Diffusion 研究(一)sd整合包v4.2 版本安装说明
AI 绘画Stable Diffusion 研究(二)sd模型ControlNet1.1 介绍与安装
AI 绘画Stable Diffusion 研究(三)sd模型种类介绍及安装使用详解
AI 绘画Stable Diffusion 研究(四)sd文生图功能详解(上)
AI 绘画Stable Diffusion 研究(五)sd文生图功能详解(下)
AI 绘画Stable Diffusion 研究(六)sd提示词插件
这里再用最直白的话说一下:SD它是一个text-to-image模型 ,通过给定的 text prompt(文本提示词),可生成一张匹配文本的图片。
二、什么是扩散模型
大家都经常听到有人说,Stable Diffusion是一种潜在扩散模型(Diffusion Models)。
那我们先弄明白什么是扩散模型?
为什么叫扩散模型呢?因为它的数学公式看起来非常像物理上的扩散现象。
1、前向扩散
假如我们训练一个模型如下:
正如上图所示,是一个前向扩散的过程,它是在训练图像上逐渐添加噪声,最后变成完全随机噪声图,并最终无法辨认噪点图对应的初始图片。
这个过程就像是一滴墨水滴在一杯清水里,会慢慢扩散最终均匀分布在清水里一样,且无法判断它最初是从水杯的中心滴入,还是从边缘滴入,扩散这个名字就是这么来的。
2、反向扩散
反向扩散的思想是:输入一张噪点图,反向扩散(Reverse Diffusion),让上述过程获得逆向从随机噪声图生成清晰图像的过程。
从反向扩散的角度来说,我们需要知道有多少“噪点”加入到了某张图片里。
那么要知道答案的方式便是:训练一个神经网络来预测添加的噪点,这在SD里称为噪点预测器(Noise Predicator),其本质是一个U-Net模型。
训练流程为:
(1)、选择一张训练图(例如一张猫的图片)
(2)、生成随机的噪点图
(3)、给这张图继续增加多轮噪点
(4)、训练Noise Predicator,预测加入了多少噪点,通过神经网络训练权重,并展示其正确答案。
反向扩散训练的重点下图中的噪声预测器(Noise Predicator),它可以通过训练得出每次需要减掉的噪声,每次需要减多少噪声是预测出来的,从而实现还原清晰图片的目的。
三、扩散模型实现原理
扩散模型(Diffusion Models)的成功,其实并非横空出世,突然出现在人们的视野中。其实早在2015年就已有人提出了类似的想法,最终在2020年提出了扩散模型的生成技术。
以下是扩散模型推导公式:
更详细的原理:
参考:扩散模型详解原理+代码
通过前面的介绍,我们大概明白了,什么是扩散模型,但这并不是 Stable Diffusion的工作原理。
这是因为:上述扩散过程是在图片空间里完成的,无论是模型训练,还是生成图片的过程,都是需要海量的算力支持和内存需求。
想象一下:一张512 x 512的图片(包含3个颜色通道:红、绿、蓝),它的空间是786432维,也就是说我们要为一张图片指定这么多的值。因此,基本无法在单个GPU上运行。
Stable Diffusion就是降低算力和内存需求的一个解决方案。它让Stable Diffusion在消费级GPU上运行成为了可能。
四、Stable Diffusion 潜扩散模型
Stable Diffusion 它是一个Latent Diffusion Model(潜扩散模型)。其方式是将图片压缩到一个“潜空间”(Latent Space)中,而不是在高维的图片空间里工作。潜空间比图片空间小了48倍,所以它可以节省大量计算,继而运行速度更快。
扩散过程会分成很多步循环,而每一步的过程如下图所示,将文本描述、隐变量、步数等数值传入UNet,生成新的隐变量,而这个过程会涉及一些模型。
在最后一步循环,将隐特征经由 Variational Autoencoder(VAE)解码成图像。
这个过程的核心思想就是:压缩图像,它通过变分自编码器 Variational Autoencoder(VAE)模型,把图像压缩到极致,我们把此类压缩方式称作降维,这种降维级别的压缩不丢失重要信息。
经过压缩后,图像被称作低维潜在(Latent)“图像”,作为U-net的输入,去潜空间(Latent Space)里一步一步降噪后,完成反向扩散的低维“图片”还得通过VAE的解码器,把图像从潜空间转换回像素空间(Pixel Space)。
VAE包含2部分:Encoder与Decoder。
- Encoder将一张图片压缩到“潜空间”里的一个低维空间表示
- Decoder从“潜空间”里的表示恢复为一张图片
下列代码演示了VAE模型的使用方法,其中load_vae为根据配置init_config去初始化模型,然后从预训练模型model.ckpt中读取参数,预训练模型的first_stage_model即指代VAE模型。
from ldm.models.autoencoder import AutoencoderKL #VAE模型 def load_vae(): #初始化模型 init_config = { "embed_dim": 4, "monitor": "val/rec_loss", "ddconfig":{ "double_z": True, "z_channels": 4, "resolution": 256, "in_channels": 3, "out_ch": 3, "ch": 128, "ch_mult":[1,2,4,4], "num_res_blocks": 2, "attn_resolutions": [], "dropout": 0.0, }, "lossconfig":{ "target": "torch.nn.Identity" } } vae = AutoencoderKL(**init_config) #加载预训练参数 pl_sd = torch.load("model.ckpt", map_location="cpu") sd = pl_sd["state_dict"] model_dict = vae.state_dict() for k, v in model_dict.items(): model_dict[k] = sd["first_stage_model."+k] vae.load_state_dict(model_dict, strict=False) vae.eval() return vae #测试vae模型 def test_vae(): vae = load_vae() img = load_image("girl_and_horse.png") #(1,3,512,512) latent = vae.encode(img).sample() #(1,4,64,64) samples = vae.decode(latent) #(1,3,512,512) save_image(samples,"vae.png") test_vae()
五、Stable Diffusion 文本如何影响图片生成
在 Stable Diffusion 模型中,prompt 是通过引导向量(guidance vector)来控制 U-Net 的。具体来说,prompt 会被编码成一个文本嵌入向量(text embeddings),然后与其他输入一起传递给 U-Net。
通过这种方式,prompt 能够影响 U-Net 的输出,从而在生成过程中引导模型产生符合预期的结果,即通过 prompt 产生我们想要的图。
在Stable Diffusion模型限制prompt在75个单词。
下图是文本提示词(text prompt)如何处理并输入到Noise Predictor的流程:
根据上图,我们可以看到这个流程:
首先,Tokenizer(分词器)将每个输入的单词转为一个数字,我们称为token。
然后,每个token转为一个768维的向量,称为词嵌入(embedding)。
最后,由Text Transformer处理词嵌入,并可以被Noise predictor进行消费。
1、分词器 (Tokenizer)
人类可以读懂单词,但计算机只能读懂数字。所以这也是为什么文本提示词首先要转为单词。
文本提示词(text prompt)首先由一个CLIP tokenizer做分词。
CLIP是一个深度学习模型,由Open AI开发,用于为任何图片生成文本描述。
以下是CLIP具体的实例
展示了如何将文本“苹果”通过CLIP技术转化为能输入到神经网络中训练的tokens数据。
这里使用Python和OpenAI库来实现。
(1)、安装依赖库
pip install torch openai
(2)、导入相关库
import torch import openai
(3)、加载CLIP模型
model, preprocess = openai.clip.load("ViT-B/32")
(4)、准备输入文本
text_description = "苹果"