Latent Diffusion / Stable Diffusion 的原理是什么?为什么在潜空间做扩散?
简化版
Stable Diffusion 用的是 Latent Diffusion(潜空间扩散):先用一个 VAE 把高分辨率图像压缩成小得多的潜表示(如 512×512×3 压到 64×64×4),在这个压缩的潜空间里做扩散和去噪,最后再用 VAE 解码器还原成图像。核心动机是省算力——像素空间做扩散又慢又贵,而潜空间的元素少了几十倍,训练和推理成本大幅下降,才让扩散模型能在消费级显卡上跑起来。
详细版
三大组件
Stable Diffusion 由三部分拼成:
- VAE(自编码器):编码器
E把图像x压成潜表示z = E(x);解码器D把z还原成图像x̂ = D(z)。典型下采样率 8 倍,512×512×3 → 64×64×4,元素数量减少约 48 倍。 - U-Net(去噪网络):在潜空间
z上做扩散去噪,预测噪声。这是真正「学生成」的部分。 - 文本编码器(CLIP text encoder):把提示词编码成向量,通过 U-Net 的交叉注意力注入,实现文生图。
生成流程(文生图)
- 文本 → CLIP 编码成条件向量
c; - 采一张潜空间纯噪声
z_T ~ N(0,I); - U-Net 在
c条件下反复去噪:z_T → … → z₀(用 DDIM 等采样器,20–50 步); - VAE 解码器
D(z₀)还原成最终图像。
为什么在潜空间做
- 算力:像素空间每步 U-Net 要处理 512×512 的张量;潜空间只处理 64×64,计算量降一到两个数量级。
- 分工:VAE 负责「感知压缩」——去掉人眼不敏感的高频冗余细节;U-Net 负责「语义生成」——在紧凑的语义潜空间里安排内容。两者各司其职。
- 可行性:正是这个设计把扩散模型从「几百张 A100」的门槛降到「单卡可训、消费级可推」,直接引爆了开源生态。
完整版教学
一、问题的起点:像素空间扩散太贵
原始 DDPM 直接在像素上做扩散。对一张 512×512×3 的图,U-Net 每一步都要对约 78 万个数值做前向;采样又要跑几十上百步。训练一个高分辨率像素扩散模型动辄需要数百张高端 GPU 训好几周,普通团队根本玩不起。
Rombach 等人 2021 年的 Latent Diffusion Models(LDM)论文抓住一个关键观察:图像里绝大部分比特是「感知冗余」的——很多高频纹理细节对语义无关紧要,人眼也不敏感。既然如此,为什么要让昂贵的扩散过程去操心这些细节?不如先用一个自编码器把图像压到一个「去掉冗余、只保留语义骨架」的潜空间,让扩散只在这个小空间里工作。
二、两阶段设计:先压缩,再生成
LDM/SD 是明确的两阶段训练:
阶段一:训练 VAE(感知压缩)
- 用重建损失 + 感知损失(LPIPS)+ 一个轻量的 GAN 判别器(patch discriminator),训练一个高质量自编码器。
- 目标是「压得狠、还原得像」:8 倍下采样后仍能高保真解码。
- 这个 VAE 训练好后冻结,后续不再动。
- 注意:这里的 VAE 更偏「正则化的自编码器」,KL 项权重很小,主要作用是把潜空间约束得平滑、方便扩散建模,而不是当成严格的概率 VAE。
阶段二:训练潜空间扩散 U-Net(语义生成)
- 把训练图像用冻结的
E编码成z₀,然后在z空间上跑标准 DDPM 那套(加噪、预测噪声、MSE)。 - U-Net 只需处理 64×64×4 的潜张量,成本骤降。
关键心法:VAE 管「像不像」(感知保真),扩散 U-Net 管「有没有、对不对」(语义内容)。 把感知压缩和语义生成解耦,是 SD 高效的根本。
三、潜空间扩散和像素扩散在数学上是一样的
很多人误以为潜空间扩散是另一套理论。其实扩散的全部公式原封不动,只是把作用对象从像素 x 换成潜表示 z:
前向: z_t = √ᾱ_t·z₀ + √(1-ᾱ_t)·ε
训练: L = ‖ ε − ε_θ(z_t, t, c) ‖²
采样: z_T ~ N(0,I) → 去噪 → z₀ → 图像 = D(z₀)
唯一新增的是首尾的 E(编码)和 D(解码),以及条件 c(文本)。所以掌握了 DDPM,理解 SD 只需加上「先编码后解码」这一层。
四、文本条件如何注入:交叉注意力
SD 是文生图模型,文本怎么控制生成?答案是交叉注意力(cross-attention):
- 提示词经 CLIP text encoder 变成一串 token 向量
c(形状约 77×768)。 - 在 U-Net 的若干层里插入交叉注意力:Query 来自图像潜特征,Key 和 Value 来自文本向量
c。 - 这样每个空间位置都能「查询」文本,决定该位置应该长成什么样——“a red car” 里的 “red” 和 “car” 就能影响到对应区域的去噪方向。
这也是为什么 SD 能做到「换个词,图就变」——文本通过交叉注意力持续参与每一步去噪。
五、组件拆解一览
| 组件 | 作用 | 是否训练 | 典型实现 |
|---|---|---|---|
VAE Encoder E | 图像→潜表示(8× 下采样) | 阶段一训,之后冻结 | KL-VAE |
VAE Decoder D | 潜表示→图像 | 阶段一训,之后冻结 | KL-VAE |
U-Net ε_θ | 潜空间预测噪声 | 阶段二训练 | 带交叉注意力的 U-Net |
| Text Encoder | 提示词→条件向量 | 通常冻结(SD1.x 用 CLIP) | CLIP ViT-L/14 |
| 采样器 | 反向去噪迭代 | 无参数 | DDIM/DPM-Solver/Euler |
六、常见误区与追问
- 误区:VAE 在这里是为了生成。 不是,生成靠扩散 U-Net。VAE 只做压缩/解压,且是冻结的。
- 误区:潜空间的噪声和像素噪声不一样。 加噪逻辑完全一样,只是对象是潜张量。
- 追问:下采样率越高越好吗? 不是。下采样率太低(如 2×)省不了多少算力;太高(如 16×、32×)潜空间丢失太多信息,解码质量下降、细节还原差。SD 选 8× 是质量与效率的甜点。
- 追问:SD 生成的图有时细节崩坏(比如手指、文字),为什么? 部分原因是 VAE 在高频细节上的压缩损失,加上 U-Net 对精细结构建模不足;这也是后续 SDXL 用更强 VAE、更大 U-Net、双文本编码器改进的方向。
- 追问:SDXL 相比 SD1.5 主要变了什么? 更大的 U-Net、两个文本编码器(CLIP ViT-L + OpenCLIP ViT-bigG)、更高基础分辨率(1024)、额外的尺寸/裁剪条件,以及一个 refiner 模型做精修。
七、加强记忆
Stable Diffusion 记「一压二扩三解码」:VAE 编码器把图压进 8× 缩小的潜空间,U-Net 在潜空间里做标准 DDPM 去噪(文本经交叉注意力注入),VAE 解码器再还原成图像。 它没有改扩散的数学,只是把昂贵的扩散从像素搬到语义潜空间,用「感知压缩 + 语义生成」的解耦,把算力砍掉一两个数量级——这才让文生图从实验室走进了千万人的显卡。