第 3 讲 · 得分函数、得分匹配与随机采样 · Score Functions, Score Matching & Stochastic Sampling

Generative AI with Stochastic Differential Equations · Lecture 03。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:MIT 6.S184 Generative AI with Stochastic Differential Equations(IAP 2026),Lecture 3-A · 23-Jan-2026 · Score Functions and Score Matching;Lab 2(Flow Matching and Score Matching)的得分匹配部分(2.4、3.2、3.3)。 阅读材料:原课讲义 Holderrieth & Erives, An Introduction to Flow Matching and Diffusion Models(2026 版,arXiv:2506.02070)第 4 章、附录 B(Fokker–Planck 方程的证明)、附录 E(扩散模型文献导读);Lecture 3 slides;原始论文 Song et al. (2021) Score-Based Generative Modeling through SDEs、Ho et al. (2020) DDPM、Song, Meng & Ermon (2021) DDIM、Vincent (2011)。 依据说明:本讲以原课讲义第 4 章为主线:条件与边缘得分、换算公式、SDE 扩展技巧、Fokker–Planck 方程、朗之万动力学、去噪得分匹配;§7 依据原课讲义附录 E 的文献导读,把 DDPM、时间反演、概率流 ODE、DDIM 翻译成本课的语言。“Tweedie 公式""得分匹配损失的期望发散""四种参数化 = 四种加权""SDE 采样能否纠正训练误差(多批噪声重复)""DDPM 祖先采样的方差偏小""CondOT 上 DDIM 就是欧拉法”等实验和讨论是本讲义补充的;其中有几处结果与常见说法不一致(§6、§7.5),如实报告。 配套代码 Code:code/lecture03/(7 个脚本 + 1 个模块;PyTorch + matplotlib;每个脚本 1–26 秒,都完整运行过) 预计阅读时间:5 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 写出高斯路径的条件得分 ∇log⁡pt(x∣z)=−ϵ/βt\nabla\log p_t(x\mid z) = -\epsilon/\beta_t,证明边缘得分是条件得分的后验平均,并用 Tweedie 公式把得分和”最优去噪器”联系起来。
  2. 推导换算公式:对高斯路径,边缘向量场和边缘得分可以互相换算;说清四种参数化(速度、噪声、数据、得分)各自在哪一端会把误差放大。
  3. 陈述 SDE 扩展技巧,并用 Fokker–Planck 方程证明它;知道修正项的系数为什么必须是 12\frac12,朗之万动力学为什么是它的特例。
  4. 推导去噪得分匹配损失,解释朴素的版本为什么在 t→1t\to1 时失效、“预测噪声”为什么是正确的加权;理解”四种参数化 = 同一个回归目标的四种加权”。
  5. 判断什么时候值得用 SDE 采样,并能用实验(而不是一次采样)说明它有没有帮助。
  6. 读懂扩散模型文献:把 DDPM 的前向链、时间反演 SDE、概率流 ODE、DDIM、VP / VE 调度翻译成本课的概率路径和向量场。

0.2 先修与本讲范围

需要的背景在哪里
SDE、欧拉–丸山法、OU 过程、朗之万动力学;“给流模型加噪声需要修正项”的预告第 1 讲 §4–§5
概率路径、边缘化技巧、连续性方程、定理 12(FM vs CFM)、Algorithm 3第 2 讲 §2–§4
得分函数的定义;高斯后验;条件期望与均方误差分解前置讲 P1 §2.5、§3.3、§4
散度、拉普拉斯算子、分部积分P1 §5.2–§5.4
autograd 算得分前置讲 P2 §2.3

本讲只讲无条件生成;按提示生成(引导)是第 4 讲。

0.3 本讲地图 Map

§1  得分函数:条件得分、边缘得分、Tweedie 公式、为什么沿路径学         ← 代码 01
§2  换算公式:学向量场 = 学得分;四种参数化与误差放大                    ← 代码 02
§3  SDE 扩展技巧:同一条概率路径,无穷多个 SDE                          ← 代码 03
§4  Fokker–Planck 方程:连续性方程 + 热方程;扩展技巧的证明;朗之万      ← 代码 04
§5  去噪得分匹配:损失、方差爆炸、预测噪声、四种加权                     ← 代码 05
§6  为什么还要 SDE?——网络有误差时的实验                                 ← 代码 06
§7  文献导读:DDPM、时间反演、概率流 ODE、DDIM、VP / VE                   ← 代码 07
§8  小结   §9  常见误区   §10 练习   §11 延伸阅读   §12 下一讲预告

0.4 记号 Notation(新增的部分)

记号意思
∇log⁡pt(x∣z)\nabla\log p_t(x\mid z)条件得分(conditional score)
∇log⁡pt(x)\nabla\log p_t(x)边缘得分(marginal score),原课讲义写作 ∇log⁡pt(x)\nabla\log p_t(x);网络版本 stθ(x)s_t^\theta(x)
z^(x,t)\hat z(x, t),ϵ^(x,t)\hat\epsilon(x, t)后验均值 E[z∣xt=x]\mathbb{E}[z\mid x_t = x]、E[ϵ∣xt=x]\mathbb{E}[\epsilon\mid x_t = x](“最优去噪器”)及其网络近似
σt\sigma_tSDE 的扩散系数(噪声强度),可以随时间变化;不要和调度的 βt\beta_t 混淆
g(s)g(s)扩散文献里的噪声速率(DDPM 的 β(s)\beta(s));本讲统一写成 gg,避免和本课的 βt\beta_t 撞名
λ(t)\lambda(t)损失在时刻 tt 的权重
s=1−ts = 1 - t扩散文献的时间(s=0s = 0 是数据),只在 §7 出现

0.5 一张总图:在流匹配矩阵上加一行

第 2 讲的流匹配矩阵有”概率路径 / 向量场 / 损失”三列。本讲给它加上得分这一行:

概率路径向量场得分损失
条件pt(x∣z)p_t(x\mid z):有公式ut(x∣z)u_t(x\mid z):有公式∇log⁡pt(x∣z)\nabla\log p_t(x\mid z):有公式LCFM\mathcal{L}_{\text{CFM}}、LCSM\mathcal{L}_{\text{CSM}}:能算
边缘pt(x)p_t(x):只能采样ut(x)u_t(x):算不出来∇log⁡pt(x)\nabla\log p_t(x):算不出来LFM\mathcal{L}_{\text{FM}}、LSM\mathcal{L}_{\text{SM}}:算不出来

结构和第 2 讲完全一样:边缘得分是条件得分的后验平均,对条件得分做回归就等于对边缘得分做回归。本讲的新东西在于得分有什么用(让我们能用 SDE 采样)、得分和向量场是什么关系(对高斯路径可以互相换算),以及扩散模型的文献怎样对应到这张表。


1. 得分函数 · Score functions

1.1 为什么需要得分

第 1 讲 §5.4 做过一个实验:给理想的流模型直接加噪声,样本被吹散(峰内散度 2.11,17% 落在峰之间);在漂移里加上 σt22∇log⁡pt\frac{\sigma_t^2}{2}\nabla\log p_t 之后,σ=0.5,1,2\sigma = 0.5, 1, 2 都重新得到正确的分布。那里的 ∇log⁡pt\nabla\log p_t 是我们提前算好的。要在真实数据上做同样的事,就得学出 ∇log⁡pt\nabla\log p_t。

∇log⁡pt(x)\nabla\log p_t(x) 叫做 ptp_t 的得分函数(score function,P1 §2.5)。它是一个向量场,指向”对数密度上升最快的方向”。对一个高斯 N(μ,σ2I)\mathcal{N}(\mu, \sigma^2 I),得分是 −(x−μ)/σ2-(x - \mu)/\sigma^2:一个指向均值、长度与距离成正比的箭头。

问题和第 2 讲一模一样:ptp_t 是边缘概率路径,它的得分算不出来(ptp_t 本身都算不出来)。解法也一模一样:先看条件版本。

1.2 条件得分:指向条件均值的箭头

高斯条件路径 pt(⋅∣z)=N(αtz,βt2I)p_t(\cdot\mid z) = \mathcal{N}(\alpha_t z, \beta_t^2 I) 的得分是

∇log⁡pt(x∣z)=−x−αtzβt2.\nabla\log p_t(x\mid z) = -\frac{x - \alpha_t z}{\beta_t^2}.

在训练用的点 x=αtz+βtϵx = \alpha_t z + \beta_t\epsilon 处,它化简成

∇log⁡pt(x∣z)=−ϵβt.\nabla\log p_t(x\mid z) = -\frac{\epsilon}{\beta_t}.

知道了条件得分,就知道了加进去的噪声(差一个因子 −βt-\beta_t)。“去噪”扩散模型这个名字就是这么来的:学得分,本质上是在学”这张带噪的图里加了什么噪声”。

01 号脚本第 1 部分固定 z=(2,1)z = (2, 1),用 20 万个样本核对这个公式(与 autograd 对 log⁡N\log\mathcal{N} 求导的差在 3×10−143\times10^{-14} 以内,与 −ϵ/βt-\epsilon/\beta_t 的差在 3×10−123\times10^{-12} 以内),并测量它的大小:

ttβt\beta_tE∥∇log⁡pt(x∣z)∥2\mathbb{E}\lVert\nabla\log p_t(x\mid z)\rVert^2(蒙特卡洛)理论值 d/βt2d/\beta_t^2
01.002.02
0.30.704.14.1
0.60.4012.512.5
0.90.10199.9200
0.990.0120001.920000

t→1t\to 1 时条件路径收缩成 δz\delta_z,它的得分按 1/βt21/\beta_t^2 爆炸。§1.5 和 §5 会看到,这是”朴素的得分匹配”失败的根源。

1.3 边缘得分 = 条件得分的后验平均

命题(原课讲义第 4 章):

∇log⁡pt(x)=∫∇log⁡pt(x∣z) pt(x∣z) pdata(z)pt(x) dz=E[∇log⁡pt(x∣z) ∣ xt=x].\nabla\log p_t(x) = \int \nabla\log p_t(x\mid z)\,\frac{p_t(x\mid z)\,p_{\text{data}}(z)}{p_t(x)}\,dz = \mathbb{E}\big[\nabla\log p_t(x\mid z)\,\big|\,x_t = x\big].

证明只有一行。pt(x)=∫pt(x∣z)pdata(z)dzp_t(x) = \int p_t(x\mid z)p_{\text{data}}(z)dz,对 xx 求梯度可以和积分交换:

∇log⁡pt(x)=∇pt(x)pt(x)=∫∇pt(x∣z) pdata(z) dzpt(x)=∫∇pt(x∣z)pt(x∣z)⏟∇log⁡pt(x∣z) pt(x∣z)pdata(z)pt(x)⏟p(z∣xt=x) dz.\nabla\log p_t(x) = \frac{\nabla p_t(x)}{p_t(x)} = \frac{\int \nabla p_t(x\mid z)\,p_{\text{data}}(z)\,dz}{p_t(x)} = \int \underbrace{\frac{\nabla p_t(x\mid z)}{p_t(x\mid z)}}_{\nabla\log p_t(x\mid z)}\,\underbrace{\frac{p_t(x\mid z)p_{\text{data}}(z)}{p_t(x)}}_{p(z\mid x_t = x)}\,dz.

和第 2 讲的边缘化技巧对照:那里是”边缘向量场 = 条件向量场的后验平均”,这里是”边缘得分 = 条件得分的后验平均”,后验是同一个 p(z∣xt=x)p(z\mid x_t = x)。

01 号脚本第 2 部分用 mm 个数据样本做后验加权平均(权重 ∝N(x;αtzi,βt2I)\propto \mathcal{N}(x;\alpha_t z_i,\beta_t^2 I),和第 2 讲 03 号脚本一样),与闭式的边缘得分比较(“有效样本量”衡量后验有多集中):

ttmm平均误差有效样本量闭式得分的平均长度
0.3100 / 10410^4 / 10610^60.080 / 0.016 / 0.001543 / 4396 / 4406250.41
0.7100 / 10410^4 / 10610^61.26 / 0.37 / 0.0202.7 / 300 / 302665.55
0.95100 / 10410^4 / 10610^6278 / 91 / 10.41.2 / 2.6 / 1178.64

tt 越接近 1,后验越尖(只有一两个数据点”像”是 xx 的来源),而且每个条件得分本身按 1/βt21/\beta_t^2 放大:t=0.95t = 0.95 时即使用一百万个样本,误差(10.4)仍然大于得分本身的长度(8.6)。直接用数据平均行不通,要靠网络去学,这一点和边缘向量场一样。

1.4 Tweedie 公式:得分指向去噪结果

把条件得分 −(x−αtz)/βt2-(x - \alpha_t z)/\beta_t^2 对后验取平均,zz 换成 E[z∣xt=x]\mathbb{E}[z\mid x_t = x]:

 ∇log⁡pt(x)=αt E[z∣xt=x]−xβt2 ⟺E[z∣xt=x]=x+βt2∇log⁡pt(x)αt.\boxed{\ \nabla\log p_t(x) = \frac{\alpha_t\,\mathbb{E}[z\mid x_t = x] - x}{\beta_t^2}\ } \qquad\Longleftrightarrow\qquad \mathbb{E}[z\mid x_t = x] = \frac{x + \beta_t^2\nabla\log p_t(x)}{\alpha_t}.

这就是统计学里的 Tweedie 公式(Robbins 1956;Efron 2011 的综述)。它说:

  • 得分指向去噪结果:从 xx 出发,沿得分走 βt2\beta_t^2 倍的长度,就到了 αtz^\alpha_t\hat z(“把噪声去掉后,这张图应该在的位置”,再按 αt\alpha_t 缩放)。
  • 学会得分 = 学会最优去噪器。P1 §4.5 讲过,均方误差意义下的最优去噪器就是后验均值 E[z∣xt]\mathbb{E}[z\mid x_t]。

01 号脚本第 2 部分用闭式的后验均值核对:t=0,0.3,0.7,0.95t = 0, 0.3, 0.7, 0.95 时 Tweedie 公式与闭式得分的最大差都在 4×10−134\times10^{-13} 以内。两端:t=0t = 0 时 p0=N(0,I)p_0 = \mathcal{N}(0, I),得分就是 −x-x;t=1t = 1 时 p1=pdatap_1 = p_{\text{data}},得分就是数据分布的得分(此时 β=0\beta = 0,公式不适用,但极限成立)。

得分场

(前三张:t=0.3,0.7,1t = 0.3, 0.7, 1 时的边缘得分,箭头长度已压缩、只看方向;t=0.3t = 0.3 时五个峰还连成一团,得分几乎处处指向中心。最后一张:t=0.5t = 0.5 时,每个样本 xx 指向 αtE[z∣x]\alpha_t\mathbb{E}[z\mid x] 的箭头,也就是 βt2\beta_t^2 倍的得分。)

1.5 大小:条件得分的不可约方差

01 号脚本第 3 部分比较条件得分和边缘得分的均方大小:

ttE∥条件得分∥2=d/βt2\mathbb{E}\lVert\text{条件得分}\rVert^2 = d/\beta_t^2E∥边缘得分∥2\mathbb{E}\lVert\text{边缘得分}\rVert^2差 C′(t)C'(t)βt2 C′(t)\beta_t^2\,C'(t)
022.002≈ 0≈ 0
0.253.562.081.480.83
0.585.572.430.61
0.753213.118.91.18
0.920014.31861.86
0.992×1042\times10^412.82.0×1042.0\times10^42.00
0.9992×1062\times10^612.52.0×1062.0\times10^62.00

(t=0t = 0 处 C′C' 理论上为 0,表里的 −0.0016-0.0016 是蒙特卡洛误差。)

边缘得分始终有限:t→1t\to1 时约为 d/0.42=12.5d/0.4^2 = 12.5,由数据峰的宽度决定。条件得分却按 d/βt2d/\beta_t^2 爆炸。两者之差

C′(t)=E∥∇log⁡pt(x∣z)∥2−E∥∇log⁡pt(x)∥2=E[Var⁡(∇log⁡pt(x∣z)∣xt)]C'(t) = \mathbb{E}\big\lVert\nabla\log p_t(x\mid z)\big\rVert^2 - \mathbb{E}\big\lVert\nabla\log p_t(x)\big\rVert^2 = \mathbb{E}\big[\operatorname{Var}(\nabla\log p_t(x\mid z)\mid x_t)\big]

就是第 2 讲定理 12 里那个常数的得分版:对条件得分做回归时,损失降不下去的那部分(P1 §4.3 的均方误差分解)。

麻烦在于:如果 tt 在 [0,1][0, 1] 上均匀采样,∫01C′(t) dt\int_0^1 C'(t)\,dt 发散(∫2/(1−t)2 dt=∞\int 2/(1-t)^2\,dt = \infty)。就算像代码那样把 tt 限制在 [0,1−10−4][0, 1 - 10^{-4}],期望也有 ∫01−10−42/(1−t)2dt≈2×104\int_0^{1-10^{-4}} 2/(1-t)^2dt \approx 2\times10^4,而且几乎全部来自 tt 最接近 1 的那一小段。表的最后一列给出了出路:乘上权重 βt2\beta_t^2 之后,地板 βt2C′(t)\beta_t^2 C'(t) 始终不超过 d=2d = 2。§5 会把这一点变成训练算法。

1.6 为什么要沿着一条加噪的路径学得分

能不能只学数据分布本身的得分 ∇log⁡pdata\nabla\log p_{\text{data}},然后用第 1 讲的朗之万动力学采样?第 1 讲已经看到这样会分错峰的权重。01 号脚本第 4 部分给出另一个原因:采样时粒子待在哪里。

tt粒子所在处 pdata<10−6p_{\text{data}} < 10^{-6} 的比例粒子所在处 pt<10−6p_t < 10^{-6} 的比例
093.3%0.00%
0.390.0%0.00%
0.556.7%0.00%
0.73.8%0.00%
0.9 / 1.00.0%0.00%

生成过程的前半段,绝大部分粒子都在 pdatap_{\text{data}} 几乎为 0 的地方:那里没有一个训练样本,∇log⁡pdata\nabla\log p_{\text{data}} 在那里学得再差也不会在损失里体现出来。而 ptp_t 在粒子所在之处从来不小:训练时 xt∼ptx_t \sim p_t 的样本恰好覆盖了采样时粒子会去的地方。

Song & Ermon(2019,NCSN)正是因为这个原因提出”在多个噪声水平上学得分”,再用”退火的朗之万动力学”从大噪声走到小噪声。本课的概率路径把”多个噪声水平”连成了一条连续的路径,“退火”变成了”沿着路径走”。

📌 代码 01:python3 01_score_functions.py(约 1 秒)。


2. 换算公式:学向量场 = 学得分 · The conversion formula

2.1 推导

对高斯路径,边缘向量场和边缘得分都是同一个后验下的期望(第 2 讲 §3.2;本讲 §1.3):

ut(x)=E[α˙tz+β˙tϵ∣xt=x]=α˙tz^+β˙tϵ^,∇log⁡pt(x)=E[−ϵβt ∣ xt=x]=−ϵ^βt,u_t(x) = \mathbb{E}[\dot\alpha_t z + \dot\beta_t\epsilon\mid x_t = x] = \dot\alpha_t\hat z + \dot\beta_t\hat\epsilon,\qquad \nabla\log p_t(x) = \mathbb{E}\Big[-\frac{\epsilon}{\beta_t}\,\Big|\,x_t = x\Big] = -\frac{\hat\epsilon}{\beta_t},

其中 z^=E[z∣xt=x]\hat z = \mathbb{E}[z\mid x_t = x],ϵ^=E[ϵ∣xt=x]\hat\epsilon = \mathbb{E}[\epsilon\mid x_t = x]。再对 x=αtz+βtϵx = \alpha_t z + \beta_t\epsilon 两边取条件期望,得到 x=αtz^+βtϵ^x = \alpha_t\hat z + \beta_t\hat\epsilon。三个线性关系、两个未知数 (z^,ϵ^)(\hat z, \hat\epsilon),消去它们就得到换算公式(原课讲义第 4 章):

 ut(x)=α˙tαt x+(α˙tβt2αt−β˙tβt)∇log⁡pt(x) \boxed{\ u_t(x) = \frac{\dot\alpha_t}{\alpha_t}\,x + \Big(\frac{\dot\alpha_t\beta_t^2}{\alpha_t} - \dot\beta_t\beta_t\Big)\nabla\log p_t(x)\ }

对 CondOT(αt=t\alpha_t = t,βt=1−t\beta_t = 1 - t):

ut(x)=xt+1−tt∇log⁡pt(x),∇log⁡pt(x)=t ut(x)−x1−t.u_t(x) = \frac{x}{t} + \frac{1 - t}{t}\nabla\log p_t(x),\qquad \nabla\log p_t(x) = \frac{t\,u_t(x) - x}{1 - t}.

同一个公式对条件版本也成立(把 ut(x)u_t(x)、∇log⁡pt(x)\nabla\log p_t(x) 换成 ut(x∣z)u_t(x\mid z)、∇log⁡pt(x∣z)\nabla\log p_t(x\mid z),对照第 2 讲的式 (20) 即可验证)。

含义:对高斯路径,学会了向量场就学会了得分,反之亦然。原课讲义因此说,流匹配模型可以直接当扩散模型的得分来用,训练其中一个就够了。02 号脚本第 1 部分用闭式的 utu_t 和 ∇log⁡pt\nabla\log p_t 核对,四种调度在 5 个时刻 × 4000 个点上的最大相对差:CondOT 7.6×10−157.6\times10^{-15},SqrtBeta 1.9×10−141.9\times10^{-14},Cosine 6.6×10−156.6\times10^{-15},VP(DDPM 的连续版,§7)1.1×10−131.1\times10^{-13}。

2.2 四种参数化

既然 uu、z^\hat z、ϵ^\hat\epsilon、∇log⁡pt\nabla\log p_t 在给定 (x,t)(x, t) 时可以互相换算,网络输出哪一个都行。文献里四种都有人用:

网络输出回归目标(给定 z,ϵz, \epsilon)换算文献里的例子
速度 uuα˙tz+β˙tϵ\dot\alpha_t z + \dot\beta_t\epsilon—流匹配、Rectified Flow、SD3、Movie Gen
噪声 ϵ^\hat\epsilonϵ\epsilonz^=(x−βtϵ^)/αt\hat z = (x - \beta_t\hat\epsilon)/\alpha_tDDPM(Ho et al. 2020)、Stable Diffusion 1.x
数据 z^\hat zzzϵ^=(x−αtz^)/βt\hat\epsilon = (x - \alpha_t\hat z)/\beta_t“x₀-prediction”;EDM 的去噪器(加了跳连的组合)
得分 ss−ϵ/βt-\epsilon/\beta_tϵ^=−βts\hat\epsilon = -\beta_t sNCSN(Song & Ermon 2019)、Score SDE

代码里的 score_lib.convert 实现了全部换算。理论上四者等价;实践中它们有两个重要区别:换算会在某一端放大误差(本节),以及损失在不同时刻的权重不同(§5.3)。

2.3 换算会放大误差,而且在不同的一端

假设网络的输出有一个小误差 δ\delta。换算成速度后,误差变成多大?02 号脚本第 2 部分算出放大倍数 ∣∂u^/∂(输出)∣|\partial\hat u/\partial(\text{输出})|:

CondOT 路径

tt预测速度预测噪声预测数据预测得分
0.001110001999
0.0111001.0199
0.11101.119
0.51221
0.911.11100.11
0.9911.011000.01
0.9991110000.001

VP 路径(DDPM 的连续版)

tt预测速度预测噪声预测数据预测得分
0.00119.990.0669.99
0.119.010.159
0.515.241.535.02
0.913.249.541.04
0.9913.3574.90.15
0.99915.725450.06

读法:

  • 预测噪声,在噪声那一端出问题(CondOT:放大 1/t1/t)。直觉:t=0t = 0 时 x0=ϵx_0 = \epsilon,“加了什么噪声”一眼就能看出,网络只需输出 ϵ^≈x\hat\epsilon\approx x;但这个输出几乎不含任何关于数据的信息,要从中解出 z^=(x−βtϵ^)/αt\hat z = (x - \beta_t\hat\epsilon)/\alpha_t 就得除以 αt≈0\alpha_t\approx 0。
  • 预测数据,在数据那一端出问题(放大 1/(1−t)1/(1-t)):要解出噪声得除以 βt≈0\beta_t\approx 0。
  • 预测速度处处是 1,没有奇点。
  • VP 路径几乎没有”噪声端”的问题:预测噪声的放大倍数最多约 10。原因是 VP 在噪声端 α˙t/αt=g/2≤10\dot\alpha_t/\alpha_t = g/2 \le 10 有界——路径在那里几乎不动(α˙\dot\alpha 和 α\alpha 一起趋于 0),抵消了除以 α\alpha 的放大。CondOT 的 αt\alpha_t 从 0 线性起步(α˙=1\dot\alpha = 1),才会发散。这解释了为什么 DDPM 时代用”预测噪声”没有出大问题。

不过 VP 的去噪结果 z^\hat z 本身仍然要除以 α0≈0.0066\alpha_0\approx 0.0066。Lin et al.(2024)指出,如果把 VP 调度的终点改成真正的纯噪声(α0=0\alpha_0 = 0,“零终点信噪比”),t=0t = 0 处预测噪声就毫无信息,z^\hat z 无从解出,于是改用速度类的参数化(v-prediction,Salimans & Ho 2022)。今天的大模型(SD3、FLUX、Movie Gen)几乎都用 CondOT + 速度预测。选择它的理由不止一个(SD3 论文做了大规模的比较),但”没有噪声端的奇点”是速度参数化的好处之一。

2.4 把流匹配模型换算成得分

原课 Lab 2 有一个练习:把训练好的流匹配模型(预测速度)包装成得分模型(ScoreFromVectorField),再拿去做 SDE 采样。02 号脚本第 3 部分训练一个速度模型(3000 步,约 3 秒),按 s^=(tu^−x)/(1−t)\hat s = (t\hat u - x)/(1-t) 换算:

tt速度的均方误差换算得分的均方误差得分的相对误差理论放大 (t/(1−t))2(t/(1-t))^2实际比值
00.10500%0(s^=−x\hat s = -x)
0.30.0640.0120.56%0.180.18
0.50.0990.0991.8%11
0.70.0590.322.7%5.45.4
0.90.0554.4731%8181
0.990.248243119016%98009800

速度的误差在各时刻都差不多(0.05–0.25),换算成得分后却天差地别:t=0.99t = 0.99 时速度误差被放大近一万倍,得分的相对误差是 190 倍。t=0t = 0 处换算出的得分恰好是 −x-x,与网络无关。换算在理论上精确,在实践中有代价:用流模型换算出的得分做 SDE 采样时,σt\sigma_t 在 t→1t\to1 附近必须变小(§6 会看到不这样做的后果)。

📌 代码 02:python3 02_conversion_formula.py(约 4 秒)。


3. SDE 扩展技巧 · The SDE extension trick

3.1 定理

SDE 扩展技巧(原课讲义第 4 章)。设 utu_t 是边缘向量场(它的 ODE 沿概率路径 ptp_t 走),σt≥0\sigma_t \ge 0 是任意的扩散系数。那么 SDE

 X0∼pinit,dXt=[ut(Xt)+σt22∇log⁡pt(Xt)]dt+σt dWt \boxed{\ X_0 \sim p_{\text{init}},\qquad dX_t = \Big[u_t(X_t) + \frac{\sigma_t^2}{2}\nabla\log p_t(X_t)\Big]dt + \sigma_t\,dW_t\ }

对所有 t∈[0,1]t\in[0, 1] 都满足 Xt∼ptX_t \sim p_t。特别地,X1∼pdataX_1 \sim p_{\text{data}}。

直觉上可以这样理解三个部分:

  • utu_t 负责搬运:它让粒子云的形状按 ptp_t 变化(第 2 讲);
  • 噪声 σtdWt\sigma_t dW_t 负责摊开:它让粒子云扩散,像墨水在水里化开;
  • 修正项 σt22∇log⁡pt\frac{\sigma_t^2}{2}\nabla\log p_t 负责收拢:它沿得分方向把粒子往高密度处推,推的力度恰好抵消噪声的摊开。

修正项和第 1 讲朗之万动力学的漂移 σ22∇log⁡p\frac{\sigma^2}{2}\nabla\log p 形式完全相同,只是把固定的 pp 换成了随时间变化的 ptp_t。§4 会用 Fokker–Planck 方程把”恰好抵消”变成一行等式。

这意味着同一条概率路径可以由一个 ODE 和无穷多个 SDE 实现。训练只需要学 utu_t(或 ∇log⁡pt\nabla\log p_t,两者可以换算),采样时 σt\sigma_t 可以随意选。

3.2 每个时刻都在 ptp_t 上

03 号脚本用理想场(闭式的 utu_t 和 ∇log⁡pt\nabla\log p_t)验证定理,以排除训练误差。第 1 部分让 σ\sigma 从 0 到 4,欧拉–丸山 1000 步,在中途各时刻比较粒子与 ptp_t(能量距离;噪声地板是两批真样本之间的距离):

SDEt=0.25t = 0.25t=0.5t = 0.5t=0.75t = 0.75t=1t = 1
噪声地板−0.0001+0.0018+0.0014−0.0022
σ=0\sigma = 0(ODE)−0.0006−0.0005−0.0003−0.0011
σ=0.5\sigma = 0.5−0.0004−0.0002−0.0009−0.0003
σ=1\sigma = 1−0.0001+0.0008−0.0009+0.0020
σ=2\sigma = 2−0.0002−0.0011+0.0022−0.0017
σ=4\sigma = 4+0.0008+0.0015−0.0007+0.0017

不同 σ,同样的边缘分布

全部在噪声地板内。扩展技巧保证的是整条路径,不只是终点。

3.3 系数必须恰好是 1/2

如果把修正项写成 c σt2∇log⁡ptc\,\sigma_t^2\nabla\log p_t,cc 取别的值会怎样?03 号脚本第 2 部分(σ=1\sigma = 1,1000 步):

系数 cc能量距离峰内散度(理想 1)落在峰之间权重误差 TV
0(不修正)0.05642.1216.9%0.041
0.250.00631.361.1%0.018
0.5−0.00191.000.1%0.012
0.750.00040.830.0%0.018
10.01240.710.0%0.045

c<12c < \frac12 修正不足,噪声把峰”吹胖”;c>12c > \frac12 修正过头,峰被”压瘦”。(注意 c=0.75c = 0.75 时能量距离很小,但散度只有 0.83:能量距离对”峰的宽度”不太敏感,又一次说明评估要看多个指标。)§4 的 Fokker–Planck 方程会精确地解释这张表:净效果是 (σ22−c σ2)Δp(\frac{\sigma^2}{2} - c\,\sigma^2)\Delta p。

3.4 步数与 σ\sigma:离散化误差

定理说的是连续时间。实际用欧拉–丸山法模拟时步数有限,σ\sigma 的选择就有影响了。03 号脚本第 3 部分(t=1t = 1 时的能量距离 / 峰内散度):

SDEn=10n = 10n=30n = 30n=100n = 100n=300n = 300n=1000n = 1000
σ=0\sigma = 0(ODE)0.012 / 1.070.001 / 1.01−0.001 / 1.00−0.001 / 1.00−0.001 / 1.00
σ=0.5\sigma = 0.50.007 / 1.03−0.000 / 1.00−0.001 / 1.00−0.000 / 0.99−0.001 / 1.00
σ=1\sigma = 10.001 / 1.04−0.001 / 1.01−0.001 / 1.01−0.000 / 0.99−0.000 / 1.01
σ=2\sigma = 20.018 / 1.730.000 / 1.11−0.002 / 1.03−0.002 / 1.01−0.003 / 1.00
σ=4\sigma = 445.2 / 2780.153 / 2.700.000 / 1.15−0.001 / 1.04−0.001 / 1.00
σt=2(1−t)\sigma_t = 2(1-t)0.001 / 1.05−0.001 / 1.01−0.001 / 1.01−0.002 / 0.990.000 / 1.01

两个现象:

  1. 适中的噪声在步数少时反而比 ODE 好。n=10n = 10 时 ODE 的峰内散度是 1.07(欧拉法的离散化误差让峰变模糊),σ=1\sigma = 1 和 σt=2(1−t)\sigma_t = 2(1-t) 的能量距离只有 0.001。修正项像朗之万动力学一样把粒子往 ptp_t 的高密度处拉,顺带纠正了一部分离散化误差。Song et al.(2021)的”预测–校正”(predictor–corrector)采样器就是把这个想法做成显式的两步:先用 ODE / SDE 走一步(预测),再在固定的 tt 上做几步朗之万动力学(校正)。
  2. 噪声太大就失稳。σ=4\sigma = 4、n=10n = 10 时完全失败(能量距离 45)。修正项 σ22∇log⁡pt\frac{\sigma^2}{2}\nabla\log p_t 在 t→1t\to1 时很大:峰的标准差只有 0.4,得分的尺度约 1/0.161/0.16,乘上 σ2/2=8\sigma^2/2 = 8 后每单位时间要把粒子拉动几十个单位,步长 h=0.1h = 0.1 时一步就”冲过头”。这在数值分析里叫刚性(stiffness)。让噪声在终点附近关掉就没有这个问题:把 σ=4\sigma = 4 改成 σt=4(1−t)\sigma_t = 4(1-t),n=10n = 10 时能量距离是 0.010(练习 6)。

扩散模型的实际采样器几乎都让噪声随时间变化,而不是用常数 σ\sigma。

3.5 SDE 会”忘掉”起点

ODE 是确定性的:起点决定终点。SDE 呢?03 号脚本第 4 部分从同一批起点出发,统计 SDE 的终点和 ODE 的终点落在同一个峰的比例:

σ\sigma0.250.5124
与 ODE 同峰的比例89.7%80.6%63.1%41.8%26.0%
与 ODE 终点的距离(中位数)0.270.520.954.194.86

如果终点和起点完全无关,同峰的比例是 ∑kwk2=24.6%\sum_k w_k^2 = 24.6\%;σ=4\sigma = 4 时已经接近这个水平。

ODE vs SDE 轨迹

分布一样,但”哪个起点去哪里”的配对完全不同。这带来两个后果:

  • ODE 的确定性很有用:同一个噪声永远生成同一个样本,所以可以做”在噪声空间里插值""把一张真实图片反演回噪声再编辑”等操作。
  • SDE 的遗忘也很有用:早期走错的粒子还有机会被纠正(§6);SDEdit(Meng et al. 2022)这类图像编辑方法正是利用这一点,给一张草图加噪声到中间时刻,再用 SDE 去噪,让模型”忘掉”草图的细节、只保留大致布局。

3.6 朗之万动力学是特例

取一条不随时间变化的概率路径 pt≡pp_t \equiv p。此时 ut≡0u_t \equiv 0 就满足连续性方程(粒子云不需要变化),扩展技巧给出

dXt=σt22∇log⁡p(Xt) dt+σt dWt,dX_t = \frac{\sigma_t^2}{2}\nabla\log p(X_t)\,dt + \sigma_t\,dW_t,

这正是第 1 讲的朗之万动力学,pp 是它的平稳分布。原课讲义提到,朗之万动力学在分子动力学模拟、贝叶斯推断里广泛使用,它在一定条件下会从任意起点收敛到 pp,但收敛可能很慢(第 1 讲五峰的例子分错了权重)。扩散模型沿着一条从简单到复杂的路径 ptp_t 走,避开了”在多个分得很开的峰之间重新分配质量”的难题。

📌 代码 03:python3 03_sde_extension_trick.py(约 20 秒)。


4. Fokker–Planck 方程 · The Fokker–Planck equation

4.1 从连续性方程到 Fokker–Planck 方程

第 2 讲用连续性方程刻画 ODE:粒子沿 vtv_t 走,密度 qtq_t 满足

∂tqt=−∇⋅(qtvt).\partial_t q_t = -\nabla\cdot(q_t v_t).

右边是”单位体积的净流入”:漂移把质量从一处搬到另一处,总量守恒(P1 §5.2 的散度)。

SDE 多了一个噪声项。先看最简单的情形:没有漂移,dXt=σ dWtdX_t = \sigma\,dW_t。一群粒子各自做布朗运动,它们的密度怎样变化?从一个点出发,tt 时刻的分布是 N(0,σ2tI)\mathcal{N}(0, \sigma^2 t I),密度 qtq_t 满足热方程

∂tqt=σ22Δqt.\partial_t q_t = \frac{\sigma^2}{2}\Delta q_t.

P1 §5.3 讲过拉普拉斯算子的直觉:Δq(x)\Delta q(x) 衡量”xx 周围的平均值比 xx 处高多少”。峰顶的 Δq<0\Delta q < 0(周围比中心低),所以峰顶的密度下降;峰的边缘 Δq>0\Delta q > 0,密度上升。噪声把尖的东西摊平,就像热量从热处流向冷处。

把两者加起来,就是 Fokker–Planck 方程。

定理(Fokker–Planck 方程,原课讲义第 4 章,证明见附录 B)。设 X0∼q0X_0\sim q_0,dXt=vt(Xt)dt+σtdWtdX_t = v_t(X_t)dt + \sigma_t dW_t,那么 XtX_t 的密度 qtq_t 满足

 ∂tqt(x)=−∇⋅(qtvt)(x)+σt22Δqt(x) \boxed{\ \partial_t q_t(x) = -\nabla\cdot\big(q_t v_t\big)(x) + \frac{\sigma_t^2}{2}\Delta q_t(x)\ }

反过来,如果某条概率路径 qtq_t 满足这个方程且 q0q_0 匹配,那么 SDE 的分布就是 qtq_t。第一项是连续性方程(漂移搬运),第二项是热方程(噪声摊开)。σt=0\sigma_t = 0 时就退化成第 2 讲的连续性方程。

证明的思路(附录 B,只写直觉):取一个光滑的”测试函数” ff,看 E[f(Xt)]\mathbb{E}[f(X_t)] 怎样随时间变化。泰勒展开到二阶,漂移贡献 ∇f⋅vt h\nabla f\cdot v_t\,h,噪声的一阶项期望为 0、二阶项贡献 σt22Δf h\frac{\sigma_t^2}{2}\Delta f\,h(因为 E[(ΔW)2]=h\mathbb{E}[(\Delta W)^2] = h,布朗运动的增量是 h\sqrt h 量级,平方后才是 hh 量级——这就是第 1 讲 §4 的”二次变差”)。于是

ddtE[f(Xt)]=E[∇f(Xt)⋅vt(Xt)+σt22Δf(Xt)].\frac{d}{dt}\mathbb{E}[f(X_t)] = \mathbb{E}\Big[\nabla f(X_t)\cdot v_t(X_t) + \frac{\sigma_t^2}{2}\Delta f(X_t)\Big].

左边写成 ∫f ∂tqt\int f\,\partial_t q_t,右边对 qtq_t 做分部积分(P1 §5.4),把导数从 ff 挪到 qtq_t 上,就得到 ∫f [−∇⋅(qtvt)+σt22Δqt]\int f\,[-\nabla\cdot(q_t v_t) + \frac{\sigma_t^2}{2}\Delta q_t]。对所有 ff 都成立,两个被积式就相等。严格的版本要用伊藤公式(Itô’s formula),参考 Øksendal 的 Stochastic Differential Equations 第 7–8 章。

4.2 扩展技巧的证明

把扩展 SDE 的漂移 vt=ut+σt22∇log⁡ptv_t = u_t + \frac{\sigma_t^2}{2}\nabla\log p_t 代入 Fokker–Planck 方程的右边,并用 qt=ptq_t = p_t:

−∇⋅(ptut)−σt22∇⋅(pt∇log⁡pt)+σt22Δpt.-\nabla\cdot(p_t u_t) - \frac{\sigma_t^2}{2}\nabla\cdot\big(p_t\nabla\log p_t\big) + \frac{\sigma_t^2}{2}\Delta p_t.

关键是一个恒等式:p∇log⁡p=p⋅∇pp=∇pp\nabla\log p = p\cdot\frac{\nabla p}{p} = \nabla p,所以

∇⋅(pt∇log⁡pt)=∇⋅∇pt=Δpt.\nabla\cdot(p_t\nabla\log p_t) = \nabla\cdot\nabla p_t = \Delta p_t.

后两项恰好抵消,只剩 −∇⋅(ptut)-\nabla\cdot(p_t u_t),而它等于 ∂tpt\partial_t p_t(utu_t 满足连续性方程,第 2 讲)。所以 ptp_t 满足扩展 SDE 的 Fokker–Planck 方程,扩展 SDE 的分布就是 ptp_t。证毕。

“沿得分方向的漂移”等于”反向的扩散”:修正项把质量往高密度处搬,搬运的净效果 −σ22Δp-\frac{\sigma^2}{2}\Delta p 恰好是噪声 +σ22Δp+\frac{\sigma^2}{2}\Delta p 的相反数。如果系数是 cc 而不是 12\frac12,净效果就是 (12−c)σ2Δp(\frac12 - c)\sigma^2\Delta p:c<12c < \frac12 相当于多扩散,c>12c > \frac12 相当于”反扩散”(把峰压尖),正是 §3.3 那张表。

4.3 数值核对

04 号脚本在一维网格上(dx=0.005dx = 0.005)用有限差分逐项计算。数据是三个宽窄、权重都不同的峰,路径是 CondOT。残差是相对于 ∥∂tp∥\lVert\partial_t p\rVert 的大小:

tt连续性方程(uu,σ=0\sigma = 0)∂(p ∂log⁡p)\partial(p\,\partial\log p) vs ∂2p\partial^2 pFP:扩展 SDE(σ=1.5\sigma = 1.5)FP:只加噪声(σ=1.5\sigma = 1.5)
0.22.0×10−52.0\times10^{-5}7.2×10−67.2\times10^{-6}1.8×10−51.8\times10^{-5}3.98
0.53.7×10−53.7\times10^{-5}3.3×10−53.3\times10^{-5}6.2×10−56.2\times10^{-5}0.86
0.87.5×10−57.5\times10^{-5}5.3×10−55.3\times10^{-5}1.4×10−41.4\times10^{-4}1.80
0.958.5×10−58.5\times10^{-5}6.6×10−56.6\times10^{-5}1.4×10−41.4\times10^{-4}1.83

前三列都在 10−410^{-4} 量级以下,是有限差分本身的误差;最后一列是 O(1)O(1) 的:只加噪声时多出来的 σ22∂2p\frac{\sigma^2}{2}\partial^2 p 没有东西抵消。

粒子层面(第 3 部分):10 万个一维粒子,欧拉–丸山 1000 步,σ=1.5\sigma = 1.5。加修正项时,t=1t = 1 的直方图与 p1p_1 的总变差距离是 0.010;不修正时是 0.410,三个峰都被摊宽、峰之间被填满,还有 6.3% 的粒子跑出了 [−4.5,4.5][-4.5, 4.5]。Fokker–Planck 方程说的正是”无穷多个粒子的直方图怎样随时间演化”,方程层面和粒子层面是同一件事的两种写法。

4.4 朗之万动力学的平稳性

04 号脚本第 2 部分:对 pp 自己,朗之万动力学 dX=σ22∂log⁡p dt+σ dWdX = \frac{\sigma^2}{2}\partial\log p\,dt + \sigma\,dW 的 Fokker–Planck 右边是

−∂(p⋅σ22∂log⁡p)+σ22∂2p=−σ22∂2p+σ22∂2p=0,-\partial\Big(p\cdot\frac{\sigma^2}{2}\partial\log p\Big) + \frac{\sigma^2}{2}\partial^2 p = -\frac{\sigma^2}{2}\partial^2 p + \frac{\sigma^2}{2}\partial^2 p = 0,

数值上 σ=0.5,1,2\sigma = 0.5, 1, 2 时的相对大小都是 6×10−56\times10^{-5}(有限差分误差):∂tp=0\partial_t p = 0,pp 是平稳分布。换一个分布(比如 N(0,1)\mathcal{N}(0, 1))、漂移仍用 pp 的得分,右边的相对大小是 12.1:分布还会继续变化。

📌 代码 04:python3 04_fokker_planck.py(约 14 秒)。


5. 去噪得分匹配 · Denoising score matching

5.1 得分匹配损失与条件得分匹配损失

和第 2 讲完全平行。我们想让网络 stθ(x)s_t^\theta(x) 逼近边缘得分:

LSM(θ)=Et, x∼pt∥stθ(x)−∇log⁡pt(x)∥2(算不出来),\mathcal{L}_{\text{SM}}(\theta) = \mathbb{E}_{t,\ x\sim p_t}\big\lVert s_t^\theta(x) - \nabla\log p_t(x)\big\rVert^2 \qquad\text{(算不出来)}, LCSM(θ)=Et, z∼pdata, x∼pt(⋅∣z)∥stθ(x)−∇log⁡pt(x∣z)∥2(能算).\mathcal{L}_{\text{CSM}}(\theta) = \mathbb{E}_{t,\ z\sim p_{\text{data}},\ x\sim p_t(\cdot\mid z)}\big\lVert s_t^\theta(x) - \nabla\log p_t(x\mid z)\big\rVert^2 \qquad\text{(能算)}.

命题:LCSM(θ)=LSM(θ)+C′\mathcal{L}_{\text{CSM}}(\theta) = \mathcal{L}_{\text{SM}}(\theta) + C',C′=Et[C′(t)]C' = \mathbb{E}_t[C'(t)] 与 θ\theta 无关,所以两者的梯度相同。证明和第 2 讲定理 12 一字不差:条件得分在 xtx_t 给定时的条件期望是边缘得分(§1.3),再用 P1 §4.3 的均方误差分解。

这个想法叫去噪得分匹配(denoising score matching,Vincent 2011)。更早的 Hyvärinen(2005)的”得分匹配”用分部积分把 LSM\mathcal{L}_{\text{SM}} 化成只含 sθs^\theta 及其散度的形式,但散度在高维里很贵(P2 §2.4);去噪版本只需要条件得分,后者有公式。

5.2 朴素的版本为什么不行

代入高斯路径的条件得分 −ϵ/βt-\epsilon/\beta_t:

LCSM(θ)=Et,z,ϵ∥stθ(αtz+βtϵ)+ϵβt∥2.\mathcal{L}_{\text{CSM}}(\theta) = \mathbb{E}_{t, z, \epsilon}\Big\lVert s_t^\theta(\alpha_t z + \beta_t\epsilon) + \frac{\epsilon}{\beta_t}\Big\rVert^2.

§1.5 已经算过:回归目标 −ϵ/βt-\epsilon/\beta_t 的方差 d/βt2d/\beta_t^2 在 t→1t\to1 时爆炸,常数 C′C' 是无穷大。实践中会怎样?05 号脚本第 1 部分训练了五个模型(同样的 MLP、数据、路径、5000 步),再在一批固定的 20 万个 (z,t,ϵ)(z, t, \epsilon) 上,按时间段统计训练好的模型的损失份额:

模型最后 500 步的平均损失批损失 最大/中位数t∈[0,0.5)t\in[0, 0.5)[0.5,0.9)[0.5, 0.9)[0.9,0.99)[0.9, 0.99)[0.99,1)[0.99, 1)
速度 uu(流匹配)6.891.1684.9%11.8%3.0%0.3%
噪声 ϵ\epsilon(DDPM)0.9251.1633.0%45.4%19.5%2.2%
数据 zz3.991.1997.9%2.1%0.0%0.0%
得分 ss(朴素)228501830.0%0.1%1.4%98.5%
得分 ss(权重 βt2\beta_t^2)0.9221.1733.0%45.5%19.3%2.2%

时间段 [0.99,1)[0.99, 1) 只占全部样本的 1%,朴素得分匹配的损失却有 98.5% 来自这里,批与批之间的损失相差上百倍(取决于一个批里有没有抽到 tt 极接近 1 的样本)。它的梯度几乎只在学”最后一刻”。更糟的是,§5.4 会看到它连”最后一刻”也没学好。

5.3 解决办法:加权,也就是”预测噪声”

给损失乘上权重 λ(t)=βt2\lambda(t) = \beta_t^2:

βt2∥stθ(x)+ϵβt∥2=∥βtstθ(x)+ϵ∥2=∥ϵtθ(x)−ϵ∥2,ϵtθ:=−βtstθ.\beta_t^2\Big\lVert s_t^\theta(x) + \frac{\epsilon}{\beta_t}\Big\rVert^2 = \big\lVert \beta_t s_t^\theta(x) + \epsilon\big\rVert^2 = \big\lVert \epsilon_t^\theta(x) - \epsilon\big\rVert^2,\qquad \epsilon_t^\theta := -\beta_t s_t^\theta.

这就是 DDPM 的损失(Ho et al. 2020 的 LsimpleL_{\text{simple}}):网络预测加进去的噪声。加权不改变最优解(每个 tt 上的最优 stθs_t^\theta 仍是边缘得分,因为加权只是给不同 tt 的子问题乘了一个正数),只改变”不同时刻在损失里有多重要”,以及梯度的方差。表里”得分 ss(权重 β2\beta^2)“和”噪声 ϵ\epsilon“两行几乎一模一样(0.922 vs 0.925),它们是同一个损失。

原课讲义的 Algorithm 4(高斯路径的得分匹配训练)就是这个:

Algorithm 4  得分匹配训练(高斯路径,预测噪声)
for 每个小批量:
    抽 z ~ p_data,t ~ Unif[0, 1],ε ~ N(0, I)
    x ← α_t z + β_t ε
    L(θ) ← ‖ε^θ_t(x) − ε‖²          (等价地:β_t² ‖s^θ_t(x) + ε/β_t‖²)
    θ ← 梯度更新(L(θ))
采样时:s^θ_t(x) = −ε^θ_t(x)/β_t,再按换算公式得到 u,用 ODE 或扩展 SDE 生成

更一般地:四种参数化 = 四种加权。在给定 (x,t)(x, t) 时,四种输出都由”隐含的噪声估计” ϵ^\hat\epsilon 决定(§2.2)。对 CondOT,把每种损失都写成 ∥ϵ^−ϵ∥2\lVert\hat\epsilon - \epsilon\rVert^2 的倍数:

参数化损失写成 λ(t) ∥ϵ^−ϵ∥2\lambda(t)\,\lVert\hat\epsilon - \epsilon\rVert^2 时的权重 λ(t)\lambda(t)
噪声 ϵ\epsilon∥ϵ^−ϵ∥2\lVert\hat\epsilon - \epsilon\rVert^211
速度 uu∥u^−(z−ϵ)∥2\lVert\hat u - (z - \epsilon)\rVert^21/t21/t^2
数据 zz∥z^−z∥2\lVert\hat z - z\rVert^2(1−t)2/t2(1-t)^2/t^2
得分 ss(朴素)∥s^+ϵ/(1−t)∥2\lVert\hat s + \epsilon/(1-t)\rVert^21/(1−t)21/(1-t)^2

(推导:CondOT 下 u^=(x−ϵ^)/t\hat u = (x - \hat\epsilon)/t,而目标 z−ϵ=(x−ϵ)/tz - \epsilon = (x - \epsilon)/t,相减得 (ϵ−ϵ^)/t(\epsilon - \hat\epsilon)/t;其余同理,练习 4。)这张表正好解释了上一张表的损失份额:速度和数据的权重在 t→0t\to0 时变大,它们的损失集中在 t<0.5t < 0.5;朴素得分的权重在 t→1t\to1 时爆炸。Kingma & Gao(2023)系统地论证了:扩散模型的各种训练目标,都可以看成同一个目标在不同 λ(t)\lambda(t) 下的加权。网络容量无限时它们的最优解相同;容量有限时,权重决定了网络把”精力”花在哪里。

5.4 训练出来的模型:哪里准、哪里差

05 号脚本第 2 部分把五个模型都换算成速度和得分,按时刻与理想场比较(相对误差 = 均方误差 / 理想值的均方大小):

换算成速度

模型t=0.01t = 0.010.10.30.50.70.90.99
速度 uu1.8%1.6%0.40%0.33%0.19%0.21%0.57%
噪声 ϵ\epsilon2517%75%1.4%0.74%0.24%0.07%0.15%
数据 zz1.8%1.9%0.70%0.60%0.61%7.2%975%
得分(朴素)4.6×1054.6\times10^5%6439%73%29%13%1.4%0.01%
得分(权重 β2\beta^2)4567%78%1.5%0.67%0.32%0.05%0.00%

换算成得分

模型t=0.01t = 0.010.10.30.50.70.90.99
速度 uu0.00%0.01%0.26%0.96%1.5%19%7139%
噪声 ϵ\epsilon0.38%0.58%0.95%2.1%1.9%6.0%1862%
数据 zz0.00%0.01%0.46%1.7%4.6%652%1.2×1071.2\times10^7%
得分(朴素)70%50%48%83%99%126%154%
得分(权重 β2\beta^2)0.69%0.61%1.0%1.9%2.4%4.8%11.7%

四种参数化的误差

规律和 §2.3 的放大倍数表一致:每种参数化在自己放大倍数小的地方准,在放大倍数大的地方差。噪声和加权得分模型换算成速度后,t=0.01t = 0.01 处误差是理想值的 25–46 倍;数据模型在 t=0.99t = 0.99 处差;速度模型的速度误差处处在 2% 以内,但换算成得分后在 t=0.99t = 0.99 处是 71 倍。t≥0.9t\ge 0.9 时得分最准的是加权得分模型。

朴素得分模型在所有时刻都失败:前段和中段几乎没有得到训练(误差 50–100%);它全力以赴的 t≈1t\approx1 处,条件目标的噪声(量级 d/βt2≥2×104d/\beta_t^2 \ge 2\times10^4)完全淹没了信号(边缘得分的均方大小约 12.5),误差仍有 150%。§1.5 说的”损失的期望发散”,在训练中就是这个样子。

第 3 部分把五个模型都换算成速度、用欧拉法 100 步采样(同一批噪声):

模型能量距离权重误差 TV峰内散度落在峰之间
理想向量场−0.00060.0080.990.0%
速度 uu0.00580.0281.010.3%
数据 zz0.04300.0291.240.9%
噪声 ϵ\epsilon0.14500.1072.093.7%
得分(权重 β2\beta^2)0.73740.2801.355.2%
得分(朴素)553.80.584180999.5%

速度模型最好。噪声模型和加权得分模型明显更差:欧拉法的第一步正好在 t=0t = 0,换算要除以一个很小的 tt(代码把它夹到 ≥0.001\ge 0.001),网络在那里的一点点误差被放大成一大步。值得注意的是,这两个模型的损失相同,样本质量却差了五倍:它们输出的量不同、学到的函数也不同,t≈0t\approx0 处那一点差别被换算放大了。数据模型的峰偏胖(散度 1.24),因为最后几步要除以 1−t1 - t。

这个实验的教训:在 CondOT 路径上用欧拉法采样时,速度参数化是最自然的选择。DDPM 时代用噪声参数化没有出大问题,一是因为 VP 路径在噪声端的放大有界(§2.3),二是因为它用专门的采样器(§7 的 DDIM / DDPM),而不是”换算成速度再用欧拉法”。

📌 代码 05:python3 05_denoising_score_matching.py(约 25 秒;--quick 是几秒钟的冒烟测试)。


6. 为什么还要 SDE? · Why bother with SDEs?

6.1 网络有误差时的实验

§3 说明:理想场下所有 σ\sigma 都对,差别只在离散化误差。原课 slides 给出用 SDE 采样的理由:真实的网络有训练误差,适量的噪声有时能纠正这些误差;但 slides 同时强调,ODE 采样往往就能得到最好的结果。06 号脚本用训练 500 / 1500 / 5000 步的速度模型检验这一点(欧拉–丸山 100 步;单元格 = 能量距离 / 落在峰之间 / 峰内散度)。

第 1 部分:得分由速度模型换算而来

采样方式训练 500 步训练 1500 步训练 5000 步
ODE0.0120 / 2.4% / 1.080.0049 / 0.6% / 1.020.0058 / 0.3% / 1.01
σt=0.5(1−t)\sigma_t = 0.5(1-t)0.0102 / 2.5% / 1.100.0041 / 0.5% / 1.030.0042 / 0.3% / 1.02
σt=1(1−t)\sigma_t = 1(1-t)0.0110 / 2.7% / 1.110.0036 / 0.6% / 1.020.0028 / 0.3% / 1.02
σt=2(1−t)\sigma_t = 2(1-t)0.0072 / 2.3% / 1.110.0027 / 0.5% / 1.020.0006 / 0.2% / 1.02
σt=3(1−t)\sigma_t = 3(1-t)0.0161 / 1.8% / 1.040.0026 / 0.2% / 1.000.0026 / 0.1% / 1.04
常数 σ=1\sigma = 10.0596 / 0.1% / 0.410.0404 / 0.0% / 0.530.0160 / 0.0% / 0.72

第 2 部分:修正项改用单独训练的得分模型(§5 的加权版本,5000 步)

采样方式速度模型 500 步1500 步5000 步
σt=1(1−t)\sigma_t = 1(1-t)0.0079 / 2.8% / 1.100.0026 / 0.6% / 1.030.0023 / 0.4% / 1.03
σt=2(1−t)\sigma_t = 2(1-t)0.0025 / 1.2% / 1.010.0005 / 0.2% / 1.00−0.0005 / 0.1% / 1.01
σt=3(1−t)\sigma_t = 3(1-t)0.0003 / 0.7% / 0.940.0042 / 0.3% / 0.97−0.0002 / 0.2% / 1.02
常数 σ=1\sigma = 10.0046 / 0.1% / 0.890.0002 / 0.0% / 0.930.0015 / 0.0% / 0.97

看起来 SDE 采样大多更好。但能量距离的噪声地板约 ±0.002\pm0.002,很多差别只有地板的几倍。第 3 部分换 3 批噪声重复(速度模型 5000 步;能量距离 / 落在峰之间):

采样方式噪声批 1噪声批 2噪声批 3平均能量距离
ODE0.0104 / 0.5%0.0012 / 0.3%0.0014 / 0.2%0.0043
σt=2(1−t)\sigma_t = 2(1-t),换算得分0.0085 / 0.2%0.0038 / 0.2%0.0018 / 0.2%0.0047
σt=2(1−t)\sigma_t = 2(1-t),单独的得分模型0.0061 / 0.2%−0.0003 / 0.3%−0.0009 / 0.3%0.0016

结论比第一眼保守得多:

  1. 同一个模型,换一批噪声,能量距离就能从 0.001 变到 0.010。单次采样里 0.005 以内的差别都不可靠。(这是写这一节时踩过的坑:第一版只用了一批噪声,得出”SDE 明显更好”的结论。)
  2. 得分从速度模型换算而来时,SDE 采样没有可靠的改进(平均 0.0047 vs 0.0043)。换算得分没有带来新的信息,它的误差和速度的误差是同一个来源。
  3. 单独训练的得分模型略有帮助(平均 0.0016),训练不充分时”落在峰之间”的比例也明显下降(500 步:2.4% → 1.2%)。但这个比较不完全公平:得分模型训练了 5000 步,SDE 的改进有一部分是”借用”了一个更好的网络。
  4. 常数 σ\sigma 配换算得分会出错,而且错得很有特点:峰被”压瘦”到散度 0.41–0.72。换算得分在 t→1t\to1 时误差被放大 t/(1−t)t/(1-t) 倍(§2.4),终点附近噪声不关,这个放大了的误差就直接进入漂移。σt\sigma_t 在终点附近趋于 0,是用流模型做 SDE 采样的前提。

6.2 文献怎么说

大规模图像模型上的结论也不统一。Karras et al.(2022,EDM)系统地研究了采样器,发现随机性对一些模型有帮助、对另一些没有,而且噪声的量需要仔细调;Ma et al.(2024,SiT)在同一个网络上比较 ODE 和 SDE 采样,报告合适的 SDE 采样能略好一些。原课 slides 的总结是:

  • 理论上所有 σt\sigma_t 等价;
  • 实践中有训练误差和离散化误差,适量的随机性有时能纠正它们;
  • 另有一些下游应用需要随机的演化,例如用奖励函数微调扩散模型、推理时搜索(需要在中途”分叉”出多条轨迹);
  • 但ODE 采样往往就能得到最好的结果,而且是确定性的(可以反演、编辑、插值,§3.5)。

本讲的实验与此一致。原课讲义还提到一个较新的方向(GLASS flows):设法用 ODE 实现 SDE 那样的随机转移,兼顾两者的长处,有兴趣可以读原课讲义的相应部分。

📌 代码 06:python3 06_sde_vs_ode_with_errors.py(约 19 秒;--quick 是冒烟测试)。


7. 文献导读 · A guide to the diffusion literature

原课讲义附录 E 专门写了一份”扩散模型文献导读”,因为论文里的记号五花八门,初学者很容易迷路。这一节把主要的写法翻译成本课的语言,并用 07 号脚本做数值核对。

7.1 时间方向

本课(流的约定)扩散文献(DDPM、Score SDE、EDM……)
噪声t=0t = 0s=1s = 1(或 TT,或 k=1000k = 1000)
数据t=1t = 1s=0s = 0
一个带噪样本xt=αtz+βtϵx_t = \alpha_t z + \beta_t\epsilonxs=α(s)x0+σ(s)ϵx_s = \alpha(s)x_0 + \sigma(s)\epsilon;DDPM 写成 αˉkx0+1−αˉkϵ\sqrt{\bar\alpha_k}x_0 + \sqrt{1 - \bar\alpha_k}\epsilon
生成从 t=0t = 0 正向积分到 t=1t = 1“反向过程”,从 s=1s = 1 积分回 s=0s = 0

换算只需 s=1−ts = 1 - t。读论文时第一件事就是弄清楚它用的是哪个方向。

7.2 DDPM:离散时间的前向链

DDPM(Ho et al. 2020,基于 Sohl-Dickstein et al. 2015)从”前向加噪链”出发:

xk=1−βk xk−1+βk ξk,k=1,…,1000,βk 从 10−4 线性增到 0.02.x_k = \sqrt{1 - \beta_k}\,x_{k-1} + \sqrt{\beta_k}\,\xi_k,\qquad k = 1, \dots, 1000,\qquad \beta_k\ \text{从}\ 10^{-4}\ \text{线性增到}\ 0.02.

(这里的 βk\beta_k 是 DDPM 的记号,和本课的调度 βt\beta_t 不是一回事。)因为每一步都是”缩放 + 独立高斯”,任意第 kk 步都能一步算出:xk=αˉkx0+1−αˉkϵx_k = \sqrt{\bar\alpha_k}x_0 + \sqrt{1 - \bar\alpha_k}\epsilon,αˉk=∏i≤k(1−βi)\bar\alpha_k = \prod_{i\le k}(1 - \beta_i)(P1 §2.3)。这正是本课的高斯条件路径,α=αˉ\alpha = \sqrt{\bar\alpha}、β=1−αˉ\beta = \sqrt{1 - \bar\alpha},满足 α2+β2=1\alpha^2 + \beta^2 = 1,叫方差保持(variance preserving, VP)。

它的连续时间版本(Song et al. 2021)是 α=exp⁡(−12B(s))\alpha = \exp(-\frac12 B(s)),B(s)=∫0sg(r)drB(s) = \int_0^s g(r)dr,g(s)=0.1+19.9sg(s) = 0.1 + 19.9s(就是 1000βk1000\beta_k),代码里的 VPSchedule。07 号脚本第 1 部分比较两者:

kk(本课 tt)离散 αˉk\bar\alpha_k连续 e−B(s)e^{-B(s)}相对差
1(0.999)0.999900.999890.00%
100(0.9)0.89700.89630.08%
250(0.75)0.52410.52370.08%
500(0.5)0.07860.07910.60%
750(0.25)0.003350.003442.6%
1000(0)4.04×10−54.04\times10^{-5}4.32×10−54.32\times10^{-5}6.5%

kk 很大时相对差变大,但那里 αˉ\bar\alpha 本身极小,绝对差可以忽略。真的把链一步步跑 1000 次,和直接用闭式公式采样相比,k=250,500,1000k = 250, 500, 1000 时的能量距离都在噪声地板内(−0.0012、+0.0007、−0.0007)。

两点值得注意:

  • 训练从来不需要跑这条链:只要闭式的条件分布。这正是本课”条件概率路径”的视角——DDPM 论文用”前向过程”描述它,本课直接把它写成路径。
  • 终点不是纯噪声:αˉ1000=0.0064\sqrt{\bar\alpha_{1000}} = 0.0064(连续版 0.0066),生成时从 N(0,I)\mathcal{N}(0, I) 出发有一点点不匹配,这就是 §2.3 提到的”终点信噪比不为零”。

DDPM 原文从证据下界(ELBO)推导损失,最后发现把权重全部去掉、只预测噪声的 LsimpleL_{\text{simple}} 效果最好。本课的推导更直接:得分匹配 + βt2\beta_t^2 加权(§5.3)。两条路殊途同归。

7.3 前向 SDE、VP / VE,以及”前向过程 vs 概率路径”

Score SDE(Song et al. 2021)把离散链换成”前向 SDE”:

dXs=f(s)Xs ds+g(s) dWs,s:0→1 (数据→噪声).dX_s = f(s)X_s\,ds + \sqrt{g(s)}\,dW_s,\qquad s: 0\to 1\ \text{(数据}\to\text{噪声)}.

漂移必须是线性的(f(s)Xsf(s)X_s),否则条件分布 Xs∣X0X_s\mid X_0 没有闭式,训练就没法做。常见的两种:

名字前向 SDE对应本课的路径用它的工作
VP(方差保持)dX=−12gX ds+g dWdX = -\frac12 g X\,ds + \sqrt g\,dWα2+β2=1\alpha^2 + \beta^2 = 1DDPM、Stable Diffusion 1.x
VE(方差爆炸)dX=g dWdX = \sqrt{g}\,dWα=1\alpha = 1,β=σ(s)\beta = \sigma(s) 从很小增到很大NCSN、EDM

VE 路径的终点是 N(z,σmax⁡2I)\mathcal{N}(z, \sigma_{\max}^2 I),只有 σmax⁡\sigma_{\max} 远大于数据尺度时才近似于”纯噪声”(EDM 取 σmax⁡=80\sigma_{\max} = 80)。

本课的视角更一般:先选概率路径(任意的 αt\alpha_t、βt\beta_t,甚至非高斯的路径,第 2 讲 §6.1),再在 ODE 和无穷多个 SDE 之间任选。扩散文献里的”前向过程”只是实现某条路径的一种方式,而且只能实现线性漂移能产生的那些路径。原课讲义附录 E 的说法是:概率路径是比前向过程更基本的对象。

7.4 时间反演 SDE 与概率流 ODE

扩散文献生成样本的方式是把前向 SDE 在时间上倒过来。Anderson(1982)证明,前向 SDE 的时间反演仍是一个 SDE;对 VP,换成本课的时间方向后是

dXt=[g2Xt+g ∇log⁡pt(Xt)]dt+g dWt,g=g(1−t).dX_t = \Big[\frac{g}{2}X_t + g\,\nabla\log p_t(X_t)\Big]dt + \sqrt{g}\,dW_t,\qquad g = g(1 - t).

Song et al.(2021)还给出一个和它分布相同的确定性版本,叫概率流 ODE(probability flow ODE):

dXtdt=g2Xt+g2∇log⁡pt(Xt).\frac{dX_t}{dt} = \frac{g}{2}X_t + \frac{g}{2}\nabla\log p_t(X_t).

翻译成本课的语言:

  • 概率流 ODE 就是边缘向量场 utu_t。把 VP 的 α\alpha、β\beta 代进换算公式(§2.1):α˙/α=g/2\dot\alpha/\alpha = g/2,α˙β2/α−β˙β=g2(β2+α2)=g2\dot\alpha\beta^2/\alpha - \dot\beta\beta = \frac g2(\beta^2 + \alpha^2) = \frac g2,正好是上式。
  • 时间反演 SDE 就是 SDE 扩展技巧取 σt2=g\sigma_t^2 = g:ut+g2∇log⁡pt=g2x+g∇log⁡ptu_t + \frac{g}{2}\nabla\log p_t = \frac g2 x + g\nabla\log p_t。

07 号脚本第 2 部分在 t=0.1,0.5,0.9t = 0.1, 0.5, 0.9 用闭式的 utu_t 和得分核对,两个等式的最大差都在 10−1410^{-14} 量级。时间反演是扩展技巧的一个特例,概率流 ODE 是 σ=0\sigma = 0 的特例;扩展技巧允许任意的 σt\sigma_t,比时间反演更灵活。

7.5 DDIM,以及五种采样器的比较

DDIM(Song, Meng & Ermon 2021)的更新规则(换成本课的时间方向,从 tt 走到 t′>tt' > t):

xt′=αt′z^+βt′ϵ^,z^=xt−βtϵ^αt.x_{t'} = \alpha_{t'}\hat z + \beta_{t'}\hat\epsilon,\qquad \hat z = \frac{x_t - \beta_t\hat\epsilon}{\alpha_t}.

直觉:“先用当前的噪声估计把图去噪成 z^\hat z,再按下一时刻的噪声水平,用同一个噪声估计重新加噪。“它是确定性的。DDIM 论文还给出一族带参数 η\eta 的更新,η=1\eta = 1 时恰好是 DDPM 的”祖先采样”(每一步从后验 q(xt′∣xt,z^)q(x_{t'}\mid x_t, \hat z) 中采样),代码里的 generalized_ddim 实现了这一族。

DDIM 也是一种 ODE 求解器。换一组坐标:xˉ=x/αt\bar x = x/\alpha_t,σˉ=βt/αt\bar\sigma = \beta_t/\alpha_t(噪声与信号之比)。条件路径 x=αtz+βtϵx = \alpha_t z + \beta_t\epsilon 变成 xˉ=z+σˉϵ\bar x = z + \bar\sigma\epsilon,在 (σˉ,xˉ)(\bar\sigma, \bar x) 平面上是一条直线,斜率是 ϵ\epsilon。边缘 ODE 变成 dxˉ/dσˉ=ϵ^(x)d\bar x/d\bar\sigma = \hat\epsilon(x),对它用欧拉法:

xt′αt′=xtαt+(βt′αt′−βtαt)ϵ^⟺xt′=αt′z^+βt′ϵ^,\frac{x_{t'}}{\alpha_{t'}} = \frac{x_t}{\alpha_t} + \Big(\frac{\beta_{t'}}{\alpha_{t'}} - \frac{\beta_t}{\alpha_t}\Big)\hat\epsilon \quad\Longleftrightarrow\quad x_{t'} = \alpha_{t'}\hat z + \beta_{t'}\hat\epsilon,

正是 DDIM。后来的 DPM-Solver(Lu et al. 2022)、DEIS(Zhang & Chen 2023)沿着这个思路构造了更高阶的求解器;EDM 的采样 ODE 也写在这组坐标里。

对 CondOT,DDIM 就是欧拉法:x=tz^+(1−t)ϵ^x = t\hat z + (1-t)\hat\epsilon,DDIM 走到 t′t' 得 t′z^+(1−t′)ϵ^=x+(t′−t)(z^−ϵ^)t'\hat z + (1 - t')\hat\epsilon = x + (t' - t)(\hat z - \hat\epsilon),而 z^−ϵ^\hat z - \hat\epsilon 正是 CondOT 的边缘向量场。07 号脚本第 4 部分核对:n=2,4,8,16n = 2, 4, 8, 16 步时两者的最大差都在 5×10−145\times10^{-14} 以内。

07 号脚本第 3 部分在 VP 路径上、用理想去噪器比较五种采样器(能量距离 / 峰内散度):

采样器n=5n = 5n=10n = 10n=20n = 20n=50n = 50n=200n = 200n=1000n = 1000
欧拉 · 概率流 ODE0.021 / 1.570.006 / 1.140.003 / 1.040.002 / 1.010.002 / 1.000.002 / 1.00
Heun · 概率流 ODE(每步 2 次)0.012 / 1.270.004 / 1.070.002 / 1.020.002 / 1.000.001 / 0.990.001 / 0.99
DDIM(η=0\eta = 0)0.030 / 1.250.008 / 0.960.003 / 0.950.001 / 0.970.001 / 0.990.002 / 0.99
DDPM 祖先采样(η=1\eta = 1)0.068 / 1.300.013 / 0.840.002 / 0.81−0.001 / 0.88−0.002 / 0.950.000 / 0.99
欧拉–丸山 · 反向 SDE0.162 / 2.780.016 / 1.300.004 / 1.100.001 / 1.03−0.003 / 1.000.000 / 1.01

VP 路径上的五种采样器(10 步)

读法:

  1. 步数够多时都正确:它们模拟的是同一条概率路径。
  2. 步数少时,确定性的采样器远好于随机的:n=5n = 5 时 0.012–0.030 vs 0.068–0.162。这是 DDIM 论文的核心卖点:同一个训练好的 DDPM 模型,换成确定性的 DDIM 采样,几十步就够了,不需要 1000 步。
  3. 但在这个例子里,DDIM 并不比”欧拉法解概率流 ODE”更好(n=5n = 5:0.030 vs 0.021),两者错的方向不同:欧拉法让峰变胖(散度 1.57),DDIM 在 n=10n = 10–50 时让峰略微变瘦(0.95–0.97)。“DDIM 比欧拉法好”在图像数据上常被报告,但它不是一条普适的定理;换一个数据、换一个调度,结论可能不同。
  4. DDPM 祖先采样在中等步数时把峰压瘦(散度 0.81–0.88)。原因:每一步它都把去噪结果 z^\hat z 当成真的 zz,只加上”已知 zz 时”的后验方差,忽略了 zz 本身的不确定性 Var⁡(z∣xt)\operatorname{Var}(z\mid x_t)。步子越大,漏掉的方差越多。Bao et al.(2022,Analytic-DPM)专门推导了这一步的最优方差。η\eta 介于 0 和 1 之间时,散度随 η\eta 增大而单调变小(练习 7)。

7.6 名字对照表

文献里的说法本课的说法
前向过程 / 加噪过程 q(xs∣x0)q(x_s\mid x_0)条件概率路径 pt(⋅∣z)p_t(\cdot\mid z)
反向过程、去噪过程用扩展 SDE(或 ODE)从 t=0t = 0 模拟到 t=1t = 1
噪声调度 βk\beta_k、αˉk\bar\alpha_k、σ(s)\sigma(s)调度 αt\alpha_t、βt\beta_t
噪声预测 ϵθ\epsilon_\theta、x0x_0 预测、v 预测、得分网络 sθs_\theta四种参数化(§2.2),可以互相换算
LsimpleL_{\text{simple}}βt2\beta_t^2 加权的去噪得分匹配(§5.3)
时间反演 SDE(Anderson)扩展技巧取 σt2=g\sigma_t^2 = g
概率流 ODE边缘向量场 utu_t 的 ODE
DDIM(xˉ,σˉ)(\bar x, \bar\sigma) 坐标里的欧拉法;CondOT 上就是欧拉法
预测–校正采样器ODE / SDE 步 + 固定 tt 的朗之万步
Rectified Flow、Flow MatchingCondOT 路径 + 速度参数化(第 2 讲)
随机插值(Stochastic Interpolants)概率路径 + ODE / SDE 的统一框架,与本课大体等价

原课讲义附录 E 的结论是:对高斯路径,流匹配和扩散模型本质上是同一个东西,差别只在路径(调度)、参数化(加权)和采样器的选择。

📌 代码 07:python3 07_ddpm_ddim.py(约 6 秒)。


8. 小结 · Summary

  1. 得分函数 ∇log⁡pt\nabla\log p_t 是 SDE 采样需要的修正项。高斯路径的条件得分 −x−αtzβt2=−ϵβt-\frac{x - \alpha_t z}{\beta_t^2} = -\frac{\epsilon}{\beta_t};边缘得分是条件得分的后验平均;Tweedie 公式 ∇log⁡pt(x)=αtE[z∣x]−xβt2\nabla\log p_t(x) = \frac{\alpha_t\mathbb{E}[z\mid x] - x}{\beta_t^2}:学得分 = 学最优去噪器。沿路径学得分,是因为采样时粒子待在 ptp_t 的高密度处、却在 pdatap_{\text{data}} 的低密度处。
  2. 换算公式 ut=α˙tαtx+(α˙tβt2αt−β˙tβt)∇log⁡ptu_t = \frac{\dot\alpha_t}{\alpha_t}x + (\frac{\dot\alpha_t\beta_t^2}{\alpha_t} - \dot\beta_t\beta_t)\nabla\log p_t:对高斯路径,学向量场 = 学得分。四种参数化(速度、噪声、数据、得分)理论等价,但换算会在某一端放大误差:噪声在噪声端(CondOT),数据在数据端,速度处处不放大。
  3. SDE 扩展技巧:dX=[ut+σt22∇log⁡pt]dt+σtdWdX = [u_t + \frac{\sigma_t^2}{2}\nabla\log p_t]dt + \sigma_t dW 对任意 σt\sigma_t 都沿 ptp_t 走;系数必须是 12\frac12;适中的噪声能纠正部分离散化误差,太大的噪声在少步时失稳;SDE 会忘掉起点。朗之万动力学是 pt≡pp_t\equiv p 的特例。
  4. Fokker–Planck 方程 ∂tq=−∇⋅(qv)+σ22Δq\partial_t q = -\nabla\cdot(qv) + \frac{\sigma^2}{2}\Delta q = 连续性方程 + 热方程。扩展技巧的证明只有一行:∇⋅(p∇log⁡p)=Δp\nabla\cdot(p\nabla\log p) = \Delta p,“沿得分的漂移”恰好抵消”噪声的扩散”。
  5. 去噪得分匹配:LCSM=LSM+C′\mathcal{L}_{\text{CSM}} = \mathcal{L}_{\text{SM}} + C'。朴素版本的 C′C' 是无穷大,训练被 t≈1t\approx1 支配且处处失败;乘上 βt2\beta_t^2 就是 DDPM 的”预测噪声”(Algorithm 4)。四种参数化 = 同一个目标的四种加权 λ(t)\lambda(t)。
  6. ODE 还是 SDE:理论上等价;实践中 SDE 有时能纠正误差,但改进不可靠,要用多批噪声来判断;用流模型换算的得分做 SDE 采样时,σt\sigma_t 在终点附近必须趋于 0。ODE 往往就足够好,而且是确定性的。
  7. 文献:DDPM 的前向链 = VP 概率路径;时间反演 SDE、概率流 ODE = 扩展技巧的特例;DDIM = 特殊坐标里的欧拉法(CondOT 上就是欧拉法);少步时确定性采样器远好于随机的;DDPM 祖先采样会漏掉 Var⁡(z∣xt)\operatorname{Var}(z\mid x_t)。

9. 常见误区 · Common pitfalls

  1. “扩散模型和流匹配是两类不同的模型。” 对高斯路径,两者学的是同一个后验的不同线性函数,可以互相换算(§2);差别在路径、参数化(加权)和采样器的选择。
  2. “得分匹配直接回归条件得分就行。” 朴素的条件得分匹配损失的期望是无穷大,训练在所有时刻都失败(§5.2、§5.4);必须加权,最常见的是 βt2\beta_t^2(预测噪声)。
  3. “给 ODE 加点噪声就是 SDE 采样。” 必须同时加修正项 σt22∇log⁡pt\frac{\sigma_t^2}{2}\nabla\log p_t,系数必须是 12\frac12(§3.3)。
  4. “SDE 采样总比 ODE 好(或总比 ODE 差)。” 都不对。本讲的实验里,平均下来换算得分的 SDE 与 ODE 没有区别;结论要用多批噪声来下(§6.1)。
  5. “损失一样,模型就一样。” 加权得分模型和噪声模型的损失相同,采样质量差了五倍(§5.4):输出的量不同,学到的函数不同,换算时的放大也不同。
  6. “预测噪声在哪里都好用。” 在 CondOT 这类从 α=0\alpha = 0 线性起步的路径上,预测噪声在 t→0t\to0 处换算成速度要除以 tt(§2.3);这也是大模型转向速度预测的原因之一。
  7. “DDIM 一定比欧拉法好。” CondOT 上两者完全相同;在本讲的 VP 例子里 DDIM 也没有更好(§7.5)。
  8. “DDPM 的 1000 步链是模型的一部分,训练时要跑。” 训练只用闭式的条件分布,从不跑链(§7.2)。

10. 练习 · Exercises

练习 1(VE 路径的得分与 Tweedie)。对 VE 路径 x=z+σϵx = z + \sigma\epsilon(α=1\alpha = 1,β=σ\beta = \sigma),写出条件得分、Tweedie 公式,并说明”得分 × σ2\sigma^2 = 去噪结果 − xx”。

参考答案

条件得分 −(x−z)/σ2-(x - z)/\sigma^2;Tweedie:∇log⁡pσ(x)=(E[z∣x]−x)/σ2\nabla\log p_\sigma(x) = (\mathbb{E}[z\mid x] - x)/\sigma^2,即 E[z∣x]=x+σ2∇log⁡pσ(x)\mathbb{E}[z\mid x] = x + \sigma^2\nabla\log p_\sigma(x)。所以 σ2\sigma^2 倍的得分就是”从带噪图指向去噪结果的位移”。EDM 的去噪器 D(x;σ)D(x;\sigma) 学的正是 E[z∣x]\mathbb{E}[z\mid x],得分由 (D−x)/σ2(D - x)/\sigma^2 给出。

练习 2(Cosine 调度的换算公式)。对 αt=sin⁡πt2\alpha_t = \sin\frac{\pi t}{2}、βt=cos⁡πt2\beta_t = \cos\frac{\pi t}{2},写出换算公式的两个系数,并检查 t=0t = 0 和 t→1t\to 1 时哪个系数发散。

参考答案

α˙/α=π2cot⁡πt2\dot\alpha/\alpha = \frac\pi2\cot\frac{\pi t}{2};α˙β2/α−β˙β=π2cot⁡πt2cos⁡2πt2+π2sin⁡πt2cos⁡πt2=π2cot⁡πt2\dot\alpha\beta^2/\alpha - \dot\beta\beta = \frac\pi2\cot\frac{\pi t}2\cos^2\frac{\pi t}2 + \frac\pi2\sin\frac{\pi t}2\cos\frac{\pi t}2 = \frac\pi2\cot\frac{\pi t}{2}。所以 ut=π2cot⁡πt2 (x+∇log⁡pt(x))u_t = \frac\pi2\cot\frac{\pi t}2\,(x + \nabla\log p_t(x))。t→0t\to0 时 cot⁡→∞\cot\to\infty,但 p0=N(0,I)p_0 = \mathcal{N}(0, I) 的得分是 −x-x,括号趋于 0,极限有限(=π2E[z]= \frac\pi2\mathbb{E}[z],与第 2 讲练习 1 一致);t→1t\to1 时系数趋于 0,u1=0u_1 = 0。数值上,用”得分模型”换算速度时,t→0t\to0 那一端会把误差放大。

练习 3(去噪得分匹配的命题)。仿照第 2 讲定理 12 的证明,证明 LCSM(θ)=LSM(θ)+C′\mathcal{L}_{\text{CSM}}(\theta) = \mathcal{L}_{\text{SM}}(\theta) + C',并写出 C′C'。

参考答案

记 S=∇log⁡pt(xt∣z)S = \nabla\log p_t(x_t\mid z)。由 §1.3,E[S∣xt]=∇log⁡pt(xt)\mathbb{E}[S\mid x_t] = \nabla\log p_t(x_t)。P1 §4.3 的分解:E∥sθ−S∥2=E∥sθ−E[S∣xt]∥2+E∥S−E[S∣xt]∥2\mathbb{E}\lVert s^\theta - S\rVert^2 = \mathbb{E}\lVert s^\theta - \mathbb{E}[S\mid x_t]\rVert^2 + \mathbb{E}\lVert S - \mathbb{E}[S\mid x_t]\rVert^2(交叉项为 0,因为 sθ−E[S∣xt]s^\theta - \mathbb{E}[S\mid x_t] 只依赖 xtx_t)。第一项是 LSM\mathcal{L}_{\text{SM}},第二项 C′=EtE[Var⁡(S∣xt)]C' = \mathbb{E}_t\mathbb{E}[\operatorname{Var}(S\mid x_t)] 与 θ\theta 无关。对高斯路径,C′C' 在 t∈[0,1]t\in[0,1] 上的积分发散(§1.5),所以严格说这个等式要在 t≤tmax⁡<1t\le t_{\max} < 1 或加权之后才有意义。

练习 4(四种加权)。对 CondOT,验证:若网络的隐含噪声估计是 ϵ^\hat\epsilon,则速度损失 =∥ϵ^−ϵ∥2/t2= \lVert\hat\epsilon - \epsilon\rVert^2/t^2,数据损失 =(1−t)2t2∥ϵ^−ϵ∥2= \frac{(1-t)^2}{t^2}\lVert\hat\epsilon - \epsilon\rVert^2,朴素得分损失 =∥ϵ^−ϵ∥2/(1−t)2= \lVert\hat\epsilon - \epsilon\rVert^2/(1-t)^2。

参考答案

x=tz+(1−t)ϵx = tz + (1-t)\epsilon。速度:u^=(x−ϵ^)/t\hat u = (x - \hat\epsilon)/t(§2.2 的换算),目标 z−ϵ=(x−ϵ)/tz - \epsilon = (x - \epsilon)/t,差 (ϵ−ϵ^)/t(\epsilon - \hat\epsilon)/t。数据:z^=(x−(1−t)ϵ^)/t\hat z = (x - (1-t)\hat\epsilon)/t,z=(x−(1−t)ϵ)/tz = (x - (1-t)\epsilon)/t,差 −(1−t)(ϵ^−ϵ)/t-(1-t)(\hat\epsilon - \epsilon)/t。得分:s^=−ϵ^/(1−t)\hat s = -\hat\epsilon/(1-t),目标 −ϵ/(1−t)-\epsilon/(1-t),差 −(ϵ^−ϵ)/(1−t)-(\hat\epsilon - \epsilon)/(1-t)。平方即得。

练习 5(OU 过程的平稳分布)。用 Fokker–Planck 方程验证:一维 OU 过程 dX=−θX dt+σ dWdX = -\theta X\,dt + \sigma\,dW 的平稳分布是 N(0,σ2/(2θ))\mathcal{N}(0, \sigma^2/(2\theta))(第 1 讲 §4.4 用模拟看到过)。

参考答案

设 p(x)∝e−x2/(2v)p(x)\propto e^{-x^2/(2v)},v=σ2/(2θ)v = \sigma^2/(2\theta)。平稳要求 0=−∂x(p⋅(−θx))+σ22∂x2p=∂x[θxp+σ22∂xp]0 = -\partial_x(p\cdot(-\theta x)) + \frac{\sigma^2}{2}\partial_x^2 p = \partial_x\big[\theta x p + \frac{\sigma^2}{2}\partial_x p\big]。而 ∂xp=−xvp\partial_x p = -\frac{x}{v}p,所以括号 =θxp−σ22vxp=θxp−θxp=0= \theta xp - \frac{\sigma^2}{2v}xp = \theta xp - \theta xp = 0。另一种看法:OU 的漂移 −θx=σ22⋅(−xv)=σ22∇log⁡p-\theta x = \frac{\sigma^2}{2}\cdot(-\frac{x}{v}) = \frac{\sigma^2}{2}\nabla\log p,它就是 pp 的朗之万动力学(§3.6)。

练习 6(编程:让噪声在终点关掉)。在 03_sde_extension_trick.py 第 3 部分,把 σ=4\sigma = 4 改成 σt=4(1−t)\sigma_t = 4(1-t),n=10,30,100n = 10, 30, 100 时还失稳吗?

参考答案(作者机器上的结果)

能量距离 / 峰内散度 / 落在峰之间:n=10n = 10:0.0102 / 1.07 / 0.2%;n=30n = 30:0.0002 / 1.02 / 0.07%;n=100n = 100:−0.0005 / 1.01 / 0%。常数 σ=4\sigma = 4 在 n=10n = 10 时能量距离是 45,这里只有 0.010,和 ODE(0.012)差不多。失稳完全来自终点附近”大噪声 × 大得分”的刚性。

练习 7(编程:η\eta 的作用)。在 07_ddpm_ddim.py 第 3 部分,把 η\eta 取 0、0.25、0.5、0.75、1,n=10,20,50n = 10, 20, 50,比较能量距离和峰内散度。

参考答案(作者机器上的结果)
η\etan=10n = 10n=20n = 20n=50n = 50
00.008 / 0.960.003 / 0.950.001 / 0.97
0.250.008 / 0.940.003 / 0.94−0.000 / 0.96
0.50.007 / 0.920.002 / 0.93−0.001 / 0.96
0.750.009 / 0.920.001 / 0.90−0.001 / 0.92
10.013 / 0.840.002 / 0.81−0.001 / 0.88

散度随 η\eta 增大单调变小:随机性越多,漏掉的 Var⁡(z∣xt)\operatorname{Var}(z\mid x_t) 越多(§7.5)。能量距离对这种”压瘦”不敏感,η=0.5\eta = 0.5 附近反而略好。

练习 8(思考:SDEdit)。SDEdit(Meng et al. 2022)这样编辑图像:给一张手绘草图加噪声到中间时刻 t0t_0,再从 t0t_0 开始用扩散模型生成。用 §3.5 的”SDE 忘掉起点”解释:t0t_0 取得太小(噪声太多)或太大(噪声太少)各会怎样?用 ODE 代替 SDE 去噪有什么区别?

参考答案

t0t_0 越小,加的噪声越多,草图的信息被抹掉得越多:结果更像一张”真实”的图,但和草图越不像(极端情况 t0=0t_0 = 0 就是无条件生成)。t0t_0 越接近 1,加的噪声越少,结果和草图很像,但草图本身不在数据分布上,模型来不及把它”拉回”真实图像的流形。SDE 去噪会进一步忘掉起点(§3.5),在保真和真实之间多了一个旋钮;ODE 去噪是确定性的,同一个加噪结果总得到同一张图,并且(因为 ODE 可逆)可以先把草图沿 ODE 反演到 t0t_0 再生成,保留更多结构。


11. 延伸阅读 · Further reading

  • 原课讲义第 4 章、附录 B、附录 E 和 Lab 2(https://github.com/eje24/iap-diffusion-labs ,2026 分支)。Lab 2 实现了条件得分、得分匹配训练、ScoreFromVectorField 和朗之万修正的 SDE 采样。
  • Song, Sohl-Dickstein, Kingma, Kumar, Ermon & Poole, Score-Based Generative Modeling through Stochastic Differential Equations(ICLR 2021):VP / VE SDE、时间反演、概率流 ODE、预测–校正采样器。
  • Ho, Jain & Abbeel, Denoising Diffusion Probabilistic Models(NeurIPS 2020);Sohl-Dickstein et al., Deep Unsupervised Learning using Nonequilibrium Thermodynamics(ICML 2015)。
  • Song & Ermon, Generative Modeling by Estimating Gradients of the Data Distribution(NeurIPS 2019):多噪声水平的得分 + 退火朗之万。
  • Vincent, A Connection Between Score Matching and Denoising Autoencoders(Neural Computation 2011);Hyvärinen, Estimation of Non-Normalized Statistical Models by Score Matching(JMLR 2005)。
  • Efron, Tweedie’s Formula and Selection Bias(JASA 2011)。
  • Song, Meng & Ermon, Denoising Diffusion Implicit Models(ICLR 2021);Lu et al., DPM-Solver(NeurIPS 2022);Zhang & Chen, DEIS(ICLR 2023)。
  • Karras, Aittala, Aila & Laine, Elucidating the Design Space of Diffusion-Based Generative Models(EDM,NeurIPS 2022):参数化、加权、采样器、随机性的系统研究。
  • Kingma & Gao, Understanding Diffusion Objectives as the ELBO with Simple Data Augmentation(NeurIPS 2023):各种目标 = 不同的加权。
  • Salimans & Ho, Progressive Distillation for Fast Sampling of Diffusion Models(ICLR 2022,提出 v-prediction);Lin et al., Common Diffusion Noise Schedules and Sample Steps Are Flawed(WACV 2024)。
  • Bao et al., Analytic-DPM(ICLR 2022);Meng et al., SDEdit(ICLR 2022);Ma et al., SiT(ECCV 2024)。
  • Anderson, Reverse-Time Diffusion Equation Models(Stochastic Processes and their Applications 1982)。
  • 随机微积分的严格处理:Øksendal, Stochastic Differential Equations(第 4、7、8 章:伊藤公式、生成元、Fokker–Planck)。

12. 下一讲预告 · Next lecture

到目前为止,我们只会”从 pdatap_{\text{data}} 里随便采一个样本”。可我们真正想要的是”画一只戴帽子的猫”:按提示生成。第 4 讲要回答:

  1. 怎样把提示 yy 喂给网络?最直接的做法(“vanilla guidance”:把 yy 当作额外输入,学 ut(x∣y)u_t(x\mid y))为什么提示遵循度不够?
  2. 分类器引导:贝叶斯公式 ∇log⁡pt(x∣y)=∇log⁡pt(x)+∇log⁡pt(y∣x)\nabla\log p_t(x\mid y) = \nabla\log p_t(x) + \nabla\log p_t(y\mid x)——本讲的得分在这里第一次派上用场。
  3. 无分类器引导(CFG):u~t=(1−w)ut(x∣∅)+w ut(x∣y)\tilde u_t = (1 - w)u_t(x\mid\varnothing) + w\,u_t(x\mid y)。为什么几乎所有图像和视频生成模型都离不开它?它采样的到底是什么分布?(答案会让人意外:不是 p(x∣y)wp(x)1−wp(x\mid y)^w p(x)^{1-w}。)
← 返回课程目录