最近在整理大模型的相关资料,发现了几个名词,不是很懂,这里整理一下:
stable diffusion(SD)模型:
扩散模型(Diffusion model)的一种,主要用于生成高质量的图像,GAN的替代者,扩散模型通过一些列学习步骤生成数据,逐渐从噪声中生成目标图像。
主要原理:
扩散模型主要分成两个阶段:前向过程(forward process) 和反向过程(reverse process)
1.前向过程(noise adding process):在这个过程中,模型逐步将高质量的图像添加噪声,直到图像完全变成噪声。这是一个可控的Markov链过程,也就是说图像经过一定数量的时间步骤后变成了纯噪声数据。
2.反向过程(noise removing process):反向过程即为生成过程。在这个阶段,模型学习如何将前向过程中得到的噪声数据逆向转化为清晰的图像,通过神经网络的训练,学习从噪声中移除噪声并恢复出原始图像。
要解决的问题:
扩散模型,包括stable diffusion模型,旨在解决如何生成高质量、高分辨率、具有多样性的图像问题。与传统的GAN相比,扩散模型通常能够更好的处理图像的细节,并在训练时更加稳定。
扩散模型不需要使用对抗性训练,而是依赖变分下降路径(variational lower bound),使得模型在训练过程中更加稳定,扩散模型的优势是可以避免GAN的一些模式崩溃(mode collapse)、训练不稳定的问题。
总的来说,扩散模型通过模仿如何将数据转化成噪声和如何从噪声中恢复数据的过程,以一种稳定而有效的方式生成质量高的图像。在艺术创作、游戏开发、数据增强等多个领域有潜在的应用价值。
Stable Diffusion出现之前的扩散模型虽然已经有非常强的生成能力与泛化性能,但缺点是不管是前向扩散过程还是反向扩散过程,都需要在像素级的图像上进行,当图像分辨率和Timesteps很大时,不管是训练还是前向推理,都非常的耗时。
而基于Latent的扩散模型可以将这些过程压缩在低维的Latent隐空间,这样一来大大降低了显存占用和计算复杂度,这是常规扩散模型和基于Latent的扩散模型之间的主要区别,也是SD模型火爆出圈的关键一招。
举个形象的例子理解一下,如果SD模型将输入数据压缩的倍数设为8,那么原本尺寸为[3,512,512]的数据就会进入[3,64,64]的Latent隐空间中,显存和计算量直接缩小64倍,整体效率大大提升。也正是因为这样,SD模型能够在2080Ti级别的显卡上进行前向推理,生成各种各样精美的图像,大大推动了SD模型的普惠与AI绘画生态的繁荣。
Stable Diffusion整体的训练逻辑也非常清晰:
- 从数据集中随机选择一个训练样本
- 从K个噪声量级随机抽样一个timestep
- 将timestep 对应的高斯噪声添加到图片中
- 将加噪图片输入U-Net中预测噪声
- 计算真实噪声和预测噪声的L2损失
- 计算梯度并更新SD模型参数
【1】SD训练集加入噪声
SD模型训练时,我们需要把加噪的数据集输入模型中,每一次迭代我们用random函数生成从强到弱各个强度的噪声,通常来说会生成0-1000一共1001种不同的噪声强度,通过Time Embedding嵌入到SD的训练过程中。
Time Embedding由Timesteps(时间步长)编码而来,引入Timesteps能够模拟一个随时间逐渐向图像加入噪声扰动的过程。每个Timestep代表一个噪声强度(较小的Timestep代表较弱的噪声扰动,而较大的Timestep代表较强的噪声扰动),通过多次增加噪声来逐渐改变干净图像的特征分布。
【2】SD训练中加噪与去噪
具体地,在训练过程中,我们首先看一下前向扩散过程,主要是对干净样本进行加噪处理,采用多次逐步增加噪声的方式,直至干净样本转变成为纯噪声。
接着,在前向扩散过程进行的每一步中,SD同样进行反向扩散过程。SD模型在每一步都会预测当前步加入的噪声,不断学习提升去噪能力。
其中,将去噪过程具像化,就得到使用U-Net预测噪声,并结合Schedule算法逐步去噪的过程
以看到,加噪和去噪过程都是逐步进行的,我们假设进行�步,那么每一步,SD都要去预测噪声,从而形成“小步快跑的稳定去噪”,类似于移动互联网时代的产品逻辑,这是足够伟大的关键一招。
与此同时,在加噪过程中,每次增加的噪声量级可以不同,假设有5种噪声量级,那么每次都可以取一种量级的噪声,增加噪声的多样性,如下图所示:
多量级噪声
那么怎么让网络知道目前处于的哪一步呢?本来SD模型其实需要K个噪声预测模型,这时我们可以增加一个Time Embedding(类似Positional embeddings)进行处理,通过将timestep编码进网络中,从而只需要训练一个共享的U-Net模型,就让网络知道现在处于哪一步。
我们希望SD中的U-Net模型在刚开始的反向扩散过程中可以先生成一些物体的大体轮廓,随着反向扩散过程的深入,在即将完成完整图像的生成时,再生成一些高频的特征信息。
我们了解了训练中的加噪和去噪过程,SD训练的具体过程就是对每个加噪和去噪过程进行梯度计算,从而优化SD模型参数,如下图所示分为四个步骤:
- 从训练集中选取一张加噪过的图片和噪声强度(timestep),然后将其输入到U-Net中。
- 让U-Net预测噪声(下图中的U-Net Prediction)。
- 接着再计算预测噪声与真实噪声的误差(loss)。
- 最后通过反向传播更新U-Net的权重参数。
【3】文本信息对图片生成的控制
SD模型在生成图片时,需要输入prompt提示词,那么这些文本信息是如何影响图片的生成呢?
答案非常简单:通过注意力机制。
在SD模型的训练中,每个训练样本都会对应一个文本描述的标签,我们将对应标签通过CLIP Text Encoder输出Text Embeddings,并将Text Embeddings以Cross Attention的形式与U-Net结构耦合并注入,使得每次输入的图片信息与文本信息进行融合训练,如下图所示:
Noise与Text Embeddings通过CrossAttention与U-Net结构耦合
【4】SD模型训练时的输入
有了上面的介绍,我们在这里可以小结一下SD模型训练时的输入,一共有三个部分组成:图片、文本以及噪声强度。其中图片和文本是固定的,而噪声强度在每一次训练参数更新时都会随机选择一个进行叠加。
U-net模型
【1】Stable Diffusion中U-Net的核心作用
在Stable Diffusion中,U-Net模型是一个关键核心部分,能够预测噪声残差,并结合Sampling method(调度算法:PNDM,DDIM,K-LMS等)对输入的特征矩阵进行重构,逐步将其从随机高斯噪声转化成图片的Latent Feature。
具体来说,在前向推理过程中,SD模型通过反复调用 U-Net,将预测出的噪声残差从原噪声矩阵中去除,得到逐步去噪后的图像Latent Feature,再通过VAE的Decoder结构将Latent Feature重建成像素级图像
【2】Stable Diffusion中U-Net模型的完整结构图
Stable Diffusion中的U-Net,在传统深度学习时代的Encoder-Decoder结构的基础上,增加了ResNetBlock(包含Time Embedding)模块,Spatial Transformer(SelfAttention + CrossAttention + FeedForward)模块以及CrossAttnDownBlock,CrossAttnUpBlock和CrossAttnMidBlock模块。
那么各个模块都有什么作用呢?不着急,咱们先看看SD U-Net的整体架构(AIGC算法工程师面试核心考点)。
下图是Stable Diffusion U-Net的完整结构图,大家可以感受一下其魅力,看着这个完整结构图学习Stable Diffusion U-Net部分,相信大家脑海中的思路也会更加清晰:
上图中包含Stable Diffusion U-Net的十四个基本模块:
- GSC模块:Stable Diffusion U-Net中的最小组件之一,由GroupNorm+SiLU+Conv三者组成。
- DownSample模块:Stable Diffusion U-Net中的下采样组件,使用了Conv(kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))进行采下采样。
- UpSample模块:Stable Diffusion U-Net中的上采样组件,由插值算法(nearest)+Conv组成。
- ResNetBlock模块:借鉴ResNet模型的“残差结构”,让网络能够构建的更深的同时,将Time Embedding信息嵌入模型。
- CrossAttention模块:将文本的语义信息与图像的语义信息进行Attention机制,增强输入文本Prompt对生成图片的控制。
- SelfAttention模块:SelfAttention模块的整体结构与CrossAttention模块相同,这是输入全部都是图像信息,不再输入文本信息。
- FeedForward模块:Attention机制中的经典模块,由GeGlU+Dropout+Linear组成。
- BasicTransformer Block模块:由LayerNorm+SelfAttention+CrossAttention+FeedForward组成,是多重Attention机制的级联,并且也借鉴ResNet模型的“残差结构”。通过加深网络和多Attention机制,大幅增强模型的学习能力与图文的匹配能力。
- Spatial Transformer模块:由GroupNorm+Conv+BasicTransformer Block+Conv构成,ResNet模型的“残差结构”依旧没有缺席。
- DownBlock模块:由两个ResNetBlock模块组成。
- UpBlock_X模块:由X个ResNetBlock模块和一个UpSample模块组成。
- CrossAttnDownBlock_X模块:是Stable Diffusion U-Net中Encoder部分的主要模块,由X个(ResNetBlock模块+Spatial Transformer模块)+DownSample模块组成。
- CrossAttnUpBlock_X模块:是Stable Diffusion U-Net中Decoder部分的主要模块,由X个(ResNetBlock模块+Spatial Transformer模块)+UpSample模块组成。
- CrossAttnMidBlock模块:是Stable Diffusion U-Net中Encoder和ecoder连接的部分,由ResNetBlock+Spatial Transformer+ResNetBlock组成。
为大家全面分析SD模型中U-Net结构的核心知识
(1)ResNetBlock模块
在传统深度学习时代,ResNet的残差结构在图像分类,图像分割,目标检测等主流方向中几乎是不可或缺,其简洁稳定有效的“残差思想”终于在AIGC时代跨过周期,在SD模型的U-Net结构中继续繁荣。
值得注意的是,Time Embedding正是输入到ResNetBlock模块中,为U-Net引入了时间信息(时间步长T,T的大小代表了噪声扰动的强度),模拟一个随时间变化不断增加不同强度噪声扰动的过程,让SD模型能够更好地理解时间相关性。
同时,在SD模型调用U-Net重复迭代去噪的过程中,我们希望在迭代的早期,能够先生成整幅图片的轮廓与边缘特征,随着迭代的深入,再补充生成图片的高频和细节特征信息。由于在每个ResNetBlock模块中都有Time Embedding,就能告诉U-Net现在是整个迭代过程的哪一步,并及时控制U-Net够根据不同的输入特征和迭代阶段而预测不同的噪声残差。
在上面的Stable Diffusion U-Net完整结构图中展示了完整的ResNetBlock模块,其输入包括Latent Feature和 Time Embedding。首先Latent Feature经过GSC(GroupNorm+SiLU激活函数+卷积)模块后和Time Embedding(经过SiLU激活函数+全连接层处理)做加和操作,之后再经过GSC模块和Skip Connection而来的输入Latent Feature做加和操作,进行两次特征融合后最终得到ResNetBlock模块的Latent Feature输出,增强SD模型的特征学习能力。
同时,和传统深度学习时代的U-Net结构一样,Decoder结构中的ResNetBlock模块不单单要接受来自上一层的Latent Feature,还要与Encoder结构中对应层的ResNetBlock模块的输出Latent Feature进行concat操作。举个例子,如果Decoder结构中ResNetBlock Structure上一层的输出结果的尺寸为 [512, 512, 1024],Encoder结构对应 ResNetBlock Structure的输出结果的尺寸为 [512, 512, 2048],那么这个Decoder结构中ResNeBlock Structure得到的Latent Feature的尺寸为 [512, 512, 3072]。
(2)CrossAttention模块
CrossAttention模块是我们使用输入文本Prompt控制SD模型图片内容生成的关键一招。
上面的Stable Diffusion U-Net完整结构图中展示了Spatial Transformer(Cross Attention)模块的结构。Spatial Transformer模块和ResNetBlock模块一样接受两个输入:一个是ResNetBlock模块的输出,另外一个是输入文本Prompt经过CLIP Text Encoder模型编码后的Context Embedding。
两个输入首先经过Attention机制(将Context Embedding对应的语义信息与图片中对应的语义信息相耦合),输出新的Latent Feature,再将新输出的Latent Feature与输入的Context Embedding再做一次Attention机制,从而使得SD模型学习到了文本与图片之间的特征对应关系。
Spatial Transformer模块不改变输入输出的尺寸,只在图片对应的位置上融合了语义信息,所以不管是在传统深度学习时代,还是AIGC时代,Spatial Transformer都是将本文与图像结合的一个“万金油”模块。
看CrossAttention模块的结构图,大家可能会疑惑为什么Context Embedding用来生成K和V,Latent Feature用来生成Q呢?
原因也非常简单:因为在Stable Diffusion中,主要的目的是想把文本信息注入到图像信息中里,所以用图片token对文本信息做 Attention实现逐步的文本特征提取和耦合。
3)BasicTransformer Block模块
BasicTransformer Block模块是在CrossAttention子模块的基础上,增加了SelfAttention子模块和Feedforward子模块共同组成的,并且每个子模块都是一个残差结构,这样除了能让文本的语义信息与图像的语义信息更好的融合之外,还能通过SelfAttention机制让模型更好的学习图像数据的特征。
写到这里,可能还有读者会问,Stable Diffusion U-Net中的SelfAttention到底起了什么作用呀?
首先,在Stable Diffusion U-Net的SelfAttention模块中,输入只有图像信息,所以SelfAttention主要是为了让SD模型更好的学习图像数据的整体特征。
再者,SelfAttention可以将输入图像的不同部分(像素或图像Patch)进行交互,从而实现特征的整合和全局上下文的引入,能够让模型建立捕捉图像全局关系的能力,有助于模型理解不同位置的像素之间的依赖关系,以更好地理解图像的语义。
在此基础上,SelfAttention还能减少平移不变性问题,SelfAttention模块可以在不考虑位置的情况下捕捉特征之间的关系,因此具有一定的平移不变性。
(4)Spatial Transformer模块
更进一步的,在BasicTransformer Block模块基础上,加入GroupNorm和两个卷积层就组成Spatial Transformer模块。Spatial Transformer模块是SD U-Net中的核心Base结构,Encoder中的CrossAttnDownBlock模块,Decoder中的CrossAttnUpBlock模块以及CrossAttnMidBlock模块都包含了大量的Spatial Transformer子模块。
在生成式模型中,GroupNorm的效果一般会比BatchNorm更好,生成式模型通常比较复杂,因此需要更稳定和适应性强的归一化方法。
而GroupNorm主要有以下一些优势,让其能够成为生成式模型的标配:
1. 对训练中不同Batch-Size的适应性:在生成式模型中,通常需要使用不同的Batch-Size进行训练和微调。这会导致 BatchNorm在训练期间的不稳定性,而GroupNorm不受Batch-Size的影响,因此更适合生成式模型。
2. 能适应通道数变化:GroupNorm 是一种基于通道分组的归一化方法,更适应通道数的变化,而不需要大量调整。
3. 更稳定的训练:生成式模型的训练通常更具挑战性,存在训练不稳定性的问题。GroupNorm可以减轻训练过程中的梯度问题,有助于更稳定的收敛。
4. 能适应不同数据分布:生成式模型通常需要处理多模态数据分布,GroupNorm 能够更好地适应不同的数据分布,因为它不像 Batch Normalization那样依赖于整个批量的统计信息。
(5)CrossAttnDownBlock/CrossAttnUpBlock/CrossAttnMidBlock模块
在Stable Diffusion U-Net的Encoder部分中,使用了三个CrossAttnDownBlock模块,其由ResNetBlock Structure+BasicTransformer Block+Downsample构成。Downsample通过使用一个卷积(kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))来实现。
在Decoder部分中,使用了三个CrossAttnUpBlock模块,其由ResNetBlock Structure+BasicTransformer Block+Upsample构成。Upsample使用插值算法+卷积来实现,插值算法将输入的Latent Feature尺寸扩大一倍,同时通过一个卷积(kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))改变Latent Feature的通道数,以便于输入后续的模块中。
在CrossAttnMidBlock模块中,包含ResNetBlock Structure+BasicTransformer Block+ResNetBlock Structure,作为U-Net的Encoder与Decoder之间的媒介。
(6)Stable Diffusion U-Net整体宏观角度小结
从整体上看,不管是在训练过程还是前向推理过程,Stable Diffusion中的U-Net在每次循环迭代中Content Embedding部分始终保持不变,而Time Embedding每次都会发生变化。
和传统深度学习时代的U-Net一样,Stable Diffusion中的U-Net也是不限制输入图片的尺寸,因为这是个基于Transformer和卷积的模型结构。
【3】Stable Diffusion中U-Net的训练过程与损失函数
在我们进行Stable Diffusion模型训练时,VAE部分和CLIP部分都是冻结的,所以说官方在训练SD系列模型的时候,训练过程一般主要训练U-Net部分。
我们之前我们已经讲过在Stable Diffusion中U-Net主要是进行噪声残差,在SD系列模型训练时和DDPM一样采用预测噪声残差的方法来训练U-Net,其损失函数如下所示:
到这里,Stable Diffusion U-Net的完整核心基础知识就介绍好了,欢迎大家在评论区发表自己的观点,也希望大家能多多点赞,Rocky会持续完善本文的全部内容,大家敬请期待!
【4】SD模型融合详解(Merge Block Weighted,MBW)
不管是传统深度学习时代,还是AIGC时代,模型融合永远都是学术界、工业界以及竞赛界的一个重要Trick。
在AI绘画领域,很多AI绘画开源社区里都有SD融合模型的身影,这些融合模型往往集成了多个SD模型的优点,同时规避了不足,让这些SD融合模型在开源社区中很受欢迎。
接下来Rocky将带着大家详细了解SD模型的模型融合过程与方法,大家可能会好奇为什么SD模型融合会在介绍SD U-Net的章节中讲到,原因是SD的模型融合方法主要作用于U-Net部分。
首先,我们需要知道SD模型融合的形式,一共三种有如下所示:
- SD模型 + SD模型 -> 新SD模型
- SD模型 + LoRA模型 -> 新SD模型
- LoRA模型 + LoRA模型 -> 新LoRA模型
参考:
1.深入浅出完整解析Stable Diffusion(SD)核心基础知识 - 知乎