一、扩散模型概述
扩散模型(Diffusion Model)是当前生成式AI领域最核心的范式之一,构成了Stable Diffusion、DALL-E 3、Midjourney、Sora等里程碑系统的基础。其核心思想受热力学启发:通过逐步向数据中添加噪声(前向扩散过程),然后学习逆向去噪过程,从而从纯噪声中恢复出有意义的样本。
与生成对抗网络(GAN)和变分自编码器(VAE)相比,扩散模型具有训练更稳定、模式覆盖更全面(即不塌缩)、生成质量更高等显著优势。自2020年Ho等人发表DDPM(Denoising Diffusion Probabilistic Models)以来,扩散模型迅速成为图像生成领域的事实标准。
扩散模型发展里程碑
- 2015年(Sohl-Dickstein等): 首次提出扩散模型概念,建立非平衡热力学与生成模型的联系
- 2020年(DDPM, Ho等): 提出去噪扩散概率模型,证明扩散模型可生成高质量图像,开启扩散模型时代
- 2021年(DDIM, Song等): 提出去噪扩散隐式模型,实现加速采样(50步vs1000步)
- 2021年(Improved DDPM, Nichol & Dhariwal): 改进噪声调度和学习方差,提升对数似然
- 2022年(LDM / Stable Diffusion, Rombach等): 将扩散过程迁移到潜在空间,大幅降低计算成本,实现高分辨率生成
- 2023-2024年: 扩散模型扩展到视频生成(Sora)、3D生成(Point-E, DreamFusion)、音频生成等领域
二、前向扩散过程
前向扩散过程是扩散模型的第一大支柱。其思想非常简单:给定一个真实数据样本 x₀,我们逐步向其添加高斯噪声,经过 T 步后得到一个近似纯噪声的样本 x_T。
2.1 马尔可夫链形式的噪声注入
前向过程被定义为马尔可夫链,即每一步的状态只依赖于前一步:
q(x₁, x₂, ..., x_T | x₀) = ∏_{t=1}^{T} q(x_t | x_{t-1})
其中每个转移核为高斯分布:
q(x_t | x_{t-1}) = N(x_t; √(1-β_t) · x_{t-1}, β_t · I)
这里 β_t 是噪声调度(noise schedule),控制每一步添加的噪声量。β_t 通常取值在 0.0001 到 0.02 之间,且随 t 递增(越到后面加噪越多)。
2.2 重参数化与单步采样
利用高斯分布的重参数化技巧,可以直接从 x₀ 一步计算到任意 x_t,无需逐次迭代:
x_t = √(ᾱ_t) · x₀ + √(1-ᾱ_t) · ε, ε ~ N(0, I)
其中 α_t = 1-β_t,ᾱ_t = ∏_{s=1}^{t} α_s。这个公式至关重要,它让训练时无需模拟完整的 T 步扩散,可以直接采样任意 t 时刻的噪声图像进行训练,极大提升了计算效率。
调度策略对比:线性 vs 余弦
- 线性调度(Linear Schedule): β_t 从 0.0001 线性增长到 0.02。DDPM原版采用,简单直接。但后期噪声增加太快,导致 x_T 的信号残留较多。
- 余弦调度(Cosine Schedule): β_t 按照余弦函数的平方设计,让噪声添加更平滑,特别是中期和后期。Improved DDPM提出,能提升对数似然指标。
- 调度对比: 余弦调度在中间步保留了更多信息,使得反向过程更容易学习,尤其适用于需要高对数似然的任务。
2.3 后验分布 q(x_{t-1} | x_t, x₀)
后验分布在训练中非常重要。虽然 q(x_{t-1} | x_t) 不可解,但给定 x₀ 时的条件后验是已知的高斯分布:
q(x_{t-1} | x_t, x₀) = N(x_{t-1}; μ̃_t(x_t, x₀), β̃_t · I)
μ̃_t(x_t, x₀) = (√(ᾱ_{t-1}) · β_t) / (1-ᾱ_t) · x₀ + (√(α_t) · (1-ᾱ_{t-1})) / (1-ᾱ_t) · x_t
β̃_t = (1-ᾱ_{t-1}) / (1-ᾱ_t) · β_t
这个后验分布是训练反向过程网络时的目标分布 -- 我们希望学习的逆向过程 p_θ(x_{t-1} | x_t) 能够逼近 q(x_{t-1} | x_t, x₀)。
三、反向去噪过程
反向过程是扩散模型的核心生成阶段。模型学习一个参数化的逆向马尔可夫链 p_θ(x_{t-1} | x_t),从纯噪声 x_T ~ N(0, I) 开始,逐步去噪直到恢复出 x₀。
3.1 参数化逆向分布
逆向过程同样定义为高斯分布:
p_θ(x_{t-1} | x_t) = N(x_{t-1}; μ_θ(x_t, t), Σ_θ(x_t, t))
在DDPM中,方差 Σ_θ 被固定为时间相关的常数(β̃_t 或 β_t),模型只需要学习均值 μ_θ。实际中通常采用预测噪声的策略:
μ_θ(x_t, t) = (1/√(α_t)) · [x_t - β_t/√(1-ᾱ_t) · ε_θ(x_t, t)]
也就是说,模型不直接预测 x₀ 或 μ,而是预测添加到 x_t 中的噪声 ε_θ(x_t, t)。这种"预测噪声"的设计被证明比直接预测图像本身效果更好。
┌─────────────────────────────────────────────────────┐
│ 反向去噪过程(采样) │
│ │
│ x_T → x_{T-1} → x_{T-2} → ... → x_1 → x₀ │
│ (纯噪声) (生成结果) │
│ │
│ 每一步: x_{t-1} = μ_θ(x_t, t) + σ_t · z │
│ 其中 z ~ N(0,I), 最后一步 z = 0 │
└─────────────────────────────────────────────────────┘
3.2 训练目标:变分下界与 L_simple
扩散模型的训练目标是最大化数据的对数似然 log p(x₀) 的变分下界(ELBO):
L = E_q[ -log(p(x_T)/q(x_T|x₀)) - ∑_{t>1} log(p_θ(x_{t-1}|x_t)/q(x_{t-1}|x_t,x₀)) - log p_θ(x₀|x₁) ]
经过简化,DDPM提出了一个极其简洁的训练目标:
L_simple(θ) = E_{t, x₀, ε}[ || ε - ε_θ(√(ᾱ_t)·x₀ + √(1-ᾱ_t)·ε, t) ||² ]
即:随机采样时间步 t、真实图像 x₀、高斯噪声 ε,用噪声调度生成 x_t,训练网络 ε_θ 预测添加的噪声 ε。这个简单的 MSE 损失就已经能生成高质量图像。
四、DDPM 关键设计与架构
4.1 噪声预测网络:U-Net + Attention
DDPM采用U-Net架构作为噪声预测网络 ε_θ(x_t, t)。与经典的U-Net不同,扩散模型的U-Net加入了以下几个关键设计:
- 下采样和上采样路径: 编码器逐步降低空间分辨率,解码器逐步恢复分辨率,中间有跳跃连接(skip connections)
- 残差卷积块(ResBlock): 每个分辨率级别包含多个残差块,包含GroupNorm、SiLU激活和卷积层
- 自注意力层(Self-Attention): 在低分辨率特征图上(16×16和8×8)插入多头自注意力机制,捕捉长距离依赖
- 时间步嵌入(Time Embedding): 将时间步 t 编码为特征向量后注入网络
4.2 时间步嵌入:Sinusoidal Positional Encoding
与Transformer中的位置编码类似,扩散模型使用正弦/余弦函数将时间步 t 编码为高维表示:
import torch
import torch.nn as nn
import math
class SinusoidalTimeEmbedding(nn.Module):
def __init__(self, dim):
super().__init__()
self.dim = dim
def forward(self, t):
"""t: shape (batch_size,) - 时间步"""
device = t.device
half_dim = self.dim // 2
embeddings = math.log(10000) / (half_dim - 1)
embeddings = torch.exp(torch.arange(half_dim, device=device) * -embeddings)
embeddings = t[:, None].float() * embeddings[None, :]
embeddings = torch.cat([torch.sin(embeddings), torch.cos(embeddings)], dim=-1)
return embeddings
4.3 SiLU激活函数
DDPM中的U-Net各层使用SiLU(Sigmoid Linear Unit)激活函数,也称为Swish。其表达式为 f(x) = x · σ(x),其中 σ 是sigmoid函数。SiLU保留了负值区域的梯度(不像ReLU会完全截断负值),同时具有平滑的非线性特性,有利于训练深层网络。
4.4 训练流程与采样流程对比
| 阶段 | 步骤 | 说明 |
| 训练 | 1. 从数据集中采样 x₀ | 从训练数据中取一个真实样本 |
| 2. 随机采样 t ~ Uniform(1,T) | 随机选择一个时间步 |
| 3. 采样噪声 ε ~ N(0,I) | 生成高斯噪声 |
| 4. 计算 L = ||ε - ε_θ(√(ᾱ_t)x₀+√(1-ᾱ_t)ε, t)||² | 优化MSE损失,反向传播 |
| 采样 | 1. 采样 x_T ~ N(0,I) | 从纯噪声开始 |
| 2. 对 t = T, T-1, ..., 1: | 逐步去噪 |
| 预测噪声 ε = ε_θ(x_t, t) | 网络预测当前噪声 |
| 计算 x_{t-1} = μ_θ(x_t,t) + σ_t · z | 从条件分布采样 |
| 3. 返回 x₀ | 生成完成 |
五、DDIM 加速采样
DDPM需要1000步采样才能生成高质量图像,速度极慢。DDIM(Denoising Diffusion Implicit Models)通过以下关键创新实现加速:
5.1 隐式模型设计
DDPM的逆向过程是马尔可夫链(每一步只依赖前一步),而DDIM将其重构为非马尔可夫过程:
x_{t-1} = √(ᾱ_{t-1}) · f_θ(x_t) + √(1-ᾱ_{t-1}-σ²_t) · ε_θ(x_t, t) + σ_t · z
其中 f_θ(x_t) = (x_t - √(1-ᾱ_t) · ε_θ(x_t, t)) / √(ᾱ_t) 是模型对 x₀ 的预测。当 σ_t = 0 时,逆向过程变为确定性过程,这正是DDIM加速采样的关键。
5.2 确定性采样与少步生成
设置 σ_t = 0 后,DDIM的采样变为确定性的:
def ddim_step(model, x_t, t, t_prev, alpha_bar_t, alpha_bar_t_prev):
"""使用DDIM从x_t生成x_{t_prev}"""
pred_noise = model(x_t, t)
pred_x0 = (x_t - torch.sqrt(1 - alpha_bar_t) * pred_noise) / torch.sqrt(alpha_bar_t)
pred_dir = torch.sqrt(1 - alpha_bar_t_prev) * pred_noise
x_t_prev = torch.sqrt(alpha_bar_t_prev) * pred_x0 + pred_dir
return x_t_prev
关键洞察:DDIM通过创建一个子序列 {τ₁, τ₂, ..., τ_S} ⊆ {1, 2, ..., T} 来加速。例如从1000步中均匀取50步的子序列,采样质量几乎不下降。这使得DDIM能在50步内达到与DDPM 1000步相当的质量。
5.3 DDPM vs DDIM 对比
| 特性 | DDPM | DDIM |
| 采样步数 | 1000步 | 50-100步 |
| 过程类型 | 随机(马尔可夫链) | 确定性(隐式模型) |
| 采样速度 | 慢 | 快(加速10-50倍) |
| 生成质量 | 优秀 | 与DDPM相当(同等条件) |
| 插值能力 | 无法插值 | 可在潜在空间插值 |
| 训练兼容性 | 专用训练 | 可直接使用DDPM预训练权重 |
六、潜在扩散模型(LDM / Stable Diffusion)
尽管DDPM在图像生成上效果优异,但其直接在像素空间(如256×256×3)上进行扩散的计算成本极高。潜在扩散模型(Latent Diffusion Model, LDM)通过在潜在空间(latent space)中进行扩散,大幅降低了计算开销,Stable Diffusion正是基于这一框架。
6.1 整体架构
┌──────────────────────────────────────────────────────────┐
│ 潜在扩散模型(LDM)架构 │
│ │
│ ┌─────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ VAE │ │ 扩散过程 │ │ VAE │ │
│ │ 编码器 │───▶│ (潜在空间) │───▶│ 解码器 │ │
│ │ E(x) │ │ UNet降噪 │ │ D(z) │ │
│ └─────────┘ └──────┬───────┘ └──────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ 条件注入 │ │
│ │ (Cross-Attn) │ │
│ └──────┬───────┘ │
│ │ │
│ ┌────────────┴────────────┐ │
│ │ 文本嵌入 │ │
│ │ (CLIP Text Encoder) │ │
│ └─────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
6.2 VAE编码到潜在空间
LDM使用预训练的VAE将图像压缩到低维潜在空间。例如,一张 256×256×3 的图像被编码为 32×32×4 的潜在表示,空间维度缩小8倍,显著降低了后续扩散过程的计算量。VAE解码器再将去噪后的潜在表示解码回像素空间。
潜在空间的优势
- 计算效率高: 潜在空间维度远低于像素空间,扩散过程更快
- 感知压缩: VAE编码器自动丢弃高频噪声等感知不重要的信息,让扩散过程聚焦于语义信息
- 高清生成: 在有限的计算资源下支持更高分辨率(512×512、1024×1024等)
- 架构灵活: 潜在空间的高度/宽度只是原图的1/8,使UNet的层数可以更浅
6.3 条件控制:Cross-Attention机制
LDM支持多模态条件控制(文本、图像分割图、深度图等),其中最关键的是跨注意力(Cross-Attention)机制:
class CrossAttentionBlock(nn.Module):
def __init__(self, query_dim, context_dim, n_heads=8):
super().__init__()
self.n_heads = n_heads
self.to_q = nn.Linear(query_dim, query_dim, bias=False)
self.to_k = nn.Linear(context_dim, query_dim, bias=False)
self.to_v = nn.Linear(context_dim, query_dim, bias=False)
self.to_out = nn.Linear(query_dim, query_dim)
def forward(self, x, context):
"""x: U-Net特征图展平 (B, N, C)
context: 条件嵌入 (B, M, D)"""
B, N, C = x.shape
q = self.to_q(x).reshape(B, N, self.n_heads, C//self.n_heads)
k = self.to_k(context).reshape(B, -1, self.n_heads, C//self.n_heads)
v = self.to_v(context).reshape(B, -1, self.n_heads, C//self.n_heads)
q, k, v = q.transpose(1,2), k.transpose(1,2), v.transpose(1,2)
attn = torch.softmax(q @ k.transpose(-2,-1) / math.sqrt(C//self.n_heads), dim=-1)
out = (attn @ v).transpose(1,2).reshape(B, N, C)
return self.to_out(out)
6.4 文本条件与CLIP编码
在文生图(Text-to-Image)中,文本提示经过两个阶段处理:
- CLIP文本编码器: 将文本提示编码为512维或768维的token嵌入序列(77个token)。CLIP(Contrastive Language-Image Pre-training)是OpenAI发布的对比学习模型,其文本编码器能够将语义信息映射到与图像对齐的嵌入空间中
- Cross-Attention注入: 在U-Net的每个分辨率级别上,将CLIP文本嵌入作为Cross-Attention的key和value,U-Net特征作为query,从而使噪声预测过程感知文本语义
"Cross-Attention 是LDM架构中最优雅的设计之一 -- 它让噪声预测网络在每一层都能'看到'文本条件,从而精确控制生成内容。"
七、扩散模型的主要应用领域
7.1 文本到图像生成(Text-to-Image)
这是扩散模型最成熟的应用。用户输入文本描述,模型生成对应的图像。代表性系统包括Stable Diffusion(开源)、DALL-E 3(OpenAI)、Midjourney等。核心流程:文本 → CLIP编码 → LDM扩散采样 → 图像输出。CFG(Classifier-Free Guidance)技术通过放大条件影响提升文本对齐度。
7.2 图像编辑与修复
扩散模型在图像编辑方面展现出惊人的能力。Inpainting(修复)通过"遮罩+条件"的方式:在噪声图像中混合原图的已知区域,模型只补全被遮罩部分。Image-to-Image翻译(如SDEdit)通过向前加噪再反向去噪实现风格迁移。InstructPix2Pix等模型进一步实现了指令式编辑。
7.3 超分辨率(Super-Resolution)
SR3(Image Super-Resolution via Iterative Refinement)等模型将低分辨率图像作为条件,扩散模型学习从噪声恢复出高分辨率细节。这种方法在放大倍数较大时(如4×、8×)仍能保持逼真纹理,显著优于传统方法。
7.4 视频生成
视频扩散模型将2D U-Net扩展到3D(加入时间维度)。OpenAI的Sora采用DiT(Diffusion Transformer)架构,通过时空注意力机制处理视频帧序列。关键挑战在于:① 保持跨帧的时间一致性;② 管理巨大的计算开销;③ 处理可变长度视频。2024年以来,视频扩散模型取得了爆炸式进展。
7.5 3D内容生成
DreamFusion使用预训练的2D扩散模型作为先验,通过Score Distillation Sampling(SDS)损失优化3D场景表示(NeRF或3D高斯点云)。Point-E直接在3D点云数据上训练扩散模型。这些方法大幅降低了3D资产创建的门槛。
扩散模型应用全景图
- 图像: 文生图、图生图、图像编辑、图像修复、超分辨率、调色上色
- 视频: 文生视频、视频编辑、视频预测、帧插值
- 3D: 文生3D、3D感知扩散、多视角生成
- 音频: 语音合成、音乐生成(AudioLDM 2)
- 科学: 蛋白质结构生成、分子构象生成、药物设计
八、PyTorch简化扩散模型完整实现
以下是一个简化的DDPM实现,包含噪声调度、U-Net原型、训练循环和采样过程。该实现去除了复杂的优化技巧(如EMA、自适应分组归一化等),聚焦于扩散模型的核心逻辑。
8.1 噪声调度器(Noise Scheduler)
class NoiseScheduler:
def __init__(self, T=1000, beta_start=1e-4, beta_end=0.02, schedule="linear"):
self.T = T
if schedule == "linear":
self.betas = torch.linspace(beta_start, beta_end, T)
elif schedule == "cosine":
steps = torch.arange(T + 1, dtype=torch.float32) / T
alpha_bar = torch.cos((steps + 0.008) / 1.008 * math.pi / 2) ** 2
alpha_bar = alpha_bar / alpha_bar[0]
self.betas = 1 - alpha_bar[1:] / alpha_bar[:-1]
self.betas = torch.clamp(self.betas, max=0.999)
self.alphas = 1.0 - self.betas
self.alpha_bars = torch.cumprod(self.alphas, dim=0)
def add_noise(self, x0, noise, t):
"""前向过程:根据时间步t向x0添加噪声"""
sqrt_alpha_bar = torch.sqrt(self.alpha_bars[t])[:, None, None, None]
sqrt_one_minus = torch.sqrt(1 - self.alpha_bars[t])[:, None, None, None]
return sqrt_alpha_bar * x0 + sqrt_one_minus * noise
def sample_prev_timestep(self, model_pred, x_t, t):
"""反向单步:从x_t生成x_{t-1}"""
alpha = self.alphas[t][:, None, None, None]
alpha_bar = self.alpha_bars[t][:, None, None, None]
beta = self.betas[t][:, None, None, None]
pred_x0 = (x_t - torch.sqrt(1 - alpha_bar) * model_pred) / torch.sqrt(alpha_bar)
pred_mean = (x_t - beta / torch.sqrt(1 - alpha_bar) * model_pred) / torch.sqrt(alpha)
if t[0].item() == 0:
return pred_mean, pred_x0
noise = torch.randn_like(x_t)
sigma = torch.sqrt(beta)
return pred_mean + sigma * noise, pred_x0
8.2 简化U-Net实现
class SimpleUNet(nn.Module):
def __init__(self, in_channels=3, time_dim=256):
super().__init__()
self.time_embed = SinusoidalTimeEmbedding(time_dim)
self.time_proj = nn.Sequential(
nn.Linear(time_dim, time_dim),
nn.SiLU(),
nn.Linear(time_dim, time_dim)
)
self.enc1 = nn.Sequential(
nn.Conv2d(in_channels, 64, 3, padding=1),
nn.GroupNorm(8, 64), nn.SiLU()
)
self.enc2 = nn.Sequential(
nn.Conv2d(64, 128, 4, stride=2, padding=1),
nn.GroupNorm(16, 128), nn.SiLU()
)
self.enc3 = nn.Sequential(
nn.Conv2d(128, 256, 4, stride=2, padding=1),
nn.GroupNorm(32, 256), nn.SiLU()
)
self.mid = nn.Sequential(
nn.Conv2d(256, 256, 3, padding=1),
nn.GroupNorm(32, 256), nn.SiLU(),
nn.Conv2d(256, 256, 3, padding=1),
nn.GroupNorm(32, 256), nn.SiLU()
)
self.time_inject1 = nn.Linear(time_dim, 64)
self.time_inject2 = nn.Linear(time_dim, 128)
self.time_inject3 = nn.Linear(time_dim, 256)
self.dec3 = nn.Sequential(
nn.Conv2d(512, 256, 3, padding=1),
nn.GroupNorm(32, 256), nn.SiLU()
)
self.dec2 = nn.Sequential(
nn.Conv2d(384, 128, 3, padding=1),
nn.GroupNorm(16, 128), nn.SiLU()
)
self.dec1 = nn.Sequential(
nn.Conv2d(192, 64, 3, padding=1),
nn.GroupNorm(8, 64), nn.SiLU()
)
self.out = nn.Conv2d(64, in_channels, 3, padding=1)
def forward(self, x, t):
te = self.time_proj(self.time_embed(t))
e1 = self.enc1(x)
e1 = e1 + self.time_inject1(te)[:, :, None, None]
e2 = self.enc2(e1)
e2 = e2 + self.time_inject2(te)[:, :, None, None]
e3 = self.enc3(e2)
e3 = e3 + self.time_inject3(te)[:, :, None, None]
m = self.mid(e3)
d3 = self.dec3(torch.cat([m, e3], dim=1))
d2 = self.dec2(torch.cat([d3, e2], dim=1))
d1 = self.dec1(torch.cat([d2, e1], dim=1))
return self.out(d1)
8.3 训练循环
def train_diffusion(model, dataloader, scheduler, epochs, lr=1e-4, device="cuda"):
model.train()
optimizer = torch.optim.AdamW(model.parameters(), lr=lr)
loss_fn = nn.MSELoss()
for epoch in range(epochs):
total_loss = 0
for x0, _ in dataloader:
x0 = x0.to(device)
batch_size = x0.shape[0]
t = torch.randint(0, scheduler.T, (batch_size,), device=device)
noise = torch.randn_like(x0)
x_t = scheduler.add_noise(x0, noise, t)
pred_noise = model(x_t, t)
loss = loss_fn(pred_noise, noise)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
if (epoch + 1) % 10 == 0:
print(f"Epoch {epoch+1}/{epochs}, Loss: {total_loss/len(dataloader):.6f}")
8.4 采样(生成)过程
@torch.no_grad()
def sample(model, scheduler, n_samples=16, image_size=(3, 32, 32), device="cuda"):
model.eval()
x_t = torch.randn(n_samples, *image_size, device=device)
for t in range(scheduler.T - 1, -1, -1):
t_batch = torch.full((n_samples,), t, device=device, dtype=torch.long)
pred_noise = model(x_t, t_batch)
x_t, _ = scheduler.sample_prev_timestep(pred_noise, x_t, t_batch)
return x_t
PyTorch实现要点总结
- 训练非常简单:MSE Loss + 预测噪声,没有任何对抗训练或其他复杂技巧
- U-Net的时间步注入通过逐层加法实现,确保网络知道当前是第几步
- 调度器封装了前向加噪和反向去噪的全部数学计算
- 采样过程是反向迭代(从T到1),每一步调用模型并计算均值
- 完整的生产级实现还需加入:EMA(指数移动平均)、自适应分组归一化(Adaptive GroupNorm)、Classifier-Free Guidance等
九、核心要点总结
扩散模型关键概念速查
- 前向过程: 马尔可夫链逐步加噪,重参数化可一步计算任意步 x_t
- 反向过程: 学习去噪网络 p_θ(x_{t-1}|x_t),预测所添加的噪声 ε_θ
- 训练目标: L_simple = E[||ε - ε_θ(x_t, t)||^2],即预测噪声与真实噪声的MSE
- 噪声调度: 线性调度简单有效,余弦调度在高对数似然任务中更优
- DDIM加速: 非马尔可夫确定性采样,50步达到DDPM 1000步的质量,10-50倍加速
- 潜在扩散LDM: VAE编码到潜在空间 + Cross-Attention条件注入 = Stable Diffusion
- U-Net架构: 编码器-解码器 + 跳跃连接 + 自注意力 + 时间嵌入
- Cross-Attention: 文本条件(CLIP嵌入)通过QKV注意力注入U-Net每层
- 应用范围: 文生图、图像编辑、超分辨率、视频生成、3D生成、音频生成
- CFG引导: Classifier-Free Guidance通过混合条件/无条件预测增强文本对齐度
十、进一步思考与实践
自学路径建议
- 理解数学基础: 掌握变分推理(ELBO推导)、重参数化技巧、高斯分布性质
- 阅读原始论文: DDPM(Ho et al. 2020)、DDIM(Song et al. 2021)、LDM(Rombach et al. 2022)
- 复现基础模型: 在MNIST/CIFAR-10上训练DDPM,用TensorBoard监控训练过程
- 探索高级架构: DiT(Diffusion Transformer)、Rectified Flow、Consistency Model
- 实践LDM: 使用Hugging Face Diffusers库,尝试微调Stable Diffusion
- 关注前沿方向: 视频扩散(Sora架构)、3D扩散、AI for Science中的扩散应用
扩散模型代表了生成式AI在数学优雅性和实际效果之间的最佳平衡之一。其训练稳定、质量优越、架构灵活,已成为现代机器学习工程师必须掌握的核心技术。从DDPM到Stable Diffusion再到Sora,扩散模型的发展远未停止,后续值得重点关注的方向包括:加速采样(一致性模型、Flow Matching)、更大规模的DiT架构、多模态统一生成等。
"扩散模型的美妙之处在于它的简洁 -- 前向过程只是不断加噪,反向过程只是学习去噪,但通过对噪声调度和时间步的精心设计,这个简单的框架能够生成令人惊叹的复杂数据分布。"
关键资源
- 论文: DDPM (arXiv:2006.11239), DDIM (arXiv:2010.02502), LDM (arXiv:2112.10752)
- 代码库: Hugging Face Diffusers (github.com/huggingface/diffusers), OpenAI Improved DDPM
- 博客: Lilian Weng "What are Diffusion Models?", "扩散模型"系列技术博客
- 课程: Stanford CS236 (Deep Generative Modeling), Hugging Face Diffusion Models Course