生成模型本质上是把一个分布搬到另一个分布。流匹配直接用速度场搞定,最优传输和薛定谔桥则是它的变体。本文用一个框架串起这些方法,从速度回归到逆问题解决,同一个循环里的不同配置,并介绍DeltaFlow库的实践。
生成建模最近收敛到了一个漂亮的问题:怎么把一个概率分布搬到另一个上?扩散模型的做法是先污染数据再加噪声,然后学逆向过程。流匹配更直接:它学一个速度场,让一团噪声连续地流到数据上,不需要逆过程。
本文带你走一遍这个思路和它衍生出的算法家族。从一个简单的位移向量开始,搭起流匹配,用最优传输配对改进,弯成薛定谔桥,最后复用训练好的场来解决逆问题。你会发现这五件事不是互不相干的五个方法,而是同一个对象的五种配置。
先固定两个分布:源分布 p0 是我们容易采样的(通常是标准高斯 N(0, I)),目标分布 p1 我们只能通过有限样本看到。目标是找一个映射,把源密度送到目标密度。
假设我们把源样本 x0 和数据样本 x1 配对。最直接的办法是走直线,位移为 Δ。沿这条直线插值,得到一个时间索引状态 xt,速度恒定为 Δ。每一对端点就是一个微小但确定的系统:从 x0 出发,以恒定速度 Δ,在 t=1 时刻到达 x1。问题在于生成时我们不知道 x1,只知道当前位置。所以我们要学一个速度场 vθ(x,t),输入当前位置和时间,输出应该移动的速度。
有了这个场,采样就是解一个常微分方程(ODE)。从噪声出发,从 t=0 积分到 t=1,终点就是生成样本。整个推理过程就是一个 ODE 求解器。
这个框架有两个关键对象:概率路径决定了 x0 和 x1 如何随时间连接,以及路径上每点的目标速度 vt;速度场 vθ(x,t) 是我们训练出来的神经网络去匹配这个路径。其它所有东西都是如何把这两者接起来的选择。
流匹配的关键是:我们根本不需要知道全局动态,只需要把网络回归到每个端点对的条件速度上。
具体做法:采样一个数据点 x1,采样噪声 x0,再采样随机时间 t,构造插值状态 xt,让网络 vθ 去预测条件速度 ut。损失就是一个简单的回归。
背后有个了不起的结果:最小化这个条件损失的场,恰好能生成正确的边际概率路径。对通过某点 (x,t) 的所有端点对取平均,网络学到的是那里的期望速度,而这个期望场正是能把 p0 运输到 p1 的场。我们得到了可计算的逐样本损失,它的最优解顺便解决了一个不可解的传输问题。
对于直线校正路径,目标就是位移本身,损失变成了让网络学习每个时空点的平均位移。用 DeltaFlow 的代码,训练循环只需要两行:
from deltaflow.interpolants import LinearInterpolant
from deltaflow.losses import FlowMatchingLoss
loss_fn = FlowMatchingLoss(interpolant=LinearInterpolant())
loss = loss_fn(model, x1)
loss.backward()

插值器拥有路径几何,损失拥有回归,模型拥有场。分开它们就能随意换一个而不影响其它,这也是本文接下来要拉的线。
直线只是最简单的一种连接方式。插值器(interpolant)是一个规则,给定端点 x0、x1 和时间 t,返回插值状态 xt 和条件目标速度 ut。换插值器,保持损失和求解器不变,你就训练出了一个不同的生成模型。
这是基线。速度和位移恒定,轨迹直线。这是 rectified flow 的几何。

扩散模型不走直线,它们走一条弯曲的路径,让边际方差可控。这个几何也可以用三角调度的插值器重现。α²t + σ²t = 1 在每个时间都成立。t=0 时是纯噪声,t=1 时是纯数据。路径像扩散轨迹一样弯曲。关键是只有插值器变了,损失和 ODE 求解器都不用改。
from deltaflow.interpolants import VariancePreservingInterpolant
loss_fn = FlowMatchingLoss(interpolant=VariancePreservingInterpolant())
loss = loss_fn(model, x1)
直线是确定性的:给定 x0 和 x1,轨迹就定了。薛定谔桥问一个更软的问题:在所有从 x0 出发、到 x1 结束的随机过程里,哪个路径在相对熵意义上最接近纯布朗运动?
固定端点时,答案是布朗桥。直线加上噪声鼓包,中间鼓最大、两端为零,由参数 σ 控制扩散强度。若 σ=0,就退化为线性路径。把这个桥的条件速度回归到场上,训练的随机插值器会逼近噪声与数据之间的熵最优传输桥。

模型回归的目标变了,但它最终生成的 ODE 仍是确定性的。
from deltaflow.interpolants import SchrodingerBridgeInterpolant
from deltaflow.trainer import OTCoupling
loss_fn = ConditionalFlowMatchingLoss(
interpolant=SchrodingerBridgeInterpolant(sigma=1.0),
coupling=OTCoupling(),
)
loss = loss_fn(model, x1)
这里出现了第二个旋钮:耦合(coupling),它带来的实际收益最大。
回到最开始:我们把 x0 和 x1 配对画线。但到底哪个 x0 配哪个 x1?默认是独立配对,完全随机。这能用,但浪费。
问题出在交叉路径上。如果噪声任意分配给数据,两两之间的直线会互相穿插。在轨迹相交的地方,真正边际场需要平均矛盾的流速,于是学到的场是弯曲的——即便每条条件路径都是直线。弯曲的场需要很多小步才能准确积分。
每个 mini-batch 内部,解一个离散分配问题:把 n 个噪声样本匹配到 n 个数据样本,使总平方距离最小。这叫做 mini-batch 最优传输耦合,用匈牙利算法求精确解,也可以用贪心近似加速。让最近的端点配对,位移短,轨迹不打叉。边际路径更直,采样时 ODE 的积分步数大幅减少,质量不变。
from deltaflow.losses import ConditionalFlowMatchingLoss
from deltaflow.trainer import OTCoupling
loss_fn = ConditionalFlowMatchingLoss(coupling=OTCoupling())
loss = loss_fn(model, x1)

这里有个更深的连接:这个硬零熵分配,正是静态薛定谔桥在扩散率趋于零时的极限。所以耦合旋钮和插值器旋钮,其实是同一个传输几何的两种视角。用最优传输配对端点,是让薛定谔桥近似在实践中变得紧凑的关键。
上面所有方法都是同一个训练循环,只改两个参数:插值器和耦合。


独立配对会扫出长而交叉的弧线,OT 配对则保持整齐的近平行束,传输成本更低。
训练得到场,求解器通过积分 ODE 把它变成数据。最简单是显式欧拉,固定步长 h=1/N。计算便宜,但误差累积,场弯曲时需要很多步。二阶 Heun 步用梯形平均修正欧拉预测,每步两次场计算,但在低步数时准确度显著提升——这正是 OT 耦合带来的直路径擅长的区间。
from deltaflow.samplers import FlowSampler
samples = FlowSampler(model).sample(torch.randn(1000, 2), n_steps=50)

这就是前面设计选择回报的时候:OT 耦合加二阶求解器,用几十步就到达数据流形,而不是扩散模型常见的几百步。
模块化设计的另一个好处:你有一个在干净数据上无条件下训练好的场。现在给你一个有损测量——遮挡图像、模糊扫描、降采样信号——让你重建出原始干净图像。形式上,给定测量算子 A 和观测 y,我们想从后验 p(x1 | y) 采样,而不是先验 p(x1)。
办法是引导采样 ODE。每一步我们已经有了当前状态 xt 和预测速度 vt。用 Tweedie 分解把它转成干净端点的估计 ˆx1,也就是场认为这条路要往哪去。然后用高斯似然评估这个估计对观测的解释程度,沿梯度方向调整一步。
from deltaflow.inverse import GaussianLikelihood, LinearTweedie, MaskOperator
from deltaflow.solvers import EulerSolver, PosteriorSolver
likelihood = GaussianLikelihood(y=y, operator=MaskOperator(mask), sigma=1.0)
solver = PosteriorSolver(
base_solver=EulerSolver(model),
likelihood=likelihood,
tweedie=LinearTweedie(),
guidance_scale=0.5,
)
x = solver.sample(torch.randn(16, 1, 16, 16), n_steps=60)

先验流提出可行的干净数据,似然梯度让提议与测量一致。关键是完全复用训练好的场和欧拉求解器,对每种新退化都无需重新训练。
DeltaFlow 的生成机制不限于生产样本。同一个条件场还可以用于检测和表示学习,无需修改架构。
把解剖标志点检测定义为条件流 p(标志点 | 图像)。X 光是条件,堆叠的标志点坐标是生成目标。场在条件图像下把噪声运到标志点位置。推断时采样就是检测,样本的散布就是天然的不确定性。

对条件场运行两次,一次有条件,一次无条件。两次内部特征之差 Δh 隔离了条件改变的东西,同时抵消了共享结构。在医学影像里共享结构是解剖结构,所以 Δh 成为抑制共享解剖内容的特征,只保留条件特有的信号。
对齐两个噪声级别视图的 Δh,训练一个骨干网络,其表示与底层解剖无关。用线性探针验证,预训练骨干的特征在四个数据集任务上达到几乎完美的精度,而随机初始化基线远低。特征 PCA 按数据集干净分离。

把上面的算法浓缩成一张图:插值器、耦合、求解器、似然。选一条噪声到数据的路径,选哪个噪声对应哪个数据,用单目标把场回归到路径速度,用求解器积分场,可选地注入测量似然解决逆问题。

流匹配、OT 耦合整流流、方差保持插值器、薛定谔桥、后验采样——不是五套库的代码,而是这些组件之间的五种接法。每个组件实现一次,方法就变成模块配置,而不是重写。
DeltaFlow 是一个围绕分布之差的 PyTorch 小库。所有组件都是可组合的原始构件。换掉插值器,加上耦合,包一个后验求解器——方法变了,训练循环不变。核心构件与领域无关,本文所有代码块都可以直接运行。
安装:pip install torchdeltaflow
代码、示例和图里的动画都在 github.com/phrugsa-limbunlom/deltaflow,文档在 phrugsa-limbunlom.github.io/deltaflow,PyPI 上叫 torchdeltaflow。
[1] Y. Lipman et al. Flow Matching for Generative Modeling. ICLR, 2023. arXiv:2210.02747.
[2] A. Tong et al. Improving and Generalizing Flow-Based Generative Models with Minibatch Optimal Transport. TMLR, 2024. arXiv:2302.00482.
[3] N. Ma et al. SiT: Exploring Flow and Diffusion-Based Generative Models with Scalable Interpolant Transformers. 2024. arXiv:2401.08740.
[4] M. S. Albergo et al. Stochastic Interpolants: A Unifying Framework for Flows and Diffusions. 2023. arXiv:2303.08797.
[5] V. De Bortoli et al. Diffusion Schrödinger Bridge with Applications to Score-Based Generative Modeling. NeurIPS, 2021. arXiv:2106.01357.
[6] A. Tong et al. Simulation-Free Schrödinger Bridges via Score and Flow Matching. AISTATS, 2024. arXiv:2307.03672.
[7] J. Kim et al. FlowDPS: Flow-Driven Posterior Sampling for Inverse Problems. 2025. arXiv:2503.08136.
[8] M. Pourya et al. Flower: A Flow-Matching Solver for Inverse Problems. 2025. arXiv:2509.26287.
[9] J. Ho and T. Salimans. Classifier-Free Diffusion Guidance. 2022. arXiv:2207.12598.
免费获取企业 AI 成熟度诊断报告,发现转型机会
关注公众号

扫码关注,获取最新 AI 资讯
3 步完成企业诊断,获取专属转型建议
已有 200+ 企业完成诊断