MIT 6.S184 Introduction to Flow Matching and Diffusion Models 学习笔记

Last updated on February 6, 2026 5:02 PM

前言

CSDIY 推荐,觉得还不错的课程。25 年的 B 站资源链接:BV1gc8Ez8EFL

虽然我看的是 26 年版本的 lecture notes

从微分方程的视角讲解了 flow 和 diffusion。

基本概念

需要生成的对象(图片,视频,蛋白质)等都可以使用向量 zRdz\in\mathbb{R}^{d} 来表示。

生成即采样:“生成”一个对象本质上就是在数据分布 pdatap_{\text{data}} 里面采样。

数据集:z1,z2,,znpdataz_1,z_2,\cdots,z_n\sim p_{\text{data}}

条件生成:sample 的时候带上某种条件,即 zpdata(y)z\sim p_{\text{data}}(\cdot | y),其中 yy 为控制条件的变量。

我们的目标就是,通过一个模型,将从已知的初始分布 pinitp_{\text{init}} 里面采样的 xx 转换成 pdatap_{\text{data}} 里的采样。

Flow 和 Diffusion

这一节介绍了 ODE 和 SDE 两个数学工具。

Flow 与 ODE

首先定义 ODE 的解,即 trajectory:

X:[0,1]Rd,tXtX:[0,1]\to \mathbb{R}^d,\quad t \mapsto X_t

即将 [0,1][0,1] 中的时间 tt 映射到 Rd\mathbb{R}^d 空间中的某个位置。

ODE 是由向量场定义的:

u:Rd×[0,1]Rd,(x,t)ut(x)u: \mathbb{R}^d\times [0,1] \to \mathbb{R}^d,\quad (x,t)\mapsto u_t(x)

相当于在空间中每个位置的每个时间点都有定义一个类似于速度的东西。ODE 就是希望我们的轨迹是沿着这个向量场走的:

ddtXt=ut(Xt)X0=x0\begin{aligned}\frac{\mathrm{d}}{\mathrm{d} t}X_t &= u_t(X_t)\\ X_0 &= x_0 \end{aligned}

上面的式子是相当于,XtX_t 关于时间的导数是由在此位置的向量场给出的;下面的式子则是规定了一个初始条件。

接下来定义 flow:flow 即是把所有初值的解“打包”成一个映射:

ψ:Rd×[0,1]Rd,(x0,t)ψt(x0)ddtψt(x0)=ut(ψt(x0))ψ0(x0)=x0\psi:\mathbb{R}^d\times[0,1]\to\mathbb{R}^d,\quad (x_0,t)\mapsto \psi_t(x_0)\\ \begin{aligned}\frac{\mathrm{d}}{\mathrm{d} t}\psi_t(x_0) &= u_t(\psi_t(x_0))\\ \psi_0(x_0) &= x_0 \end{aligned}

这告诉我们,对于初始位置 X0=x0X_0=x_0,一个 ODE 的解 XtX_t 可以由流 ψt(x0)\psi_t(x_0) 给出。

流的存在性与唯一性定理:若向量场 uu 连续可微且导数有界,则 ODE 有解且唯一(即 ψt\psi_t),这种情况下 ψt\psi_t 是微分同胚。

这个定理的直觉告诉我们刚才给出的流是良定义的,一个初始点对应一条轨迹,且轨迹之间是不会相交的,并且这个轨迹光滑且可逆。

在机器学习中,这个 uu 的保证几乎一定成立(通常我们用神经网络建模 uu)。

一般而言,求解 ODE 是没那么简单的,不过可以进行数值上的模拟。最简单的欧拉法:

Xt+h=Xt+hut(Xt)(t=0,h,2h,,1h)X_{t+h}=X_t+hu_t(X_t)\quad(t = 0,h,2h,\cdots, 1-h)

有了上面这些工具,我们回忆一下初始目标:把 pinitp_{\text{init}} 转换成 pdatap_{\text{data}}。很自然的想法就是利用 ODE 和 flow,而一个 flow model 如下被定义:

X0pinitddtXt=utθ(Xt)X_0\sim p_{\text{init}}\\ \frac{\mathrm{d}}{\mathrm{d} t}X_t = u_t^{\theta}(X_t)

这个向量场由参数为 θ\theta 的神经网络定义(具体架构之后讨论)。我们的目标就是让 X1X_1 服从数据分布:

X1pdata    ψ1θ(X0)pdataX_1\sim p_{\text{data}}\iff \psi_1^{\theta}(X_0) \sim p_{\text{data}}

注意:神经网络建模的是向量场而不是 flow 本身

Diffusion 与 SDE

简单来说,就是把 ODE 换成 SDE。这里先给出 SDE 的简要概念。莫名 callback 暑假的量化金融专题。?

SDE 相当于把 ODE 的确定轨迹变成了一个随机过程 (Xt)0t1(X_t)_{0\le t\le 1}

在给出 SDE 之前先给出 布朗运动 的概念。布朗运动是一个随机过程 (Wt)0t1(W_t)_{0\le t\le 1},其中 W0=0W_0 = 0,然后满足两个性质:

  • Normal Increments:WtWsN(0,(ts)Id)W_t-W_s\sim \mathcal N(0,(t-s)I_d)
  • Independent Increments:对于任意 0t0<t1<<tn=10\le t_0<t_1<\cdots<t_n=1 都有 Wt1Wt0,Wt2Wt1,,WtnWtn1W_{t_1}-W_{t_0}, W_{t_2}-W_{t_1},\cdots, W_{t_n}-W_{t_{n-1}} 相互独立。

SDE 的想法就是在 ODE 的基础上加上随机的布朗运动。但是布朗运动几乎处处不可导所以不太可能有上面那种利用导数给出的微分方程。我们先利用导数的语言,把 ODE 转写一下:

ddtXt=ut(Xt)1h(Xt+hXt)=ut(Xt)+Rt(h)Xt+h=Xt+hut(Xt)+hRt(h)\begin{aligned}\frac{\mathrm{d}}{\mathrm{d} t}X_t &= u_t(X_t)\\ \frac 1h (X_{t+h}-X_t) &= u_t(X_t)+R_t(h)\\ X_{t+h}&= X_t + hu_t(X_t)+hR_t(h) \end{aligned}

其中 Rt(h)R_t(h) 是误差余项满足 limh0Rt(h)=0\lim_{h\to 0}R_t(h) = 0。我们把最后那个式子修改成随机的,即在每个微小时间步 hh 里面加入布朗运动的贡献:

Xt+h=Xt+hut(Xt)+σt(Wt+hWt)+hRt(h)X_{t+h}=X_t+hu_t(X_t)+\sigma_t(W_{t+h}-W_t)+hR_t(h)

其中 σt0\sigma_t\ge 0扩散系数Rt(h)R_t(h) 为随机误差项。上面这个式子就构成一个随机微分方程,可以用下面的符号来表示:

dXt=ut(Xt)dt+σtdWtX0=x0\begin{aligned} \mathrm{d} X_t &= u_t(X_t)\mathrm{d} t + \sigma_t \mathrm{d} W_t\\ X_0&= x_0 \end{aligned}

类似地,SDE 的解也有唯一性之类的性质,但此处不会进行说明。

对于 SDE 的模拟,可以使用 Euler-Maruyama 方法,和 ODE 的 Euler 方法很像:

Xt+h=Xt+hut+hσtϵt,ϵtN(0,Id)X_{t+h} = X_t+h u_t + \sqrt h \sigma_t\epsilon_t,\quad \epsilon_t\sim \mathcal{N}(0,I_d)

通过 SDE,我们也可以构造一个生成式模型,称为扩散模型

X0pinitdXt=ut(Xt)dt+σtdWt\begin{aligned} X_0&\sim p_{\text{init}} \\ \mathrm{d} X_t &= u_t(X_t)\mathrm{d} t + \sigma_t \mathrm{d} W_t \end{aligned}

其中 σt:[0,1][0,+),tσt\sigma_t: [0,1]\to [0,+\infty),t\mapsto \sigma_t 是一开始固定的超参。

Flow Matching

上面已经讲了 flow model 的基本概念,但没有说怎么训练这样的一个模型。接下来介绍 flow matching(流匹配)

不过现在我们只知道 X0pinitX_0\sim p_{\text{init}} 以及我们希望让 X1pdataX_1\sim p_{\text{data}},让模型凭空学出来这个转化还是比较难的。所以 flow matching 的思路就是不直接让模型“凭空学会”如何从噪声到数据,而是先规定中间每个时刻 tt 的“应该长什么样”(分布路径 ptp_t),再去学习一个向量场让轨迹的分布匹配这条路径。

这一节会反复强调 conditional(条件)和 marginal(边缘)两个概念。提到条件的时候总是相当于在 pinitp_{\text{init}} 上已经取了一个 zz 作为条件的情况,而边缘的意思就是相当于对于所有的 pinitp_{\text{init}} 上的 zz

概率路径

对每个数据点 zRdz\in\mathbb{R}^d,定义一条条件插值路径 pt(z)p_t(\cdot| z),满足端点条件:

  • t=0t=0 时是噪声分布 pinitp_{\text{init}}
  • t=1t=1 时退化成把概率质量“钉死在 zz”上的 Dirac δz\delta_z

原文定义为:

p0(z)=pinit,p1(z)=δzp_0(\cdot| z)=p_{\text{init}},\qquad p_1(\cdot| z)=\delta_z

直觉:这是“把初始噪声逐渐变成一个特定样本 zz”的分布轨迹。

条件路径会诱导一条边缘路径 pt(x)p_t(x):先采样 zpdataz\sim p_{\text{data}},再采样 xpt(z)x\sim p_t(\cdot| z)。这给出了一个可采样ptp_t

  • 采样过程:  zpdata,xpt(z)xpt\;z\sim p_{\text{data}},\,x\sim p_t(\cdot| z)\Rightarrow x\sim p_t
  • 概率密度:

    pt(x)=pt(xz)pdata(z)dzp_t(x)=\int p_t(x| z)p_{\text{data}}(z)\mathrm{d}z

并且由端点条件推出边缘路径确实从噪声插到数据:

p0=pinit,p1=pdatap_0=p_{\text{init}},\qquad p_1=p_{\text{data}}

这告诉我们可以直接采样 xptx\sim p_t,但是无法显式计算概率密度 pt(x)p_t(x)

条件向量场与边缘向量场

说完了我们想要的概率路径,但还没说怎么构造出能让 XtX_t 沿着概率路径走的向量场。本节就进行构造。

对于每个数据 zz,定义条件向量场 uttarget(z)u_t^{\text{target}}(\cdot|z)​:

X0pinit,dXtdt=uttarget(Xtz)Xtpt(z)X_0\sim p_{\text{init}},\quad \frac{\mathrm{d} X_t}{\mathrm{d} t}=u_t^{\text{target}}(X_t | z)\quad\Rightarrow\quad X_t\sim p_t(\cdot| z)

直觉:给定终点 zz,这个速度场会把噪声“推向 zz”并在每个时刻呈现出我们指定的条件分布。而且好消息是这个条件向量场一般是容易有解析解的。但是条件向量场没法给我们直接用,他只是把 pinitp_{\text{init}} 坍缩成 δz\delta_z

但是,利用 marginalization trick,我们可以把条件向量场给利用起来,构造出边缘向量场

定理(Marginalization trick):

uttarget(xz)u_t^{\text{target}}(x|z) 为条件向量场,则边缘向量场

uttarget(x)=uttarget(xz)pt(xz)pdata(z)pt(x)dzu_t^{\text{target}}(x) = \int u_t^{\text{target}} (x|z) \frac{p_t(x|z)p_{\text{data}}(z)}{p_t(x)}\mathrm{d}z

满足

X0pinit,ddtXt=uttarget(Xt)Xtpt(0t1)X_0\sim p_{\text{init}},\quad \frac{\mathrm{d}}{\mathrm{d} t}X_t = u_t^{\text{target}}(X_t)\quad \Rightarrow \quad X_t\sim p_t\quad(0\le t\le 1)

即这样定义的边缘向量场会遵循边缘概率路径。

注意到,uttarget(xz)u_t^{\text{target}}(x|z) 乘上的系数 pt(xz)pdata(z)pt(x)\displaystyle \frac{p_t(x|z)p_{\text{data}}(z)}{p_t(x)} 实际上就是给定噪声数据 xxzz 的后验 pt(zx)p_t(z|x)

这告诉我们 X1pdataX_1\sim p_{\text{data}},即这个边缘向量场可以将初始分布 pinitp_{\text{init}} 转变为数据分布 pdatap_{\text{data}}

为什么这个式子成立呢?先给出一个引理(此处不打算证明):

连续性方程

对于向量场 uttargetu_t^{\text{target}}X0pinitX_0\sim p_{\text{init}}。对于 t[0,1]\forall t\in [0,1]XtptX_t\sim p_t 成立当且仅当

tpt(x)=div(ptuttarget)(x)xRd,t[0,1]\partial_t p_t(x) = -\mathrm{div}(p_t u_t^{\text{target}})(x)\qquad\forall x\in\R^d,t\in[0,1]

其中散度 div\mathrm{div} 定义如下:

div(vt)(x)=i=1dxivti(x)\mathrm{div}(v_t)(x) = \sum_{i=1}^d\frac{\partial}{\partial x_i}v_t^i(x)

直觉:

  • 左边 tpt(x)\partial_t p_t(x):某点处概率密度随时间的变化
  • 右边 div(ptut)-\mathrm{div}(p_t u_t):概率质量“流入/流出”的净效应(div 表示净流出,所以加负号是净流入)

对于边缘向量场的证明:

tpt(x)=(i)tpt(xz)pdata(z)dz=tpt(xz)pdata(z)dz=(ii)div ⁣(pt(z)uttarget(z))(x)pdata(z)dz=(iii)div ⁣(pt(xz)uttarget(xz)pdata(z)dz)=(iv)div ⁣(pt(x)uttarget(xz)pt(xz)pdata(z)pt(x)dz)(x)=(v)div ⁣(ptuttarget)(x)\begin{aligned} \partial_t p_t(x)&\overset{(i)}{=}\partial_t \int p_t(x | z)p_{\mathrm{data}}(z)\mathrm{d} z \\ &= \int \partial_t p_t(x | z)p_{\mathrm{data}}(z)\mathrm{d} z \\ &\overset{(ii)}{=} \int -\operatorname{div}\!\left(p_t(\cdot | z)u_t^{\mathrm{target}}(\cdot | z)\right)(x)p_{\mathrm{data}}(z)\mathrm{d} z \\ &\overset{(iii)}{=} -\operatorname{div}\!\left(\int p_t(x | z)u_t^{\mathrm{target}}(x | z)p_{\mathrm{data}}(z)\mathrm{d} z\right) \\ &\overset{(iv)}{=} -\operatorname{div}\!\left( p_t(x)\int u_t^{\mathrm{target}}(x | z) \frac{p_t(x | z)p_{\mathrm{data}}(z)}{p_t(x)}\mathrm{d} z \right)(x) \\ &\overset{(v)}{=} -\operatorname{div}\!\left(p_tu_t^{\mathrm{target}}\right)(x) \end{aligned}

(i)(i) 比较显然;(ii)(ii) 是代入连续性方程;(iii)(iii) 是根据散度的定义式交换了散度和积分的顺序;(iv)(iv) 是同时乘/除 pt(x)p_t(x)(v)(v) 是代入 uttargetu_t^{\text{target}} 的定义。

训练方法

现在我们已经知道要用神经网络学习的向量场长什么样了(即我们已经明确了训练目标)。那么现在怎么学习一个这样的向量场呢?首先需要定义误差函数。定义 Unif=Uniform[0,1]\text{Unif} = \text{Uniform}_{[0,1]}[0,1][0,1] 上的均匀分布,E\mathbb{E} 为期望。直观上我们希望 utθu^\theta_t 接近 uttargetu_t^{\text{target}} 所以可以用一个均方误差,定义 flow matching loss 如下:

LFM(θ)=EtUnif,xpt[utθ(x)uttarget(x)2]=(i)EtUnif,zpdata,xpt(z)[utθ(x)uttarget(x)2]\begin{aligned} \mathcal{L}_{\text{FM}}(\theta) &= \mathbb{E}_{t\sim \text{Unif},x\sim p_t}\left[\| u_t^{\theta}(x)-u_t^{\text{target}}(x) \|^2\right]\\ &\overset{(i)}{=} \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\| u_t^{\theta}(x)-u_t^{\text{target}}(x) \|^2\right] \end{aligned}

其中 pt(x)=pt(xz)pdata(z)p_t(x) = \int p_t(x|z)p_{\text{data}}(z) 是边缘概率路径,(i)(i) 则使用了 sample 的技巧。但是问题在于,我们不知道 uttargetu_t^{\text{target}} 怎么算(也算不出来)。所以先定义 conditional flow matching loss 如下:

LCFM(θ)=EtUnif,zpdata,xpt(z)[utθ(x)uttarget(xz)2]\mathcal{L}_{\text{CFM}}(\theta) = \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\| u_t^{\theta}(x)-u_t^{\text{target}}(x|z) \|^2\right]

注意到这个 uttarget(xz)u_t^{\text{target}}(x|z) 通常是有解析解的,那么这个 loss 就好算了。但是我们要学的是边缘向量场 uttargetu_t^{\text{target}} 啊?

定理:边缘流损失函数等于条件流损失函数加上与 θ\theta 无关的常数

LFM(θ)=LCFM(θ)+C\mathcal{L}_{\text{FM}}(\theta) = \mathcal{L}_{\text{CFM}}(\theta) + C

这说明他们的梯度是相同的:

θLFM(θ)=θLCFM(θ)\nabla_{\theta}\mathcal{L}_{\text{FM}}(\theta) = \nabla_{\theta}\mathcal{L}_{\text{CFM}}(\theta)

所以利用 SGD 优化 CFM loss 是等价于优化 FM loss 的!这说明我们只要对着 CFM 优化就可以了。

证明:利用 ab2=a22ab+b2\|a-b\|^2=\|a\|^2-2a^\top b + \|b\|^2,把这两个 loss 拆开。

LFM(θ)=EtUnif,xpt[utθ(x)uttarget(x)2]=EtUnif,xpt[utθ(x)22utθ(x)uttarget(x)+uttarget(x)2]=EtUnif,xpt[utθ(x)2]2EtUnif,xpt[utθ(x)uttarget(x)]+EtUnif,xpt[uttarget(x)2]=EtUnif,zpinit,xpt(z)[utθ(x)2]2EtUnif,xpt[utθ(x)uttarget(x)]+C1\begin{aligned} \mathcal{L}_{\text{FM}}(\theta) &= \mathbb{E}_{t\sim\text{Unif},x\sim p_t}[\|u_t^{\theta}(x)-u_t^{\text{target}}(x) \|^2]\\ &= \mathbb{E}_{t\sim\text{Unif},x\sim p_t}[\|u_t^{\theta}(x)\|^2 - 2u_t^{\theta}(x)^\top u_t^{\text{target}}(x) + \|u_t^{\text{target}}(x) \|^2]\\ &= \mathbb{E}_{t\sim\text{Unif},x\sim p_t}[\|u_t^{\theta}(x)\|^2] - 2\mathbb{E}_{t\sim\text{Unif},x\sim p_t}[u_t^{\theta}(x)^\top u_t^{\text{target}}(x)] + \mathbb{E}_{t\sim\text{Unif},x\sim p_t}[\|u_t^{\text{target}}(x) \|^2]\\ &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{init}},x\sim p_t(\cdot|z)}[\|u_t^{\theta}(x)\|^2] - 2\mathbb{E}_{t\sim\text{Unif},x\sim p_t}[u_t^{\theta}(x)^\top u_t^{\text{target}}(x)] +C_1 \end{aligned}

令最后和 θ\theta 无关的一项为常数 C1C_1,然后打开中间这项:

EtUnif,xpt[utθ(x)uttarget(x)]=01pt(x)utθ(x)uttarget(x)dxdt=01pt(x)utθ(x)[uttarget(xz)pt(xz)pdata(z)pt(x)dz]dxdt=01utθ(x)uttarget(xz)pt(xz)pdata(z)dzdxdt=EtUnif,zpdata,xpt(z)[utθ(x)uttarget(xz)]\begin{aligned} \mathbb{E}_{t\sim\text{Unif},x\sim p_t}[u_t^{\theta}(x)^\top u_t^{\text{target}}(x)] &= \int_0^1\int p_t(x)u_t^{\theta}(x)^\top u_t^{\text{target}}(x)\mathrm{d} x\mathrm{d} t\\ &= \int_0^1\int p_t(x) u_t^{\theta}(x)^\top \left[\int u_t^{\text{target}} (x|z) \frac{p_t(x|z)p_{\text{data}}(z)}{p_t(x)}\mathrm{d}z\right] \mathrm{d} x\mathrm{d} t\\ &= \int_0^1\int \int u_t^{\theta}(x)^\top u_t^{\text{target}} (x|z) p_t(x|z)p_{\text{data}}(z)\mathrm{d}z \mathrm{d} x\mathrm{d} t\\ &= \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}}, x\sim p_t(\cdot|z)}[u_t^{\theta}(x)^\top u_t^{\text{target}}(x|z)] \end{aligned}

发现我们居然得到了条件向量场相关的项,把这个往回带,然后加一项减一项 uttarget(xz)2\|u_t^{\text{target}}(x|z)\|^2 来配凑:

LFM(θ)=EtUnif,zpinit,xpt(z)[utθ(x)2]2EtUnif,xpt[utθ(x)uttarget(x)]+C1=EtUnif,zpinit,xpt(z)[utθ(x)22utθ(x)uttarget(xz)+uttarget(xz)2uttarget(xz)2]+C1=EtUnif,zpdata,xpt(z)[utθ(x)uttarget(xz)2]+EtUnif,zpdata,xpt(z)[uttarget(xz)2]+C1=LCFM(θ)+C2+C1\begin{aligned} \mathcal{L}_{\text{FM}}(\theta) &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{init}},x\sim p_t(\cdot|z)}\left[\|u_t^{\theta}(x)\|^2\right] - 2\mathbb{E}_{t\sim\text{Unif},x\sim p_t}\left[u_t^{\theta}(x)^\top u_t^{\text{target}}(x)\right] +C_1\\ &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{init}},x\sim p_t(\cdot|z)}\left[\|u_t^{\theta}(x)\|^2- 2u_t^{\theta}(x)^\top u_t^{\text{target}}(x|z) + \|u_t^{\text{target}}(x|z)\|^2 - \|u_t^{\text{target}}(x|z)\|^2\right]+ C_1\\ &= \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\| u_t^{\theta}(x)-u_t^{\text{target}}(x|z) \|^2\right] + \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[-\|u_t^{\text{target}}(x|z)\|^2\right]+C_1\\ &= \mathcal{L}_{\text{CFM}}(\theta)+C_2+C_1 \end{aligned}

最后一步是因为 EtUnif,zpdata,xpt(z)[uttarget(xz)2]\mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[-\|u_t^{\text{target}}(x|z)\|^2\right] 也是与 θ\theta 无关的常数。所以推导出来发现 FM loss 和 CFM loss 真的只差一个常数。

这个算法有几个关键特性:

  • Simulation-free:训练的时候从来不真正模拟 ODE,所以节省很多资源;
  • 训练的目标是一个非常简单的回归目标 uttarget(xz)u_t^{\text{target}}(x|z)
  • 最后直接使用 Euler 方法就可以进行目标生成(从 pinitp_{\text{init}} 采样,然后用 Euler 法模拟 ODE,最后得到 pdatap_{\text{data}} 分布下的样本)。

这就叫做 Flow Matching(流匹配)

高斯路径

是 denoising diffusion model 使用的概率路径。令 αt,βt\alpha_t,\beta_tnoise schedulers:两个连续可微且单调的关于 tt 的函数,且 α0=β1=0\alpha_0=\beta_1=0α1=β0=1\alpha_1=\beta_0=1。则条件概率路径定义如下:

pt(z)=N(αtz,βt2Id)p_t(\cdot| z) = \mathcal{N}(\alpha_t z, \beta_t^2I_d)

相当于天然满足了 p0(z)=N(0,Id)p_0(\cdot|z) = \mathcal{N}(0,I_d)p1(z)=δzp_1(\cdot|z) = \delta_z。并且其使得采样特别简单:

zpdata, ϵN(0,I)x=αtz+βtϵptz\sim p_{\text{data}},\ \epsilon\sim\mathcal{N}(0,I)\quad\Rightarrow\quad x=\alpha_t z+\beta_t\epsilon\sim p_t

这一步很关键:训练时我们只需要数据样本 zz 和噪声 ϵ\epsilon,就能构造任意时刻的“中间状态” xx

接下来我们证明高斯路径对应的条件向量场为

uttarget(xz)=(α˙tβ˙tβtαt)z+β˙tβtxu_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

证明:定义条件流模型 ψttarget(xz)=αtz+βtx\psi_t^{\text{target}}(x|z) = \alpha_t z + \beta_t x,若 XtX_t 为初始条件 X0pinit=N(0,Id)X_0\sim p_{\text{init}} = \mathcal N(0,I_d),然后根据定义

Xt=ψttarget(X0z)=αtz+βtX0N(αtz,βt2Id)=pt(z)X_t = \psi_t^{\text{target}}(X_0|z) = \alpha_t z + \beta_t X_0\sim \mathcal N(\alpha_t z, \beta_t^2 I_d) = p_t(\cdot | z)

现在已经说明轨迹是按照条件概率路径分布的了。接下来推导向量场就就行了。根据流的定义:

ddtψttarget(xz)=uttarget(ψttarget(xz)z)α˙tz+β˙tz=uttarget(αtz+βtzz)α˙tz+β˙t(xαtzβt)=uttarget(xz)reparameterize x(xαtz)/βt(α˙tβ˙tβtαt)z+β˙tβtx=uttarget(xz)\begin{aligned} \frac{\mathrm{d}}{\mathrm{d} t}\psi_t^{\text{target}}(x|z) &= u_t^{\text{target}}(\psi_t^{\text{target}}(x|z)|z)\\ \dot\alpha_t z + \dot\beta_t z &= u_t^{\text{target}}(\alpha_t z + \beta_t z | z)\\ \dot\alpha_t z + \dot\beta_t \left( \frac{x-\alpha_t z}{\beta_t} \right) &= u_t^{\text{target}}(x|z)&\text{reparameterize }x\to(x-\alpha_tz)/\beta_t\\ \left(\dot{\alpha}_t - \frac{\dot\beta_t}{\beta_t}\alpha_t \right)z + \frac{\dot\beta_t}{\beta_t}x &= u_t^{\text{target}}(x|z) \end{aligned}

接下来把上面的结果代入进 CFM loss:

LCFM(θ)=EtUnif,zpdata,xpt(z)[utθ(x)uttarget(xz)2]=EtUnif,zpdata,xpt(z)[utθ(x)(α˙tβ˙tβtαt)zβ˙tβtx2]=EtUnif,zpdata,ϵN(0,Id)[utθ(αtz+βtϵ)(α˙tz+β˙tϵ)2]\begin{aligned} \mathcal{L}_{\text{CFM}}(\theta) &= \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\| u_t^{\theta}(x)-u_t^{\text{target}}(x|z) \|^2\right]\\ &= \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\left\lVert u_t^{\theta}(x)-\left(\dot{\alpha}_t - \frac{\dot\beta_t}{\beta_t}\alpha_t \right)z - \frac{\dot\beta_t}{\beta_t}x \right\rVert^2\right]\\ &= \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},\epsilon\sim\mathcal N(0,I_d)}\left[\left\lVert u_t^{\theta}(\alpha_t z + \beta_t\epsilon)-\left(\dot\alpha_t z + \dot\beta_t\epsilon \right) \right\rVert^2\right] \end{aligned}

如果我们使用 CondOT probability path,即令 αt=t,βt=1t\alpha_t = t, \beta_t = 1-t 的话,形式会变得更简单:

LCFM(θ)=EtUnif,zpdata,ϵN(0,Id)[utθ(tz+(1t)ϵ)(zϵ)2]\mathcal L_{\text{CFM}}(\theta) =\mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},\epsilon\sim\mathcal N(0,I_d)}\left[\| u_t^{\theta}(t z + (1-t)\epsilon) - (z-\epsilon)\|^2 \right]

总结

所以,流匹配是什么呢?核心目标是为了学习边缘向量场 uttargetu_t^{\text{target}}。为了构造之,先定义条件概率路径 pt(xz)p_t(x|z) 使得 p0(z)=pinitp_0(\cdot|z) = p_{\text{init}}p1(z)=δzp_1(\cdot|z) = \delta_z。接下来构造条件向量场 uttarget(xz)u_t^{\text{target}}(x|z) 使得其对应的流 ψttarget(xz)\psi_t^{\text{target}}(x|z) 满足

X0pinit    Xt=ψttarget(X0z)pt(z)X_0\sim p_{\text{init}} \implies X_t= \psi_t^{\text{target}}(X_0|z)\sim p_t(\cdot|z)

然后定义边缘向量场

uttarget(x)=uttarget(xz)pt(xz)pdata(z)pt(x)dzu_t^{\text{target}}(x) = \int u_t^{\text{target}} (x|z) \frac{p_t(x|z)p_{\text{data}}(z)}{p_t(x)}\mathrm{d}z

这个向量场可以把 pinitp_{\text{init}} 沿着边缘概率路径转变成 pdatap_{\text{data}}

为了学习之,构造一个条件流匹配损失函数

LCFM(θ)=EtUnif,zpdata,xpt(z)[utθ(x)uttarget(xz)2]\mathcal{L}_{\text{CFM}}(\theta) = \mathbb{E}_{t\sim \text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\| u_t^{\theta}(x)-u_t^{\text{target}}(x|z) \|^2\right]

对于 CondOT 路径的情况,学习的伪代码如下:

1Input. A dataset of samples zpdata, and neural network utθ2Method. 3for each mini-batch of data do4Sample a data example z from the dataset5Sample a random time tUnif6Sample noise ϵN(0,Id)7Set x=tz+(1t)ϵ(General case: xpt(z))8Compute loss L(θ)=utθ(x)(zϵ)2(General case:=utθ(x)uttarget(xz)2)9Update θgrad_update(L(θ))10end for\begin{array}{ll} 1 & \textbf{Input. } \text{A dataset of samples }z\sim p_{\text{data}}\text{, and neural network }u_t^{\theta} \\ 2 & \textbf{Method. } \\ 3 & \textbf{for } \text{each mini-batch of data}\textbf{ do} \\ 4 & \qquad\text{Sample a data example }z \text{ from the dataset}\\ 5 & \qquad\text{Sample a random time }t\sim\text{Unif} \\ 6 & \qquad\text{Sample noise }\epsilon\sim\mathcal{N}(0,I_d)\\ 7 & \qquad\text{Set }x=tz+(1-t)\epsilon&(\text{General case: }x\sim p_t(\cdot|z))\\ 8 & \qquad\text{Compute loss } \mathcal{L}(\theta) = \|u_t^{\theta}(x) - (z - \epsilon) \|^2&(\text{General case:} =\| u_t^{\theta}(x)-u_t^{\text{target}}(x|z) \|^2)\\ 9 & \qquad\text{Update }\theta\gets \text{grad\_update}(\mathcal{L}(\theta))\\ 10 & \textbf{end for} \end{array}

非常之简单优雅。

Score Matching

Score Function

前面的 flow model 的视角是向量场 ut(x)u_t(x),而 diffusion 采取的是另一个视角:score function。接下来会先给出 score 的定义,然后一步步说明为什么我们在 diffusion 里面需要 score。

假设 q(x)q(x) 为某概率分布,那么其 score function 定义为他的对数似然的梯度 logq(x)\nabla \log q(x),直觉上来看就是对数似然增长最陡峭的方向。回顾条件概率路径和边缘概率路径的相关概念,我们同样可以定义 conditional score function logpt(xz)\nabla\log p_t(x|z)marginal score function logpt(x)\nabla\log p_t(x)。并且我们也可以得到

logpt(x)=logpt(xz)pt(xz)pdata(z)pt(x)dz\nabla\log p_t(x) = \int\nabla \log p_t(x|z)\frac{p_t(x|z)p_{\text{data}}(z)}{p_t(x)}\mathrm{d}z

条件/边缘 score function 的关系和条件/边缘向量场的关系就很像了。上面的式子证明起来也很简单:

logpt(x)=pt(x)pt(x)=pt(xz)pdata(z)dzpt(x)=pt(xz)pdata(z)dzpt(x)=logpt(xz)pt(xz)pdata(z)pt(x)dz\nabla\log p_t(x) = \frac{\nabla p_t(x)}{p_t(x)} = \frac{\nabla \int p_t(x|z)p_{\text{data}}(z)\mathrm{d} z}{p_t(x)} = \frac{\int \nabla p_t(x|z)p_{\text{data}}(z)\mathrm{d} z}{p_t(x)} = \int\nabla \log p_t(x|z)\frac{p_t(x|z)p_{\text{data}}(z)}{p_t(x)}\mathrm{d}z

对于高斯概率路径 pt(xz)=N(x;αtz,βt2Id)p_t(x|z)=\mathcal{N}(x;\alpha_t z,\beta_t^2I_d),根据高斯的概率密度函数可以算出来条件 score:

logpt(xz)=logN(x;αtz,βt2Id)=xαtzβt2\nabla\log p_t(x|z) = \nabla \log\mathcal{N}(x;\alpha_tz,\beta_t^2I_d) = -\frac{x-\alpha_tz}{\beta_t^2}

注意到,其是关于 x,zx,z 的线性函数,而 uttarget(xz)u_t^{\text{target}}(x|z) 也是关于 x,zx,z 的线性函数,所以这二者是可以互相转换的:

uttarget(xz)=atlogpt(xz)+btx,at=(βt2α˙tαtβ˙tβt),bt=α˙tαtu_t^{\text{target}}(x|z) = a_t\nabla \log p_t(x|z)+b_tx,\quad a_t=\left(\beta_t^2 \frac{\dot\alpha_t}{\alpha_t} - \dot\beta_t\beta_t\right),\quad b_t = \frac{\dot\alpha_t}{\alpha_t}

代入积分的式子会发现,对于边缘的情况也成立:

uttarget(x)=atlogpt(x)+btu_t^{\text{target}}(x) = a_t\nabla\log p_t(x) + b_t

所以对于高斯路径学习边缘向量场就等价于学习边缘 score function

SDE 采样

定理 (SDE Extension Trick)

条件/边缘向量场如前文定义。对于任意扩散系数 σt0\sigma_t\ge0,可以构造通过往 ODE 的动力学里面添加随机动力学来构造 SDE:

X0pinitdXt=uttarget(Xt)dt+σt22logpt(Xt)dt+σtdWt=[uttarget(Xt)+σt22logpt(Xt)]dt+σtdWt    Xtpt(0t1)\begin{aligned} &X_0\sim p_{\text{init}} &\mathrm{d} X_t &= {\color{blue}u_t^{\text{target}}(X_t)\mathrm{d} t} + {\color{green}\frac{\sigma_t^2}{2}\nabla \log p_t(X_t) \mathrm{d} t + \sigma_t \mathrm{d} W_t}\\ && &= \left[{\color{blue}u_t^{\text{target}}(X_t)} + {\color{green}\frac{\sigma_t^2}{2}\nabla\log p_t(X_t)} \right]\mathrm{d} t + {\color{green}\sigma_t }\mathrm{d} W_t\\ \implies&X_t\sim p_t \quad (0\le t\le 1) \end{aligned}

这告诉我们,如果要添加 σtdWt\sigma_t\mathrm{d}W_t 这个随机项的话,需要用一个含 score 的项来“校正”这个分布。

这个的证明依赖 Fokker-Planck 方程,作者的数理基础非常薄弱,本文就不展开了。

对于高斯概率路径,这个对应的 SDE 自然就是

dXt=[(at+σt22)logpt(Xt)+btXt]dt+σtdWt\mathrm{d} X_t = \left[\left(a_t + \frac{\sigma_t^2}{2} \right)\nabla\log p_t(X_t) + b_t X_t\right]\mathrm{d} t + \sigma_t \mathrm{d} W_t

Score Matching

和 flow matching 很像,定义 score 网络 stθ:Rd×[0,1]Rds_t^{\theta}:\R^d\times[0,1]\to \R^d。分别定义 score matching lossdenoising score matching loss(下面会解释为什么这样叫):

LSM(θ)=EtUnif,zpdata,xpt(z)[stθ(x)logpt(x)2]LCSM(θ)=EtUnif,zpdata,xpt(z)[stθ(x)logpt(xz)2]\begin{aligned} \mathcal{L}_{\text{SM}}(\theta) &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\left\lVert s_t^{\theta}(x) - \nabla\log p_t(x) \right\rVert^2\right]\\ \mathcal{L}_{\text{CSM}}(\theta) &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\left\lVert s_t^{\theta}(x) - \nabla\log p_t(x|z) \right\rVert^2\right]\\ \end{aligned}

跟 flow matching 一样的叙事,上面的 untractable,下面的有解析解可以算。而他们正好相差常数 CC(证明方法一模一样),所以只优化下面那个就可以了。

对于高斯路径,代入式子:

LCSM(θ)=EtUnif,zpdata,xpt(z)[stθ(x)logpt(xz)2]=EtUnif,zpdata,xpt(z)[stθ(x)+xαtzβt22]=EtUnif,zpdata,ϵN(0,Id)[stθ(αtz+βtϵ)+ϵβt2]=EtUnif,zpdata,ϵN(0,Id)[1βt2βtstθ(αtz+βtϵ)+ϵ2]\begin{aligned} \mathcal{L}_{\text{CSM}}(\theta) &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\left\lVert s_t^{\theta}(x) - \nabla\log p_t(x|z) \right\rVert^2\right]\\ &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},x\sim p_t(\cdot|z)}\left[\left\lVert s_t^{\theta}(x) +\frac{x-\alpha_tz}{\beta_t^2}\right\rVert^2\right]\\ &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},\epsilon\sim\mathcal{N}(0,I_d)}\left[\left\lVert s_t^{\theta}(\alpha_t z + \beta_t\epsilon) +\frac{\epsilon}{\beta_t}\right\rVert^2\right]\\ &= \mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},\epsilon\sim\mathcal{N}(0,I_d)}\left[\frac{1}{\beta_t^2}\left\lVert \beta_t s_t^{\theta}(\alpha_t z + \beta_t\epsilon) +\epsilon\right\rVert^2\right]\\ \end{aligned}

那他什么时候取最小值呢,当然是当 stθ(x)ϵβts_t^{\theta}(x) \to -\frac{\epsilon}{\beta_t} 的时候了,究其本质,高斯路径下真实的 conditional score 本身就等于“噪声的线性函数”,所以这个网络本质上是在预测噪声,这就解释了为什么这个 loss 叫做 denoising score matching loss。但是注意到当 βt0\beta_t\to 0 的时候(即噪声水平很低的时候)数值会很不稳定。所以 DDPM 直接把 βt\beta_t 相关这个系数给丢了,然后把 stθs_t^{\theta} 重参数化为噪声预测网络 ϵtθ:Rd×[0,1]Rd\epsilon_t^{\theta}:\R^d\times[0,1]\to\R^d

ϵtθ(x):=βtstθ(x)    LDDPM(θ)=EtUnif,zpdata,ϵN(0,Id)[ϵtθ(αtz+βtϵ)ϵ2]\epsilon_t^{\theta}(x):=-\beta_ts_t^{\theta}(x)\implies\mathcal{L}_{\text{DDPM}}(\theta)=\mathbb{E}_{t\sim\text{Unif},z\sim p_{\text{data}},\epsilon\sim\mathcal{N}(0,I_d)}\left[\left\lVert \epsilon_t^{\theta}(\alpha_t z + \beta_t\epsilon) -\epsilon\right\rVert^2\right]

Guidance

我们当然不满足于只在宽泛的 pdatap_{\text{data}} 中采样,希望模型按照我们的 guidance yy 来在一个更小的分布 pdata(zy)p_{\text{data}}(z|y) 上生成(比如按照提示词)。这一节将讨论相关内容。

假设现在我们的 guidance 是以文字形式,这些文字 yy 处于离散的空间 Y\mathcal Y 中。定义 guided diffusion modelguided vector field utθ(y)u_t^{\theta}(\cdot|y) 如下(不使用“条件”是因为容易引起混淆)。这个时候的 uθu^{\theta} 就应该是 Rd×Y×[0,1]\R^d\times\mathcal{Y}\times[0,1] 了。在 σt=0\sigma_t = 0 的情况下就是 flow model,接下来只讨论 flow。

最简单的情况,我们从 pdata(z,y)p_{\text{data}}(z,y) 这个联合分布里面采样 z,yz,y,然后用下面的损失函数训练:

LCFMguided(θ)=E(z,y)pdata(z,y),tUnif,xpt(z)[utθ(xy)uttarget(xz)2]\mathcal{L}^{\text{guided}}_{\text{CFM}}(\theta)=\mathbb{E}_{(z,y)\sim p_{\text{data}(z,y)},t\sim\text{Unif},x\sim p_t(\cdot|z)}\left[\lVert u_t^{\theta}(x|y)-u_t^{\text{target}}(x|z) \rVert^2\right]

也没啥区别就是说。但是经验表明,这样的生成效果并不够好,可能源于模型欠拟合,没有学到正确的边缘向量场,也有可能是数据质量(图片以及对应的标注不够完美),总之我们需要某种方式强化这个 guidance。现有的 SOTA 生成模型常用的方法称为 classifier-free guidance (CFG)

Classifier Guidance

在讨论 CFG 之前先讨论一下这个。

为了简便,讨论上文说的高斯路径。我们知道

uttarget(xy)=atlogpt(xy)+btx,at=(βt2α˙tαtβ˙tβt),bt=α˙tαtu_t^{\text{target}}(x|y) = a_t\nabla \log p_t(x|y)+b_tx,\quad a_t=\left(\beta_t^2 \frac{\dot\alpha_t}{\alpha_t} - \dot\beta_t\beta_t\right),\quad b_t = \frac{\dot\alpha_t}{\alpha_t}

logpt(xy)\nabla\log p_t(x|y) 用贝叶斯拆一下:

logpt(xy)=log(pt(x)pt(yx)pt(y))=logpt(x)+logpt(yx)\nabla\log p_t(x|y) = \nabla\log\left(\frac{p_t(x)p_t(y|x)}{p_t(y)} \right) = \nabla\log p_t(x) + \nabla\log p_t(y|x)

xlogpt(y)=0\nabla_x\log p_t(y) = 0 所以扔了。再把它丢回去:

uttarget(xy)=at(logpt(x)+logpt(yx))+btx=uttarget(x)+atlogpt(yx)u_t^{\text{target}}(x|y) = a_t(\nabla\log p_t(x)+\nabla\log p_t(y|x)) + b_t x = u_t^{\text{target}}(x) + a_t\nabla\log p_t(y|x)

这啥意思,说明 guided 向量场等于 unguided 向量场加上一个在引导变量 yy 下的对数似然 logpt(yx)\log p_t(y|x) 的梯度,直觉上后者在 控制引导的强度,而人们觉得引导强度还不够大所以加一个系数 ww

u~t(xy)=uttarget(x)+watlogpt(yx)\tilde{u}_t(x|y) = u_t^{\text{target}}(x) + w a_t\nabla\log p_t(y|x)

这就是 classifier guidance。这个 logpt(yx)\log p_t(y|x) 本质上是在加噪数据上的一个分类器,所以可以用监督学习训练。注意到若 w1w\ne 1,则学习到的 u~t(xy)\tilde{u}_t(x|y) 不是“真实的”guided 向量场,这是一种 heuristic。

Classifier-free Guidance

Classifier guidance 看似 make sense,但有如下问题:

  • 我们需要在训练一个 flow/diffusion 模型的同时训练一个 classifier;
  • 如果 yy 比较高维,那 classifier 几乎没法训练。

所以 classifier-free guidance 出现了,正如其名,其不需要单独训练一个 classifier。如何做到的呢?先从

logpt(xy)=logpt(x)+logpt(yx)\nabla\log p_t(x|y) = \nabla \log p_t(x) + \nabla\log p_t(y|x)

这个式子说起,把它再次代入 classifier guidance 的式子:

u~t(xy)=uttarget(x)+watlogpt(yx)=uttarget(x)+wat(logpt(xy)logpt(x))=uttarget(x)(wbtx+watlogpt(x))+(wbtx+watlogpt(xy))=(1w)uttarget(x)+wuttarget(xy)\begin{aligned} \tilde{u}_t(x|y) &= u_t^{\text{target}}(x) + w a_t\nabla\log p_t(y|x)\\ &= u_t^{\text{target}}(x) + w a_t(\nabla\log p_t(x|y)-\nabla\log p_t(x))\\ &= u_t^{\text{target}}(x) - (w b_t x + w a_t\nabla\log p_t(x)) + (wb_t x + wa_t\nabla \log p_t(x|y))\\ &= (1-w)u_t^{\text{target}}(x) + w u_t^{\text{target}}(x|y) \end{aligned}

相当于把这个 scaled guided vector field 表示成了 uttarget(x)u_t^{\text{target}}(x)uttarget(xy)u_t^{\text{target}}(x|y) 的线性组合。可能你会说这下可以一起训练这两个模型了?但事实上并不需要。很关键的想法是,在标签空间里添加一个 \varnothing 来表示无条件引导的情况,即 uttarget(x)u_t^{\text{target}}(x) 可以视为 uttarget(x)u_t^{\text{target}}(x|\varnothing)

值得注意的是,这个式子

u~t=(1w)uttarget(x)+wuttarget(xy)\tilde{u}_t = (1-w)u_t^{\text{target}}(x) + w u_t^{\text{target}}(x|y)

对于任意概率路径都成立,不止是高斯路径。利用高斯路径来推导是一种简化。

那么如何训练呢?目前的数据集里面是没有这个所谓的 \varnothing 标签的,但解决方案也很简单,指定一个超参数 η\eta 来使得以 η\eta 的概率把数据标签替换成 \varnothing 就可以了,最终的目标函数如下:

LCFMCFG(θ)=E[utθ(xy)uttarget(xz)2]=(z,y)pdata,tUnif,xpt(z),replace y with prob. η\begin{aligned} \mathcal{L}_{\text{CFM}}^{\text{CFG}}(\theta) &= \mathbb{E}_{\square}\left[\lVert u_t^{\theta}(x|y)-u_t^{\text{target}}(x|z) \rVert^2\right]\\ \square &= (z,y)\sim p_{\text{data}}, t\sim\text{Unif},x\sim p_t(\cdot|z),\text{replace }y\gets\varnothing\text{ with prob. }\eta \end{aligned}

注意到,如果我们使用 w>1w>1 的话,我们拿到的 X1X_1 就不是完全和 X1pdata(y)X_1\sim p_{\text{data}}(\cdot|y) 对齐了,但经验说明取 w4w\ge 4 的效果会相当之好。

生成的时候就从 X0pinitX_0\sim p_{\text{init}} 出发,按照 u~t(xy)\tilde u_t(x|y) 这个动力学来走就行了。

Architecture Design & Latent Space

这部分懒得更新了,直接看 lecture notes 吧。


MIT 6.S184 Introduction to Flow Matching and Diffusion Models 学习笔记
https://blog.imyangty.com/note-mit-diffusion/
Author
YangTY
Posted on
February 4, 2026
Licensed under