Flow Matching
给定一个只会「模拟 ODE」的神经网络,怎样找到它该拟合的那个向量场?答案是:用一个我们算得出来的条件目标,去训练一个我们算不出来的边际目标。
0. 本讲导读
上一讲我们造好了「发动机」:给定一个向量场(vector field)$\vf_t^\theta$,我们知道怎么从噪声出发、沿着 ODE 一路积分到 $t=1$,得到一个样本。但我们从来没说过 $\theta$ 该取什么值。一个随机初始化的神经网络当然给不出猫的照片——它给出的是一团随机涂鸦。这一讲要解决的,就是「训练」这两个字。
问题的形状很清楚。我们希望
$$ X_0 \sim \simple, \quad \dd{X_t} = \vf_t^\theta(X_t)\dd{t} \quad \Longrightarrow \quad X_1 \sim \data . $$这是一个关于轨迹终点分布的要求。困难在于:我们手上只有一堆数据样本 $z^{(1)},\dots,z^{(N)} \sim \data$,既不知道 $\data$ 的密度,更不知道「能把 $\simple$ 搬运到 $\data$ 的那个向量场」长什么样。没有标签,怎么做回归?
Flow matching 的回答分三步走,每一步都会在本讲里被完整推导:
- 先规定路线,再反推速度。 我们不去猜向量场,而是先人为指定一条从 $\simple$ 到 $\data$ 的分布插值路径 $(p_t)_{0\le t\le 1}$,称为概率路径(probability path)。路径一旦定死,能生成它的向量场就被连续性方程钉住了。
- 把「对整个数据分布」的难题拆成「对单个数据点」的易题。 对每个固定的数据点 $z$,条件路径 $p_t(\cdot|z)$ 和它的条件向量场 $\vf_t^{\text{target}}(\cdot|z)$ 都有闭式解——我们能用纸笔算出来。然后由边际化技巧(marginalization trick),把这些条件向量场按后验概率加权平均,就得到了真正想要的边际向量场。
- 把「不可算的回归目标」换成「可算的回归目标」。 边际向量场虽然存在,却是一个高维积分,训练时根本算不出来。关键定理告诉我们:直接对条件向量场做回归,其损失与对边际向量场做回归的损失只差一个与 $\theta$ 无关的常数,因此两者梯度完全相同。于是我们可以放心地用可算的目标训练。
整个方法的骨架可以用一张「Flow Matching 矩阵」概括:横向是「概率路径 → 向量场 → 损失函数」三级递进,纵向是「条件(单个数据点)/边际(整个数据分布)」两层。上面一行样样可算,下面一行样样不可算,而这一讲的全部技术含量,就是证明「优化上面一行 = 优化下面一行」。
- 高斯条件概率路径:$p_t(\cdot|z) = \N(\alpha_t z,\ \beta_t^2 I_d)$,噪声调度 $\alpha_0=\beta_1=0$、$\alpha_1=\beta_0=1$。采样即 $x = \alpha_t z + \beta_t \epsilon$。
- 条件向量场闭式解:$\vf_t^{\text{target}}(x|z) = \left(\dot\alpha_t - \dfrac{\dot\beta_t}{\beta_t}\alpha_t\right)z + \dfrac{\dot\beta_t}{\beta_t}x$;沿路径代入后化简为 $\dot\alpha_t z + \dot\beta_t \epsilon$,即插值曲线的速度。
- 边际化技巧:$\vf_t^{\text{target}}(x) = \displaystyle\int \vf_t^{\text{target}}(x|z)\,\frac{p_t(x|z)\data(z)}{p_t(x)}\dd{z} = \E\!\left[\vf_t^{\text{target}}(X_t|Z)\,\middle|\,X_t = x\right]$。边际向量场是条件向量场关于「后验 $p(z|x)$」的加权平均。
- 梯度等价定理:$\mathcal{L}_{\text{FM}}(\theta) = \mathcal{L}_{\text{CFM}}(\theta) + C$,$C$ 与 $\theta$ 无关,故 $\nabla_\theta \mathcal{L}_{\text{FM}} = \nabla_\theta \mathcal{L}_{\text{CFM}}$。根本原因:平方损失的最优解是条件期望,而边际向量场恰好就是条件向量场的条件期望。
- CondOT 路径($\alpha_t=t,\ \beta_t=1-t$):训练目标退化为 $\norm{\vf_t^\theta\big(tz+(1-t)\epsilon\big) - (z-\epsilon)}^2$——线性插值的输入,噪声到数据的直线方向作为标签。Stable Diffusion 3 与 Meta Movie Gen Video 用的就是它。
- 训练是 simulation-free 的:整个训练过程中一次 ODE 都不用模拟,只是一个普通的监督回归。这是 flow matching 能被推到工业规模的根本原因。
1. 训练问题:我们到底要拟合什么
先把对象和维度钉死,后面所有推导都以此为准。
| 对象 | 类型 / 维度 | 含义 |
|---|---|---|
| $x, z, \epsilon$ | $\R^d$ | 状态点、数据点、标准高斯噪声 |
| $t$ | $[0,1]$ | 时间,$t=0$ 是噪声端,$t=1$ 是数据端 |
| $\simple$ | $\R^d$ 上的概率密度 | 初始(易采样)分布,本讲默认 $\N(0,I_d)$ |
| $\data$ | $\R^d$ 上的概率密度 | 数据分布,只能采样,密度未知 |
| $p_t(\cdot|z)$ | $\R^d \to \R_{\ge 0}$,对每个 $z$ 一族 | 条件概率路径 |
| $p_t$ | $\R^d \to \R_{\ge 0}$ | 边际概率路径 |
| $\vf_t^{\text{target}}(\cdot|z)$ | $\R^d \to \R^d$ | 条件向量场(每个 $z$ 一个) |
| $\vf_t^{\text{target}}$ | $\R^d \to \R^d$ | 边际向量场(训练的目标) |
| $\vf_t^\theta$ | $\R^d \times [0,1] \to \R^d$ | 神经网络,参数 $\theta$ |
本讲限定在 flow model
上一讲同时讲了 flow model(ODE)和 diffusion model(SDE)。本讲只处理 flow model:生成过程就是
$$ X_0 \sim \simple, \qquad \dd{X_t} = \vf_t^\theta(X_t)\dd{t}, $$模拟到 $t=1$,返回 $X_1$ 作为样本。SDE 版本要等到下一讲引入 score function 之后才能处理。
于是「怎么训练」这个含糊的问题,被翻译成一个非常具体的数学问题:
如何优化 $\theta$,使得模拟上述 ODE 得到的终点满足 $X_1 \sim \data$?
为什么这个问题不是普通的监督学习
把它和一个标准回归任务对比一下,困难就浮出来了。监督学习里我们有成对的 $(\text{输入},\text{标签})$;这里我们只有 $\data$ 的样本,没有任何一条数据告诉我们「在时刻 $t$、位置 $x$ 处速度应该是多少」。更糟的是:
- 损失定义在终点分布上,而终点是长长一串 ODE 积分的结果。如果直接对「终点分布与 $\data$ 的某种距离」求梯度,就必须反向传播穿过整条模拟轨迹(这正是 neural ODE / continuous normalizing flow 的做法)。代价极高,而且要算 Jacobian 的迹或行列式。
- 中间时刻 $0 \lt t \lt 1$ 发生什么,问题本身没有规定。也就是说约束只在两端,中间是完全自由的。
第二点看起来是坏消息,实际上是本讲全部智慧的来源:既然中间没被规定,那就由我们自己规定。一旦把中间过程也钉死,「向量场该是什么」就从一个开放问题变成了一个有唯一答案(准确说是一族答案)的计算题,而且这个答案可以写成解析式。这就是「概率路径」这个概念要干的事。
想象你要把一堆沙子($\simple$)搬成一座城堡($\data$)。直接问「该往哪个方向铲」无从下手。但如果有人先给你一段延时摄影,规定了每一个时刻沙堆应该长什么样,那么「这一秒该往哪铲」就变成了一个局部的、可计算的问题。概率路径就是这段延时摄影;连续性方程就是「从每一帧的形状反推出铲沙速度」的换算公式。
2. 条件概率路径与边际概率路径
2.1 定义:条件概率路径
先引入一个记号。对数据点 $z \in \R^d$,用 $\delt{z}$ 表示 Dirac delta(狄拉克 δ)「分布」:从 $\delt{z}$ 采样永远返回 $z$,它是最简单的确定性分布。严格来说它不是密度函数而是测度,但在本讲的所有计算里,只要记住 $\int f(x)\delt{z}(x)\dd{x} = f(z)$ 就够用了。
条件(插值)概率路径(conditional interpolating probability path)是一族分布 $p_t(\cdot|z)$,$t \in [0,1]$,$z \in \R^d$,满足边界条件
$$ p_0(\cdot|z) = \simple, \qquad p_1(\cdot|z) = \delt{z} \qquad \text{对所有 } z \in \R^d . $$用白话说:固定一个数据点 $z$,条件概率路径描述「整个初始分布逐渐塌缩到这一个点 $z$ 上」的过程。$t=0$ 时它是整个 $\simple$,$t=1$ 时它已经完全集中在 $z$ 这一个点上。可以把概率路径理解为分布空间里的一条轨迹:每个时刻 $t$ 对应一个分布,$t$ 从 $0$ 走到 $1$,分布从 $\simple$ 走到 $\delt{z}$。
2.2 定义:边际概率路径
单个数据点显然不够。把 $z$ 按数据分布随机抽取,就得到边际版本。
每个条件概率路径 $p_t(\cdot|z)$ 都诱导出一个边际概率路径(marginal probability path)$p_t$,定义为「先从 $\data$ 抽 $z$,再从 $p_t(\cdot|z)$ 抽 $x$」所得到的 $x$ 的分布:
$$ z \sim \data,\quad x \sim p_t(\cdot|z) \quad \Longrightarrow \quad x \sim p_t \qquad \text{(采样方式)} $$ $$ p_t(x) = \int p_t(x|z)\,\data(z)\dd{z} \qquad \text{(密度公式)} $$这两行的地位极不对称,这个不对称贯穿整门课,务必看清楚:
第一行(采样)是可执行的:从数据集里随机取一张图 $z$,再往里加噪声,就得到了一个 $p_t$ 的样本。两行代码的事。
第二行(密度)是不可执行的:$\int \cdots \data(z)\dd{z}$ 是一个 $d$ 维积分,而且被积函数里含有我们根本不知道的 $\data$。即使把 $\data$ 换成经验分布 $\frac1N\sum_i \delt{z^{(i)}}$,也要遍历整个数据集才能算出一个点的 $p_t(x)$。
Flow matching 的全部设计,都是为了让训练算法只用到第一行、不用到第二行。
2.3 验算:边际路径确实连接了噪声与数据
讲义在这里写了一句「Check for yourself」。我们把这个检验真的做出来——它只有两行,但把「为什么条件端点要取 $\delt{z}$ 而不是 $\data$」这个疑问彻底解决了。
$t=0$ 端。 代入 $p_0(\cdot|z) = \simple$:
$$ \begin{aligned} p_0(x) &\overset{(i)}{=} \int p_0(x|z)\,\data(z)\dd{z} \\[4pt] &\overset{(ii)}{=} \int \simple(x)\,\data(z)\dd{z} \\[4pt] &\overset{(iii)}{=} \simple(x)\int \data(z)\dd{z} \;\overset{(iv)}{=}\; \simple(x). \end{aligned} $$其中 (i) 是边际路径的定义;(ii) 用了条件路径在 $t=0$ 的边界条件,注意 $\simple(x)$ 不依赖 $z$,这是关键;(iii) 把与积分变量无关的因子提到积分号外;(iv) 用了 $\data$ 是概率密度,积分为 $1$。
$t=1$ 端。 代入 $p_1(\cdot|z) = \delt{z}$:
$$ p_1(x) \overset{(i)}{=} \int p_1(x|z)\,\data(z)\dd{z} \overset{(ii)}{=} \int \delt{z}(x)\,\data(z)\dd{z} \overset{(iii)}{=} \data(x). $$其中 (iii) 用了 Dirac delta 的挑选性质:$\delt{z}(x)$ 作为 $z$ 的函数在 $z=x$ 处「挑出」被积函数的值。若嫌不严谨,可以对任意测试函数 $f$ 计算 $\int f(x)p_1(x)\dd{x} = \int\!\!\int f(x)\delt{z}(x)\dd{x}\,\data(z)\dd{z} = \int f(z)\data(z)\dd{z}$,这正说明 $p_1 = \data$。
这段验算解释了一个初学者常见的困惑:为什么条件路径的终点是单个数据点 $\delt{z}$,而不是数据分布 $\data$? 因为「对 $z\sim\data$ 取平均」这件事已经由边际化那一步完成了。每个条件路径只负责瞄准一个靶心,所有靶心按 $\data$ 的权重叠加起来,正好还原出整个数据分布。让条件路径直接瞄准 $\data$ 反而是错的——那样边际路径的终点会变成 $\data$ 与自身的某种混合,而且条件路径也就不再有闭式解了。
2.4 一个致命的细节:概率路径不含动力学
这是最容易被跳过、却在后面反复咬人的一点。
概率路径只规定了每个时刻的「快照」(边际分布),它对「单个粒子如何随时间移动」什么都没说。
换句话说,$(p_t)_{0\le t\le 1}$ 是一列分布,不是一列轨迹。给定同一条概率路径,可以有无穷多个不同的向量场生成它:如果 $\vf_t$ 生成 $p_t$,而 $w_t$ 满足 $\divg(p_t w_t) = 0$(不产生净流动的「环流」),那么 $\vf_t + w_t$ 同样生成 $p_t$——它们的快照一模一样,但粒子的运动轨迹完全不同。
因此「找一个生成 $p_t$ 的向量场」是有解的,但解不唯一。Flow matching 并不追求唯一性,它只需要某一个能被写出闭式解的解。
3. 高斯概率路径:把一切都算出来
概率路径的定义只给了两端的约束,中间怎么走完全自由。高斯概率路径(Gaussian probability path)是迄今为止最重要、也是几乎所有 state-of-the-art 模型实际使用的选择。这一节把它彻底算穿。
3.1 定义与边界条件的验证
取两个连续可微的单调函数 $\alpha_t, \beta_t : [0,1] \to \R$,称为噪声调度(noise scheduler),满足
$$ \alpha_0 = 0,\quad \alpha_1 = 1, \qquad \beta_0 = 1,\quad \beta_1 = 0 . $$定义条件概率路径
$$ p_t(\cdot|z) = \N\!\left(\alpha_t z,\ \beta_t^2 I_d\right), $$即密度为
$$ p_t(x|z) = \left(2\pi\beta_t^2\right)^{-d/2}\exp\!\left(-\frac{\norm{x - \alpha_t z}^2}{2\beta_t^2}\right),\qquad x \in \R^d . $$先验证它确实是一条合法的条件插值路径。
$t=0$: 代入 $\alpha_0 = 0,\ \beta_0 = 1$,
$$ p_0(\cdot|z) = \N\!\left(\alpha_0 z,\ \beta_0^2 I_d\right) = \N\!\left(0\cdot z,\ 1^2 \cdot I_d\right) = \N(0, I_d) = \simple . $$注意均值项 $\alpha_0 z = 0$ 对任意 $z$ 都成立,所以 $p_0(\cdot|z)$ 与 $z$ 无关——这正是条件路径定义所要求的($p_0(\cdot|z)=\simple$ 不依赖 $z$)。这也顺带说明了:这套构造默认 $\simple = \N(0,I_d)$。
$t=1$: 代入 $\alpha_1 = 1,\ \beta_1 = 0$,
$$ p_1(\cdot|z) = \N\!\left(\alpha_1 z,\ \beta_1^2 I_d\right) = \N\!\left(z,\ 0\right) = \delt{z} . $$这里用了「方差为零、均值为 $z$ 的正态分布就是 $\delt{z}$」这个事实。可以这样看:若 $X \sim \N(z,\sigma^2 I_d)$,则对任意 $\varepsilon \gt 0$,$\Pr(\norm{X-z} \gt \varepsilon) \to 0$($\sigma \to 0$),即 $X$ 依分布收敛到常数 $z$。
两端都对上了,所以高斯路径是合法的条件插值概率路径。$\square$
3.2 采样:重参数化
高斯路径最实用的性质是采样极其简单。由高斯分布的线性变换性质(若 $\epsilon\sim\N(0,I_d)$,则 $A\epsilon + b \sim \N(b, AA^\top)$,此处 $A = \beta_t I_d$):
$$ z \sim \data,\ \ \epsilon \sim \simple = \N(0, I_d) \quad \Longrightarrow \quad x = \alpha_t z + \beta_t \epsilon \sim p_t(\cdot|z), $$而由边际路径的采样定义,同一个 $x$ 也就是边际路径的样本:$x \sim p_t$。这一行是整个训练算法的数据生成器:从数据集里取一张图 $z$,抽一个标准高斯噪声 $\epsilon$,抽一个时间 $t$,做一次线性混合,就得到了一个训练输入。没有任何模拟、没有任何积分。
$\alpha_t$ 是「数据的音量」,$\beta_t$ 是「噪声的音量」。$t=0$ 时数据音量为零、噪声满格,$t=1$ 时反过来。中间的 $t$ 就是两个信号的调音台。$\alpha_t$ 单调增、$\beta_t$ 单调减,保证了「越往后越像数据」这个直观要求。
3.3 具体算例一:两点数据集
抽象公式必须落到具体例子上才算真懂。取 $d=1$,数据分布是两个点的均匀混合 $\data = \frac12\left(\delt{z_1} + \delt{z_2}\right)$。此时边际路径是
$$ \begin{aligned} p_t(x) &= \int p_t(x|z)\,\data(z)\dd{z} \\[4pt] &= \tfrac12\, p_t(x|z_1) + \tfrac12\, p_t(x|z_2) \\[4pt] &= \tfrac12\,\N\!\left(x;\ \alpha_t z_1,\ \beta_t^2\right) + \tfrac12\,\N\!\left(x;\ \alpha_t z_2,\ \beta_t^2\right). \end{aligned} $$也就是一个两分量高斯混合:两个分量的中心分别以速度 $\dot\alpha_t z_1$ 和 $\dot\alpha_t z_2$ 从原点向外滑动,同时各自的标准差 $\beta_t$ 从 $1$ 收缩到 $0$。$t=0$ 时两个分量完全重合成一个 $\N(0,1)$(因为 $\alpha_0=0$),$t=1$ 时收缩成两根 delta 尖峰。整条路径就是「一个高斯团裂变成两个尖峰」的过程。推广到 $K$ 个数据点是显然的:$\data = \sum_k w_k \delt{z_k}$ 给出 $p_t = \sum_k w_k \N(\alpha_t z_k, \beta_t^2 I_d)$。
注意即使在这个最简单的例子里,$p_t(x)$ 也已经是一个求和;数据集有 $N$ 个样本时就是 $N$ 项求和,$N$ 是百万量级时求值一次的代价就已经不可接受了。这个玩具例子恰恰说明了为什么真实场景里 $p_t(x)$ 不可算。
3.4 具体算例二:高斯数据分布(全解析)
再看一个能一路算到底的例子:设数据分布本身就是高斯,$\data = \N(\mu, \sigma^2 I_d)$。这时边际路径也有闭式解。
用采样表述最省力。由 $Z \sim \N(\mu,\sigma^2 I_d)$、$\epsilon \sim \N(0,I_d)$ 且二者独立,
$$ X_t = \alpha_t Z + \beta_t \epsilon . $$独立高斯的线性组合仍是高斯,只需算均值与协方差:
$$ \begin{aligned} \E[X_t] &= \alpha_t \E[Z] + \beta_t \E[\epsilon] = \alpha_t \mu, \\[4pt] \Cov(X_t) &\overset{(i)}{=} \alpha_t^2 \Cov(Z) + \beta_t^2 \Cov(\epsilon) = \left(\alpha_t^2\sigma^2 + \beta_t^2\right) I_d, \end{aligned} $$其中 (i) 用了 $Z \perp \epsilon$(独立随机变量之和的协方差可加)。记
$$ \gamma_t := \sqrt{\alpha_t^2\sigma^2 + \beta_t^2}, $$则
$$ p_t = \N\!\left(\alpha_t \mu,\ \gamma_t^2 I_d\right). $$检查两端:$\gamma_0 = \sqrt{0 + 1} = 1$,$p_0 = \N(0, I_d) = \simple$ ✓;$\gamma_1 = \sqrt{\sigma^2 + 0} = \sigma$,$p_1 = \N(\mu,\sigma^2 I_d) = \data$ ✓。
值得玩味的是:边际路径 $p_t = \N(\alpha_t\mu, \gamma_t^2 I_d)$ 自己也是一条「同样形状」的高斯路径,只不过把「数据点 $z$」换成了「数据均值 $\mu$」、把「噪声尺度 $\beta_t$」换成了 $\gamma_t$。这个观察在 §7.4 会被用来验证边际化技巧——我们将用两种完全不同的方法算出同一个边际向量场,从而给公式一次独立的正确性检验。
3.5 常用调度对照
满足边界条件的 $(\alpha_t,\beta_t)$ 有无穷多种。下表列出两个典型选择,两者都可以直接代入后面推出的所有公式。
| 调度 | $\alpha_t$ | $\beta_t$ | $\dot\alpha_t$ | $\dot\beta_t$ | 特点 |
|---|---|---|---|---|---|
| CondOT(线性 / 直线) | $t$ | $1-t$ | $1$ | $-1$ | $\alpha_t+\beta_t=1$;插值是噪声与数据之间的直线段;SD3、Movie Gen 采用 |
| 三角(方差保持型) | $\sin\frac{\pi t}{2}$ | $\cos\frac{\pi t}{2}$ | $\frac{\pi}{2}\cos\frac{\pi t}{2}$ | $-\frac{\pi}{2}\sin\frac{\pi t}{2}$ | $\alpha_t^2+\beta_t^2=1$;若 $\data$ 各分量方差为 $1$,则沿路径方差恒为 $1$ |
两者的边界条件都易验:$\sin 0 = 0$、$\sin\frac{\pi}{2}=1$、$\cos 0 = 1$、$\cos\frac{\pi}{2}=0$,且在 $[0,1]$ 上分别单调增/单调减。本讲的所有定理对任意合法调度都成立;调度的选择只影响常数因子与数值稳定性,不影响正确性。
4. 条件向量场与边际向量场
概率路径规定了「每一帧应该长什么样」,但没规定粒子怎么动(§2.4)。现在补上动力学。
4.1 定义:条件向量场
对每个数据点 $z \in \R^d$,称 $\vf_t^{\text{target}}(\cdot|z) : \R^d \to \R^d$ 是一个条件向量场(conditional vector field),如果它对应的 ODE 生成条件概率路径,即
$$ X_0 \sim \simple,\quad \frac{\dd{}}{\dd{t}}X_t = \vf_t^{\text{target}}(X_t|z) \quad \Longrightarrow \quad X_t \sim p_t(\cdot|z) \quad (0 \le t \le 1). $$三点必须说清楚:
- 这是一个要求,不是一个构造。任何满足这个性质的向量场都算数(回忆 §2.4:这样的向量场不唯一)。
- 它对每个 $z$ 是一个不同的向量场——「条件」二字就是「以 $z$ 为条件」。$z$ 在这里是参数,不是自变量。
- 关键优势:因为条件路径是我们自己挑的简单分布(比如高斯),$\vf_t^{\text{target}}(\cdot|z)$ 常常可以用手推出来。§5 就做这件事。
4.2 条件向量场单独看毫无用处
先泼一盆冷水,因为这盆冷水正是理解边际化技巧的入口。
「既然条件向量场能把噪声送到目标,那直接用它生成不就行了?」——不行。条件 ODE 的终点分布是 $p_1(\cdot|z) = \delt{z}$,意味着无论初始噪声 $X_0$ 抽到什么,终点 $X_1$ 恒等于 $z$。它是一个「把整个空间压缩到一个已知数据点」的映射,生成出来的永远是训练集里那张原图,没有任何生成能力可言。
条件向量场的价值不在于自己能生成,而在于它是积木:它可算、有闭式解,而真正有生成能力的边际向量场可以由它加权平均得到。
4.3 定理:边际化技巧
现在是本讲的第一根支柱。
设 $\vf_t^{\text{target}}(\cdot|z)$ 是一个条件向量场(即满足 §4.1 的定义)。定义边际向量场(marginal vector field)
$$ \vf_t^{\text{target}}(x) = \int \vf_t^{\text{target}}(x|z)\,\frac{p_t(x|z)\,\data(z)}{p_t(x)}\dd{z}, $$则它生成边际概率路径:
$$ X_0 \sim \simple,\quad \frac{\dd{}}{\dd{t}}X_t = \vf_t^{\text{target}}(X_t) \quad \Longrightarrow \quad X_t \sim p_t \quad (0 \le t \le 1). $$特别地,取 $t=1$ 得 $X_1 \sim p_1 = \data$。也就是说,$\vf_t^{\text{target}}$ 把噪声 $\simple$ 变成了数据 $\data$——它正是我们要让神经网络去拟合的那个目标。
4.4 先读懂公式再证明它
在动手证明之前,先把这个积分读明白。注意到由贝叶斯公式,
$$ p_{t}(z \mid x) \;=\; \frac{p_t(x|z)\,\data(z)}{p_t(x)} $$正是「在时刻 $t$ 观测到带噪点 $x$ 时,它来自哪个数据点 $z$」的后验分布:分子是「先验 $\data(z)$ × 似然 $p_t(x|z)$」,分母 $p_t(x) = \int p_t(x|z)\data(z)\dd{z}$ 是归一化常数(这也再次说明了为什么 $p_t(x)$ 是配分函数式的、不可算的量)。于是边际化技巧可以写成一句话:
$$ \boxed{\ \vf_t^{\text{target}}(x) \;=\; \E\!\left[\vf_t^{\text{target}}(X_t \mid Z)\ \middle|\ X_t = x\right]\ } $$其中期望是关于联合分布 $Z \sim \data,\ X_t \sim p_t(\cdot|Z)$ 取的。边际向量场 = 条件向量场关于后验的条件期望。 这个形式在 §7 证明梯度等价定理时会立刻派上用场,请务必记住。
站在带噪点 $x$ 上,你不知道自己「本来是哪张图」。于是你对每一个候选数据点 $z$ 都问一句:「如果我的目标是 $z$,我该往哪走?」——答案是 $\vf_t^{\text{target}}(x|z)$,即指向 $z$ 的那个方向。然后你按「我有多相信自己来自 $z$」(后验 $p_t(z|x)$)给这些方向加权平均,走那个平均方向。
时间早($t$ 小、$\beta_t$ 大)时噪声铺天盖地,后验很平,你几乎对所有数据点一视同仁,于是平均方向指向数据集的「重心」——粗略的、模糊的方向。时间晚($t$ 接近 $1$、$\beta_t \to 0$)时后验急剧尖锐,几乎全部质量集中在最接近的那个数据点上,于是你笔直冲向它——细节被确定下来。这就是「先定轮廓、后定细节」这一生成模型经典现象的数学来源。
4.5 混合数据分布下的显式形式
把 §3.3 的有限数据集代进去,可以把这个「加权平均」写得完全具体。设 $\data = \sum_{k=1}^{K} w_k \delt{z_k}$($w_k \ge 0$,$\sum_k w_k = 1$),高斯路径。则积分退化成求和:
$$ \vf_t^{\text{target}}(x) = \sum_{k=1}^{K} w_k(t,x)\, \vf_t^{\text{target}}(x|z_k), \qquad w_k(t,x) = \frac{w_k \exp\!\left(-\dfrac{\norm{x-\alpha_t z_k}^2}{2\beta_t^2}\right)}{\displaystyle\sum_{j=1}^{K} w_j \exp\!\left(-\dfrac{\norm{x-\alpha_t z_j}^2}{2\beta_t^2}\right)} . $$这里高斯密度前的常数因子 $(2\pi\beta_t^2)^{-d/2}$ 在分子分母中约掉了。可以看到 $w_k(t,x)$ 就是一个以 $-\norm{x-\alpha_t z_k}^2/(2\beta_t^2)$ 为 logit 的 softmax,「温度」是 $\beta_t^2$。当 $\beta_t \to 0$(即 $t\to1$)时温度趋于零,softmax 退化成 argmax——边际向量场直接指向最近的那个训练样本。
上式说明:若把 $\data$ 当作有限训练集的经验分布,那么精确的边际向量场在 $t \to 1$ 时会把每个点送到某个训练样本本身,即完美拟合 = 完全记忆训练集。真实模型之所以能泛化,是因为神经网络容量有限、训练不充分、并且用了平滑的归纳偏置,它拟合的是这个理想目标的光滑近似。这一点在讨论扩散模型的泛化能力时非常重要。
定理 1 的完整证明需要连续性方程这个工具,我们在下一节先把工具建好,再回来收网。
5. 高斯路径的条件向量场:一步步解出来
定理 1 说「只要有条件向量场,就能造出边际向量场」。那条件向量场从哪来?对高斯路径,答案可以完全用手推出来。这一节把讲义 Example 10 的推导拆成每一步。
5.1 先造 flow,再从 flow 里提取向量场
回忆上一讲:向量场 $\vf_t$ 的流(flow)$\psi_t : \R^d \to \R^d$ 定义为 ODE 的解映射,满足
$$ \psi_0(x_0) = x_0, \qquad \frac{\dd{}}{\dd{t}}\psi_t(x_0) = \vf_t\!\left(\psi_t(x_0)\right). $$直接猜向量场很难,但猜流很容易——因为高斯路径的采样公式 $x = \alpha_t z + \beta_t \epsilon$ 已经把答案摆在脸上了:它就是「把初始噪声 $\epsilon$ 送到时刻 $t$ 的位置」的映射。于是定义
$$ \psi_t^{\text{target}}(x_0|z) := \alpha_t z + \beta_t x_0, \qquad x_0 \in \R^d . $$设 $X_0 \sim \simple = \N(0, I_d)$,令 $X_t = \psi_t^{\text{target}}(X_0|z) = \alpha_t z + \beta_t X_0$。由高斯分布在仿射变换下封闭:
$$ X_t = \underbrace{\beta_t}_{\text{线性部分}} X_0 + \underbrace{\alpha_t z}_{\text{平移}} \ \sim\ \N\!\left(\alpha_t z,\ \beta_t^2 I_d\right) = p_t(\cdot|z). $$具体地:$\E[X_t] = \beta_t\E[X_0] + \alpha_t z = \alpha_t z$;$\Cov(X_t) = \beta_t I_d \cdot \Cov(X_0)\cdot \beta_t I_d = \beta_t^2 I_d$。且初始条件 $\psi_0^{\text{target}}(x_0|z) = \alpha_0 z + \beta_0 x_0 = 0 + x_0 = x_0$ ✓。
所以「轨迹的分布 = 条件概率路径」这一条已经满足,剩下的只是把向量场从流里解出来。
按 flow 的定义,对所有 $x_0, z \in \R^d$ 有
$$ \frac{\dd{}}{\dd{t}}\psi_t^{\text{target}}(x_0|z) = \vf_t^{\text{target}}\!\left(\psi_t^{\text{target}}(x_0|z)\,\middle|\,z\right). $$逐步化简:
$$ \begin{aligned} &\phantom{\overset{(i)}{\Longleftrightarrow}}\ \frac{\dd{}}{\dd{t}}\psi_t^{\text{target}}(x_0|z) = \vf_t^{\text{target}}\!\left(\psi_t^{\text{target}}(x_0|z)|z\right) \\[6pt] &\overset{(i)}{\Longleftrightarrow}\ \dot\alpha_t z + \dot\beta_t x_0 = \vf_t^{\text{target}}\!\left(\alpha_t z + \beta_t x_0 \,\middle|\, z\right) &&\text{对所有 } x_0, z \in \R^d \\[6pt] &\overset{(ii)}{\Longleftrightarrow}\ \dot\alpha_t z + \dot\beta_t\left(\frac{x - \alpha_t z}{\beta_t}\right) = \vf_t^{\text{target}}(x|z) &&\text{对所有 } x, z \in \R^d \\[6pt] &\overset{(iii)}{\Longleftrightarrow}\ \left(\dot\alpha_t - \frac{\dot\beta_t}{\beta_t}\alpha_t\right) z + \frac{\dot\beta_t}{\beta_t}\, x = \vf_t^{\text{target}}(x|z) &&\text{对所有 } x, z \in \R^d \end{aligned} $$逐条解释:
- (i) 把 $\psi_t^{\text{target}}(x_0|z) = \alpha_t z + \beta_t x_0$ 代进去。左边对 $t$ 求导时 $x_0, z$ 都是常数,所以只有 $\alpha_t,\beta_t$ 被求导,得 $\dot\alpha_t z + \dot\beta_t x_0$,其中 $\dot\alpha_t := \partial_t \alpha_t$,$\dot\beta_t := \partial_t \beta_t$。
- (ii) 换元。这是全场唯一的技巧点:等式对所有 $x_0$ 成立,所以我们可以把自变量从 $x_0$ 换成 $x := \alpha_t z + \beta_t x_0$。反解得 $x_0 = \dfrac{x - \alpha_t z}{\beta_t}$,代回左边即可。这一步要求 $\beta_t \neq 0$,即 $t \lt 1$;而且因为 $x_0 \mapsto x$ 是双射($\beta_t \ne 0$ 时),「对所有 $x_0$」和「对所有 $x$」是等价的。
- (iii) 纯代数:把左边按 $z$ 和 $x$ 归并,$\dot\alpha_t z - \frac{\dot\beta_t \alpha_t}{\beta_t}z + \frac{\dot\beta_t}{\beta_t}x$。
于是得到高斯条件向量场:
$$ \vf_t^{\text{target}}(x|z) = \left(\dot\alpha_t - \frac{\dot\beta_t}{\beta_t}\alpha_t\right) z + \frac{\dot\beta_t}{\beta_t}\, x . \qquad \square $$5.2 合理性检查
推完公式一定要做几个廉价的检查,这是抓错最有效的手段。
- 维度。 $\left(\dot\alpha_t - \frac{\dot\beta_t}{\beta_t}\alpha_t\right)$ 与 $\frac{\dot\beta_t}{\beta_t}$ 都是标量,$z, x \in \R^d$,所以 $\vf_t^{\text{target}}(\cdot|z) : \R^d \to \R^d$ ✓。它对 $x$ 是仿射的(一个标量乘 $x$ 加一个常向量),这也是它如此好算的原因。
- 分布中心的速度。 把分布的中心 $x = \alpha_t z$ 代进去: $$ \vf_t^{\text{target}}(\alpha_t z|z) = \left(\dot\alpha_t - \frac{\dot\beta_t \alpha_t}{\beta_t}\right)z + \frac{\dot\beta_t}{\beta_t}\alpha_t z = \dot\alpha_t z . $$ 而条件分布的均值是 $\alpha_t z$,其时间导数正是 $\dot\alpha_t z$。中心点的速度与中心的移动速度一致 ✓。
- 坐标形式。 令 $r := x - \alpha_t z$(相对于中心的偏移),则 $$ \vf_t^{\text{target}}(x|z) = \dot\alpha_t z + \frac{\dot\beta_t}{\beta_t}\, r . $$ (验证:$\left(\dot\alpha_t - \frac{\dot\beta_t\alpha_t}{\beta_t}\right)z + \frac{\dot\beta_t}{\beta_t}(r + \alpha_t z) = \dot\alpha_t z + \frac{\dot\beta_t}{\beta_t}r$ ✓。) 读法非常干净:「跟着中心平移」+「以相对速率 $\dot\beta_t/\beta_t$ 向中心收缩」。因为 $\beta_t$ 递减,$\dot\beta_t \lt 0$,所以第二项确实是指向中心的收缩。这个形式在 §6.3 验算连续性方程时会直接用到。
5.3 沿路径代入:目标就是插值曲线的速度
训练时我们不会在任意 $x$ 处求值,而只在路径上的点 $x = \alpha_t z + \beta_t \epsilon$ 处求值。代进去看看会发生什么:
(i) 是代入闭式解;(ii) 展开;(iii) 中间两项精确抵消,同时分母上的 $\beta_t$ 也被约掉了。
这个结果值得裱起来。记 $x_t := \alpha_t z + \beta_t \epsilon$ 是固定 $(z,\epsilon)$ 时的插值曲线,则
$$ \frac{\dd{}}{\dd{t}} x_t = \dot\alpha_t z + \dot\beta_t \epsilon = \vf_t^{\text{target}}(x_t|z). $$条件向量场在路径点上的取值,就是插值曲线自身的速度。 训练目标因此有一个完全初等的解释:随机取一个数据点 $z$ 和一个噪声 $\epsilon$,把它们连成一条曲线 $x_t = \alpha_t z + \beta_t \epsilon$,然后让网络在曲线上的每个点预测这条曲线的切向速度 $\dot\alpha_t z + \dot\beta_t\epsilon$。
两个重要的副产品:(a) 分母上的 $\beta_t$ 消失了,所以 $t\to1$ 时没有数值奇异性;(b) 训练时根本不需要显式写出 $\vf_t^{\text{target}}(x|z)$ 的公式,只需要 $\dot\alpha_t z + \dot\beta_t\epsilon$。
5.4 CondOT 特例
取 $\alpha_t = t$、$\beta_t = 1-t$,于是 $\dot\alpha_t = 1$、$\dot\beta_t = -1$。代入闭式解:
$$ \begin{aligned} \vf_t^{\text{target}}(x|z) &= \left(1 - \frac{-1}{1-t}\cdot t\right) z + \frac{-1}{1-t}\, x \\[6pt] &= \left(1 + \frac{t}{1-t}\right) z - \frac{x}{1-t} \\[6pt] &= \frac{(1-t) + t}{1-t}\, z - \frac{x}{1-t} \\[6pt] &= \frac{z - x}{1-t}. \end{aligned} $$形式漂亮得不像话:从当前位置 $x$ 指向目标 $z$ 的方向,除以剩余时间 $1-t$。这正是「在剩余 $1-t$ 的时间里匀速走完剩下的 $z-x$ 这段路」所需的速度——CondOT 之所以叫「直线调度」,原因就在这里。
再用 §5.3 的结论核对一遍:路径点是 $x = tz + (1-t)\epsilon$,则
$$ \frac{z-x}{1-t} = \frac{z - tz - (1-t)\epsilon}{1-t} = \frac{(1-t)z - (1-t)\epsilon}{1-t} = z - \epsilon, $$而 §5.3 的通式给出 $\dot\alpha_t z + \dot\beta_t \epsilon = 1\cdot z + (-1)\cdot\epsilon = z - \epsilon$ ✓。两条路殊途同归。
看到 $\frac{z-x}{1-t}$ 分母上的 $1-t$ 就担心 $t\to1$ 时爆炸——这个担心在训练时是多余的:训练只在路径点上求值,而上面刚算过那里的值恒等于 $z-\epsilon$,完全有界。
但在采样时要小心:模拟 ODE 时网络会被喂进偏离真实路径的点 $x$,此时 $\frac{z-x}{1-t}$ 型的量确实会被 $\frac{1}{1-t}$ 放大,$t$ 接近 $1$ 处的误差被显著放大。实践中常见的处理是在末端用更小的步长,或在 $t=1-\varepsilon$ 处停下。另外,若代码里显式使用 $\dot\beta_t/\beta_t$ 这个系数(例如为了做闭式解验证),$t=1$ 处必须 clamp。
6. 连续性方程:从「分布怎么变」到「粒子怎么动」
要证明定理 1,需要一件工具:一个把「概率路径」和「向量场」严格挂钩的等价条件。这就是连续性方程(continuity equation)。
6.1 散度
先定义散度(divergence)算子。对向量场 $v_t : \R^d \to \R^d$,
$$ \divg(v_t)(x) = \sum_{i=1}^{d} \frac{\partial}{\partial x_i} v_t^i(x), $$其中 $v_t^i$ 是 $v_t$ 的第 $i$ 个分量。注意 $\divg(v_t)(x) \in \R$ 是标量(把向量场「压」成一个数)。物理含义:$\divg v_t(x) \gt 0$ 表示 $x$ 处是「源」(流出多于流入),$\lt 0$ 表示是「汇」。
6.2 定理与直觉
考虑 flow model:$X_0 \sim \simple = p_0$,$\frac{\dd{}}{\dd{t}}X_t = \vf_t^{\text{target}}(X_t)$。则
$$ X_t \sim p_t \ \ (0 \le t \le 1) \qquad \Longleftrightarrow \qquad \partial_t p_t(x) = -\divg\!\left(p_t \vf_t^{\text{target}}\right)(x) \quad \forall x \in \R^d,\ t\in[0,1]. $$注意这是一个充要条件,而且前提里已经包含了初始条件 $X_0 \sim p_0$。这一点在用它证明定理 1 时至关重要:验证了 PDE,再加上初值对上,就足以断定整条轨迹的边际分布是 $p_t$。
把 $p_t(x)$ 想成流体在 $x$ 处的密度,$\vf_t(x)$ 是流速,那么 $p_t\vf_t$ 就是质量流量(单位时间穿过单位面积的质量)。散度 $\divg(p_t\vf_t)(x)$ 度量 $x$ 处的净流出,加负号就是净流入。方程说:
「$x$ 处密度的变化率」=「$x$ 处的净流入」
这就是质量守恒——概率质量既不能凭空产生也不能消失(总积分永远是 1),它只能被向量场搬来搬去。反过来说,连续性方程是「$\int p_t = 1$ 对所有 $t$ 成立」的局部化(逐点)版本。
6.3 验算:高斯路径确实满足连续性方程
讲义在这里留了一个脚注:「One can also double check this by plugging it into the continuity equation」。我们把它做出来——这既是对 §5 结果的独立验证,也是熟悉连续性方程的最好练习。
记 $p := p_t(x|z)$,$\vf := \vf_t^{\text{target}}(x|z)$,$r := x - \alpha_t z \in \R^d$。由 §5.2 的坐标形式,
$$ \vf = \dot\alpha_t z + \frac{\dot\beta_t}{\beta_t}\, r . $$因为 $p \gt 0$,把连续性方程 $\partial_t p = -\divg(p\,\vf)$ 两边同除以 $p$,并用乘积法则 $\divg(p\vf) = \inner{\nabla p}{\vf} + p\,\divg(\vf)$,得到一个等价的、更好算的形式:
$$ \partial_t \log p \;=\; -\inner{\nabla_x \log p}{\vf} \;-\; \divg(\vf). \qquad (\ast) $$左边。 由高斯密度取对数,
$$ \log p = -\frac{d}{2}\log\!\left(2\pi\beta_t^2\right) - \frac{\norm{r}^2}{2\beta_t^2}. $$对 $t$ 求导(注意 $x$ 固定,$r$ 通过 $\alpha_t$ 依赖 $t$,且 $\partial_t \norm{r}^2 = 2\inner{r}{\partial_t r} = 2\inner{r}{-\dot\alpha_t z} = -2\dot\alpha_t\inner{r}{z}$):
$$ \begin{aligned} \partial_t \log p &= -\frac{d}{2}\cdot\frac{2\beta_t\dot\beta_t}{\beta_t^2} \;-\; \partial_t\!\left(\frac{\norm{r}^2}{2\beta_t^2}\right) \\[6pt] &\overset{(i)}{=} -\,d\,\frac{\dot\beta_t}{\beta_t} \;-\; \left[\frac{-2\dot\alpha_t\inner{r}{z}}{2\beta_t^2} \;+\; \norm{r}^2\cdot\left(-\frac{\dot\beta_t}{\beta_t^3}\right)\right] \\[6pt] &= -\,d\,\frac{\dot\beta_t}{\beta_t} \;+\; \frac{\dot\alpha_t\inner{r}{z}}{\beta_t^2} \;+\; \frac{\dot\beta_t\norm{r}^2}{\beta_t^3}. \end{aligned} $$(i) 用了商的求导:$\partial_t\left(\frac{1}{2\beta_t^2}\right) = -\frac{\dot\beta_t}{\beta_t^3}$。
右边。 先算两个零件。
$$ \nabla_x \log p = \nabla_x\!\left(-\frac{\norm{x-\alpha_t z}^2}{2\beta_t^2}\right) = -\frac{r}{\beta_t^2}, $$ $$ \divg(\vf) = \divg\!\left(\dot\alpha_t z + \frac{\dot\beta_t}{\beta_t}(x - \alpha_t z)\right) = \frac{\dot\beta_t}{\beta_t}\,\divg(x) = d\,\frac{\dot\beta_t}{\beta_t}, $$后者因为常向量的散度为零,而 $\divg(x) = \sum_{i=1}^d \partial x_i/\partial x_i = d$。于是
$$ \begin{aligned} -\inner{\nabla_x\log p}{\vf} - \divg(\vf) &= \frac{1}{\beta_t^2}\inner{r}{\ \dot\alpha_t z + \frac{\dot\beta_t}{\beta_t}r\ } \;-\; d\,\frac{\dot\beta_t}{\beta_t} \\[6pt] &= \frac{\dot\alpha_t \inner{r}{z}}{\beta_t^2} \;+\; \frac{\dot\beta_t\norm{r}^2}{\beta_t^3} \;-\; d\,\frac{\dot\beta_t}{\beta_t}. \end{aligned} $$与左边逐项相同,$(\ast)$ 成立。$\square$
三项的物理意义各自清晰:$-d\,\dot\beta_t/\beta_t$ 来自分布整体的收缩(体积项),$\dot\alpha_t\inner{r}{z}/\beta_t^2$ 来自中心的平移,$\dot\beta_t\norm{r}^2/\beta_t^3$ 来自尺度变化对形状的影响。这次验算完全独立于 §5 的推导路线(那里用的是 flow,这里用的是 PDE),两者一致大大提高了对结果的信心。
7. 边际化技巧的完整证明
7.1 证明策略
要证的是定理 1:由
$$ \vf_t^{\text{target}}(x) = \int \vf_t^{\text{target}}(x|z)\,\frac{p_t(x|z)\data(z)}{p_t(x)}\dd{z} $$定义的边际向量场,其 ODE 轨迹满足 $X_t \sim p_t$。
直接从「轨迹的分布」下手是没法做的——那要求解一个非线性 ODE 再算像测度。连续性方程把这件事变成了纯粹的微积分:由定理 2(充要条件),只要验证 $\partial_t p_t = -\divg(p_t \vf_t^{\text{target}})$,再配上初值 $X_0 \sim \simple = p_0$(这是 ODE 的初始条件,本来就成立),结论就跟着来了。
我们手上有什么?只有一条信息:每个条件向量场都生成对应的条件路径,也就是(再次由定理 2,这次用在条件对象上)
$$ \partial_t\, p_t(x|z) = -\divg\!\left(p_t(\cdot|z)\,\vf_t^{\text{target}}(\cdot|z)\right)(x) \qquad \text{对每个固定的 } z. \tag{C} $$所以整个证明就是:把 $\partial_t p_t$ 展开成对 $z$ 的积分,对每个 $z$ 用 (C),再把散度提到积分号外,最后凑回定义式。
7.2 证明
链条的起点是 $\partial_t p_t(x)$,终点是 $-\divg(p_t\vf_t^{\text{target}})(x)$,这正是连续性方程。再由定理 2 的「$\Leftarrow$」方向(PDE 成立 $\Rightarrow$ 轨迹分布正确),并注意 ODE 的初值就是 $X_0\sim\simple = p_0$,即得 $X_t \sim p_t$ 对所有 $t\in[0,1]$。取 $t=1$ 得 $X_1 \sim p_1 = \data$。$\square$
7.3 每一步用了什么
| 步骤 | 依据 | 细节 |
|---|---|---|
| (i) | 边际概率路径的定义 | $p_t(x) = \int p_t(x|z)\data(z)\dd{z}$,即 §2.2 的密度公式。 |
| (ii) | 积分号下求导 | 把 $\partial_t$ 挪到积分号内。这需要正则性条件(见下方「注意」),讲义与本课默认所有对象足够光滑、可交换。 |
| (iii) | 条件路径的连续性方程 (C) | 对每个固定的 $z$,条件向量场按定义生成条件路径,故由定理 2 该 PDE 成立。这是唯一用到假设的地方。 |
| (iv) | 散度与积分交换 | $\divg$ 是关于 $x$ 的线性微分算子($\divg(v)(x)=\sum_i \partial_{x_i} v^i(x)$),而积分是关于 $z$ 的。交换 $\partial_{x_i}$ 与 $\int\cdot\dd{z}$ 同样是积分号下求导。 |
| (v) | 乘一个 $1 = \dfrac{p_t}{p_t}$ | 在被积函数上同时乘除 $p_t(\cdot)$,并把与 $z$ 无关的 $p_t(\cdot)$ 提到积分号外。要求 $p_t(x) \gt 0$。 |
| (vi) | 边际向量场的定义 | 括号里的积分正是 $\vf_t^{\text{target}}$ 的定义式。 |
(ii) 与 (iv) 都是「把微分算子挪进积分号」。严格化的标准工具是 Leibniz 积分法则 / 控制收敛定理:只要被积函数关于 $t$(或 $x_i$)逐点可微,且其偏导数被某个与 $t$(或 $x$)无关的可积函数一致控制,交换就合法。对高斯路径这类指数衰减的光滑密度,这些条件在 $t \lt 1$ 上是满足的。
$t \to 1$ 时 $p_t(\cdot|z) \to \delt{z}$ 不再是函数,(v) 里的 $p_t(x) \gt 0$ 也可能失效。标准处理是先在 $[0, 1-\varepsilon]$ 上证明,再取极限。这些分析细节不影响算法,本课按讲义惯例略去。
关键在 (iv):散度是线性算子。 每个条件路径都自带一个「质量守恒账本」$\partial_t p_t(\cdot|z) = -\divg(p_t(\cdot|z)\vf_t^{\text{target}}(\cdot|z))$。把这些账本按 $\data(z)$ 加权求和,左边自动合成 $\partial_t p_t$,右边合成 $-\divg\left(\int p_t(\cdot|z)\vf^{\text{target}}_t(\cdot|z)\data(z)\dd{z}\right)$。
于是可加的量是「质量流量」$p_t \vf_t$,而不是速度 $\vf_t$ 本身。要从相加后的流量里解出速度,就必须除以相加后的密度 $p_t$——而 $\frac{p_t(x|z)\data(z)}{p_t(x)}$ 恰好就是这个除法的结果,它同时也正好是后验概率。「按后验加权」不是一个巧妙的猜测,而是「流量可加、速度不可加」这一事实的必然产物。
7.4 独立验算:高斯数据分布
定理 1 的公式含有一个不可算的积分,看上去无法检验。但在 §3.4 的高斯数据例子里,我们可以把积分真的算出来,再和另一条完全独立的推导对照。这是对定理 1 的一次实打实的检验。
路线 A(用定理 1 的积分)。 由 §4.4,边际向量场是条件期望。而由 §5.1,$\vf_t^{\text{target}}(x|z)$ 对 $z$ 是仿射的:
$$ \vf_t^{\text{target}}(x|z) = A_t z + B_t x, \qquad A_t := \dot\alpha_t - \frac{\dot\beta_t}{\beta_t}\alpha_t,\quad B_t := \frac{\dot\beta_t}{\beta_t}. $$期望对仿射函数可以直接穿进去,于是
$$ \vf_t^{\text{target}}(x) = \E\!\left[A_t Z + B_t x \,\middle|\, X_t = x\right] = A_t\,\hat z(x) + B_t x, \qquad \hat z(x) := \E[Z \mid X_t = x]. $$算后验均值 $\hat z(x)$。 后验 $\propto$ 似然 × 先验:
$$ p(z|x) \propto \exp\!\left(-\frac{\norm{x-\alpha_t z}^2}{2\beta_t^2}\right)\exp\!\left(-\frac{\norm{z-\mu}^2}{2\sigma^2}\right). $$指数上关于 $z$ 配方,二次项系数(精度)为 $\frac{\alpha_t^2}{\beta_t^2} + \frac{1}{\sigma^2}$,一次项系数为 $\frac{\alpha_t x}{\beta_t^2} + \frac{\mu}{\sigma^2}$,故这是一个高斯,均值为
$$ \hat z(x) = \frac{\dfrac{\alpha_t x}{\beta_t^2} + \dfrac{\mu}{\sigma^2}}{\dfrac{\alpha_t^2}{\beta_t^2} + \dfrac{1}{\sigma^2}} = \frac{\alpha_t \sigma^2 x + \beta_t^2 \mu}{\alpha_t^2\sigma^2 + \beta_t^2} = \frac{\alpha_t\sigma^2 x + \beta_t^2\mu}{\gamma_t^2}, $$末式用了 §3.4 的记号 $\gamma_t^2 = \alpha_t^2\sigma^2+\beta_t^2$(分子分母同乘 $\beta_t^2\sigma^2$ 即得中间那步)。因此
$$ \vf_t^{\text{target}}(x) = \left(\frac{A_t \alpha_t \sigma^2}{\gamma_t^2} + B_t\right) x \;+\; \frac{A_t\beta_t^2}{\gamma_t^2}\,\mu . \tag{A} $$路线 B(把 $p_t$ 当成一条新的高斯路径)。 §3.4 已证 $p_t = \N(\alpha_t\mu,\ \gamma_t^2 I_d)$。这与高斯条件路径同形,只是把 $(z,\beta_t)$ 换成了 $(\mu,\gamma_t)$。于是 §5 的闭式解可以原样套用:
$$ \vf_t^{\text{target}}(x) = \left(\dot\alpha_t - \frac{\dot\gamma_t}{\gamma_t}\alpha_t\right)\mu + \frac{\dot\gamma_t}{\gamma_t}\,x . \tag{B} $$核对 (A) = (B)。 先记一个恒等式:对 $\gamma_t^2 = \alpha_t^2\sigma^2+\beta_t^2$ 两边求导得 $2\gamma_t\dot\gamma_t = 2\alpha_t\dot\alpha_t\sigma^2 + 2\beta_t\dot\beta_t$,即
$$ \gamma_t\dot\gamma_t = \alpha_t\dot\alpha_t\sigma^2 + \beta_t\dot\beta_t. \tag{S} $$$x$ 的系数:
$$ \begin{aligned} A_t\alpha_t\sigma^2 + B_t\gamma_t^2 &= \left(\dot\alpha_t - \frac{\dot\beta_t}{\beta_t}\alpha_t\right)\alpha_t\sigma^2 + \frac{\dot\beta_t}{\beta_t}\left(\alpha_t^2\sigma^2+\beta_t^2\right) \\[4pt] &= \dot\alpha_t\alpha_t\sigma^2 - \frac{\dot\beta_t\alpha_t^2\sigma^2}{\beta_t} + \frac{\dot\beta_t\alpha_t^2\sigma^2}{\beta_t} + \dot\beta_t\beta_t \\[4pt] &= \alpha_t\dot\alpha_t\sigma^2 + \beta_t\dot\beta_t \;\overset{(S)}{=}\; \gamma_t\dot\gamma_t . \end{aligned} $$所以 (A) 中 $x$ 的系数 $= \dfrac{\gamma_t\dot\gamma_t}{\gamma_t^2} = \dfrac{\dot\gamma_t}{\gamma_t}$,与 (B) 一致 ✓。
$\mu$ 的系数:(A) 给出 $\dfrac{A_t\beta_t^2}{\gamma_t^2} = \dfrac{\dot\alpha_t\beta_t^2 - \dot\beta_t\alpha_t\beta_t}{\gamma_t^2}$。而 (B) 给出
$$ \dot\alpha_t - \frac{\dot\gamma_t}{\gamma_t}\alpha_t \overset{(S)}{=} \dot\alpha_t - \frac{\alpha_t\dot\alpha_t\sigma^2+\beta_t\dot\beta_t}{\gamma_t^2}\alpha_t = \frac{\dot\alpha_t\left(\alpha_t^2\sigma^2+\beta_t^2\right) - \alpha_t^2\dot\alpha_t\sigma^2 - \alpha_t\beta_t\dot\beta_t}{\gamma_t^2} = \frac{\dot\alpha_t\beta_t^2 - \alpha_t\beta_t\dot\beta_t}{\gamma_t^2}, $$两者完全相同 ✓。$\square$
两条路线一条走的是「后验加权平均」(定理 1 的定义式),另一条走的是「把边际路径本身当成高斯路径直接套公式」,中间没有任何共享的中间结果,却给出同一个答案。这就是对边际化技巧的一次硬检验。
「为什么用条件版本能得到边际版本?」在向量场这一层的答案是:条件路径各自满足的连续性方程,按 $\data(z)$ 加权后线性叠加,正好拼成边际路径的连续性方程;由于叠加发生在流量 $p_t\vf_t$ 上而非速度上,还原速度时必须除以 $p_t$,这就自动生成了后验权重。
但这只解决了「目标是什么」。真正的困难还在后面:这个目标含有不可算的积分,没法当回归标签用。下一节解决它。
8. 两个损失函数:可算的与不可算的
8.1 边际 Flow Matching 损失
现在我们知道了训练目标:让神经网络等于边际向量场,$\vf_t^\theta \approx \vf_t^{\text{target}}$。最自然的做法是均方误差回归。
利用 §2.2 的采样表述 $\left(z\sim\data,\ x\sim p_t(\cdot|z) \Rightarrow x\sim p_t\right)$,可以等价地写成
$$ \mathcal{L}_{\text{FM}}(\theta) = \E_{t\sim\text{Unif}[0,1],\ z\sim\data,\ x\sim p_t(\cdot|z)}\left[\norm{\vf_t^\theta(x) - \vf_t^{\text{target}}(x)}^2\right]. $$读法:随机抽一个时间 $t$;随机抽一个数据点 $z$ 并给它加噪得到 $x$(这就是从 $p_t$ 采样);比较网络输出与真值向量场;取平方误差的期望。若 $\mathcal{L}_{\text{FM}}(\theta) = 0$,则 $\vf_t^\theta = \vf_t^{\text{target}}$(在 $p_t$ 的支撑上几乎处处成立),由定理 1 模拟 ODE 就能得到 $X_1\sim\data$。逻辑完全闭合。
损失里出现了 $\vf_t^{\text{target}}(x)$——那个含有 $\int\cdots\dd{z}$ 且分母是 $p_t(x)$ 的家伙。要算一个样本的损失,就得遍历整个数据分布做积分。$\mathcal{L}_{\text{FM}}$ 在数学上定义良好,在计算上完全不可用:连一次前向都跑不了,更别说反向传播。
8.2 条件 Flow Matching 损失
解决方案出人意料地朴素:既然 $\vf_t^{\text{target}}(x)$ 算不出来,而 $\vf_t^{\text{target}}(x|z)$ 有闭式解,那就直接回归后者。反正采样 $x$ 的时候我们本来就抽了一个 $z$,它就在手边。
与 $\mathcal{L}_{\text{FM}}$ 的唯一差别:回归目标从 $\vf_t^{\text{target}}(x)$ 换成了 $\vf_t^{\text{target}}(x|z)$,多了一根竖线。
这个损失每一项都可算:$t$ 是 $\text{Unif}[0,1]$ 采样,$z$ 从数据集里取,$x = \alpha_t z + \beta_t\epsilon$ 一行代码,目标 $\vf_t^{\text{target}}(x|z) = \dot\alpha_t z + \dot\beta_t\epsilon$(§5.3)也是一行代码。这是一个彻头彻尾的普通监督回归。
网络 $\vf_t^\theta(x)$ 的输入只有 $x$ 和 $t$,看不到 $z$;而标签 $\vf_t^{\text{target}}(x|z)$ 依赖 $z$。同一个 $x$ 在不同的 batch 里可能配上完全不同的 $z$,因而给出完全不同(甚至方向相反)的标签。这看起来像是在用互相矛盾的标签训练——损失怎么可能收敛到有意义的东西?
下一节的定理给出精确回答,而答案的种子已经埋在 §4.4:最小二乘回归在标签有噪声时,最优解不是任何单个标签,而是标签的条件期望;而边际向量场恰恰就是条件向量场的条件期望。矛盾的标签会自动被平均掉,平均出来的正是我们真正想要的东西。
8.3 两者的对照
| $\mathcal{L}_{\text{FM}}$(边际) | $\mathcal{L}_{\text{CFM}}$(条件) | |
|---|---|---|
| 回归目标 | $\vf_t^{\text{target}}(x)$ | $\vf_t^{\text{target}}(x|z)$ |
| 目标的表达式 | $\int \vf_t^{\text{target}}(x|z)\frac{p_t(x|z)\data(z)}{p_t(x)}\dd{z}$ | $\left(\dot\alpha_t-\frac{\dot\beta_t}{\beta_t}\alpha_t\right)z+\frac{\dot\beta_t}{\beta_t}x$ |
| 可算性 | 不可算(含 $d$ 维积分与未知的 $\data$) | 闭式,$O(d)$ 计算 |
| 标签是否唯一 | 是($x,t$ 确定则标签确定) | 否(同一 $x$ 因 $z$ 不同而标签不同) |
| 最小值 | $0$(表达力无限时) | 严格大于 $0$,等于常数 $-C$ |
| 最优参数 $\theta^*$ | 相同 | 相同 |
| 梯度 $\nabla_\theta$ | 相同 | 相同 |
9. 核心定理:两个损失只差一个常数
边际 flow matching 损失与条件 flow matching 损失只相差一个与 $\theta$ 无关的常数:
$$ \mathcal{L}_{\text{FM}}(\theta) = \mathcal{L}_{\text{CFM}}(\theta) + C, \qquad \frac{\partial C}{\partial \theta} = 0 . $$因此二者的梯度完全相同:
$$ \nabla_\theta \mathcal{L}_{\text{FM}}(\theta) = \nabla_\theta \mathcal{L}_{\text{CFM}}(\theta). $$于是用 SGD 最小化 $\mathcal{L}_{\text{CFM}}$ 与最小化 $\mathcal{L}_{\text{FM}}$ 是同一件事。特别地,对 $\mathcal{L}_{\text{CFM}}$ 的最小值点 $\theta^*$,在表达力无限的假设下有 $\vf_t^{\theta^*} = \vf_t^{\text{target}}$,即神经网络等于边际向量场。
下面给两个证明。证明一是讲义的直接展开法,机械但完全自足;证明二用条件期望的塔性质,短得多,而且解释了「为什么」。两个都值得看。
9.1 证明一:直接展开
记号约定:下文所有期望里 $t\sim\text{Unif}[0,1]$,$z\sim\data$,$x\sim p_t(\cdot|z)$(等价地 $x\sim p_t$)。「常数」一律指与 $\theta$ 无关的量。
用 $\norm{a-b}^2 = \norm{a}^2 - 2a^\top b + \norm{b}^2$:
$$ \begin{aligned} \mathcal{L}_{\text{FM}}(\theta) &\overset{(i)}{=} \E_{t,\ x\sim p_t}\left[\norm{\vf_t^\theta(x) - \vf_t^{\text{target}}(x)}^2\right] \\[6pt] &\overset{(ii)}{=} \E_{t,\ x\sim p_t}\left[\norm{\vf_t^\theta(x)}^2 - 2\,\vf_t^\theta(x)^\top \vf_t^{\text{target}}(x) + \norm{\vf_t^{\text{target}}(x)}^2\right] \\[6pt] &\overset{(iii)}{=} \E_{t,\ x\sim p_t}\left[\norm{\vf_t^\theta(x)}^2\right] - 2\,\E_{t,\ x\sim p_t}\left[\vf_t^\theta(x)^\top \vf_t^{\text{target}}(x)\right] + \underbrace{\E_{t,\ x\sim p_t}\left[\norm{\vf_t^{\text{target}}(x)}^2\right]}_{=:\ C_1} \\[6pt] &\overset{(iv)}{=} \E_{t,\ z,\ x\sim p_t(\cdot|z)}\left[\norm{\vf_t^\theta(x)}^2\right] - 2\,\E_{t,\ x\sim p_t}\left[\vf_t^\theta(x)^\top \vf_t^{\text{target}}(x)\right] + C_1 . \end{aligned} $$(i) 是定义;(ii) 展开平方;(iii) 期望的线性性,并把最后一项记作 $C_1$——它完全不含 $\theta$,是个常数(虽然我们算不出它的值,但这不重要);(iv) 只是把第一项的采样方式改写成「先抽 $z$ 再抽 $x$」,这依据 §2.2 的采样表述,两者是同一个分布。
现在,第一项已经可算,第三项是常数。唯一的障碍是中间那个交叉项,它还含着不可算的 $\vf_t^{\text{target}}(x)$。
(i) 把期望写成积分($t\sim\text{Unif}[0,1]$ 的密度恒为 $1$,故只是 $\int_0^1\cdots\dd{t}$);(ii) 代入边际化技巧(定理 1)——这是整个证明中唯一用到定理 1 的地方,也是全部魔法发生之处;(iii) 把 $\vf_t^\theta(x)^\top$ 移进内层积分(它不依赖 $z$),并注意到 $p_t(x)$ 与分母的 $p_t(x)$ 精确抵消,然后交换积分次序;(iv) 认出 $p_t(x|z)\data(z)\dd{z}\dd{x}$ 正是「$z\sim\data$、$x\sim p_t(\cdot|z)$」这个联合分布,于是重新写回期望。
请注意这一步做了什么:等式左端含有边际向量场 $\vf_t^{\text{target}}(x)$(不可算),右端含有条件向量场 $\vf_t^{\text{target}}(x|z)$(可算)。那个碍事的 $p_t(x)$ 之所以能被消掉,正是因为定理 1 的分母里也有一个 $p_t(x)$,而外层的期望测度恰好提供了一个 $p_t(x)$ 与之相消。这个约分就是 flow matching 全部可行性的技术支点。
(i) 是把第 2 步的结果代回第 1 步;(ii) 加一项再减同一项($\pm\norm{\vf_t^{\text{target}}(x|z)}^2$),被减掉的那份记作 $C_2$,它同样不含 $\theta$;(iii) 把三项重新收拢成完全平方;(iv) 认出它就是 $\mathcal{L}_{\text{CFM}}$ 的定义,并令 $C := C_1 + C_2$。由于 $C_1, C_2$ 都与 $\theta$ 无关,$C$ 也与 $\theta$ 无关。$\square$
9.2 证明二:条件期望视角
直接展开法虽然完备,却像变戏法——加加减减之后答案就出来了,但没解释「为什么」。下面这个证明短得多,并且揭示了本质。
设 $X, Y$ 是任意随机变量($Y$ 取值于 $\R^d$,$\E\norm{Y}^2 \lt \infty$),$g$ 是任意可测函数。则
$$ \E\norm{Y - g(X)}^2 = \underbrace{\E\norm{Y - \E[Y|X]}^2}_{\text{与 } g \text{ 无关}} + \E\norm{\E[Y|X] - g(X)}^2 . $$证明。 记 $M := \E[Y|X]$。作分解 $Y - g(X) = (Y - M) + (M - g(X))$ 并展开:
$$ \E\norm{Y-g(X)}^2 = \E\norm{Y-M}^2 + 2\,\E\!\left[\inner{Y-M}{M-g(X)}\right] + \E\norm{M-g(X)}^2 . $$只需证交叉项为零。用塔性质(全期望公式)先对 $X$ 取条件:
$$ \begin{aligned} \E\!\left[\inner{Y-M}{M-g(X)}\right] &\overset{(a)}{=} \E\Big[\ \E\!\left[\inner{Y-M}{M-g(X)}\ \middle|\ X\right]\Big] \\[4pt] &\overset{(b)}{=} \E\Big[\ \inner{\E[Y-M \mid X]}{M-g(X)}\Big] \\[4pt] &\overset{(c)}{=} \E\Big[\ \inner{0}{M-g(X)}\Big] = 0 . \end{aligned} $$(a) 是塔性质;(b) 因为 $M = \E[Y|X]$ 与 $g(X)$ 都是 $X$ 的函数,在条件于 $X$ 时可以当常数提出内积;(c) 因为 $\E[Y - \E[Y|X]\mid X] = \E[Y|X] - \E[Y|X] = 0$。$\square$
取
$$ X := (t, X_t), \qquad Y := \vf_t^{\text{target}}(X_t \mid Z), \qquad g(X) := \vf_t^\theta(X_t), $$其中随机性来自 $t\sim\text{Unif}[0,1]$、$Z\sim\data$、$X_t\sim p_t(\cdot|Z)$。注意 $g$ 只看得见 $(t,X_t)$、看不见 $Z$——这正是 §8.2 中那个「可疑」之处,现在它变成了引理里对 $g$ 的形式要求,恰好吻合。
关键观察:由 §4.4(边际化技巧的条件期望形式),
$$ \E[Y \mid X] = \E\!\left[\vf_t^{\text{target}}(X_t|Z)\ \middle|\ t,\ X_t = x\right] = \vf_t^{\text{target}}(x). $$也就是说,「条件向量场关于 $(t,x)$ 的条件期望」正好就是「边际向量场」。把这个代入引理:
$$ \underbrace{\E\norm{\vf_t^{\text{target}}(X_t|Z) - \vf_t^\theta(X_t)}^2}_{=\ \mathcal{L}_{\text{CFM}}(\theta)} = \underbrace{\E\norm{\vf_t^{\text{target}}(X_t|Z) - \vf_t^{\text{target}}(X_t)}^2}_{=:\ -C,\ \text{与}\ \theta\ \text{无关}} + \underbrace{\E\norm{\vf_t^{\text{target}}(X_t) - \vf_t^\theta(X_t)}^2}_{=\ \mathcal{L}_{\text{FM}}(\theta)} . $$移项即得 $\mathcal{L}_{\text{FM}}(\theta) = \mathcal{L}_{\text{CFM}}(\theta) + C$。$\square$
因为平方损失回归的最优解是条件期望,而边际向量场就是条件向量场的条件期望。
更具体地:网络 $\vf_t^\theta$ 的输入里没有 $z$,所以它不可能拟合出依赖 $z$ 的标签;面对同一个 $(t,x)$ 却收到各种不同的标签 $\vf_t^{\text{target}}(x|z)$,最小二乘会逼它输出这些标签的平均值——而平均是按「$x$ 来自 $z$ 的后验概率」加权的,因为这正是给定 $x$ 时 $z$ 的分布。这个加权平均就是定理 1 的积分式。
换句话说:边际化那个不可算的积分,并没有被我们算出来,而是被 SGD 隐式地、通过对 mini-batch 里随机出现的 $z$ 求平均而完成了。 我们把积分外包给了随机采样。
9.3 三条必须搞清楚的推论
(1) 「$\mathcal{L}_{\text{CFM}}$ 应该降到 0」——错。 由证明二,$\mathcal{L}_{\text{CFM}}(\theta) \ge -C = \E\norm{\vf_t^{\text{target}}(X_t|Z) - \vf_t^{\text{target}}(X_t)}^2 \gt 0$,这是标签相对于其条件期望的条件方差,是数据本身的固有噪声,与模型好坏无关。训练损失会停在这个正的地板上。想通过看损失值判断「模型学好了没有」是无效的——这个地板值取决于数据分布和调度,不同实验之间也不可比。
(2) 「网络学到的是 $\vf_t^{\text{target}}(x|z)$」——错。 网络学到的是它的条件期望 $\vf_t^{\text{target}}(x)$。前者根本不是 $(t,x)$ 的函数,网络想学也学不到。
(3) 「$C$ 需要算出来」——不需要。 优化只关心梯度,常数平移不影响 $\arg\min$ 与 $\nabla_\theta$。事实上 $C$ 和 $\mathcal{L}_{\text{FM}}$ 一样不可算——但我们从头到尾都不需要它。
这套论证的结构与 flow matching 本身无关,它对任何「目标 = 某个可算量的条件期望」的问题都成立。下一讲的 score matching($\score{t}(x) = \E[\score{t}(x|z)\mid X_t=x]$)、扩散模型里的 denoising 目标(预测 $\epsilon$ 或预测 $x_0$)、乃至 Tweedie 公式,全都是同一个引理的不同实例。把 §9.2 的引理吃透,后面几讲会省掉大量重复劳动。
10. 训练算法:CondOT 路径与最小实现
10.1 把损失落到高斯路径上
定理 3 说「优化 $\mathcal{L}_{\text{CFM}}$ 就行」。现在把高斯路径的具体公式代进去,看看训练目标最终长什么样。
从定义出发:
$$ \begin{aligned} \mathcal{L}_{\text{CFM}}(\theta) &\overset{(i)}{=} \E_{t\sim\text{Unif},\ z\sim\data,\ x\sim\N(\alpha_t z,\ \beta_t^2 I_d)}\left[\norm{\vf_t^\theta(x) - \left(\dot\alpha_t - \frac{\dot\beta_t}{\beta_t}\alpha_t\right)z - \frac{\dot\beta_t}{\beta_t}x}^2\right] \\[8pt] &\overset{(ii)}{=} \E_{t\sim\text{Unif},\ z\sim\data,\ \epsilon\sim\N(0,I_d)}\left[\norm{\vf_t^\theta\!\left(\alpha_t z + \beta_t\epsilon\right) - \left(\dot\alpha_t z + \dot\beta_t\epsilon\right)}^2\right]. \end{aligned} $$(i) 代入 §5.1 的条件向量场闭式解与高斯条件路径;(ii) 用重参数化 $x = \alpha_t z + \beta_t\epsilon$(§3.2)替换采样,同时把目标里的 $x$ 也一并替换——由 §5.3 的计算,那一串恰好化简成 $\dot\alpha_t z + \dot\beta_t \epsilon$。分母上的 $\beta_t$ 彻底消失了。
最终形式干净到令人怀疑:输入是噪声与数据的加权混合,标签是两个权重的导数做同样的混合。 没有 ODE 模拟、没有积分、没有除法。
10.2 CondOT:直线调度
取 $\alpha_t = t$、$\beta_t = 1-t$($\dot\alpha_t = 1$、$\dot\beta_t=-1$),得到本讲最著名的公式:
$$ \mathcal{L}_{\text{cfm}}(\theta) = \E_{t\sim\text{Unif}[0,1],\ z\sim\data,\ \epsilon\sim\N(0,I_d)}\left[\norm{\vf_t^\theta\!\left(t z + (1-t)\epsilon\right) - (z - \epsilon)}^2\right]. $$对应的条件概率路径写作 $p_t(x|z) = \N\!\left(tz,\ (1-t)^2 I_d\right)$,称为 CondOT 概率路径(conditional optimal transport path,也叫 rectified flow / 线性插值路径)。
两条插值线段在某点 $x$ 相交,意味着同一个输入 $(t,x)$ 会收到两个不同的标签 $z_1-\epsilon_1$ 和 $z_2-\epsilon_2$。网络输出唯一,只能取折中——这就是 §9 那个条件期望在具体图像上的样子。
值得强调:条件路径是直线,边际向量场的轨迹却不是。 图中右侧「ODE 轨迹」(§7.4 的插图下排)之所以呈弯曲的分叉状,就是因为真实轨迹走的是平均场,而非任何单条插值直线。「rectified flow」这个名字来源于一个后续想法:用训练好的模型重新配对 $(\epsilon, z)$ 再训练一遍,可以把边际轨迹逐步「拉直」,从而减少采样步数。
10.3 训练算法
输入:数据集($z\sim\data$ 的样本),神经网络 $\vf_t^\theta$。
- for 每个 mini-batch do
- 从数据集采样 $z$;
- 采样时间 $t\sim\text{Unif}[0,1]$;
- 采样噪声 $\epsilon\sim\N(0,I_d)$;
- 置 $x = tz + (1-t)\epsilon$ (一般情形:$x\sim p_t(\cdot|z)$,即 $x=\alpha_t z+\beta_t\epsilon$);
- 计算损失 $\mathcal{L}(\theta) = \norm{\vf_t^\theta(x) - (z-\epsilon)}^2$ (一般情形:$\norm{\vf_t^\theta(x) - \vf_t^{\text{target}}(x|z)}^2$);
- 梯度更新 $\theta \leftarrow \text{grad\_update}(\mathcal{L}(\theta))$。
- end for
请注意这个算法里没有任何一步在模拟 ODE。训练过程中我们从未展开过一条轨迹、从未反向传播穿过一个积分器、从未计算过 Jacobian 的迹或行列式。这个性质叫 simulation-free。
对比 continuous normalizing flow 的经典训练方式(最大似然需要沿轨迹积分 $\divg$),flow matching 把成本从「每步都要跑一遍 ODE」降到了「一次前向 + 一次反向」。这正是它能被推到 Stable Diffusion 3、Movie Gen Video 这种规模的根本原因。训练与采样在这里是完全解耦的:训练是回归,采样才是模拟。
| 训练阶段 | 采样阶段 | |
|---|---|---|
| 做什么 | 回归条件向量场 | 模拟 ODE |
| 时间 $t$ | 随机、独立采样 | 从 $0$ 顺序推进到 $1$ |
| 网络调用次数 | 每个样本 1 次 | 每个样本 = 积分步数(几十至几百) |
| 是否需要数据 | 需要 | 不需要(只需 $\simple$ 的噪声) |
| 是否需要模拟 | 否 | 是 |
10.4 最小 PyTorch 实现
下面是一份可直接运行的完整实现,每一块都与前面的公式一一对应。
(1) 网络:$\vf_t^\theta : \R^d\times[0,1]\to\R^d$。 时间作为额外输入拼接进去(真实模型会用正弦位置编码,这里从简)。
import torch
import torch.nn as nn
class VectorField(nn.Module):
"""u_t^theta(x):输入 x 与 t,输出 R^d 中的速度向量。"""
def __init__(self, dim=2, hidden=256):
super().__init__()
self.net = nn.Sequential(
nn.Linear(dim + 1, hidden), nn.SiLU(),
nn.Linear(hidden, hidden), nn.SiLU(),
nn.Linear(hidden, hidden), nn.SiLU(),
nn.Linear(hidden, dim),
)
def forward(self, x, t): # x: (bs, dim), t: (bs, 1)
return self.net(torch.cat([x, t], dim=-1)) # (bs, dim)
(2) CFM 损失(CondOT)。 直接抄 §10.2 的公式:三行采样、一行标签、一行 MSE。
def cfm_loss(model, z): # z: (bs, dim),来自 p_data
bs = z.shape[0]
t = torch.rand(bs, 1, device=z.device) # (bs, 1) t ~ Unif[0,1]
eps = torch.randn_like(z) # (bs, dim) eps ~ N(0, I_d)
x = t * z + (1.0 - t) * eps # (bs, dim) x = alpha_t z + beta_t eps
target = z - eps # (bs, dim) u_t^target(x|z) = da z + db eps
pred = model(x, t) # (bs, dim)
return ((pred - target) ** 2).sum(dim=-1).mean() # E ||.||^2
注意 sum(dim=-1) 对应 $\norm{\cdot}^2$(在 $d$ 个坐标上求和),mean() 对应期望 $\E$。两者顺序不能颠倒成 mean() 全平均——那只会把损失缩放 $1/d$,虽然不改变 $\arg\min$,但会影响学习率的语义。
(3) 任意调度的通用版本。 直接实现 §10.1 的一般公式 $\norm{\vf_t^\theta(\alpha_t z+\beta_t\epsilon) - (\dot\alpha_t z + \dot\beta_t\epsilon)}^2$:
def cfm_loss_general(model, z, sched):
"""sched(t) 返回 (alpha, beta, dalpha, dbeta),形状均为 (bs, 1)。"""
t = torch.rand(z.shape[0], 1, device=z.device)
eps = torch.randn_like(z)
a, b, da, db = sched(t)
x = a * z + b * eps # (bs, dim) x ~ p_t(.|z)
target = da * z + db * eps # (bs, dim) 沿路径的速度
return ((model(x, t) - target) ** 2).sum(dim=-1).mean()
def condot(t): # alpha_t = t, beta_t = 1 - t
return t, 1.0 - t, torch.ones_like(t), -torch.ones_like(t)
def trig(t): # alpha_t = sin(pi t / 2), beta_t = cos(pi t / 2)
h = torch.pi / 2
return (torch.sin(h * t), torch.cos(h * t),
h * torch.cos(h * t), -h * torch.sin(h * t))
(4) 训练循环与采样器。 采样就是上一讲的 Euler 法。
def sample_checkerboard(n, device='cpu'):
"""二维棋盘分布 p_data,用拒绝采样生成。返回 (n, 2)。"""
out = []
total = 0
while total < n:
y = torch.rand(4 * n, 2, device=device) * 4.0 - 2.0 # 铺满 [-2, 2]^2
keep = (torch.floor(y[:, 0]) + torch.floor(y[:, 1])) % 2 == 0
y = y[keep]
out.append(y); total += y.shape[0]
return torch.cat(out, dim=0)[:n]
device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = VectorField(dim=2).to(device)
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
for step in range(20000):
z = sample_checkerboard(2048, device) # (bs, 2) z ~ p_data
loss = cfm_loss(model, z) # 标量
opt.zero_grad(); loss.backward(); opt.step()
@torch.no_grad()
def sample(model, n, dim=2, steps=200, device='cpu'):
x = torch.randn(n, dim, device=device) # (n, dim) X_0 ~ p_init
dt = 1.0 / steps
for i in range(steps): # Euler 法模拟 ODE
t = torch.full((n, 1), i * dt, device=device)
x = x + model(x, t) * dt # X_{t+dt} = X_t + u_t(X_t) dt
return x # (n, dim) 近似 X_1 ~ p_data
跑起来会看到损失快速下降后停在一个明显大于零的平台上,之后几乎不动。这不是没训好——由 §9.3 推论 (1),损失的下界是标签的条件方差 $\E\norm{\vf_t^{\text{target}}(X_t|Z)-\vf_t^{\text{target}}(X_t)}^2$,对 CondOT 就是 $\E\norm{(Z-\epsilon) - \E[Z-\epsilon\mid X_t]}^2$。判断模型好坏要看生成样本,不是看损失值。
10.5 用有限数据集验证边际化技巧
最后给一段验证代码:当 $\data$ 是有限个点的均匀混合时,§4.5 的显式公式可以精确计算边际向量场。把它与训练好的网络对比,就能直接检验定理 1 与定理 3。
def marginal_vf_exact(x, t, Z):
"""把 §4.5 的求和写出来(CondOT,p_data = 均匀混合 of Z)。
x: (bs, dim) t: (bs, 1) Z: (K, dim) 返回 (bs, dim)"""
a = t # (bs, 1) alpha_t = t
b = (1.0 - t).clamp_min(1e-4) # (bs, 1) beta_t = 1 - t,末端 clamp
# 后验 logit:-||x - alpha_t z_k||^2 / (2 beta_t^2)
diff = x[:, None, :] - a[:, None] * Z[None] # (bs, K, dim)
logit = -(diff ** 2).sum(dim=-1) / (2 * b ** 2) # (bs, K)
w = torch.softmax(logit, dim=-1) # (bs, K) 后验 p_t(z_k | x)
u_cond = (Z[None] - x[:, None, :]) / b[:, None] # (bs, K, dim) (z - x)/(1 - t)
return (w[..., None] * u_cond).sum(dim=1) # (bs, dim) 加权平均
代码与公式的对应关系一目了然:w 是后验 $\frac{p_t(x|z_k)\data(z_k)}{p_t(x)}$(softmax 里已自动完成归一化,即除以 $p_t(x)$),u_cond 是条件向量场 $\frac{z-x}{1-t}$(§5.4),最后一行的加权求和就是定理 1 的积分。把训练好的 model(x, t) 与 marginal_vf_exact(x, t, Z) 在同一批 $(x,t)$ 上比较,应当高度吻合——这就是定理 3 在说的事情:用逐样本的、互相矛盾的条件标签做回归,收敛到的正是这个后验加权平均。
b = (1.0 - t).clamp_min(1e-4) 这个 clamp 是必要的:$t=1$ 时 $\beta_t=0$,softmax 的温度为零、$u_{\text{cond}}$ 的分母为零,会直接产生 NaN。而训练用的 cfm_loss 里不需要任何 clamp——因为那里的标签是 $z-\epsilon$,$\beta_t$ 早已被约掉(§5.3)。这两处的差别,正是「沿路径求值」与「在任意点求值」的差别。
本讲小结
把所有关键公式集中列一遍。全部以 $x, z, \epsilon \in \R^d$、$t\in[0,1]$、$\alpha_t,\beta_t\in\R$ 为准。
| 对象 | 公式 | 说明 |
|---|---|---|
| 条件概率路径 | $p_t(\cdot|z)$,$p_0(\cdot|z)=\simple$,$p_1(\cdot|z)=\delt{z}$ | 从噪声塌缩到单个数据点 |
| 边际概率路径 | $p_t(x)=\int p_t(x|z)\data(z)\dd{z}$ | 可采样、不可求值;$p_0=\simple$、$p_1=\data$ |
| 高斯条件路径 | $p_t(\cdot|z)=\N(\alpha_t z,\ \beta_t^2 I_d)$ | $\alpha_0=\beta_1=0$,$\alpha_1=\beta_0=1$ |
| 高斯路径采样 | $x=\alpha_t z+\beta_t\epsilon$,$\epsilon\sim\N(0,I_d)$ | 训练的数据生成器 |
| 条件 flow | $\psi_t^{\text{target}}(x_0|z)=\alpha_t z+\beta_t x_0$ | 先猜 flow 再反解向量场 |
| 条件向量场 | $\vf_t^{\text{target}}(x|z)=\left(\dot\alpha_t-\frac{\dot\beta_t}{\beta_t}\alpha_t\right)z+\frac{\dot\beta_t}{\beta_t}x$ | 对 $x$ 仿射;等价形式 $\dot\alpha_t z+\frac{\dot\beta_t}{\beta_t}(x-\alpha_t z)$ |
| 沿路径的取值 | $\vf_t^{\text{target}}(\alpha_t z+\beta_t\epsilon|z)=\dot\alpha_t z+\dot\beta_t\epsilon$ | 插值曲线的速度;$\beta_t$ 被约掉 |
| CondOT 条件向量场 | $\vf_t^{\text{target}}(x|z)=\frac{z-x}{1-t}$;沿路径 $=z-\epsilon$ | $\alpha_t=t,\ \beta_t=1-t$ |
| 连续性方程 | $\partial_t p_t(x)=-\divg\!\left(p_t\vf_t^{\text{target}}\right)(x)$ | 充要条件:轨迹分布 $\Leftrightarrow$ PDE |
| 边际化技巧 | $\vf_t^{\text{target}}(x)=\int \vf_t^{\text{target}}(x|z)\frac{p_t(x|z)\data(z)}{p_t(x)}\dd{z}$ | 等价于 $\E\!\left[\vf_t^{\text{target}}(X_t|Z)\mid X_t=x\right]$ |
| 有限数据集下的显式形式 | $\sum_k w_k(t,x)\vf_t^{\text{target}}(x|z_k)$,$w_k=\operatorname{softmax}_k\!\left(-\frac{\norm{x-\alpha_t z_k}^2}{2\beta_t^2}\right)$ | 温度 $\beta_t^2\to0$ 时退化为最近邻 |
| FM 损失(不可算) | $\E_{t,x\sim p_t}\norm{\vf_t^\theta(x)-\vf_t^{\text{target}}(x)}^2$ | 目标含不可解积分 |
| CFM 损失(可算) | $\E_{t,z\sim\data,x\sim p_t(\cdot|z)}\norm{\vf_t^\theta(x)-\vf_t^{\text{target}}(x|z)}^2$ | 纯监督回归 |
| 等价定理 | $\mathcal{L}_{\text{FM}}=\mathcal{L}_{\text{CFM}}+C$,$\nabla_\theta\mathcal{L}_{\text{FM}}=\nabla_\theta\mathcal{L}_{\text{CFM}}$ | $-C=$ 标签的条件方差 $=$ CFM 损失的地板 |
| 高斯 CFM 损失 | $\E_{t,z,\epsilon}\norm{\vf_t^\theta(\alpha_t z+\beta_t\epsilon)-(\dot\alpha_t z+\dot\beta_t\epsilon)}^2$ | 无奇异性,无需模拟 |
| CondOT 训练目标 | $\E_{t,z,\epsilon}\norm{\vf_t^\theta\!\left(tz+(1-t)\epsilon\right)-(z-\epsilon)}^2$ | SD3 / Movie Gen Video 采用 |
| 采样 | $X_0\sim\simple$,$\dd{X_t}=\vf_t^\theta(X_t)\dd{t}$,返回 $X_1$ | Euler 法即可 |
三个母题在本讲的进度
| 母题 | 本讲的回答 |
|---|---|
| (a) 为什么用条件版本训练边际版本? | 两层原因。结构层(定理 1):条件路径各自的连续性方程按 $\data(z)$ 线性叠加,正好合成边际路径的连续性方程;因为可加的是流量 $p_t\vf_t$ 而非速度,还原速度时的除法自动产生后验权重。优化层(定理 3):平方损失的最优解是条件期望,而边际向量场恰是条件向量场的条件期望,于是 SGD 对随机 $z$ 的平均隐式完成了那个不可算的积分。 |
| (b) 为什么 ODE 与 SDE 给出同一边际分布? | 本讲只处理 ODE(连续性方程)。SDE 版本需要 Fokker–Planck 方程与 score function,下一讲展开。 |
| (c) 「看起来不可能算」的量怎么变可算? | $\vf_t^{\text{target}}(x)$ 里的 $p_t(x)$ 与期望测度中的 $p_t(x)$ 在交叉项里精确约分(§9.1 第 2 步)。剩下的部分只含条件对象,而条件对象在高斯路径下有闭式解。 |
延伸阅读
本讲的原始文献
- Flow Matching for Generative Modeling (Lipman et al., 2022) — 本讲全部内容的出处。条件流匹配、边际化技巧、CondOT 路径都出自这篇。先读它的第 3、4 节,与本讲逐节对应。
- Flow Straight and Fast: Rectified Flow (Liu et al., 2022) — 独立提出线性插值路径,并给出「反复重配对以拉直轨迹」的 reflow 过程,解释了 §10.2 里「轨迹为什么是弯的、怎么把它弄直」。
- Stochastic Interpolants (Albergo, Boffi & Vanden-Eijnden, 2023) — 把 $\alpha_t z+\beta_t\epsilon$ 推广成任意插值 $I_t(z,\epsilon)$ 的统一框架,同时涵盖 ODE 与 SDE,是理解「调度到底能有多自由」的最佳参考。
- Flow Matching Guide and Code (Lipman et al., 2024) — 综述加代码,覆盖离散、黎曼流形等推广。想动手时从这里抄实现最省事。
把本讲的算法用到工业规模
- Scaling Rectified Flow Transformers for High-Resolution Image Synthesis (Esser et al., 2024) — Stable Diffusion 3。用的正是 §10.2 那个 CondOT 目标,重点看它对时间 $t$ 采样分布的改造(不用均匀分布而是偏向中间时刻)。
- Movie Gen: A Cast of Media Foundation Models (Polyak et al., 2024) — Meta 的视频生成模型,同样是 $\alpha_t=t,\ \beta_t=1-t$ 的条件流匹配目标,说明本讲的公式在 $d$ 极大时依然照搬即可。
- SiT: Exploring Flow and Diffusion-based Generative Models with Scalable Interpolant Transformers (Ma et al., 2024) — 在同一网络架构下系统对比不同插值路径与训练目标,是判断「调度选择到底有多重要」的实证参考。
推广方向
- Flow Matching on General Geometries (Chen & Lipman, 2023) — 把 $\R^d$ 换成黎曼流形。$x=\alpha_t z+\beta_t\epsilon$ 这种线性插值在流形上没有意义,需要用测地线替代,是检验自己是否真正理解「路径—向量场」对应关系的好材料。
- Scalable Diffusion Models with Transformers (Peebles & Xie, 2023) — DiT。本讲把 $\vf_t^\theta$ 当黑箱,这篇讲这个黑箱在图像上应该怎么造。