寒夏摸鱼站

Stable Diffusion 拆解分析笔记 #2

2024年09月30日

上一章 中我们讨论了什么是扩散(Diffusion),这一章我们来深入 Diffusion 的技术细节

Diffusion 的工作原理

我们知道 Diffusion 是一个针对随机张量的降噪过程,它需要针对张量多次运行以达成最终的扩散张量

与直接通过类似于高斯过滤器等传统过滤器降噪方法不同,Diffusion 依赖的是一个 UNet 模型
更进一步的,UNet 模型并不是输入噪声图片输出降噪图片,它实际上是一个 噪声预测模型

通过预测一张有噪声的图片所含有的可能噪声图,将 原图减去噪声图,就可以得到一个去噪图像

Diagram

通过迭代地进行噪声预测+减去噪声,最终噪声会趋于平静,对输入图片几乎不会产生影响,也就完成了最终的扩散

Diagram

但是以上过程其实还缺失了一个部分,具体是什么请继续看下一节

如何训练 UNet 模型

既然 Diffusion 使用的是噪声预测原理,那么这个模型是怎么训练出来的?

训练数据集处理

我们知道 UNet 输入的是一个加噪图片,输出的是预测的噪声图,那么我们就可以利用已有图片来生成一整套训练数据集了,具体步骤如下:

  1. 选择一张无噪图片
  2. 随机生成一个与 大小相同的噪声 ,一般会使用高斯噪声
  3. 随机选择一个 0 到 1 的系数 ,它决定了最终混合出来的加噪图片的噪声比重
  4. 基于 混合 ,即 ,得到加噪图片

显然,以上的图片加噪用的是加性噪声过程,且一张图片可以通过不同的随机 生成多种不同的训练数据

在实际过程中, 是一个整数,你可以将其看作把 0~1 数值当成 个离散采样点,表示噪声等级
时,有 0~4 共 5 个等级,分别表示 的噪声混合比例,当然最后的完全噪声我们一般不会使用

那么我们就可以要求模型接收 作为输入, 作为预测输出,通过比较 进行反向传播学习,这对于目前的机器学习来说并不是难事

Diagram

这里我们可以看见 UNet 除了输入的噪声图像,还需要一个噪声等级 ,但是我们之前的工作原理讲解中并没有出现
这就是我们在上一节中说的 “缺失”

通过训练过程我们可以知道, 越大,噪声越强,回想 Diffusion 的工作过程,什么时候输入图片的噪声是最强的?
当然是一开始的时候,之后随着降噪过程,噪声会越来越弱,直到最后到达几乎稳定

假设我们的 Diffusion 一共有 轮,那么我们只需要让输入的 一开始为 ,然后每过一步使输入的 比上一步少 1,到最后一步结束之后我们的 就变成 0 了,此时根据我们对 UNet 训练过程的学习,我们可以认为此时已经完成了从原图到最弱的噪声预测过程
因此我们可以大概率地保证我们最后一步输出的应该是完全实现了降噪的图片,也就是我们最终的输出图片

Diagram

加速训练

根据上面的过程,我们已经可以轻松实现对应的训练了,但是如果对于每一个 3x512x512 的图片都进行 UNet 训练,一共需要输入和计算 786,432 个参数
如此多的参数会极大地影响训练速度,因此我们不会在一般的像素空间中对 UNet 的进行训练,而是先将图片映射到一个 低维潜空间 中,然后使用潜空间数据进行 UNet 训练,到需要输出图片的时候,再将潜空间数据重新映射回像素空间中

如果你对上一章还有印象的话,可以知道这个低维的潜空间张量是 4x64x64,一共只有 16,384(~16k)个参数,可比之前差不多 786k 个参数高到不知道哪里去了

Diagram

这里我们用的一对编码器和解码器就是 自编码器,特别的在 SD 中你更常见的叫 VAE(变分自编码器)

在将图片编码至潜空间之后,我们训练时的加噪过程也应该在潜空间中完成了,整个模型将变成 在潜空间中进行噪声预测

通过这一对自编码器,我们可以压缩 UNet 的尺寸以加速训练过程,同时也可以获得更小的模型尺寸

小结

这一章我们谈论了 Diffusion 相关的工作和训练原理,下一章我们将研究 SD 的主要交互入口 —— CLIP 编码器

文章标题:Stable Diffusion 拆解分析笔记 #2

文章链接:https://blog.rainiar.top/posts/30/

最近修改:未曾修改过

分享协议:CC BY-NC-SA 4.0 | 署名-非商业使用-相同方式共享