前言
Stable Diffusion原理
1. Stable Diffusion能做什么
直白地说,SD是一个text-to-image模型,通过给定text prompt(文本提示词),它可以返回一个匹配文本的图片。
2. Diffusion 模型
Stable Diffusion属于深度学习模型里的一个类别,称为diffusion models(扩散模型)。这类模型时生成式模型,也就是说它们用于生成新的数据,这类新数据类似于它们训练时的数据。对于SD来说,这类新数据便是图片。
为什么叫diffusion model?因为它的数学公式看起来非常像物理上的扩散现象。下面我们具体介绍它的原理。
假设我们训练了一个diffusion model,训练时只给了2类图片:猫与狗。如下图所示,左边便是送入训练的猫与狗的图片。
所有的AI设计工具,模型和插件,都已经整理好了,👇获取~
2.1. 前向扩散
前向扩散将图片转为噪点(图片基于此文图片进行修改 this article)
前向扩散的过程是给训练图片添加噪点的过程,并逐渐将图片转为一个反常的噪点图。也就是会将任何猫或狗的图片转为一张噪点图,并最终无法辨认噪点图对应的初始图片是猫还是狗(这点非常重要)。
这个过程就像是滴入了一滴墨水到一杯水里,墨水在水里diffuses(扩散)。在几分钟后,墨水会随机分散并融入水中。且无法判断它最初是从水杯的中心滴入,还是从边缘滴入。
下面是一张图经历前向扩散的过程。猫的图片转为了一张随机噪点图。
2.2. 反向扩散
然后再看反向扩散部分。我们预期的表现是:输入一张噪点图(毫无意义的图),反向扩散(reverse diffusion)可以将这张噪点图恢复为一张猫或狗的图片。这就是反向扩散的主要思想。
从技术角度来说,每个扩散过程分为2部:
- 漂移或定向运动(例如,针对这个案例来说,噪点图要么偏向狗的方向,要么定向于猫的方向)
- 随机移动
反向扩散会朝着猫或狗的图片方向进行漂移,但绝对不会停留在中间状态。这也是为什么结果智能是猫或狗的图片。
3. 训练过程
从反向扩散的角度来说,我们需要知道有多少“噪点”加入到了某张图片里。回答此问题的方式便是:训练一个神经网络来预测添加的噪点。这个在SD里称为噪点预测器(noise predicator)。其本质是一个U-Net模型。
训练流程为:
- 选择一张训练图(例如一张猫的图片)
- 生成随机的噪点图
- 给这张图继续增加多轮噪点
- 训练noise predictor,预测加入了多少噪点。通过神经网络训练权重,并展示其正确答案
按顺序每步都增加噪点,noise predictor预测每步增加的噪点
在训练后,便可得到一个noise predictor,可以预测一张噪点图中,加入到图片的噪点信息。
3.1. 反向扩散
现在我们有了noise predictor(噪点预测器),应该如何使用?
我们首先生成一张完全随机的图片,并让noise predictor告诉我们噪点是什么。然后从原图中移除噪点。并重复此过程多次,最终遍得到一张猫或狗的图片。
可以看到在这个生成猫或狗的图片的过程中,我们没有加入任何人为控制。这个“人为控制”是我们后续会讨论到的条件“conditioning”。当前来说,图片的生成是unconditioned。
4. Stable Diffusion模型
现在我们需要强调的是:上面讨论的过程并非是SD工作的原理。
原因是:由于上述扩散过程是在图片空间里完成的,所以它的计算过程是非常非常慢的。上述过程基本无法在单个GPU上运行。
图片空间太广阔了。试想:一张512 x 512的图片(包含3个颜色通道:红、绿、蓝),它的空间是786,432维。也即是说我们要为一张图片指定这么多的值。
Diffusion模型如谷歌的Imagen以及Open AI的DALL-E都是在像素空间的,他们使用了一些技巧让模型运行更快,但是仍不够快。
4.1. Latent diffusion模型
Stable Diffusion便是用于解决速度问题的,它是一个latent diffusion model(潜扩散模型)。其方式是将图片压缩到一个“潜空间”(latent space)中,而不是在高维的图片空间里工作。
潜空间比图片空间小了48倍,所以它可以节省大量计算,继而运行速度更快。
4.2. Variational Autoencoder
如何将图片压缩到潜空间?使用的技术是variational autoencoder(变分自动编码器),也即为VAE文件。
VAE神经网络包含2部分:Encoder与Decoder。
Encoder将一张图片压缩到“潜空间”里的一个低维空间表示。Decoder从“潜空间”里的表示恢复为一张图片。
SD模型的潜空间为4 x 64 x 64 维,比图片的像素点空间要小48倍。前面提到的前向与反向扩散都是在潜空间里完成。
所以在训练时,不再是生成一张噪点图,而是在潜空间里生成一个随机张量(tensor)。并且在给图片每一步增加噪点时,也不再是给图片增加噪点,而是给图片在潜空间里的张量增加潜噪点。这么做的原因当然是由于潜空间更小,执行速度更快。
4.3. 图像分辨率
图像分辨率会反映在潜空间里对应图片张量的大小。对于512 x 512的图片来说,其在潜空间里的大小为4 x 64 x 64。而对于768 x 512的人像图来说,对应潜空间张量的维度即为4 x 96 x 64。这也是为什么需要更长的时间与资源生成分辨率更高的图片。
由于Stable Diffusion v1是在512 x 512的图片上进行的fine tune,所以若是生成超过512 x 512 大小的图片时,会导致有重复的对象。例如生成的人物有“双头”问题。如果一定要用v1版本,则至少先保持512像素,然后在使用AI upscaler工具生成更高的分辨率。
4.4. 为什么潜空间是合理的
为什么VAE可以压缩一张图片到非常小的一个潜空间而不损失信息呢?这是因为:自然图片并非是随机的,它们有很高的规律性。例如,一张脸上,鼻子、脸颊和嘴巴之间有特定的空间关系。一只狗有4只腿并且有特定的形状。
换句话说,高维的图片是人为的。自然图像可以轻松地压缩到较小的潜空间中,而不会丢失任何信息。这在机器学习中被称为流形假设。
4.5. 潜空间里的反向扩散
下面是SD模型里反向扩散在潜空间里的工作流程:
- 生成随机的潜空间矩阵
- Noise predictor预测潜矩阵的噪点
- 将预测的噪点从潜矩阵中去除
- 重复步骤2与3,直到特定的采样步数
- VAE的decoder将潜矩阵转为最终图片
4.6. VAE文件是什么?
在Stable Diffusion v1里,VAE files用于提升眼睛与脸的准确度。它们实际上是我们前面提到的autoencoder中的decoder。通过进一步的fine-tune decoder,模型可以生成出更多的细节。
5. Conditioning(条件)
到目前为止,我们还没介绍文本是如何影响图片生成的。如果没有文本prompt的影响,SD模型也不会是一个text-to-image模型。我们可以得到一张猫或狗的图片,但是没有方式来控制它。
这部分就是“条件”(conditioning)要做的事情。“条件”的目的便是引导noise predictor,让其知道:在抽取预测的噪点后,我们需要的是什么。
5.1. 文本条件(text-to-image)
下面展示的是:文本提示(text prompt)如何处理并输入到noise predictor:
首先,Tokenizer(分词器)将每个输入的单词转为一个数,称为token。每个token然后转为一个768维的向量,称为词嵌入(embedding)。词嵌入然后由Text Transformer处理,并可以被Noise predictor进行消费。
可以使用这个notebook来检查prompt的token与embedding。
5.2. Tokenizer
文本提示词首先由一个CLIP tokenizer做分词。CLIP是一个深度学习模型,由Open AI开发,用于为任何图片生成文本描述。Stable Diffusion v1使用了CLIP模型的tokenizer。
Tokenization是计算机理解单词的方式。人类可以读懂单词,但是计算机智能读懂数字。所以这也是为什么文本提示词首先要转为单词。
Tokenizer只能将其在训练过程中见到过的单词进行分词。例如,假设CLIP模型里有“dream”与“beach”单词,但是没有“dreambeach”单词。Tokenizer会将“dreambeach”分成2个单词“dream”与“beach”。所以,1个单词并非代表1个token,而是有可能进一步进行拆分。
另一个细节是:空格也是token的一部分。例如,短语 “dream beach” 产生了两个token “dream” 和 “[space]beach”。这些标记与 “dreambeach” 产生的标记不同,后者是 “dream” 和 “beach”(beach 前没有空格)。
Stable Diffusion模型限制提示词在75个单词。
5.3. 词嵌入(Embedding)
Stable diffusion v1使用Open AI的ViT-L/14模型,词嵌入为768维的向量。每个单词有其特定的词嵌入向量。词嵌入由CLIP模型决定,是在训练过程中得来。
为什么我们需要词嵌入?因为有些单词相互之间是非常相似的,我们希望利用到这些信息。例如,man、gentleman、guy的词嵌入是非常相近的,因此它们可以相互替换。Monet、Manet以及Degas都以印象派的风格绘画,但是方式各不相同。这些名字看起来是非常相似,但是在词嵌入里是很不一样的。
在另一片文章里,我们讨论的使用关键词来触发不同的风格,两者的embedding含义是一样的。Embedding在里面起了至关重要的作用。已经证明的是,使用合适的词嵌入可以触发任意对象与风格,一个fine-tune的技巧称为textual inversion。
5.4. 将词嵌入输入noise predictor
词嵌入需要进一步由文本转换器(text transformer)进行处理,然后输入到noise predictor中。这个转换器就像是一个通用的条件(conditioning)适配器。在这个例子中,它的输入是文本嵌入向量,但是它也可以是其他的东西,例如类别标签,图片,以及depth maps。转换器不仅是进一步处理数据的组件,也提供了一种机制来加入不同的条件形式。
5.5. Cross-attention
文本转换器的输出,会被noise predictor在U-Net中使用到多次。U-Net以一个叫做cross-attention机制的方式来使用它。这即是prompt适配图片的地方。
这里我们使用提示词“A man with blue eyes”作为例子。SD将单词blue与eyes组合到一起(self-attention within the prompt),这样便可以生成一个蓝眼睛的男人,而不是穿蓝衬衫的男人。然后它会使用这个信息引导反向扩散,使得最终生成的图片包含蓝色眼睛(cross-attention between 提示词与图片)
一个备注:Hypernetwork是一种fine-tune Stable Diffusion模型的技术,它会操纵cross-attention网络来注入风格。LoRA模型修改cross-attention模块的权重来修改风格。可以看到,单独修改这个模块即可fine-tune一个SD模型的风格,说明了这个模块有多重要。
5.6. 其他条件
文本提示词并非SD模型可以参考的条件。Text prompt与depth image都可以用于depth-to-image模型的条件。
ControlNet利用监测到的轮廓、人体姿势等对noise predictor进行调节,可以实现对图像生成的出色控制。
6. Stable Diffusion step-by-step
现在我们了解了Stable Diffusion的机制,下面我们再通过几个例子看看底层是如何运行的。
6.1. 文本生成图
在文本生成图的场景下,我们给SD模型输入一组文本提示词,它可以返回一张图片。
Step 1. Stable Diffusion在潜空间里生成一个随机张量。我们通过设置随机种子seed来控制这个张量的生成。如果我们设置这个随机种子为一个特定的值,则会得到相同的随机张量。这就是我们在潜空间里的图片。但是当前还全是噪点。
Step 2. Noise predictor U-Net将潜噪点图已经文本提示词作为输入,并预测噪点,此噪点同样也在潜空间内(一个4 x 64 x 64的张量)
Step 3. 从潜图片中抽取潜噪点,并生成了新的潜图片
Step 2 与 Step 3 重复特定采样次数,例如20次。
Step 4. 最后,VAE的decoder将潜图片转回像素空间,这便是我们通过SD模型最终得到的图片。
下图是图片在每个采样步生成的结果:
6.1.2. noise schedule
可以看到,整个过程是图片是由噪点转为干净的的过程。大家可能会考虑到,是不是最开始几步noise predictor的性能不够好,所以前几步生成的图片仍包含噪点。这个实际上是因为我们希望在每个采样步中得到一个预期的噪点,而不是一次性完全抹除噪点。这个称为noise schedule。下面是一个例子:
Noise schedule是我们定义的一个选项。我们可以选择在每一个step中剔除等量的噪点。或者是在最开始提出更多的噪点(如上图所示)。采样器每次剔除足够的噪点,以达到下一步中预期的噪点。这便是我们在step-by-step图片中见到的样子。
6.2. 图生图
图生图的方法首先是在SDEdit方法中提出的。SDEdit可以应用到任何扩散模型中。所以我们也有Stable Diffusion的图生图模式。
图生图的输入是一张输入图片以及一组文本提示词。生成的图片会由输入图片以及文本提示词两者共同调节。例如,使用下面的简笔画,以及提示词“带茎、水滴和戏剧性照明的完美绿色苹果照片”作为输入,图生图可以将其转换成专业绘画。
下面是图生图的具体流程。
Step 1. 输入图片编码到潜空间
Step 2. 加入噪点到潜图片。**Denoising strength**控制加入多少噪点。如果为0,则不会加入噪点。如果为1,则会加入最多的噪点,这样潜图片则转为一张完全随机的张量。
Step 3. Noise predictor U-Net使用潜噪点图以及文本提示词作为输入,并预测潜空间内的噪点(一个4 x 64 x 64 的张量)
Step 4. 从潜图片中剔除潜噪点,并生成新的潜图片。
Step 3 与 4 重复多次,直到特定采样步数,例如20次。
Step 5. 最后,VAE的解码器将潜图片转回像素空间,便得到了最终生成的图片。
现在我们知道了图生图的原理,它所要做的便是设置一个初始的、带噪点的潜图片,作为输入图片。如果denoising strength设置为1,则等同于文本生成图了,因为初始的潜图片是完全随机的噪点。
6.2.1. 图像修复
图像修复是图生图里的一个特殊例子。只需将噪点加入到需要被修复的图片。加入多少噪点同样也由denoising strength决定。
6.3. Depth-to-Image
Depth-to-image是图生图的一个增强。它生成的图片时,会使用depth map作为额外的条件。
Step 1. 输入图片编码到潜空间
Step 2. MiDaS(一个是AI深度模型)基于输入图片预测depth map
Step 3. 为潜图片添加噪点。同样,denoising strength控制加入多少噪点。
Step 4. Noise predictor预测潜空间的噪点,由文本提示词与depth map共同调控
Step 5. 从潜图片中剔除噪点,生成新的潜图片
Step 4 与 5 重复特定次数采样步数。
Step 6. VAE decoder解码潜图片,得到最终生成的depth-to-image图片
7. 什么是CFG值
在解释Classifier-Free Guidance(CFG)前,这篇文章仍是不够完整的。CFG是AI艺术家们每天都在调整的一个重要参数。为了明白这个参数是做什么,我们首先了解它的前身:classifier guidance(分类器指导)。
7.1. Classifier Guidance
分类器指导是将图片标签融入扩散模型的一种方法。我们可以使用标签来指导扩散的过程。例如,标签“猫”可以引导反向扩散过程,从而生成猫的照片。
Classifier guidance系数是一个参数,用于控制扩散过程应如何遵循标签。下面是一个从这篇论文paper中摘取的一个例子。假设有3组带标签的图片分别为:“猫”、“狗”、“人”。如果扩散过程没有被指导,则模型会从每个组的所有样本中绘制样本,但有时它可能会画出一张可以适用于两个标签的图片。例如一个男孩抚摸一只狗的图片。
使用更高的classifier guidance系数,由DF模型生成的图片将偏向于极端或是明显的例子。如果我们让模型生成一只猫,则它会返回明显是一只猫的图片而不是其他东西。
Classifier guidance 系数控制了遵循指导的程度。在上图中,右侧的采样比中间的采用有更高的Classifier guidance系数。在实践中,这个比值只是向带有该标签的数据漂移项的乘数。
7.2. Classifier-free guidance
尽管classifier guidance取得了创纪录的性能,但它仍需要一个额外的模型来提供这种指导。也就在训练过程中带来了些困难。
在作者的术语中,Classifier-free guidance是一种实现“没有分类器的分类器指导”的方法。不需要使用类别标签以及额外的模型来做指导,而是提出了使用图片说明并训练一个带条件的扩散模型来取代。这个方式与我们前面提到的“文本生成图”的原理相同。
它们将分类器部分作为noise predictor U-Net的条件,从而在图像生成中实现了称为“classifier-free”(即没有单独的图片分类器)的指导。
文本提示词在“文本生成图”中提供了这个指导。
7.3. CFG值
现在我们知道了通过“条件”实现classifier-free的扩散过程,那该如何控制这个“指导”被follow的程度呢?
Classifier-free guidance(CFG)系数便是控制“文本提示词”条件对扩展过程控制的程度值。在其值设置为0时,图片生成是不附加条件的(即prompt是忽略的)。更高的值会引导扩散过程朝着提示词方向前进。
8. Stable Diffusion v1与v2
下面对比v1与v2的区别。
8.1. 模型区别
SD v2使用OpenClip做文本词嵌入。SD v1使用Open AI的CLIP ViT-L/14做文本词嵌入。
做出此变更的原因:
- OpenClip规模提升了5倍,更大的文本嵌入模型可以提升图片质量
- 尽管Open AI的CLIP模型是开源的,但模型是使用专有数据进行训练的。切换到OpenClip模型可以使研究人员在研究与优化模型时获得更多的透明度,这对于长期发展是更好的
8.2. 训练数据区别
Stable Diffusion v1.4 使用的训练trained数据是:
l 237k steps,分辨率为256 x 256,数据集为laion2B-en
l 194k steps,分辨率为512 x 512,数据集为laion-high-resolution
l 225k steps,分辨率为512 x 512,数据集为laion-aesthetics v2 5+,使用10%的文本条件剔除
Stable Diffusion v2使用的训练数据为trained with:
l 550k steps,分辨率为256 x 256,数据集为 LAION-5B的子集。过滤了明显色情的材料,使用LAION-NSFW classifier(punsafe=0.1参数)以及aesthetic score >= 4.5
l 850k steps,分辨率为512 x 512,在同样的数据集上(分辨率>=512 x 512)
l 150k steps,在同样的数据集上使用 v-objective
l 在 768 x 768 的图片上继续训练140k steps
Stable Diffusion v2.1是基于v2.0进行fine-tune的来:
l 额外55k steps训练,同样数据集(使用punsafe=0.1)
l 另外155k steps,使用punsafe=0.98
基本上,他们在最后的训练步骤中关闭了NSFW过滤器。
8.3. 结果表现的区别
用户发现使用Stable Diffusion v2控制风格以及生成名人通常会更难。虽然Stability AI并没有显式过滤艺术家以及名人的姓名,但它们在v2中的效果要弱得多。这可能是由于训练数据的不同导致的。Open AI的专有数据可能拥有更多的艺术作品和名人照片。他们的数据可能经过了高度过滤,使得每件事和每个人都看起来非常美好。
这里分享给大家一份Adobe大神整理的《AIGC全家桶学习笔记》,相信大家会对AIGC有着更深入、更系统的理解。
有需要的朋友,可以点击下方免费领取!
AIGC所有方向的学习路线思维导图
这里为大家提供了总的路线图。它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。如果下面这个学习路线能帮助大家将AI利用到自身工作上去,那么我的使命也就完成了:
AIGC工具库
AIGC工具库是一个利用人工智能技术来生成应用程序的代码和内容的工具集合,通过使用AIGC工具库,能更加快速,准确的辅助我们学习AIGC
有需要的朋友,可以点击下方卡片免费领取!
精品AIGC学习书籍手册
书籍阅读永不过
时,阅读AIGC经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验,结合自身案例融会贯通。
AI绘画视频合集
我们在学习的时候,往往书籍源码难以理解,阅读困难,这时候视频教程教程是就很适合了,生动形象加上案例实战,科学有趣才能更方便的学习下去。