💡

文章摘要

系统讲解扩散模型的三大数学框架:DDPM(去噪扩散概率模型)、Score-Based Generative Models(基于分数的生成模型)与 SDE(随机微分方程)统一框架。从变分下界推导到前向/反向马尔可夫链,从 Score Matching 到 Langevin Dynamics 采样,从离散时间到连续时间的统一视角。一篇讲透扩散模型背后的全部数学原理,为理解 Flow Matching、Stable Diffusion、DALL·E 等现代生成系统奠定坚实基础。

一、为什么扩散模型需要如此多的数学?

扩散模型Diffusion Models) 是 2020-2026 年最成功的生成模型家族。Stable Diffusion、DALL·E 2/3、Imagen、Midjourney 背后都是扩散模型。2025 年的 Flow Matching(见 dl-022)虽然提出了更简洁的训练范式,但其动机和优势只有理解了经典扩散模型的数学才能深刻体会。

扩散模型的核心思想极其优雅:

  1. 前向过程:逐步向数据添加高斯噪声,直到数据变成纯噪声
  2. 反向过程:训练一个神经网络逐步去噪,从纯噪声恢复出数据

但「优雅」的背后是深层的数学。理解扩散模型需要掌握四个数学支柱:

数学支柱 核心概念 扩散模型中的角色
概率图模型 马尔可夫链、条件概率 前向/反向过程的建模
变分推断 ELBO、KL 散度 训练目标的推导
随机过程 SDE、布朗运动 连续时间统一框架
Score 函数 对数密度梯度、Langevin 动力学 采样算法的核心

缺少任何一个支柱,你对扩散模型的理解都是不完整的。本文的目标是从零开始,完整推导这三个框架的数学,并证明它们本质上是等价的。

💡 一句话理解

扩散模型的美在于:前向过程是精确已知的(不需要学习),反向过程是唯一需要学习的部分。这种「一半已知、一半学习」的设计是它训练稳定的根本原因——相比 GAN 的两个网络互相博弈。

二、DDPM:去噪扩散概率模型

DDPMDenoising Diffusion Probabilistic Models 由 Ho et al. (2020) 提出,是扩散模型最具影响力的具体实现。它的数学框架基于离散时间的马尔可夫链

2.1 前向过程:逐步加噪

定义数据分布 (x_0 \sim q(x_0))。给定一组噪声调度(noise schedule) (\beta_1, \beta_2, \ldots, \beta_T)(其中 (\beta_t \in (0, 1))),前向过程定义为:

$$q(x_t | x_{t-1}) = \mathcal{N}(x_t; \sqrt{1 - \beta_t} , x_{t-1}, , \beta_t I)$$

即每一步都向 (x_{t-1}) 添加方差为 (\beta_t) 的高斯噪声,同时乘以 (\sqrt{1-\beta_t}) 进行缩放。

关键性质:任意时刻的边际分布可解析计算。 利用高斯分布的叠加性质,定义 (\alpha_t = 1 - \beta_t),(\bar{\alpha}t = \prod{s=1}^t \alpha_s),则:

$$q(x_t | x_0) = \mathcal{N}(x_t; \sqrt{\bar{\alpha}_t} , x_0, , (1 - \bar{\alpha}_t) I)$$

这意味着我们可以一步跳到任意时刻 t,不需要逐步模拟前向过程。采样公式为:

$$x_t = \sqrt{\bar{\alpha}_t} , x_0 + \sqrt{1 - \bar{\alpha}_t} , \epsilon, \quad \epsilon \sim \mathcal{N}(0, I)$$

这个性质对训练至关重要——训练时可以随机采样时间步 t,然后直接用上述公式得到 (x_t),不需要模拟整个前向链。

噪声调度 (\beta_t) 的选择

  • 原始 DDPM 使用线性调度:(\beta_t) 从 (10^{-4}) 线性增长到 (0.02)
  • Improved DDPM (Nichol & Dhariwal, 2021) 使用余弦调度,效果更好
  • 调度的选择直接影响生成质量和采样效率
python
ddpm_forward.py
import torch
import numpy as np

def linear_beta_schedule(T, beta_start=1e-4, beta_end=0.02):
    """线性噪声调度"""
    return torch.linspace(beta_start, beta_end, T)

def cosine_beta_schedule(T, s=0.008):
    """余弦噪声调度 (Nichol & Dhariwal, 2021)"""
    steps = torch.arange(T + 1, dtype=torch.float64)
    alpha_bar = torch.cos(((steps / T) + s) / (1 + s) * np.pi / 2) ** 2
    alpha_bar = alpha_bar / alpha_bar[0]
    betas = 1 - (alpha_bar[1:] / alpha_bar[:-1])
    return betas.clamp(max=0.999)

def q_sample(x_0, t, betas):
    """前向过程:从 x_0 直接采样 x_t"""
    alphas = 1.0 - betas
    alphas_cumprod = torch.cumprod(alphas, dim=0)
    
    # 收集对应时间步的 alpha_bar
    sqrt_alpha_bar = torch.sqrt(alphas_cumprod[t])
    sqrt_one_minus_alpha_bar = torch.sqrt(1.0 - alphas_cumprod[t])
    
    #  reshape for broadcasting
    while sqrt_alpha_bar.dim() < x_0.dim():
        sqrt_alpha_bar = sqrt_alpha_bar.unsqueeze(-1)
        sqrt_one_minus_alpha_bar = sqrt_one_minus_alpha_bar.unsqueeze(-1)
    
    noise = torch.randn_like(x_0)
    return sqrt_alpha_bar * x_0 + sqrt_one_minus_alpha_bar * noise

三、DDPM 训练目标:变分下界(ELBO)

DDPM 的训练目标通过变分推断(Variational Inference) 推导。我们的目标是最大化数据的对数似然 (\log p(x_0)),但由于反向过程的复杂性,直接计算不可行。

3.1 变分下界推导

将反向过程参数化为:
$$p_\theta(x_{t-1} | x_t) = \mathcal{N}(x_{t-1}; \mu_\theta(x_t, t), \Sigma_\theta(x_t, t))$$

完整的生成过程为 (p_\theta(x_{0:T}) = p(x_T) \prod_{t=1}^T p_\theta(x_{t-1}|x_t))。

对数似然的变分下界(ELBO / Evidence Lower BOund):

$$\mathcal{L} = \mathbb{E}q\left[\log p\theta(x_{0:T}) - \log q(x_{1:T}|x_0)\right]$$

展开后可以分为四项:

$$\mathcal{L} = \underbrace{\mathbb{E}q[-\log p(x_T)]}{L_T} + \sum_{t=2}^{T} \underbrace{\mathbb{E}q[D{KL}(q(x_{t-1}|x_t,x_0) | p_\theta(x_{t-1}|x_t))]}{L{t-1}} + \underbrace{\mathbb{E}q[-\log p\theta(x_0|x_1)]}_{L_0}$$

关键推导步骤

  1. (L_T) 是常数:因为前向过程在 (T) 足够大时 (q(x_T) \approx \mathcal{N}(0, I)),与模型参数无关,可以忽略。

  2. (L_{t-1}) 可以解析计算:由于 (q) 和 (p_\theta) 都是高斯分布,KL 散度有封闭解。

  3. 简化假设:Ho et al. 固定 (\Sigma_\theta(x_t, t) = \sigma_t^2 I)(不学习方差),只学习均值 (\mu_\theta)。

3.2 简化训练目标

经过代数化简(利用高斯 KL 的公式),(L_{t-1}) 可以写成:

$$L_{t-1} = \mathbb{E}_{t, x_0, \epsilon}\left[\frac{\beta_t^2}{2\sigma_t^2 \alpha_t (1-\bar{\alpha}t)} | \epsilon - \epsilon\theta(x_t, t) |^2\right]$$

其中 (\epsilon_\theta(x_t, t)) 是网络预测的噪声,(\epsilon) 是实际添加的噪声。

丢弃权重系数后的简化目标

$$\mathcal{L}{\text{simple}} = \mathbb{E}{t, x_0, \epsilon}\left[| \epsilon - \epsilon_\theta(x_t, t) |^2\right]$$

这就是 DDPM 最终使用的训练目标——简单的 MSE 损失,预测添加的噪声。

这个简化目标之所以有效,是因为:

  • 权重系数 (\frac{\beta_t^2}{2\sigma_t^2 \alpha_t (1-\bar{\alpha}_t)}) 在不同时间步的变化相对平缓
  • 简化后模型在所有时间步上均匀学习,反而效果更好
  • 网络用 U-Net 架构,输入 (x_t) 和时间步 (t),输出预测噪声 (\epsilon_\theta)

⚠️ 常见踩坑

ELBO 推导中有一个微妙之处:(q(x_{t-1}|x_t, x_0)) 是后验分布,可以通过贝叶斯定理从前向过程解析计算。这个后验是训练时的「教师信号」——它告诉我们,如果知道原始数据 (x_0),反向去噪的最优策略是什么。

四、Score Matching:基于分数的生成模型

Score-Based Generative ModelsDDPM 几乎同时期发展,但走了一条不同的数学路径。核心概念是 Score 函数Score Matching

4.1 Score 函数

给定数据分布 (p(x)),其 score 函数定义为对数密度的梯度

$$\nabla_x \log p(x)$$

Score 函数的直觉:它指向数据密度增长最快的方向。在数据密集区域,score 的模较小(已经在高密度区);在数据稀疏区域,score 指向最近的数据流形。

4.2 Langevin Dynamics:用 Score 采样

Langevin Dynamics 是一种仅使用 score 函数就能从分布中采样的迭代算法:

$$x^{(k+1)} = x^{(k)} + \frac{\eta}{2} \nabla_x \log p(x^{(k)}) + \sqrt{\eta} , z^{(k)}, \quad z^{(k)} \sim \mathcal{N}(0, I)$$

其中 (\eta) 是步长。当 (\eta \to 0) 且迭代次数 (K \to \infty) 时,(x^{(K)}) 的分布收敛到 (p(x))。

这个定理的深刻之处在于:我们不需要知道 (p(x)) 的归一化常数,只需要知道 score(梯度和归一化常数无关)。

4.3 Score Matching:学习 Score

问题是,真实的 score (\nabla_x \log p(x)) 是未知的。Hyvärinen (2005) 提出了 Score Matching 方法,通过最小化以下目标来估计 score:

$$J(\theta) = \mathbb{E}{p(x)}\left[| s\theta(x) - \nabla_x \log p(x) |^2\right]$$

直接计算这个目标需要知道真实的 score(不可知)。Hyvärinen 的关键贡献是通过分部积分(Integration by Parts) 将目标转化为不需要知道真实 score 的形式:

$$J(\theta) = \mathbb{E}{p(x)}\left[\text{tr}(\nabla_x s\theta(x)) + \frac{1}{2}|s_\theta(x)|^2\right]$$

但这个目标需要计算 (s_\theta) 的 Jacobian 的迹,在高维空间中计算代价极大。

4.4 降噪 Score Matching(Denoising Score Matching)

Vincent (2011) 提出了降噪 Score Matching(DSM),解决了上述问题。核心思想:

  1. 用噪声扰动数据:(q_\sigma(\tilde{x}|x) = \mathcal{N}(\tilde{x}; x, \sigma^2 I))
  2. 训练网络预测原始数据:(\min_\theta \mathbb{E}[|s_\theta(\tilde{x}) - \nabla_x \log q_\sigma(\tilde{x}|x)|^2])
  3. 由于 (\nabla_x \log q_\sigma(\tilde{x}|x) = -(\tilde{x} - x)/\sigma^2),目标简化为:

$$\min_\theta \mathbb{E}{x, \tilde{x}}\left[\left|s\theta(\tilde{x}) + \frac{\tilde{x} - x}{\sigma^2}\right|^2\right]$$

关键洞察:DSM 等价于去噪任务——给定被噪声破坏的 (\tilde{x}),预测噪声 ((\tilde{x} - x)/\sigma^2)。这与 DDPM 的噪声预测目标在数学上完全等价!

4.5 多噪声级别 Score Matching

单一噪声级别的问题是:低密度区域的 score 估计不准确。Song & Ermon (2019) 提出使用多个噪声级别 (\sigma_1 < \sigma_2 < \ldots < \sigma_L):

$$\min_\theta \sum_{i=1}^L \lambda_i , \mathbb{E}_{x, \tilde{x}i}\left[\left|s\theta(\tilde{x}_i, \sigma_i) + \frac{\tilde{x}_i - x}{\sigma_i^2}\right|^2\right]$$

采样时使用退火 Langevin Dynamics:从最大噪声 (\sigma_L) 开始,逐步降低到 (\sigma_1),在每个噪声级别上运行若干步 Langevin 采样。

python
denoising_score_matching.py
import torch
import torch.nn as nn

class ScoreNetwork(nn.Module):
    """预测 score 的神经网络(噪声条件)"""
    def __init__(self, data_dim, hidden_dim=256, n_noise_levels=10):
        super().__init__()
        self.noise_embed = nn.Embedding(n_noise_levels, hidden_dim)
        self.net = nn.Sequential(
            nn.Linear(data_dim + hidden_dim, hidden_dim),
            nn.SiLU(),
            nn.Linear(hidden_dim, hidden_dim),
            nn.SiLU(),
            nn.Linear(hidden_dim, data_dim)
        )
    
    def forward(self, x_noisy, sigma_idx):
        noise_emb = self.noise_embed(sigma_idx)
        h = torch.cat([x_noisy, noise_emb], dim=-1)
        return self.net(h)

def dsm_loss(model, x_0, sigma, sigma_idx):
    """降噪 Score Matching 损失"""
    noise = torch.randn_like(x_0)
    x_noisy = x_0 + sigma * noise
    
    score_pred = model(x_noisy, sigma_idx)
    # 目标 score = -(x_noisy - x_0) / sigma^2
    target_score = -noise / sigma
    
    return ((score_pred - target_score) ** 2).sum(dim=-1).mean()

@torch.no_grad()
def annealed_langevin_sample(model, sigmas, n_steps_each=100, 
                              step_size=0.5, dim=2, batch_size=1000):
    """退火 Langevin Dynamics 采样"""
    device = next(model.parameters()).device
    x = torch.randn(batch_size, dim, device=device) * sigmas[0]
    
    for i, sigma in enumerate(sigmas):
        sigma_idx = torch.tensor([i], device=device)
        for _ in range(n_steps_each):
            score = model(x, sigma_idx)
            x = x + step_size * score + torch.randn_like(x) * (2 * step_size) ** 0.5
    
    return x

五、SDE 统一框架:从离散到连续

Song et al. (2021) 提出了随机微分方程(SDE)框架,将 DDPM 和 Score-Based Models 统一在连续时间的数学框架下。这是扩散模型理论的一次重大统一。

5.1 前向 SDE

将离散的前向马尔可夫链 (q(x_t|x_{t-1}) = \mathcal{N}(\sqrt{1-\beta_t}x_{t-1}, \beta_t I)) 视为 Euler-Maruyama 离散化,对应的连续时间 SDE 为:

$$dx = f(x, t) , dt + g(t) , dw$$

其中:

  • (f(x, t)) 是漂移系数(drift)
  • (g(t)) 是*扩散系数(diffusion
  • (w) 是标准布朗运动(Brownian motion / Wiener process)

两种标准 SDE

SDE 类型 漂移 (f(x,t)) 扩散 (g(t)) 对应离散模型
VP-SDE (Variance Preserving) (-\frac{1}{2}\beta(t)x) (\sqrt{\beta(t)}) DDPM
VE-SDE (Variance Exploding) (0) (\sqrt{\frac{d[\sigma^2(t)]}{dt}}) NCSN

VP-SDE 的前向过程保持方差有界(数据逐渐变成标准正态),VE-SDE 让方差随时间单调递增。

5.2 反向 SDE

Anderson (1982) 证明了任何 SDE 都有时间反转,反向 SDE 为:

$$dx = \left[f(x, t) - g^2(t) \nabla_x \log p_t(x)\right] dt + g(t) , d\bar{w}$$

其中 (\bar{w}) 是反向时间的布朗运动,(\nabla_x \log p_t(x)) 是时刻 (t) 的 score 函数。

这个公式的深刻含义

  • 反向过程的漂移 = 前向漂移 - 扩散系数的平方 × score
  • 只需要知道 score 函数就能反转任何前向扩散过程
  • Score 网络 (s_\theta(x, t) \approx \nabla_x \log p_t(x)) 替代了真实的 score

5.3 概率流 ODE

SDE 框架还有一个惊人的性质:每个 SDE 都对应一个确定性 ODE(常微分方程),称为概率流 ODE(Probability Flow ODE)

$$dx = \left[f(x, t) - \frac{1}{2}g^2(t) \nabla_x \log p_t(x)\right] dt$$

概率流 ODE 的关键性质:

  1. 与 SDE 共享边际分布:在任意时刻 t,ODE 的解的分布等于 SDE 的解的分布
  2. 确定性:没有随机项,给定初始条件,轨迹唯一
  3. 可逆:可以精确地从 (t=0) 积分到 (t=T) 再反向积分回来
  4. 似然计算:通过 ODE 的变量替换公式,可以精确计算数据似然 (p(x_0))

5.4 三种采样方法的统一

方法 类型 步数 似然计算 质量
反向 SDE(Euler-Maruyama) 随机 多步(~1000)
概率流 ODE(RK45) 确定性 少步(~100)
DDPM(离散) 随机 多步(~1000)
DDIM 确定性 少步(~50) 较好

DDIMDenoising Diffusion Implicit Models)实际上是概率流 ODE 的一种离散化形式——这个联系在 SDE 框架下变得自然。

图表加载中…

六、DDPM 与 Score Matching 的等价性

一个经常被忽视的事实是:DDPM 的噪声预测目标和 Score Matching 的目标在数学上完全等价。这个等价性通过 Tweedie's Formula 建立。

6.1 Tweedie's Formula

Tweedie (1956) 证明了一个优美的结果:如果 (x_t = \sqrt{\bar{\alpha}_t} x_0 + \sqrt{1-\bar{\alpha}_t} \epsilon),则:

$$\nabla_{x_t} \log p_t(x_t) = -\frac{1}{\sqrt{1-\bar{\alpha}_t}} \mathbb{E}[\epsilon | x_t]$$

score 函数正比于条件期望噪声

6.2 等价性证明

DDPM 训练的网络 (\epsilon_\theta(x_t, t)) 预测噪声。将其转换为 score 估计:

$$s_\theta(x_t, t) = -\frac{1}{\sqrt{1-\bar{\alpha}t}} \epsilon\theta(x_t, t)$$

Score Matching 的目标是:

$$\mathbb{E}\left[|s_\theta(x_t, t) - \nabla_{x_t} \log p_t(x_t)|^2\right]$$

代入 Tweedie 公式:

$$= \frac{1}{1-\bar{\alpha}t} \mathbb{E}\left[|\epsilon\theta(x_t, t) - \epsilon|^2\right]$$

这与 DDPM 的 MSE 损失只差一个常数因子 (\frac{1}{1-\bar{\alpha}_t})!

结论DDPM 和 Score-Based Models 不是两个不同的方法,而是同一个方法的两种参数化DDPM 预测噪声,Score-Based Models 预测 score,两者通过 Tweedie 公式线性对应。

6.3 实践中的差异

虽然数学等价,但不同参数化在实践中有不同特点:

参数化 预测目标 优势 代表工作
噪声预测 (\epsilon_\theta) 添加的噪声 训练稳定,直觉清晰 DDPM, Stable Diffusion
Score 预测 (s_\theta) 对数密度梯度 理论优雅,连接经典统计 NCSN, Score SDE
数据预测 (x_\theta) 原始数据 某些场景质量更好 Imagen, DALL·E
速度预测 (v_\theta) 前向过程速度 训练更稳定 Flow Matching (dl-022)

三种参数化之间的关系:
$$\epsilon_\theta = \frac{x_t - \sqrt{\bar{\alpha}t} x\theta}{\sqrt{1-\bar{\alpha}_t}} = \frac{\sqrt{\bar{\alpha}t}(x_t - x\theta) + \sqrt{1-\bar{\alpha}t} \epsilon\theta'}{\sqrt{1-\bar{\alpha}_t}}$$

2024-2026 年的趋势是 v-prediction(速度预测)Flow Matching,它们在数学上更统一,训练更稳定。

💡 一句话理解

理解 DDPM ↔ Score Matching 等价性的关键是 Tweedie 公式。记住一句话:「预测噪声 = 预测 score = 预测数据」,只是参数化不同。

七、采样加速:从 1000 步到 1 步

扩散模型的采样需要多步迭代,这是其最大劣势。从 1000 步加速到 1-4 步是 2023-2026 年的核心研究方向。

7.1 高阶 ODE 求解器

概率流 ODE 可以用高阶求解器加速:

  • DPM-Solver (Lu et al., 2022):二阶/三阶多步求解器,10-20 步达到高质量
  • DPM-Solver++ (Lu et al., 2023):改进的稳定性,5-10 步
  • UniPC (Zhao et al., 2023):统一预测-校正框架,5 步

核心思想:利用 ODE 解的半线性结构(linear + nonlinear),对线性部分精确求解,对非线性部分用高阶近似。

7.2 一致性模型(Consistency Models)

Song et al. (2023) 提出一致性模型,直接学习从任意噪声水平到数据的映射:

$$f_\theta(x_t, t) = f_\theta(x_{t'}, t') = x_0 \quad \forall t, t'$$

即对同一条 ODE 轨迹上的任意两点,模型输出相同的数据点 (x_0)。

训练方式:

  1. 预训练蒸馏:从已训练好的扩散模型蒸馏
  2. 独立训练:通过一致性损失直接训练

一致性模型可以实现单步生成,但质量通常低于多步采样。

7.3 蒸馏方法

  • Progressive Distillation (Salimans & Knowles, 2022):每轮将步数减半,2-4 轮达到 4 步
  • Latent Consistency Models (LCM) (Luo et al., 2023):在潜空间训练一致性模型,1-4 步生成
  • Adversarial Diffusion Distillation (ADD) (Sauer et al., 2024):结合 GAN 判别器,1-4 步达到 SOTA

7.4 2026 年现状

方法 步数 FID (ImageNet 256) 速度
DDPM 1000 2.9 很慢
DDIM 50 4.2
DPM-Solver++ 10 3.5
LCM 4 3.8 很快
SDXL Turbo (ADD) 1-4 2.5 极快
Flow Matching (Rectified Flow) 1-4 2.1 极快

Flow Matching(dl-022)通过直线化 ODE 路径,在少步采样上展现了最优性能,是当前最先进的范式。

⚠️ 常见踩坑

采样步数与生成质量之间存在 trade-off。生产环境中通常使用 20-50 步(DPM-Solver++ 或 DDIM),兼顾质量和速度。单步生成适合实时交互场景,但质量有损。

八、潜空间扩散模型:Stable Diffusion 的核心

像素空间的扩散模型计算成本极高。一张 512×512×3 的图像有 786,432 个像素值,每一步去噪都需要一个完整的 U-Net 前向传播。

8.1 核心思想

Latent Diffusion Models (LDM) (Rombach et al., 2022) 的核心思想:

  1. 先用自编码器 (\mathcal{E}) 将图像压缩到潜空间:(z = \mathcal{E}(x))
  2. 在潜空间 (z) 上训练扩散模型
  3. 生成时先在潜空间采样,再用解码器 (\mathcal{D}) 解码:(\hat{x} = \mathcal{D}(\hat{z}))

Stable Diffusion 就是 LDM 的开源实现,使用预训练的 VQGAN 或 KL-VAE 的编码器/解码器。

8.2 数学形式

设编码器 (\mathcal{E}: \mathbb{R}^{H \times W \times 3} \to \mathbb{R}^{h \times w \times c}),通常压缩比为 8(即 (h = H/8, w = W/8))。

扩散过程在潜空间进行:

$$q(z_t | z_{t-1}) = \mathcal{N}(z_t; \sqrt{1-\beta_t} z_{t-1}, \beta_t I)$$

训练目标:

$$\mathcal{L} = \mathbb{E}{z_0, t, \epsilon}\left[|\epsilon - \epsilon\theta(z_t, t, c)|^2\right]$$

其中 (c) 是条件信息(文本嵌入等),通过 Cross-Attention 注入 U-Net。

8.3 条件注入:Cross-Attention

文本条件通过预训练的 CLIP 或 T5 编码器生成嵌入 (c = \text{Encoder}(\text{text})),然后通过 Cross-Attention 注入 U-Net 的每一层:

$$\text{CrossAttn}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d}}\right) V$$

其中 (Q) 来自 U-Net 的隐状态,(K, V) 来自文本嵌入。

8.4 计算效率对比

空间 维度 单步 FLOPs 内存
像素空间 (512²) 786K ~100 GFLOPs ~4 GB
潜空间 (64², c=4) 16K ~2 GFLOPs ~0.5 GB

潜空间扩散将计算量降低了约 50 倍,这就是 Stable Diffusion 能在消费级 GPU 上运行的原因。

python
latent_diffusion_concept.py
# 潜空间扩散的核心流程(伪代码)

# 1. 训练阶段
# ============
# 预训练 VAE
vae = KL_VAE(pretrained=True)  # 编码器 E, 解码器 D

# 冻结 VAE,只训练扩散 U-Net
unet = UNet(in_channels=4, condition_dim=768)  # 潜空间通道数 c=4
optimizer = Adam(unet.parameters(), lr=1e-4)

for x_0 in dataloader:  # x_0: 512x512x3 图像
    # 编码到潜空间
    z_0 = vae.encode(x_0)  # 512x512x3 → 64x64x4
    
    # 随机采样时间步和噪声
    t = torch.randint(0, T, (1,))
    noise = torch.randn_like(z_0)
    
    # 前向加噪
    z_t = q_sample(z_0, t, betas)  # z_t = sqrt(alpha_bar)*z_0 + sqrt(1-alpha_bar)*noise
    
    # 预测噪声
    text_embed = clip_encoder(text)  # 768 维文本嵌入
    noise_pred = unet(z_t, t, condition=text_embed)
    
    # MSE 损失
    loss = F.mse_loss(noise_pred, noise)
    loss.backward()

# 2. 生成阶段
# ============
z_T = torch.randn(1, 4, 64, 64)  # 从纯噪声开始
for t in reversed(range(T)):
    noise_pred = unet(z_t, t, condition=text_embed)
    z_t = ddpm_step(z_t, t, noise_pred)  # 去噪一步

x_0 = vae.decode(z_t)  # 64x64x4 → 512x512x3

八点五、Classifier-Free Guidance:条件生成的核心技巧

文本到图像模型(Stable Diffusion、DALL·E 2/3)的质量很大程度上取决于 Classifier-Free GuidanceCFG。这是 Ho & Salimans (2022) 提出的条件生成技巧,无需额外训练分类器即可增强条件控制。

8.5.1 条件扩散的数学形式

条件扩散模型学习 (p_\theta(x_{t-1}|x_t, c)),其中 (c) 是条件(文本嵌入、类别标签等)。训练时使用标准 MSE 损失:

$$\mathcal{L} = \mathbb{E}{t, x_0, \epsilon, c}\left[|\epsilon - \epsilon\theta(x_t, t, c)|^2\right]$$

8.5.2 CFG 的推导

CFG 的核心思想:在采样时,同时计算条件预测无条件预测,然后线性外推:

$$\tilde{\epsilon}\theta(x_t, t, c) = \epsilon\theta(x_t, t, \emptyset) + w \cdot \left(\epsilon_\theta(x_t, t, c) - \epsilon_\theta(x_t, t, \emptyset)\right)$$

其中 (w) 是 guidance scale(通常 7-12),(\emptyset) 表示空条件。

直觉解释

  • (\epsilon_\theta(x_t, t, c) - \epsilon_\theta(x_t, t, \emptyset)) 是「条件方向」——从无条件预测指向条件预测的方向
  • 乘以 (w > 1) 后,模型被「推向」更符合条件 (c) 的生成结果
  • (w = 1) 时退化为普通条件采样;(w) 过大则图像过饱和、细节丢失

8.5.3 训练时的关键技巧

CFG 要求模型同时学会有条件无条件去噪。训练时以概率 (p_{\text{uncond}})(通常 10-20%)将条件 (c) 替换为空条件 (\emptyset):

$$c' = \begin{cases} c & \text{with probability } 1 - p_{\text{uncond}} \ \emptyset & \text{with probability } p_{\text{uncond}} \end{cases}$$

这样同一个网络 (\epsilon_\theta) 就能同时处理两种输入,推理时无需额外模型。

8.5.4 实践参数与常见陷阱

参数 典型值 效果
guidance scale (w) 7-12 越高越贴合 prompt,但可能过饱和
(p_{\text{uncond}}) 0.1-0.2 训练时无条件 dropout 比例
采样步数 20-50 CFG 配合使用

常见陷阱

  1. CFG 过高:(w > 15) 时颜色过饱和、对比度失真,出现「塑料感」
  2. CFG 过低:(w < 3) 时生成结果与 prompt 关联弱,语义漂移
  3. 训练时未做无条件 dropout:推理时无法使用 CFG,条件控制效果差

CFGStable Diffusion 生态中 prompt 工程 的数学基础——理解它有助于调试生成质量,也是理解后续 Classifier-Free Guidance DistillationCFG-aware 蒸馏 的前提。

💡 一句话理解

生产环境中 Stable Diffusion 的 guidance scale 通常设为 7.5。如果生成图像颜色过于鲜艳或细节丢失,首先尝试降低 guidance scale,而不是增加采样步数。

九、知识图谱:扩散模型核心概念关系

以下是扩散模型核心概念的完整知识图谱,展示了各个概念之间的逻辑关系:

图表加载中…

十、总结与延伸阅读

核心要点回顾

  1. 扩散模型的三大框架DDPM(离散马尔可夫链)、Score-Based Models(Score Matching + Langevin)、SDE(连续时间统一框架)——它们本质等价。

  2. 训练目标:无论从 ELBO 推导(DDPM)还是 Score Matching(Score-Based),最终都简化为噪声预测的 MSE 损失

  3. 采样方法:反向 SDE(随机)和概率流 ODE(确定性)共享边际分布。高阶 ODE 求解器可将步数从 1000 降至 10-20。

  4. 潜空间扩散:通过 VAE 压缩到潜空间,计算量降低 50 倍,是 Stable Diffusion 的核心。

  5. Flow Matching 的关系Flow Matching(dl-022)是扩散模型的下一代范式,通过直线化 ODE 路径实现 1-4 步生成。理解本文的数学基础是理解 Flow Matching 优势的前提。

核心论文

论文 年份 贡献
Sohl-Dickstein et al. 2015 扩散模型最早提出
Ho et al. (DDPM) 2020 高质量扩散生成
Song & Ermon 2019 降噪 Score Matching
Song et al. (Score SDE) 2021 SDE 统一框架
Rombach et al. (LDM) 2022 潜空间扩散
Song et al. (Consistency) 2023 单步生成
Lipman et al. (Flow Matching) 2023 下一代范式(→ dl-022)

建议学习路线

本文(扩散模型数学基础)→ dl-022(Flow Matching 与 Rectified Flow)→ llm-032(Test-Time Compute Scaling)→ dl-005(GAN,对比理解)

理解扩散模型的数学,不仅是理解生成式 AI 的基础,也是理解现代 AI 中概率建模、变分推断、随机过程等核心数学工具的最佳实践场景。

💡 一句话理解

如果只能记住一件事:扩散模型的本质是「学习一个去噪函数」。无论数学多么复杂,核心就是:给模型一张被噪声破坏的图,让它预测噪声是什么。就这么简单。

十一、常见误区与调试指南

在实际训练和使用扩散模型时,以下误区最为常见:

误区一:认为更多采样步数一定更好。 超过 50 步后,DDIM/DPM-Solver 的边际收益急剧递减。生产环境应优先调 guidance scale 和 scheduler,而非盲目增加步数。

误区二:忽略噪声调度对训练的影响。 余弦调度(cosine schedule)通常优于线性调度,尤其在低分辨率图像上。切换调度后需要重新训练,不能简单替换。

误区三:在像素空间直接训练高分辨率模型。 512×512 以上的像素空间扩散需要多卡并行和极大内存。应优先使用潜空间扩散(LDM)或级联超分辨率方案。

调试 checklist

  1. 检查 loss 曲线是否在 50K step 后趋于平稳
  2. 可视化中间去噪步骤,确认结构逐步清晰
  3. 对比不同 guidance scale 的生成结果
  4. 验证 VAE 重建质量((|x - \mathcal{D}(\mathcal{E}(x))|) 应足够小)

掌握这些调试技巧,能显著缩短从论文到可用模型的迭代周期。

🎯 相关面试题

巩固本篇知识点,备战 AI 岗位面试。