我在这里简单理一下SD生成图像的基本流程,快速建立起对SD的原理了解su。
官方论文:https://stable-diffusion-art.com/how-stable-diffusion-work/
首先我们的文本包含正面提示词和负面提示词,通过text coder文本编码器(一般是CLIP模型)转换成固定长度的、易于电脑计算的矢量数据 ,然后与初始化噪声图像一起带入Unet模型网络进行多个采样迭代次数的去噪处理,去噪后的图像数据再通过VAE模型进行解码,还原成最终的图像。
(这也是我们在生成图像的时候,首先需要一个采样方法和采样迭代次数的原因。)
上述三个模型,CLIP模型+Unet模型+VAE模型,我们可以把它们都简单看作一个函数,函数内包含多个参数,能将输入数据转换为输出数据。我们把这三个模型打包看作一个合并的大函数FSD。
一般情况了解这些就够了,但为了更好的理解后面的微调模型,我们需要更加深入地去了解SD的各个功能的实际运作过程和运作机制。
稳定扩散模型(Stable Diffusion)属于深度学习模型中的一个大类,即扩散模型。它们属于生成式模型,它们是被设计用于根据学习内容来生成相似的新的数据的。对于稳定扩散模型而言,新的数据即为图像数据。
新的图像数据与训练集(学习内容)相似但不完全相同,所以是新的图像数据。
这可能是因为:
在AI训练中,利用梯度下降学习的过程不断地调整参数来使机器学习的损失函数不断逼近最优值。但实际上,一般情况不可能找到全局最优解!我们训练的模型几乎都是局部最优,接近全局最优解。
为什么称之为扩散模型?因为模型中使用的数学看起来与物理学中的扩散公式非常相似。我们来了解一下这个模型的理念。
假设我们只使用猫和狗这两类图像来训练这个稳定扩散模型。如图所示,图中左侧曲线的两个峰值代表了猫与狗这两组图像。
所谓前向扩散(forward diffusion)过程就是向训练图像中不断地添加噪声,从而使其逐渐变为一张毫无意义的纯噪声图。在我们的例子中,前向扩散过程会将猫与狗的图片转变为噪声图。最终你将无法从得到的噪声图中分别出原来的图究竟是猫还是狗(这点很重要)。
这就好比往一杯水中滴入一滴墨水。墨滴将在水中扩散,在几分钟之后,它将随机均匀的遍布于整杯水中,你将再也无法从这杯水中看出原来的墨滴究竟是从杯子的中心还是边缘滴入的了。
下图演示了一张图像经由前向扩散逐渐变为纯噪声图的过程。
现在来到神奇的部分了。如果我们能够逆转扩散的过程会怎样呢?就像影片倒带一样,在时间线上逆向移动,那我们最终将会看到墨滴最初是从哪里滴落的了。
从一张完全无意义的噪声图,逆向扩散过程使其还原为一张猫【或】狗的图像,这就是逆向扩散的核心理念。
从技术上来说,每个扩散过程都有两个分量:(1)漂移或引导的方向;(2)随机的方向。逆向扩散会将结果导向猫或者狗的图像,但并不会是二者之间的图像。这也是为什么我上面说,逆向扩散的结果将会是猫或者狗。
神经网络模型训练是是如何完成现在问题来了,是,怎么来逆向扩散呢它呢?
为了将扩散过程逆转,我们需要知道到底有多少噪声被添加到了图像中。而这个问题的答案,将会由一个经过训练的神经网络模型来预测解答。在Stable Diffusion模型中,这个模块被称为**噪声预测器(noise predictor)**。训练的过程如下:
1,选择一张训练图片,比如一张狗或猫的图像
2,生成一个随机的噪声图
往原始训练图片中添加特定和特定量的噪声次数,使图像变得嘈杂
4,以正确答案为基准,通过调试参数,训练噪声预测器最终能够识别出究竟有多少次噪声被添加到了这张图片中。
在训练完成后,我们将得到一个能够估计出有多少噪声被添加到了一张图像中的噪声预测器。
现在我们有了一个噪声预测器,我们将怎样使用它呢?
我们将首先生成一张完全随机的图像,并让噪声预测器告诉我们这张图像中被添加了哪些噪声。随后我们就可以将噪声预测器给出的噪声图像从原始图像中剔除出去。重复以上步骤几次,我们即可以得到一张猫或是狗的图像了。
你可能注意到了,按上面的描述,我们所实现的逆向扩散过程没法控制最终结果是一个猫还是狗的图像。在后面的“调节”章节中我们会着重来论述这一点。就目前我们所介绍的内容来说,图像的生成是无条件的(unconditioned)。
现在,我将告诉你:以上我们所描述的过程,并不是Stable Diffusion模型的工作机制!原因是,以上所描述的扩散过程都是在图像(像素)空间(image space)进行的。它的计算量是非常非常巨大的,因而生成的速度会非常的慢。而且你不可能在任何一个单一的GPU中跑通这个过程,更别说那些笔记本电脑上的垃圾GPU了。
图像的像素空间是非常巨大的。想象有一张512x512大小RBG三通道的彩色图片,这将是一个768,432(512x512x3)维度的空间。(意味着为了生成一张图,你需要确定768,432个值)
稳定扩散模型(Stable Diffusion)的设计目的,就是要解决速度的问题。它是这么做的:
Stable Diffusion模型实际上是在潜空间( latent space)中的扩散模型。为避免在高维度的图像空间中操作,它首先将图像压缩到了一个称作潜空间的区域中。潜空间相较于像素空间小了48倍【你可以简单的理解将图像压缩了48倍】。也就是说,模型所处理的计算数据相比之下少了许多,也因此它比标准的扩散模型快了非常多。
实现图像潜空间压缩的技术叫做变分自动编码器,是的,就是那个你在SD工具中需要设置的VAE文件。
变分自动编码器(VAE)神经网络有两个部分:(1)编码器;(2)解码器。编码器将图像压缩至潜空间这个低维度,而解码器则是将潜空间的数据还原为原始的图像。
Stable Diffusion所使用的是一个4x64x64的 latent space,相较于图像的像素空间【512x512的图像】而言小了48倍。所有我们前面所描述的前向扩散与逆向扩散的过程都实际是在这个空间中完成的。
训练的过程也是一样的,训练流程中生成的并不是噪声图像,而是latent space中的random tensor 随机张量(即一个4x64x64的噪声图)。训练中向潜空间的图像添加潜空间的噪声,而不是像素图添加像素噪声。这样做的原因都是因为由于潜空间较小从而可以使整个过程的执行速度得到大幅的提升。
你可能震惊于为什么VAE可以将图像压缩到如此小的空间之中而不损失信息。
原因很简单:自然图像并不是纯随机的。它们有着很高的规律性:一张脸上的五官总是有着特定的空间关系,一只狗总是有着4条腿以及总体的一类特征形状。
换句话说,图像的高维度是人为刻意产生的,而自然图像可以很容易地压缩到更小的潜在空间中而不会丢失任何信息。 这在机器学习中被称为 流形假设。
我们来整理一下在Stable Diffusion模型中,逆向扩散如何在潜空间中进行的
一个随机的潜空间矩阵被生成(4x64x64维)
1,噪声预测器预测出一个潜空间噪声,其在前向扩散过程中被作用在了这个潜空间噪声矩阵上
2,从原始潜空间噪声中减去预测出的噪声
3,重复2到3步指定的采样次数(sampling steps)
4,VAE的解码器(decoder)将得到的潜空间矩阵数据还原为最终的像素图像。
VAE文件 在 Stable Diffusion一代中用于提升眼睛与面部的绘画结果。正如前面讲的,它们是自动编码器所对应的解码器。通过对解码器进行调教,Stable Diffusion模型的生成图像可以拥有更好的细节表现。
你可能注意到了我前面有一处描述并不是完全正确的。将图片压缩至潜空间是会丢失原始图像的信息的,因为原始的VAE并不能对细节进行恢复。因此VAE解码器将负责在解码过程中绘制那些精细的细节内容。
以上关于模型的描述仍然是不完整的:当我们使用SD时所传入的文字指令是如何生效的呢?没有指令的存在,SD并不是一个完整的text-to-image模型。你没有办法控制SD最终为你生成一张猫的图片还是一张狗的图片。
这时候我们就需要引入“调节(Conditioning)”了。调节的目的是引导噪声预测器,以便预测的噪声在从图像中减去后,会使图像朝着我们想要的结果演变。
下图展现了文字指令(Text Prompt)如何经过处理并送入噪声预测器的过程。分词器(Tokenizer)首先将指令中的每个单词转化为一个数字表示的词元(token)。每个词元随后将转换为一个包含768个数值的向量,我们称之为标签(Embedding)(是的,就是那个你在SD GUI工具中所使用的Embedding)。这些标签随后传递给文本Transformer模型【可理解为一个通用的神经网络模型】,并经过其处理后交由噪声预测器使用。
文本指令被处理并送入噪声预测器以控制图像生成的过程
文本指令将会首先被一个CLIP分词器分解为一组词元。CLIP是一个由OpenAI开发的深度学习模型,被用于生成对任意图像的文本描述。Stable Diffusion第一代版本使用的是CLIP分词器。
将文本词元化,是使其可以被计算机所理解的第一步。我们人类可以阅读文字,但是计算机只能阅读数字,这就是文本指令处理过程中首先被转换成一组词元所对应的数字的原因。
一个分词器只能对其在训练过程中见到过的词汇进行分词。比如说,在CLIP模型中有“dream“和”beach“这两个词元,但是并没有”dreambeach“这个词元。分词器在处理时会将dreambeach这个单词拆分为”dream”和“beach”这两个它所认识的词元·。因此,一个单词并不一定只对应一个词元!
另一个细则是,空格也是词元的一部分。“dream beach"这个单词将会生成两个词元“dream“与”[空格]beach"。这些词元实际上与上个例子中由“dreambeach”解析出来的两个词元是不一样的(前面例子中的词元是不带空格的)。
Stable Diffusion模型所使用的指令长度被限制为75个词元。(现在你知道了这并不等同于75个单词)
Stable Diffusion一代版本使用的是OpenAI的ViT-L/14 CLIP模型。在这个模型中标签向量的长度是768。每个词元都有其唯一对应的标签向量。这些标签向量的值在CLIP模型中是固定的,通过训练所得到的。
我们为什么需要标签?这是因为不同的单词之间可能会有很强的关联性。我们需要使用到这种关联性的信息。举例来说,man(男人), gentleman(绅士), guy(男的)这几个词对应的标签值几乎是一样的,因为这些单词在文字中大多情况是可以相互替换的。Monet,Manet与Degas都是印象派的画家,但各自风格又有显著区别,所以这几个名字所对应的标签向量有相近的部分,但又不完全一样。
这里我们所讨论的标签(Embedding),与在使用SD时所用于调教模型的标签是一个东西。标签的使用是有魔法的。科学家们已经证明了,在SD中找到一个合适的标签向量即可以触发任意物体与风格要素,这种模型调教技术被称作逆向构建(Textual Inversion)。
上一步得到的那些标签在传入噪声预测器前,还需要先交由文本Transformer做进一步处理。Transformer模型类似于一个通用的调节因子适配器。当下,输入给Transformer的是标签向量,但实际上也可以将其他种类的数据如:类型标签、图像、深度图等作为输入传入这个模型中。Transformer存在的意义,不仅仅是需要其作为数据处理的一个环节,更在于它可以提供一个能包含不同调节方式的数据处理机制。
经由Transformer模型输出的数据,将在后面的U-Net神经网络中被噪声预测器多次使用。而U-Net使用一种叫做交叉注意力(cross-attention)的机制来使用这些数据。正是这个机制使得在前面步骤中被拆散的单词指令能够被正确的组合关联起来。举例来说:指令“A man with blue eyes"需要在“blue”与“eyes”之间形成交叉注意力,这样Stable Diffusion才能知道需要绘制的是一个有蓝色眼睛的男人,而不是一个有眼睛的蓝色男人。
文本指令并不是唯一能够调节Stable Diffusion的方式。
在depth-to-image功能中,文本与深度图都可以作为调节参数来使用。
ControlNet通过轮廓线、人物姿态等来控制噪声预测器,在对于生成图像的控制上取得了非常卓越的效果。
在使用文本到图像功能时,你通过给SD传入一个文本指令,使其返回一张图像。
第一步,Stable Diffusion生成一个潜空间的random tensor随机张量(初始噪声图像)。这个随机张量的生成是受你在SD中设置的随机种子(seed)的值所控制的。如果你将随机种子设置成了一个固定值,那SD将始终使用同样的初始随机张量。不要忘了,这个随机张量就是你图像在潜空间中的表达形式,只不过目前他还只是完全的噪声。
A random tensor is generated in latent space.
第二步,噪声预测器的U-Net网络会将这个初始随机张量与文本指令作为输入传入其中,并预测出应移除的噪声,当然其也是个潜空间的张量。
第三步,将这个潜空间噪声从潜空间初始图像中减去,得到潜空间中新的图像。
第二步与第三步将根据你设置的采样步数(sampling steps)重复特定次数,比如20次。
第四步,VAE解码器将最后得到的潜空间图像恢复为像素空间的图像,这也是你在Stable Diffusion工具中最终得到的图像。
这里展示了图像经过每一次去噪步骤后的变化情况。
一般来说,去噪的过程不是一步到位的(DDPM例外),这张图演示了不同采样迭代次数的去噪程度。
我们可以选择在每个步骤中减去相同数量的噪声。或者我们可以在开始时减去更多,就像上面那样。采样器在每一步减去足够的噪声,以达到下一步的预期噪声。这就是你在一步一步的图像中看到的情况。
我们选择采样方法实际上就是在选择如何去噪。
图生图方法首先是由 SDEdit 所提出的。SDEdit可以应用于任何的扩散模型。因此我们在Stable Diffusion中也有了图生图的功能。
图生图功能使用一张图片与一段文字指令共同作为输入。生成的图像将受到这两个输入的共同调节作用。比如,使用下面这张初级草图以及一段指令 ”photo of perfect green apple with stem, water droplets, dramatic lighting" 作为输入,图生图功能会将其转化为一张很专业的绘画:
下面介绍其具体生成的过程。
第一步,输入的图片会被编码至潜空间中
第二步,我们会向其添加噪声。通过在SD工具中设置降噪强度(Denoising strength)可以控制究竟要添加多少噪声到原始输入图像中去(在潜空间)。如果这个值设置为0,不会有任何噪声添加进去,如果是1则会向其添加最大量的噪声以使其成为一个在潜空间中完全随机的张量。
第三步,噪声预测器将上一步处理后的潜空间图像与文字指令作为输入传入其U-Net网络,并给出预测应减去的潜空间噪声张量。
第四步,将这个潜空间噪声从潜空间初始图像中减去,得到潜空间中新的图像。
第三步与第四步将根据你设置的采样步数(sampling steps)重复特定次数,比如20次。
第五步,VAE解码器将最后得到的潜空间图像恢复为像素空间的图像,这也是你在image-to-image工具中最终得到的图像。
参考图生图的运作过程,我们也可以去理解其他类型的引导。