❝昨天的选择,决定了今天的结局❞
大家好,我是「柒八九」。
许久未见,是否有点想念。
最近,更文速度有点慢,不是说创作到了瓶颈,(放心,原来的各种系列文章都有准备和更文计划
,当然,如果大家有想了解的技术方向也可以评论和私聊。我可以和大家一起学习研究)而是,最近新公司业务比较多,每天下班回来了,有点心力交瘁
了。熟悉博主的都知道,平时的学习和更文都是利用下班时间。
其实,这篇文章的雏形早在3周前
就定了,只是有些地方的行文有点拖沓,本着质量优先的原则。宁愿不发也不想发一些半成品来混文章数量。所以,就一直拖着没有发布。而今天正好空闲了,所以乘热打铁。
本文主要讲述稳定扩散Stable Diffusion的实现原理。
如果,想了解该系列(AI相关)的文章,可以参考我们已经发布的文章。如下是往期文章。
v1
vs v2
「推荐阅读指数」 ⭐️⭐️⭐️⭐️好了,天不早了,干点正事哇。
稳定扩散Stable Diffusion是由StabilityAI
、CompVis
和RunwayML
团队开发的一系列图像生成模型,最初于2022
年发布。它的主要功能是「基于文本输入生成具有美感和细节的图像」,但它还可以执行其他任务,如「修复图像缺失部分」(inpainting
)、「扩展图像」(outpainting
)和「图生图」。
❝简而言之,稳定扩散Stable Diffusion是一个「文本到图像」的模型。给它一个文本提示。它将返回一个与文本相匹配的图像。 ❞
稳定扩散Stable Diffusion属于一类称为扩散模型Diffusion model的深度学习模型。它们是「生成模型」,意味着它们被设计用来生成类似于在训练中所见到的新数据。在稳定扩散的情况下,「数据是图像」。
为什么它被称为 扩散模型Diffusion model?因为它的数学模型非常类似于物理中的扩散过程。
前向扩散Forward Diffusion过程会向训练图像「添加噪声」,逐渐将其转化为不具特征的噪声图像
。前向过程
会将任何猫或狗
图像转化为噪声图像。最终,你将无法确定它们最初是一只狗还是一只猫。
❝就像一滴墨水掉进了一杯水中一样。墨水在水中扩散。几分钟后,它会「随机分布」在整个水中。你无法再判断它最初是掉在中心还是靠近边缘。 ❞
下面是一个图像经过前向扩散Forward Diffusion的示例。猫的图像变成了「随机噪声」。
逆向扩散Reverse Diffusion 就像倒着播放一段视频。「在时间上往回走」。我们将看到墨滴最初被添加的地方。
反向扩散过程恢复了一个图像。
❝从一个
噪声、无意义的图像
开始,逆向扩散Reverse Diffusion 过程可以恢复出一只猫或一只狗的图像。 ❞
从技术上讲,每个扩散过程都有两个部分:
逆向扩散Reverse Diffusion 过程朝着猫或狗图像的方向漂移,但没有中间状态。这就是为什么结果只能是猫或狗的原因。
在我们深入探讨稳定扩散Stable Diffusion的架构和机制之前,让我们快速回顾一下图像生成的历史以及稳定扩散的演变。
2015
年:多伦多大学提出了alignDRAW
。这是一个文本到图像
模型。该模型只能生成模糊的图像,但展示了通过文本输入生成模型“未见过”的图像的可能性。2016
年:Reed、Scott
等人提出了使用「生成对抗网络」(GAN
,一种神经网络结构)生成图像的方法。他们成功地从详细的文本描述中生成了逼真的鸟类和花卉图像。在这项工作之后,一系列基于GAN
的模型被开发出来。2021
年:OpenAI
发布了基于Transformer
架构(另一种神经网络架构)的DALL-E
,引起了公众的关注。2022
年:Google Brain
发布了Imagen
,与OpenAI
的DALL-E
竞争。2022
年:稳定扩散Stable Diffusion被宣布为「潜在空间扩散模型」的改进。由于其开源性质,基于它的许多变体和微调模型被创建,并引起了广泛的关注和应用。2023
年:出现了许多新的模型和应用,甚至超出了文本到图像的范畴,扩展到文本到视频或文本到3D等领域。从时间线上可以看出,「文本到图像」实际上是一个相当年轻的领域。稳定扩散Stable Diffusion的出现是一个重要的里程碑,作为一个开源模型,它需要比之前的模型更少的资源,促进了该领域的指数增长。
稳定扩散Stable Diffusion并不是一个简单的AI模型,它是将不同的神经网络
组合起来的一个过程。我们可以将稳定扩散Stable Diffusion的整个文本到图像生成过程分解为不同的步骤,并逐步解释这些步骤。
让我们从文本到图像生成过程的概述开始。
数字数组
)。文本
为条件,在「潜在空间」中生成新的图像。(即输入文本引导了在潜在空间中图像的生成)。❝每个步骤都使用自己的神经网络完成。 ❞
想象一下,你想让一个外国艺术家为你画一幅画,但你「不懂他们的语言」,你可能会使用谷歌翻译或找一个人来帮助你将你想要表达的内容翻译给他们。
对于图像生成模型来说,情况也是如此——「机器学习模型无法直接理解文本」,因此它们需要一个文本编码器Text Encoder将你的「文本指令转换为它们可以理解的数字」。这些数字不是随机的数字,它们被称为「文本嵌入」,是能够捕捉文本的语义含义(即词与其上下文之间的关系)的高维向量。
将文本转换为嵌入向量
可以有多种方法。稳定扩散Stable Diffusion使用了一个Transformer
大型语言模型来完成这个任务。如果你对语言模型有所了解,你可能对Transformer
这个术语感到熟悉——它是GPT
的基础架构。如果想了解更多的关于ChatGPT
的相关原理。可以参考ChatGPT:你应该知道的知识
事实上,稳定扩散Stable Diffusionv1
使用了CLIP
,这是OpenAI
基于GPT
开发的模型。稳定扩散Stable DiffusionV2
使用了OpenClip
,一个更大的CLIP
版本。
这些「编码器模型在包含数十亿个文本和图像对的大型数据集上进行训练」,以便学习我们用来描述图像的单词和短语的含义。数据集来自于网络上的图像,以及我们用来描述这些图像的图像标签(alt
标签)。
❝扩散模型Diffusion model是稳定扩散的「核心组成部分」,它是综合图像的组件。 ❞
为了训练扩散模型,有两个过程:
在稳定扩散Stable Diffusion中,这两个过程都在「潜在空间」中进行,以提高速度。
❝在前向扩散Forward Diffusion过程中,模型逐渐向图像添加
高斯噪声
,将清晰的图像转变为噪声图像。在每个步骤中,图像都会添加少量的噪声,并在多个步骤中重复此过程。 ❞
正如“扩散”一词所暗示的那样,这个过程就像是将一滴墨水滴入水中,墨水逐渐在水中扩散,直到你无法再看到它最初是一滴墨水的痕迹。「添加到图像中的噪声模式是随机的」,就像墨水颗粒随机扩散到水颗粒中一样,但「可以控制噪声的数量」。此过程在LAION
数据集的许多图像上进行,每个图像都添加不同数量的噪声,以创建大量噪声样本来训练逆向扩散Reverse Diffusion模型。
❝在逆向扩散Reverse Diffusion 过程中,训练了一个噪声预测器Noise Predictor,用于预测添加到原始图像的噪声,以便模型可以「从噪声图像中去除预测的噪声」,得到一个更清晰的图像(在
潜在空间
中)。你可以将这个过程想象成观察部分扩散的墨水滴在水中,并试图预测它之前所在的位置。 ❞
噪声预测器Noise Predictor是基于ResNet
骨干结构的U-Net
(一种神经网络架构)。
噪声预测器Noise Predictor训练过程如下所示:
调整其权重
并向其展示正确答案来完成的。噪声在每一步都是依次加入的。噪声预测器
估计到每一步加入的总噪声。
经过训练,我们有一个能够估计添加到图像中的噪声的噪声预测器Noise Predictor。
它在之前通过前向扩散Forward Diffusion准备的训练数据集上进行训练,其目标是尽可能准确地估计噪声,以使去噪后的图像尽可能接近原始图像。一旦训练完成,它将在其权重中“记住”图像表示,并可以用于从随机的初始噪声图像张量“生成”图像。实际的图像和图像质量在很大程度上取决于原始图像数据集,因为它试图回到原始图像。这个逆向扩散过程逐步进行多个步骤,以去除噪声。进行更多的去噪步骤,图像变得越来越清晰。
在获取更清晰图像的逆向扩散Reverse Diffusion过程中,研究人员希望通过一种称为「条件化的过程」来控制图像的外观。如果我们使用文本,这个过程被称为「文本条件化」。它通过将文本编码步骤中的文本嵌入
传递给U-Net
,并通过「交叉注意机制」进行操作。
交叉注意机制
基本上将文本嵌入
与逆向扩散Reverse Diffusion每个步骤的结果进行合并。例如,如果你有一个输入提示“猫”,你可以将条件化
理解为告诉噪声预测器Noise Predictor:“对于下一个去噪步骤,图像应该更像一只猫。现在进行下一步。”条件化也可以通过除文本以外的其他指导方式进行,例如图像、语义地图、表示等。
由于我们进行的扩散
和条件化
都是在「潜在空间」中进行的,所以我们无法直接查看生成的图像。我们需要将潜在图像转换回我们可以看到的像素。这个转换是通过图像解码器Image Decoder完成的。
在稳定扩散Stable Diffusion中,这个转换器是一个「变分自动编码器」(VAE
)。在早期的前向扩散Forward Diffusion过程中,我们使用VAE
的编码器部分将原始的训练图像从像素转换为潜在空间,以添加噪声。现在,我们使用VAE
的解码器部分将潜在图像转换回像素。
变分自编码器Variational Autoencoder(VAE
)神经网络包含两个部分:
变量自动编码器将图像转换到潜伏空间,并从潜伏空间转换出来。
稳定扩散Stable Diffusion模型的潜在空间是4x64x64
,比图像像素空间小48倍。「所有前向和逆向扩散实际上都是在潜在空间中进行的」。
因此,在训练过程中,它不是生成一个带有噪声的图像,而是在潜在空间中生成一个随机张量Tensor(潜在噪声)。它不是用噪声破坏图像,而是用潜在噪声破坏图像在潜在空间中的表示。这样做的原因是速度更快,因为潜在空间更小。
❝在深度学习里,
Tensor
实际上就是一个多维数组。 而Tensor
的目的是能够「创造更高维度的矩阵、向量」。 ❞❝稳定扩散Stable Diffusion将所有的处理、扩散和条件化都在「潜在空间」中进行,而不是在像素空间中进行的原因是潜在空间更小。这样我们可以更快地进行这个过程,而不需要消耗大量的计算资源。 ❞
如果没有文本提示,稳定扩散Stable Diffusion就不是一个文本到图像的模型。你将只会得到一张猫或狗的图片,没有任何控制它的方法。
这就是条件控制Conditioning的作用。
❝
条件控制
的目的是引导噪声预测器,使得在从图像中减去预测的噪声后,我们可以得到我们想要的结果。 ❞
下面是一个概述,说明了文本提示是如何被处理并输入到噪声预测器中的。
token
)的数字。向量
,称为嵌入embedding。这些嵌入向量接着被文本转换器处理,并准备好供噪声预测器使用。如何处理文本提示并将其输入噪声预测器以引导图像生成。
文本提示首先通过CLIP
分词器进行分词。CLIP
是OpenAI
开发的一个深度学习模型,用于生成任何图像的文本描述。稳定扩散Stable Diffusion v1
使用了CLIP
的分词器。
分词是计算机理解单词的方式。我们人类可以读取单词,但计算机只能读取数字。这就是为什么文本提示中的单词首先被转换为数字。
分词器只能对其在训练期间见过的单词进行分词。例如,CLIP
模型中有“dream”
和“beach”
,但没有“dreambeach”
。分词器会将单词“dreambeach”
分割为两个标记“dream”
和“beach”
。因此,一个单词并不总是对应一个标记!
另一个需要注意的细节是空格字符也是标记的一部分。在上述情况中,短语“dream beach”
产生了两个标记“dream”
和“[space]beach
”。这些标记与“dreambeach”
产生的标记“dream”
和“beach”
(beach之前没有空格)不同。
❝稳定扩散Stable Diffusion模型限制了文本提示中使用的标记数量为
75
个。 ❞
稳定扩散Stable Diffusion v1
使用了OpenAI
的ViT-L/14 CLIP
模型。嵌入embedding是一个包含768
个值的向量
。每个标记都有其自己独特的嵌入embedding向量。嵌入embedding是由CLIP
模型固定的,在训练过程中学习得到。
为什么我们需要嵌入embedding?这是因为某些单词彼此之间密切相关。我们希望利用这些信息。例如,man
(男人)、gentleman
(绅士)和guy
(家伙)的嵌入几乎相同,因为它们可以互换使用。
将嵌入投喂给噪声预测器
在输入嵌入向量到噪声预测器
之前,嵌入
需要经过文本变换器的进一步处理。这个「变换器就像一个通用的适配器,用于条件控制」。在这种情况下,它的输入是文本嵌入向量,但它也可以是其他东西,比如类别标签、图像和深度图。变换器不仅进一步处理数据,还提供了一种包含不同条件模态的机制。
文本变换器的输出在整个U-Net
中被噪声预测器多次使用。U-Net
通过交叉注意Cross-attention 机制来利用它。这就是prompt
与图像相遇的地方。
以提示“一个有蓝眼睛的男人”为例。稳定扩散Stable Diffusion将“蓝”和“眼睛”这两个词进行配对(在提示内部进行自我注意),这样它就生成了一个有蓝眼睛的男人,而不是一个穿着蓝色衬衫的男人。然后,它利用这个信息来引导逆向扩散Reverse Diffusion朝着包含蓝眼睛的图像方向进行。(prompt
和图像之间的交叉注意)
到目前为止,我们对前向扩散Forward Diffusion中的训练过程以及如何根据文本输入在逆向扩散Reverse Diffusion过程中生成图像有了更好的理解。但这只是个开始,更有趣的部分是我们如何根据我们的需求调整这个过程,以「产生更高质量的图像」。研究人员和爱好者提出了许多不同的技术来改善稳定扩散的结果。
这些方法中的大多数是在「已经训练好的稳定扩散模型的基础上进行」的。训练好的模型意味着它已经看到并学会了如何使用其模型权重(指导模型工作的数字)生成图像。
其中一组技术是针对稳定扩散Stable Diffusion的文本编码器Text Encoder部分的,包括文本反演
和DreamArtist
。
DreamArtist
通过「学习正面和负面关键词」来描述参考图像。这就像是告诉翻译器“这是一张图片,记住它的样子,并称呼它为你认为最能描述它的名字”。U-Net
(噪声预测器部分)另一组技术主要针对U-Net
,即图像生成组件
,包括DreamBooth
、LoRA
和Hypernetworks
。
DreamBooth
通过使用新图像数据集
对扩散模型进行「微调」,直到它能理解新概念。LoRA
通过在交叉注意模型
中添加一小组额外的「权重」,并仅训练这些额外的权重。Hypernetworks
使用一个「辅助网络来预测新的权重」,并利用噪声预测器Noise Predictor中的交叉注意部分插入新的样式。这些方法基本上是告诉艺术家学习一些新的绘画方式,要么是自己学习(DreamBooth
),要么是调整现有的样式(LoRA
),要么是通过外部帮助(Hypernetworks
)。DreamBooth
非常有效,但需要更多的存储空间,而LoRA
和Hypernetworks
的训练相对较快,因为它们不需要训练整个稳定扩散模型。
另一个技术是通过「控制噪声来改善生成图像的方法」,包括DALL-E 2
和Diffusion Dallying
。
DALL-E 2
是对原始的DALL-E
模型的改进,通过对噪声进行控制来生成更具指导性的图像。Diffusion Dallying
则是在逆向扩散Reverse Diffusion过程中加入额外的迭代步骤,使模型有更多的时间去学习并生成更高质量的图像。这些方法通过更好地控制噪声的引入和图像生成的迭代过程来改善稳定扩散的结果。
除了上述方法外,还有其他一些技术可用于改进稳定扩散的结果,例如使用更大的模型,优化训练策略,调整超参数等。这些「技术的目标是通过不断改进稳定扩散的各个组件和流程,以获得更高质量、更符合预期的图像生成结果」。
❝总而言之,稳定扩散的结果可以通过改进
文本编码器
、U-Net
、噪声控制
以及其他技术来提升。这些技术可以根据具体需求选择和应用,以实现更好的图像生成效果。 ❞
刚才我们从上帝视角审视扩散模型Diffusion model的内部机制,让我们来看一些具体的示例,了解其运作方式。
在文本到图像的过程中,你给扩散模型Diffusion model一个文本提示,它会返回一张图像。
第一步:稳定扩散Stable Diffusion在「潜在空间」中生成一个随机张量Tensor。
你可以通过设置「随机数生成器的种子」来控制这个张量
。如果你将种子设置为特定的值,每次都会得到相同的随机张量。这个张量代表了潜在空间中的图像,但目前只是一片噪声。
在潜伏空间产生一个随机张量
第二步:噪声预测器Noise Predictor 也就是 U-Net
接收潜在噪声图像
和文本提示
作为输入,并预测出潜在空间
中的噪声(一个4x64x64
的张量)。
第三步:从潜在图像
中减去潜在噪声
。这将成为你的新潜在图像。
第二步和第三步将「重复进行一定次数的采样步骤」,例如20次。
第四步:最后,VAE
的解码器将潜在图像转换回像素空间。这就是在运行稳定扩散Stable Diffusion之后得到的图像。
以下是图像在每个采样步骤中的演变情况。
图像从嘈杂变为清晰。真正的原因是我们在每个采样步骤中尝试得到预期的噪声。这就是「噪声调度」。
下面是一个例子。
噪声调度是我们自己定义的。我们可以选择在每个步骤中减去相同数量的噪声。或者我们可以在开始时减去更多的噪声,就像上面的例子。采样器
在每个步骤中减去恰好足够的噪声,以达到下一个步骤中的预期噪声。这就是你在上面图像中看到的过程。
「图生图」是首次在SDEdit
方法中提出的一种方法。SDEdit
可以应用于任何扩散模型。因此,我们可以使用「图生图」方法来进行稳定扩散
。
「图生图」的输入包括输入图像和文本提示。生成的图像将「同时受到输入图像和文本提示的约束」。
例如,使用左侧的简单图片和提示Prompt为“拍摄完美绿色苹果带茎、水滴和戏剧性灯光”的输入,「图生图」可以将其转换为专业绘画:
下面是详细的处理过程。
第一步:将输入图像编码Encoder到「潜在空间」中。
第二步:向「潜在图像」中添加噪声。去噪强度控制添加了多少噪声。如果去噪强度为0,不会添加任何噪声。如果去噪强度为1,将添加最大量的噪声,使潜在图像变成完全随机的张量。
第三步:噪声预测器Noise Predictor 也就是 U-Net
以潜在的噪声图像和文本提示作为输入,并预测潜在空间中的噪声(一个4x64x64
的张量)。
第四步:从潜在图像中减去潜在噪声。这成为你的新潜在图像。
第三步和第四步会重复执行一定数量的采样步骤,例如,重复20次。
第五步:最后,VAE
的解码器将潜在图像转换回像素空间。这就是在运行图像到图像的过程中得到的图像。
❝「图生图」的含义:它的主要作用是在初始潜在图像中添加一些噪声和一些输入图像。将去噪强度设置为1等同于「文本到图像」(
text-to-image
)的过程,因为初始潜在图像完全是随机噪声。 ❞
修复Inpainting实际上只是「图生图」的一个特殊情况。噪声被添加到需要修复的图像部分。噪声的量同样由去噪强度控制。
深度到图像Depth-to-image是对「图生图」的增强,它利用「深度图」进行附加的条件约束生成新的图像。
步骤1:将输入图像编码为潜在状态latent state。
第2步。MiDaS
(一种AI深度模型)从输入图像中估计深度图。
第3步。向潜在图像添加噪声。去噪强度控制添加的噪声量。如果去噪强度为0,则不添加噪声。如果去噪强度为1,则添加最大噪声,使潜在图像成为随机张量。
第4步。噪声预测器Noise Predictor根据文本提示和深度图来估计潜在空间的噪声。
第5步。从潜在图像中减去潜在噪声,得到新的潜在图像。
第4步和第5步在采样步骤中重复进行。
第6步。VAE
的解码器将潜在图像解码。现在你从深度到图像得到了最终的图像。
CFG是无需分类器辅助Classifier-Free Guidance的简称。为了理解CFG是什么,我们需要首先了解它的前身,分类器辅助
。
分类器辅助
是在扩散模型Diffusion model中将「图像标签」纳入考虑的一种方式。你可以使用标签来指导扩散过程。例如,标签“猫”将引导逆向扩散Reverse Diffusion 过程生成猫的照片。
❝分类器辅助尺度是一个参数,用于控制扩散过程应该多大程度上遵循标签。 ❞
假设有3组带有标签“猫”、“狗”和“人类”的图像。如果扩散是未引导的,模型将从每个组的总体中抽取样本,但有时可能会生成适合两个标签的图像,例如一个男孩抚摸一只狗的图像。
分类器指导。左:无引导。中间:小的引导尺度。右图:大引导比例
在高分类器辅助下,扩散模型Diffusion model生成的图像会偏向极端或明确的示例。如果你要求模型生成一只猫的图像,它将返回一张明确是猫而不是其他东西的图像。
分类器辅助尺度控制着辅助的紧密程度。在上面的图中,右侧的采样比中间的采样具有更高的分类器辅助尺度。在实践中,这个尺度值只是对朝着具有该标签数据的漂移项的乘法因子。
无分类器辅助(CFG)尺度是一个值,用于控制文本提示对扩散过程的影响程度。当该值设为0时,图像生成是无条件的(即忽略了提示)。较高的值将扩散过程引导向提示的方向。
Stable Diffusion v2
使用OpenClip
进行文本嵌入,而Stable Diffusion v1
使用Open AI
的CLIP ViT-L/14
进行文本嵌入。这个改变的原因如下:
OpenClip
的模型比CLIP
模型大五倍。更大的文本编码器模型可以提高图像质量。Open AI
的CLIP
模型是开源的,但这些模型是使用专有数据进行训练的。切换到OpenClip
模型使研究人员在研究和优化模型时拥有更多的透明度,有利于长期的发展。Stable Diffusion v1.4
在以下数据集上进行训练:laion2B-en
数据集上进行了237,000个步骤,分辨率为256×256
。laion-high-resolution
数据集上进行了194,000
个步骤,分辨率为512×512
。Stable Diffusion v2
在以下数据集上进行训练:LAION-5B
子集上进行了550,000个步骤,分辨率为256x256,使用LAION-NSFW
分类器进行筛选,设置punsafe=0.1
,美学评分>=4.5。v-objective
在相同数据集上进行了150,000个步骤。768x768
的图像上再进行了额外的140,000
个步骤。Stable Diffusion v2.1
在v2.0的基础上进行了微调,包括:punsafe=0.1
)。punsafe=0.98
),最后关闭了NSFW过滤器。在本文中,我试图用简单的术语解释稳定扩散的工作原理。以下是一些要点:
文本反演
和DreamArtist,以及在扩散模型上进行的LoRA
、DreamBooth
和Hypernetworks
。而这些技术列表还在不断增长。「分享是一种态度」。
参考资料: