☰
霹雳吧啦Wz | AIGC | 图像生成篇 | Latent Diffusion Model
2026/10/9 5:24:13 网站建设 项目流程

目录

    • 前言
    • 1. 内容介绍
    • 2. 感知压缩模型
    • 3. 隐空间扩散模型结构
    • 4. 条件注入方式
    • 5. 训练和推理
    • 结语
    • 参考

前言

学习 UP 主 霹雳吧啦Wz 的 Latent Diffusion Model 视频,了解一下 LDM 的相关工作,记录下个人学习笔记,和大家一起分享交流😄

video:Latent Diffusion Model

1. 内容介绍

本期内容我们来简单聊一聊 LDM(Latent Diffusion Model)。

上图展示的是 LDM 原论文的标题,这篇论文的下载地址是 https://arxiv.org/abs/2112.10752,有兴趣的小伙伴可以自己去下载阅读。

本期内容主要分为以下五个部分:

  • 往期内容回顾
  • Perceptual Compression Models
  • Latent Diffusion Models
  • Conditioning Mechanisms
  • 训练与推理

首先回顾一下往期的内容,接着讲解 LDM 的三个核心模块—感知压缩模型、隐空间的扩散模型和条件注入机制,最后再讲一讲 LDM 的训练与推理流程。

在之前的内容中,我们讲过 DDPM:它把原本困难的单步生成任务拆解成了多个简单的子任务。

比如说 DDPM 生成一张干净图像需要迭代去噪 1000 次,推理成本太高。于是在 DDIM 中,作者通过一系列假设与公式推导,把推理步数从 1000 步缩减到 100 步甚至 50 步,大幅提升了生成效率。

除了减少步数,还有没有别的办法来加速生成呢?像素级的扩散模型每一步都要处理全分辨率的图像,分辨率一高,单步的计算成本就相当高—能不能降低每一步的计算量呢?

有经验的同学可能会想到剪枝或量化,但在 LDM 这篇论文中,作者想到的是:能不能把送入扩散模型的图像分辨率降低一点?很明显,一张 1K 分辨率图像的计算量,要远大于一张 128×128 分辨率图像的计算量。

2. 感知压缩模型

那我们该如何把高分辨率的图像压缩到一个更低的维度上呢?在 LDM 工作当中,作者提出了感知压缩模型,业界一般称之为 VAE,其结构如图所示:

它主要由 encoder 和 decoder 两部分组成:encoder 负责把原始的高分辨率图像压缩到更低维的隐空间。比如原图分辨率为( H , W ) (H,W)(H,W),对 RGB 3 通道图像而言通道数为 3,经过 encoder 之后,我们就得到了高宽为H / f H/fH/f、W / f W/fW/f,通道数为C CC的隐变量z zz。如果能在z zz所在的隐空间上做迭代去噪,就能提升整个扩散模型的推理效率—论文中也提到,除了加速推理,这还能让训练收敛得更快。最后,我们再把隐变量z zz通过 decoder 还原到像素空间,还原后的分辨率与输入图像完全一致。

下面这两幅图是用官方开源的 VAE 做的演示。

左边这幅图是原始图,我把它作为模型输入(即这里的x xx),经过 encoder 编码、decoder 解码后得到右边的重建图。对比来看,肉眼几乎看不出差异;只有放得非常大时才会发现些许不同—比如把某个区域放大后,就能看到齿轮的齿和铭牌边缘明显糊掉。

当然,也有同学可能更关心中间的隐变量z zz长什么样子。这里同样以刚才的原始图为例,把隐变量z zz的四个通道展示出来:

这里把每个通道单独缩放后以灰度图的形式展示,也就是上面这四张图,每个通道分别编码了不同频率、不同语义的图像特征,共同构成完整的隐空间表示:通道 0 保留了天空光束和整体轮廓;通道 1 里松鼠、鹿、狐狸的形体呈成块的亮斑;通道 2 大面积偏暗,主要把字母边缘勾勒出来;通道 3 最 “噪”,LDM 三个字母被编码成一片高亮的团块。

那感知压缩模型(VAE)是如何训练的?论文当中给出了具体的训练策略:

  • Perceptual Loss
  • Patch-based Adversarial Objective
  • KL-reg/VQ-reg

前两项分别是感知损失和对抗损失,用它们约束能让感知压缩模型获得较好的重建效果,重建图像看上去也更合理真实。但如果只用这两个损失,隐变量z zz的分布方差会比较大;而我们训练的扩散模型都基于 “数据服从正态分布” 这一假设设计,为了让z zz的分布更适配扩散模型,作者给出了两种方案:一种是用 KL 正则约束隐空间的分布,另一种是 VQ 正则,但当前业界更主流的是较弱的 KL 正则。

实际训练时,下采样倍率f ff该如何选择呢?作者通过一系列实验建议f ff取{ 4 , 8 , 16 } \{4, 8, 16\}{4,8,16};在 2025 年及以前,主流的做法是取f = 8 f = 8f=8,也就是高宽各下采样 8 倍,像素数量(面积)变为原来的 1/64,从而让扩散模型的推理速度更快、显存峰值更小。但随着生成图像的分辨率越来越高(比如 4K、8K),越来越多的工作也开始采用下采样倍率更高的 VAE,比如 16 倍甚至 32 倍。

这里有一个容易忽略的小点:隐变量在送入扩散模型之前,需要乘以一个缩放因子scale_factor \text{scale\_factor}scale_factor做全局归一化,让z zz的分布更加匹配扩散模型的标准正态分布。注意:训练 VAE(也就是感知压缩模型)时并不涉及缩放因子这一项;只有在训练好感知压缩模型、再基于它训练扩散模型时,才会引入缩放因子。

scale_factor = 1 σ \text{scale\_factor} = \frac{1}{\sigma}scale_factor=σ1​

这个缩放因子怎么算呢?其实就是统计一批数据对应的隐变量全局标准差,再用 1 除以这个标准差即可。比如我前面用的官方 SD v1 的 VAE,缩放因子就是 0.18215。扩散模型迭代去噪完毕后,还需要先除以这个缩放因子,再通过 decoder 解码回图像空间。

这些是具体使用时的小细节,大家也需要稍微注意一下。

3. 隐空间扩散模型结构

接下来讲隐空间的扩散模型。图像域的扩散模型和隐空间的扩散模型,本质上完全一样,可以对比一下它们的训练损失:

L D M = E x , ϵ ∼ N ( 0 , 1 ) , t [ ∥ ϵ − ϵ θ ( x t , t ) ∥ 2 2 ] L L D M = E E ( x ) , ϵ ∼ N ( 0 , 1 ) , t [ ∥ ϵ − ϵ θ ( z t , t ) ∥ 2 2 ] \begin{align*} L_{DM} &= \mathbb{E}_{x, \epsilon \sim \mathcal{N}(0,1), t} \left[ \left\| \epsilon - \epsilon_\theta(x_t, t) \right\|_2^2 \right] \\ L_{LDM} &= \mathbb{E}_{\mathcal{E}(x), \epsilon \sim \mathcal{N}(0,1), t} \left[ \left\| \epsilon - \epsilon_\theta(z_t, t) \right\|_2^2 \right] \end{align*}LDM​LLDM​​=Ex,ϵ∼N(0,1),t​[∥ϵ−ϵθ​(xt​,t)∥22​]=EE(x),ϵ∼N(0,1),t​[∥ϵ−ϵθ​(zt​,t)∥22​]​

可以看到,两者的形式完全一致,只不过图像域的输入x t x_txt​对应的是图像,而隐空间的输入z t z_tzt​对应的是前面感知压缩模型(VAE)encoder 的输出结果,别忘了还要乘以刚刚提到的缩放因子。

在 LDM 工作当中,作者采用的是 Unet 架构,下面以文生图为例展示模型结构:

这里简单过一下,上图是根据作者开源的代码仓库、以文生图为例绘制的 Unet 结构。

对于文生图任务,模型有三个输入:第一个是去噪过程中每一步对应的时间步;第二个是用户输入的描述指令,也就是这里的 prompt;第三个是模型在迭代过程中的带噪 latent,也就是这里的x xx。

这个 U-Net 结构可以分为三个子模块:第一个子模块是 input block,也就是 U-Net 左半部分,它负责将输入的带噪数据逐步下采样—比如每经过一次 downsample,高宽都会缩小为原来的一半;第二个子模块是中间的三个小模块(middle block);第三个子模块是 U-Net 右半部分(output block),它会与 input block 中对应的输出(skip connection)进行 concat,然后不断上采样—每经过一次 upsample,高宽都会放大为原来的两倍,最终得到与x xx分辨率相同的输出h hh。

从 Unet 架构图可以看到,网络中有两个比较核心的模块:Resblock 和 Spatial Transformer。Resblock 主要由 group norm、卷积以及残差结构组成,大家有兴趣可以自己去看源码。Spatial Transformer 的结构在下图中有更详细的展开,这里大家留意一下:Resblock 会额外接收时间步相关的信息,而 Spatial Transformer 还会额外接收注入的 condition 信息,也就是 prompt 经 text encoder 编码后的结果。

接着简单过一下 Spatial Transformer 的结构。如图所示,输入会依次经过 group norm、卷积以及 rearrange(把高和宽合并成一个维度,也就是序列长度),再经过 layer norm 和 self attention 模块;对 self attention 不太了解的同学,可以回顾一下之前讲过的内容。这些模块周围还带有残差结构,之后再通过 layer norm 和 cross attention。

cross attention 的结构对应右侧部分,它的输入由两部分组成:一个是x xx,也就是我们的带噪数据;另一个是 context,也就是前面提到的 prompt 经过 text encoder 得到的结果。如果 context 等于x xx,那整个流程其实就是传统的 self attention;而当 Q 仍来自带噪特征、K 和 V 换成注入的 context 时,就变成了 cross attention—可以简单理解为:带噪的 token 序列根据自己的需要,去汇总融合注入的条件信息。

再回到 Spatial Transformer:刚刚讲到的 cross attention 同样带有残差结构;之后经过 layer norm 和 Feedforward,这里同样也有一个残差结构;紧接着通过 rearrange 把维度还原成 BCHW 的形式,再经过一个卷积层,最外侧还有一个来自最开始输入的残差,最后输出。

这就是 LDM 中所采用的 Unet 模型的大致结构。了解完隐空间的扩散模型结构之后,我们接着来看条件注入机制。

4. 条件注入方式

2022年这篇论文首次发布时,作者仓库中贴出的各种 demo 极具冲击力,让人不禁感叹扩散模型的生成能力之强。

比如我们输入一张语义分割图,图中不同的颜色对应不同的物体,最上方的玫红色区域对应的是天空,中上部横贯画面的亮绿色区域对应的是山脉,中部大片的深紫色区域对应的是树林,左下角的浅青色区域对应的是草地,右下角的淡紫色区域对应的是湖泊。如果把这幅语义图作为条件注入扩散模型,就能生成右侧的三张图片,生成内容的语义与给定条件基本保持一致。

接下来看另一个例子—Inpainting。不知大家是否还记得,在 2022 年及以前,手机上的消除功能一旦遇到面积较大的目标,基本就会崩掉。但是借助扩散模型的强大生成能力,即使消除的目标面积很大,我们也能够得到比较好的效果。

比如上面这幅图,我们想消除人所在的区域,把原始图像和要消除的 mask 一并注入扩散模型,就能得到右边这张图。在当时看来,这个消除效果非常惊艳,即使放到现在,效果也还是不错的。下面这张图同理:把红框区域内的目标消除掉,就得到了右边这张图。

最后看一个超分的例子。超分在移动端非常常用,我们同样可以利用扩散模型强大的生成能力来完成。

比如左边这幅图,把它注入到扩散模型当中,借助其强大的生成能力就能得到右边这幅高清图像,下面这张图同理。

接下来结合论文当中的图三,进一步了解这些条件是如何注入到扩散模型当中的。

首先看这张图的最右侧,也就是 conditioning,即我们要注入的各种条件。不同条件可能对应不同的编码器,比如图中的τ θ \tau_\thetaτθ​:对于文本这类条件,可以用当时的 BERT、CLIP 等模型作为文本编码器;而像刚才提到的超分、Inpainting 这类任务,其实并不需要额外的编码器—以超分为例,只需要把图像送入 VAE 的 encoder 编码即可。

左边这个区域的 switch 想表达的是:不同的注入条件,注入形式也不太一样。还是以刚才提到的超分和语义分割为例,它们走的是 concat 这条路线—条件会直接在 channel 维度上与输入的带噪数据拼接,从而注入模型;而像文本这类条件,走的则是开关的另一侧,即通过 cross attention 注入到模型内部。

那具体哪些任务要走哪些注入形式,我们可以看一下:

论文中作者给出了这样一张表格:conditioning 这一行列出了各任务采用的条件注入形式,比如 CA 对应 cross attention,concat 对应通道维度拼接。那么,什么样的场景推荐用 concat,什么样的场景推荐用 cross attention 呢?像超分这类空间严格对齐的稠密条件,就适合采用 concat 的形式;而像文本这种跨模态、非空间对齐的条件,则适合使用 cross attention 的注入形式。

LDM 发表于 2021 年底(CVPR 2022),距今已有几年,如今的注入方式也发生了变化,这里简单提一句:当前一些生成类模型主流的条件注入方式同样是 concat,但要注意,这里的 concat 并不是 LDM 论文中那样在 channel 维度拼接,而是在序列维度拼接。等后面讲到 SD3 或 Flux 时,就能看到具体的拼接形式了。

这里给出 cross attention 与传统自注意力机制的区别:

传统自注意力计算公式:

Attention ( Q , K , V ) = softmax ( Q K T d ) ⋅ V \text{Attention}(Q, K, V) = \text{softmax} \left( \frac{Q K^T}{\sqrt{d}} \right) \cdot VAttention(Q,K,V)=softmax(d​QKT​)⋅V

cross attention 的核心区别:Q 来自图像特征,K、V 来自条件特征

Q = W Q ( i ) ⋅ φ i ( z t ) , K = W K ( i ) ⋅ τ θ ( y ) , V = W V ( i ) ⋅ τ θ ( y ) . Q = W_Q^{(i)} \cdot \varphi_i(z_t), \quad K = W_K^{(i)} \cdot \tau_\theta(y), \quad V = W_V^{(i)} \cdot \tau_\theta(y).Q=WQ(i)​⋅φi​(zt​),K=WK(i)​⋅τθ​(y),V=WV(i)​⋅τθ​(y).

刚刚在讲 U-Net 结构时已经简单提到过 cross attention,它与 self attention 的区别在于:Q 依然来自带噪的图像特征,而 K、V 换成了注入的条件特征。所以对于带条件的 LDM 损失,其实只需要在ϵ θ \epsilon_\thetaϵθ​的输入中多加一个条件y yy即可。

L LDM : = E E ( x ) , y , ϵ ∼ N ( 0 , 1 ) , t [ ∥ ϵ − ϵ θ ( z t , t , τ θ ( y ) ) ∥ 2 2 ] L_{\text{LDM}} := \mathbb{E}_{\mathcal{E}(x), y, \epsilon \sim \mathcal{N}(0,1), t} \left[ \left\| \epsilon - \epsilon_\theta(z_t, t, \tau_\theta(y)) \right\|_2^2 \right]LLDM​:=EE(x),y,ϵ∼N(0,1),t​[∥ϵ−ϵθ​(zt​,t,τθ​(y))∥22​]

5. 训练和推理

最后,简单讲一下如何训练我们自己的模型。

首先把 DDPM 当中的 Algorithm 1 和 Algorithm 2 摆出来:算法一对应训练流程,算法二对应采样(推理)流程。

对于训练流程,以文生图为例,训练数据是成对的文本-图像:文本 prompt 用文本编码器编码成模型能够识别的特征,图像则用 VAE 的 encoder 编码到隐空间。

编码得到的隐变量就可以看作 DDPM 当中的x 0 \mathbf{x}_0x0​。接着随机采样一个时间步和高斯噪声,根据前面在 DDPM 中推导的公式,由x 0 \mathbf{x}_0x0​和噪声得到带噪数据,连同时间步t tt一起输入模型,让模型预测噪声,再用预测噪声与真实噪声计算 L2 loss、反传梯度,直到模型收敛为止。

推理(采样)时,用户输入一个 prompt,同样要先用文本编码器把指令编码成模型能够识别的特征。对于文生图场景,推理时并不需要 VAE 的 encoder,我们直接在隐空间采样一个高斯噪声,也就是这里的x T \mathbf{x}_TxT​,再经过多步迭代去噪,得到隐空间中完成去噪的x 0 \mathbf{x}_0x0​;最后把x 0 \mathbf{x}_0x0​通过 VAE 的 decoder 还原到图像空间,就能得到可以直接查看的 RGB 图像了。

这里同样要注意:在送入 decoder 之前,还要再除以前面提到的缩放因子。如果是超分这类任务,则需要先把低分辨率图片经 VAE 的 encoder 编码到隐空间,再与带噪数据在通道维度 concat,一起送入扩散模型。

OK,以上就是本次分享的全部内容了。

结语

本篇文章我们跟随 UP 主完整梳理了 LDM 的三个核心模块:感知压缩模型、隐空间扩散模型以及条件注入机制,最后简单过了一遍训练与推理的流程。

感知压缩模型(VAE)的作用是把高分辨率图像压缩到一个低维隐空间,让扩散模型不必在像素空间上做去噪。以f = 8 f=8f=8为例,高宽各下采样 8 倍,意味着扩散模型每一步要处理的数据量只有原来的1 / 64 1/641/64,推理速度和显存峰值都得到了明显改善;而 Perceptual Loss 与对抗损失保证了重建质量,KL 正则则把隐空间的分布约束得更加贴近标准正态,使其满足扩散模型的前提假设。此外,隐变量在送入扩散模型前还需要乘以缩放因子scale_factor \text{scale\_factor}scale_factor做一次全局归一化,推理结束后再除回来。

隐空间的扩散模型在形式上和图像域的扩散模型没有任何区别,只是把输入从x t x_txt​换成了z t z_tzt​,损失函数也只是多加了一个条件y yy。网络结构上依然是 U-Net—时间步信息通过 Resblock 注入,条件信息则通过 Spatial Transformer 中的 cross attention 注入。

条件注入方式上,LDM 用 concat 处理空间严格对齐的稠密条件(超分、Inpainting、语义分割),用 cross attention 处理跨模态非空间的条件(文本),因此同一个 Unet 能够适配多种任务。看似庞大的文生图、超分、Inpainting 系统,其核心可以概括为:先在隐空间里学噪声,再用合适的方式把条件喂给模型。

值得一提的是,LDM 发表于 2021 年底,条件注入的形式如今已经发生了变化—concat 从 channel 维度转移到了序列维度,U-Net 主干也逐渐被更纯粹的 Transformer 架构(如 DiT)取代,条件改由 self-attention 统一处理。理解 LDM 这套压缩 + 隐空间扩散 + 条件注入的框架,是读懂后续 SD、SD3、Flux 等工作的基础,我们后面的内容也会接着聊到它们。

感兴趣的同学可以多看看 UP 主的视频,非常感谢 UP 主的精彩讲解 🤗。

参考

  • Latent Diffusion Model
  • https://github.com/compvis/latent-diffusion
  • High-Resolution Image Synthesis with Latent Diffusion Models

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询