扩散模型进阶:DDPM、Stable Diffusion原理

一句话概述

DDPM(Denoising Diffusion Probabilistic Models)建立了扩散模型的训练和采样标准框架:U-Net作为去噪网络,简化损失L_simple使得训练极其稳定。DDIM进一步将扩散模型的逆向过程重新解读为常微分方程(ODE),通过去掉随机噪声项实现确定性采样和跳步加速。Stable Diffusion则在DDPM的基础上进行了革命性改进——将扩散过程从高维像素空间转移到低维潜在空间(Latent Space),通过预训练的VAE编码器将图像压缩为潜在编码(8×到48×压缩),在潜在空间中训练扩散模型,这大幅降低了计算和内存需求,使得在消费级GPU上训练和推理大规模文本到图像模型成为可能。Stable Diffusion还引入了交叉注意力机制,将文本条件(CLIP文本编码器输出)注入U-Net的每一层,实现了文本到图像的精准控制。

💡 核心要点:①DDPM建立了扩散模型的标准训练框架(U-Net + 简化损失)②DDIM通过ODE框架实现确定性跳步采样,将推理加速20-50倍 ③Stable Diffusion在潜在空间而非像素空间扩散,大幅降低计算量 ④Stable Diffusion使用CLIP文本编码器+交叉注意力实现文本到图像生成

教学与演示

一、DDPM的U-Net与时间嵌入

是什么(定义):DDPM的U-Net是专门为去噪任务设计的网络架构。它由编码器(下采样路径)和解码器(上采样路径)组成,中间有跳跃连接将编码器的特征传递给解码器的对应层。关键设计:①时间嵌入——将时间步t通过正弦/余弦位置编码后,注入U-Net的每个残差块(通过scale+shift调制特征);②残差块——每个层级由GroupNorm+SiLU激活+卷积组成;③自注意力——在最低分辨率层添加自注意力机制,捕获全局结构。

大白话 DDPM的U-Net就像一个"多尺度分析仪"。编码器逐步"缩小"观察范围(从全图到区域再到像素),解码器逐步"放大"恢复细节。跳跃连接确保"缩小"时丢失的细节信息能在"放大"时找回。时间嵌入告诉网络"现在是去噪的第几步"——早期(t大)需要粗粒度的全局恢复,后期(t小)需要细粒度的纹理补充。自注意力在最粗糙的尺度上帮助网络"看清大局"——比如人脸中眼睛和鼻子的位置关系。

为什么(原理):U-Net的编码器-解码器结构天然适合"从噪声中恢复信号"——编码器提取噪声模式的多尺度特征,解码器根据这些特征重建信号。时间嵌入通过MLP将标量t映射为高维向量,然后通过scale+shift操作调制特征:h' = h · (1 + scale(t)) + shift(t)。这种调制方式使网络能够在不同时间步表现出不同的"行为"——t=800时激进去噪,t=100时精细调整。

import numpy as np

# DDPM U-Net的简化实现:时间嵌入与残差块
# 展示U-Net如何处理不同时间步的输入

class SimplifiedUNet:
    def __init__(self, d_model=8, d_time=4):
        np.random.seed(42)
        self.d_model = d_model
        # 时间嵌入的权重
        self.W_time = np.random.randn(1, d_time) * 0.3
        # 特征调制权重
        self.W_scale = np.random.randn(d_time, d_model) * 0.1
        self.W_shift = np.random.randn(d_time, d_model) * 0.1
        # 残差块权重
        self.W_res = np.random.randn(d_model, d_model) * 0.1

    def time_embedding(self, t):
        """将时间步t转换为嵌入向量"""
        # 正弦位置编码(简化)
        angle = t * np.pi / 1000
        return np.array([np.sin(angle), np.cos(angle)])

    def forward_block(self, x, t):
        """U-Net的一个残差块:时间调制 + 卷积 + 残差"""
        # 时间嵌入
        t_emb = self.time_embedding(t) @ self.W_time  # (d_time,)

        # 时间调制:缩放和偏移
        scale = t_emb @ self.W_scale  # (d_model,)
        shift = t_emb @ self.W_shift  # (d_model,)

        # 调制特征
        h_modulated = x * (1 + scale) + shift

        # 残差块
        h_res = h_modulated @ self.W_res
        # 残差连接
        out = x + h_res

        return out, scale, shift


unet = SimplifiedUNet(d_model=8, d_time=4)
x = np.array([0.5, -0.3, 0.8, 0.1, -0.5, 0.2, 0.0, 0.4])

print("=== DDPM U-Net:时间嵌入与残差块 ===\n")

# 不同时间步的调制效果
for t in [900, 500, 100]:
    out, scale, shift = unet.forward_block(x, t)
    print(f"t={t:3d}:")
    print(f"  时间嵌入: {np.round(unet.time_embedding(t), 3)}")
    print(f"  缩放:     {np.round(scale[:4], 3)}")
    print(f"  偏移:     {np.round(shift[:4], 3)}")
    print(f"  输出:     {np.round(out[:4], 3)}")
    print()

print("关键:不同时间步有不同的scale和shift")
print("→ t=900: 大局粗调")
print("→ t=100: 细节精调")
print("→ 时间嵌入让U-Net知道'当前在扩散的哪个阶段'")
DDPM的简化训练损失\(L_{\text{simple}} = \mathbb{E}_{t, x_0, \varepsilon}\left[\|\varepsilon - \varepsilon_\theta(x_t, t)\|^2\right], \quad x_t = \sqrt{\bar{\alpha}_t} x_0 + \sqrt{1 - \bar{\alpha}_t} \varepsilon\)
大白话 DDPM的训练简单得令人吃惊——随机选一张图,随机加噪声,让U-Net猜"我加了什么噪声",猜错了扣分。没有任何对抗、没有任何KL散度、没有任何博弈——就是一个简单的"噪声回归"任务。这种简单性正是扩散模型训练稳定的秘密。

什么用(应用):DDPM的U-Net架构被后续所有扩散模型继承和改进。Stable Diffusion在U-Net中加入了交叉注意力层来处理文本条件。Imagen使用多个级联的U-Net(不同分辨率)来生成超高清图像。DALL-E 2使用扩散模型作为其图像生成的后端。

哪些坑(缺点):U-Net参数多(通常数亿到数十亿),训练需要大量GPU资源。高分辨率图像的像素空间扩散计算量极大(Stable Diffusion的潜在空间方案解决了这个问题)。U-Net在t很小时预测噪声的任务更简单,但误差对最终图像影响更大(因为是最后一步)。

二、Stable Diffusion:潜在空间扩散

是什么(定义):Stable Diffusion由Stability AI于2022年发布,将图像生成民主化。其核心创新是"在潜在空间中扩散"——使用预训练的VAE将图像压缩到潜在空间(如512×512→64×64,8倍压缩),然后在潜在空间中进行扩散和去噪。生成的低维潜在编码通过VAE解码器还原为高分辨率图像。这种设计将计算量从O(512²)降低到O(64²),减少了约64倍。

大白话 Stable Diffusion就像"先画缩略图,再放大"。直接在高清图像(512×512)上做扩散,每一步都要处理大型张量,消费级GPU根本吃不消。Stable Diffusion先把图像压缩成一个"浓缩版"(64×64的潜在编码)——这个浓缩版保留了图像的"语义精髓"但丢弃了"像素细节"。在浓缩版上做扩散,又快又省内存。生成完浓缩版后,用VAE解码器"放大"成高清图——VAE解码器专门负责补细节。

为什么(原理):潜在空间扩散的可行性基于两个发现:①图像的"感知信息"(如物体形状、结构、语义)集中在低频分量中,"像素细节"(如纹理、噪声)在高频分量中;②VAE的潜在空间保留了感知信息而丢弃了像素级细节。在潜在空间中扩散只需要建模"感知层面"的分布,像素细节由VAE解码器负责——实现了"分工协作"。文本条件通过CLIP文本编码器提取文本嵌入,通过交叉注意力注入U-Net。

import numpy as np

# Stable Diffusion的潜在空间扩散核心概念
# 对比像素空间和潜在空间扩散的效率差异

def demo_latent_diffusion():
    print("=== Stable Diffusion:潜在空间扩散 ===\n")

    # 像素空间 vs 潜在空间
    pixel_size = 512 * 512  # 512×512
    latent_size = 64 * 64   # 8倍压缩

    print("【像素空间扩散 vs 潜在空间扩散】")
    print(f"  像素空间: {pixel_size} 个值需要处理")
    print(f"  潜在空间: {latent_size} 个值需要处理")
    print(f"  压缩比: {pixel_size // latent_size}倍")
    print(f"  内存节省: ~{(1 - latent_size/pixel_size)*100:.0f}%\n")

    print("【Stable Diffusion的三个模块】")
    print("1. VAE编码器:将图像压缩到潜在空间")
    print("   512×512×3 像素 → 64×64×4 潜在编码")
    print("   → 丢弃像素细节,保留语义信息")
    print()
    print("2. U-Net(扩散模型):在潜在空间中生成")
    print("   + CLIP文本编码器提取文本嵌入")
    print("   + 交叉注意力将文本条件注入U-Net各层")
    print("   → 根据文本描述生成潜在编码")
    print()
    print("3. VAE解码器:解码为高清图像")
    print("   64×64×4 潜在编码 → 512×512×3 图像")
    print("   → 恢复像素细节,添加纹理和光照")

    print("\n【交叉注意力:文本控制】")
    print("  文本'一只坐在花园里的猫'")
    print("  ↓ CLIP文本编码器 ↓")
    print("  文本嵌入向量 (77, 768)")
    print("  ↓ 交叉注意力 ↓")
    print("  U-Net的每一层都能'看到'文本描述")
    print("  → 生成的内容与文本语义对齐")


demo_latent_diffusion()
潜在空间扩散\(L_{\text{LDM}} = \mathbb{E}_{\mathcal{E}(x), \varepsilon, t}\left[\|\varepsilon - \varepsilon_\theta(z_t, t, \tau(y))\|^2\right], \quad z_t = \sqrt{\bar{\alpha}_t} \cdot \mathcal{E}(x) + \sqrt{1 - \bar{\alpha}_t} \cdot \varepsilon\)
大白话 Stable Diffusion最巧妙的设计是"分工":VAE负责像素→语义的压缩(学一次,生成时复用),扩散U-Net只负责"画缩略图"(在64×64的语义空间操作),CLIP文本编码器负责"理解指令"(把文字翻译成U-Net能懂的向量)。三部分各司其职,让生成既高质量又高效。

什么用(应用):Stable Diffusion是当前最流行的开源图像生成模型。它支持文本到图像(txt2img)、图像到图像(img2img)、图像修复(inpainting)、图像扩展(outpainting)等任务。ControlNet、LoRA、DreamBooth等微调技术进一步扩展了其应用场景。

哪些坑(缺点):VAE的压缩能力限制了图像质量——对于包含精细文字或微小细节的场景,VAE解码可能产生伪影。CLIP文本编码器的77-token限制意味着长文本描述需要截断。生成分辨率受限于训练分辨率(通常512或768),超分辨率需要额外的模型。

三、扩散模型的加速与条件控制

是什么(定义):扩散模型的推理加速是研究热点。DDIM跳步采样将步数从1000减少到50-100步。蒸馏方法(如Progressive Distillation、LCM)通过将多步采样知识蒸馏到更少的步骤(甚至1-4步)。条件控制技术如ControlNet(可训练的网络副本控制预训练扩散模型)和IP-Adapter(图像提示适配器)极大地扩展了扩散模型的可控性。

大白话 扩散模型就像一个"慢性子的画家"——画一张图要1000笔。加速方法就是教他"一笔当20笔用"。DDIM是"跳着画"——跳过不重要的笔触,保留关键笔触。蒸馏是"快速画法速成班"——让一个已经很会画的大师(1000步模型)教一个新手(4步模型)"怎么画得快还不差"。ControlNet是给画家一个"临摹模板"——拿着边缘检测图、深度图这些模板,画家照着模板画,能精确控制构图。

概念关系图谱

概念核心含义与AI的关系关联概念
DDPM扩散模型的标准训练框架建立了U-Net+简化损失的范式U-Net、时间嵌入
Stable Diffusion在潜在空间中扩散使扩散模型在消费级GPU上可行VAE、潜在空间、CLIP
潜在空间数据经过VAE压缩的低维表示大幅降低扩散模型的计算量编码器、解码器
交叉注意力U-Net关注文本条件的机制实现文本到图像生成的关键CLIP、条件生成
DDIM确定性跳步采样将推理加速20-50倍ODE、跳步
ControlNet可训练的控制网络精确控制扩散模型的输出结构边缘检测、深度图

重点答疑

Q1: Stable Diffusion为什么在潜在空间而非像素空间扩散?

高分辨率图像(512×512)的像素空间扩散需要处理约78万维的张量(3通道),每个U-Net层都需要处理这个尺寸,计算量和显存需求极大。潜在空间(64×64×4)只有约1.6万维,减少了约50倍的计算量。这使得Stable Diffusion可以在消费级GPU(如8GB显存)上运行。

Q2: CLIP文本编码器在Stable Diffusion中的作用是什么?

CLIP文本编码器将文本描述(如"一只坐在花园里的猫")转换为文本嵌入向量(77×768)。这个嵌入通过交叉注意力注入U-Net的每一层——U-Net特征作为Query,文本嵌入作为Key和Value。这使得去噪过程受到文本的"指引"——网络在去噪时知道"应该生成猫的形状,应该加上花园的背景"。

Q3: DDIM为什么能跳步而不显著影响质量?

DDIM将逆向过程重新形式化为ODE求解。在ODE框架下,可以用更大的步长来近似求解——就像用数值方法解微分方程时可以用不同的步长。步长越大,数值误差越大(质量下降),但速度越快。50步通常是在速度和质量之间的良好平衡点,误差在视觉上不太明显。

章节单词汇总

英文音标术语/释义
DDPM/diː diː piː em/去噪扩散概率模型,扩散模型的基准实现
Stable Diffusion/ˈsteɪbəl dɪˈfjuːʒən/潜在空间扩散模型,开源文本到图像生成
Latent Space/ˈleɪtənt speɪs/潜在空间,数据经VAE压缩的低维表示
CLIP/klɪp/对比语言-图像预训练,文本和图像的联合嵌入
Cross-Attention/krɔːs əˈtenʃən/交叉注意力,U-Net与文本条件的交互机制
ControlNet/kənˈtroʊl net/可训练控制网络,精细控制扩散模型输出
ODE/oʊ diː iː/常微分方程,DDIM确定性采样的数学框架

面试练习

Q1 [单选] Stable Diffusion在什么空间中训练扩散模型?

  • A. 像素空间
  • B. 潜在空间(Latent Space)
  • C. 频率空间
  • D. 文本空间
解答:Stable Diffusion使用预训练的VAE将图像压缩到潜在空间,在低维潜在空间中训练扩散模型,大幅降低计算和显存需求。

Q2 [单选] Stable Diffusion使用什么文本编码器?

  • A. BERT
  • B. GPT
  • C. CLIP
  • D. T5
解答:Stable Diffusion使用CLIP的文本编码器(基于Transformer),通过交叉注意力将文本条件注入U-Net的去噪过程。

Q3 [单选] DDIM的确定性采样可以在多少步完成?

  • A. 必须1000步
  • B. 50-100步
  • C. 1步
  • D. 无限步
解答:DDIM通过ODE框架支持跳步采样,通常50-100步即可获得良好质量,相比DDPM的1000步加速10-20倍。

Q4 [多选] 关于DDPM的U-Net,以下哪些是正确的?

  • A. 使用正弦/余弦编码将时间步t嵌入网络
  • B. 时间嵌入通过scale+shift调制特征
  • C. 编码器-解码器结构+跳跃连接
  • D. 不需要任何时间信息
  • E. 低分辨率层使用自注意力
解答:DDPM的U-Net使用时间嵌入+scale/shift调制、编码器-解码器+跳跃连接、低分辨率层自注意力。时间信息是必需的——网络需要知道当前扩散阶段。

Q5 [单选] ControlNet的主要功能是什么?

  • A. 加速采样
  • B. 通过额外的条件输入(如边缘图、深度图)精确控制生成
  • C. 减少模型参数
  • D. 替换CLIP文本编码器
解答:ControlNet是一个可训练的控制网络,接收边缘检测图、深度图、人体姿态等条件输入,精确控制预训练扩散模型的输出结构,如"按这个轮廓画一只猫"。