Diffusion 三种预测目标:epsilon、sample、v prediction

Diffusion 三种预测目标:epsilon、sample、v prediction

本文解释 diffusion 模型里常见的三种 prediction_type

  • epsilon:预测噪声
  • sample:预测干净样本 x0
  • v_prediction:预测速度变量 v

在 3D Diffusion Policy 这类动作生成模型里,x 不是图像,而是一段动作轨迹。例如:

text 复制代码
x0: [B, horizon, action_dim]

但数学原理和图像 diffusion 是一样的。

1. 前向加噪过程

先定义:

text 复制代码
x0      = 干净样本,例如专家动作轨迹
epsilon = 标准高斯噪声,epsilon ~ N(0, I)
t       = diffusion timestep
xt      = 第 t 步加噪后的样本

前向过程可以写成:

text 复制代码
xt = alpha_t * x0 + sigma_t * epsilon

通常:

text 复制代码
alpha_t = sqrt(alpha_bar_t)
sigma_t = sqrt(1 - alpha_bar_t)

并且常见情况下:

text 复制代码
alpha_t^2 + sigma_t^2 = 1

直观理解:

text 复制代码
t 小:alpha_t 大,sigma_t 小,xt 更像 x0
t 大:alpha_t 小,sigma_t 大,xt 更像 noise

训练时,模型输入一般都是:

text 复制代码
model(xt, t, condition)

区别只在于模型输出被监督成什么。

2. epsilon prediction:预测噪声

原理

epsilon prediction 让模型预测前向过程中加入的噪声:

text 复制代码
epsilon_pred = model(xt, t, condition)
target = epsilon
loss = MSE(epsilon_pred, epsilon)

如果知道 xtepsilon_pred,就可以反推出干净样本:

text 复制代码
x0_pred = (xt - sigma_t * epsilon_pred) / alpha_t

所以模型虽然直接预测的是噪声,但 scheduler 可以用它得到 x0_pred,再继续反向去噪。

直觉

模型在回答:

text 复制代码
这个 noisy sample 里面,哪些成分是噪声?

推理时从纯噪声开始,模型一步步预测并移除噪声。

优点

  • 最经典,DDPM/DDIM 早期和大量 baseline 都使用这种方式。
  • 数学推导和工程实现最常见。
  • 高噪声阶段比较自然,因为 xt 本来就接近噪声。
  • 很多 scheduler、论文、代码默认支持。

缺点

  • 优化目标和最终想要的 x0 是间接关系。
  • 低噪声阶段 xt 已经很接近 x0,但模型仍然要预测完整的标准高斯噪声,目标不一定最自然。
  • 对动作轨迹这种低维连续控制任务,直接预测噪声有时不如直接预测动作直观。

3. sample prediction:预测干净样本 x0

原理

sample prediction 让模型直接预测干净样本:

text 复制代码
x0_pred = model(xt, t, condition)
target = x0
loss = MSE(x0_pred, x0)

如果知道 xtx0_pred,可以反推出噪声:

text 复制代码
epsilon_pred = (xt - alpha_t * x0_pred) / sigma_t

所以它和 epsilon prediction 信息等价:知道一个,就能算出另一个。

直觉

模型在回答:

text 复制代码
这个 noisy sample 对应的干净样本应该是什么?

在 DP3 中,默认配置是:

text 复制代码
prediction_type: sample

也就是模型直接学习:

text 复制代码
noisy action trajectory -> clean expert action trajectory

优点

  • 目标最直观:最终要什么,就直接预测什么。
  • 对动作轨迹、状态轨迹等低维连续数据很自然。
  • 低噪声阶段比较容易,因为 xt 已经接近 x0
  • 在强条件生成任务中常常合理,例如已知点云和机器人状态后生成动作。

缺点

  • 高噪声阶段更难,因为此时 xt 几乎是纯噪声,却要求模型直接预测 x0
  • 不同 timestep 的难度差异明显:低噪声步容易,高噪声步困难。
  • 如果条件不够强或数据分布多峰,高噪声阶段直接预测 x0 可能更容易平均化。

4. v prediction:预测速度变量 v

原理

v_prediction 不直接预测噪声,也不直接预测干净样本,而是预测一个线性组合:

text 复制代码
v = alpha_t * epsilon - sigma_t * x0

配合前向过程:

text 复制代码
xt = alpha_t * x0 + sigma_t * epsilon

可以写成矩阵形式:

text 复制代码
[ xt ] = [  alpha_t   sigma_t ] [ x0      ]
[ v  ]   [ -sigma_t   alpha_t ] [ epsilon ]

如果 alpha_t^2 + sigma_t^2 = 1,这个矩阵可以看成旋转矩阵。因此 (xt, v) 只是 (x0, epsilon) 的另一种坐标表示,没有丢失信息。

知道 xtv_pred 后,可以恢复:

text 复制代码
x0_pred      = alpha_t * xt - sigma_t * v_pred
epsilon_pred = sigma_t * xt + alpha_t * v_pred

训练时:

text 复制代码
v_pred = model(xt, t, condition)
target = alpha_t * epsilon - sigma_t * x0
loss = MSE(v_pred, target)

为什么叫 velocity

如果令:

text 复制代码
alpha_t = cos(theta)
sigma_t = sin(theta)

那么:

text 复制代码
xt = cos(theta) * x0 + sin(theta) * epsilon

theta 求导:

text 复制代码
d xt / d theta = -sin(theta) * x0 + cos(theta) * epsilon

也就是:

text 复制代码
d xt / d theta = alpha_t * epsilon - sigma_t * x0 = v

所以 v 可以理解为:样本沿着加噪轨迹变化时的速度方向。

直觉

模型在回答:

text 复制代码
当前 xt 沿着 diffusion 轨迹应该往哪个方向走?

它不是纯噪声,也不是纯数据,而是二者随 timestep 改变的混合目标。

两个极端

低噪声阶段:

text 复制代码
alpha_t ≈ 1
sigma_t ≈ 0
xt ≈ x0
v ≈ epsilon

这时 v_prediction 接近 epsilon prediction

高噪声阶段:

text 复制代码
alpha_t ≈ 0
sigma_t ≈ 1
xt ≈ epsilon
v ≈ -x0

这时 v_prediction 接近负的 sample prediction

因此它是一种折中参数化:

text 复制代码
低噪声时更像预测噪声
高噪声时更像预测数据

优点

  • 不同噪声强度下训练目标更平衡。
  • 高噪声阶段不只是预测噪声,而更接近预测数据方向。
  • 低噪声阶段不只是重复预测已经可见的 x0,而更关注残余变化方向。
  • 在一些现代 diffusion 模型中更稳定,尤其是复杂生成任务或大模型。

缺点

  • 概念不如 epsilonsample 直观。
  • scheduler 必须明确知道模型输出是 v_prediction
  • 如果训练和采样时 prediction_type 不匹配,结果会明显错误。
  • 对简单低维任务不一定一定优于前两种。

5. 三种预测目标的统一关系

三种方式本质上等价,因为给定 xtt,它们可以互相转换。

如果模型预测 epsilon

text 复制代码
epsilon_pred = model(xt, t, cond)
x0_pred = (xt - sigma_t * epsilon_pred) / alpha_t

如果模型预测 x0

text 复制代码
x0_pred = model(xt, t, cond)
epsilon_pred = (xt - alpha_t * x0_pred) / sigma_t

如果模型预测 v

text 复制代码
v_pred = model(xt, t, cond)
x0_pred      = alpha_t * xt - sigma_t * v_pred
epsilon_pred = sigma_t * xt + alpha_t * v_pred

因此采样时统一流程是:

text 复制代码
1. 模型输出某种 prediction
2. scheduler 根据 prediction_type 转成 x0_pred 和/或 epsilon_pred
3. scheduler 用 x0_pred、epsilon_pred、当前 xt 计算下一个 sample

6. DDIM 如何从 xt 得到 x_

DDIM 的核心是:先估计 x0_predepsilon_pred,再按更低噪声等级重新组合。

设:

text 复制代码
xt              = 当前 noisy sample
alpha_t         = sqrt(alpha_bar_t)
sigma_t         = sqrt(1 - alpha_bar_t)
alpha_prev      = sqrt(alpha_bar_prev)
sigma_prev      = sqrt(1 - alpha_bar_prev)
x0_pred         = 预测的干净样本
epsilon_pred    = 预测的噪声

确定性 DDIM,也就是 eta = 0 时:

text 复制代码
x_{t-1} = alpha_prev * x0_pred + sigma_prev * epsilon_pred

直观理解:

text 复制代码
x_t     = 当前噪声比例下的数据和噪声混合
x_{t-1} = 更低噪声比例下的数据和噪声混合

其中 x0_pred 表示模型认为的干净数据,epsilon_pred 表示模型认为的噪声方向。

7. DDIM 如何跳步:从 xt 到 x_

DDIM 不要求每次只走一步。只要有目标 timestep 的噪声系数,就可以直接跳到更早的 timestep。

设目标 timestep 是 s,并且:

text 复制代码
s < t
alpha_s = sqrt(alpha_bar_s)
sigma_s = sqrt(1 - alpha_bar_s)

确定性 DDIM 跳步公式:

text 复制代码
x_s = alpha_s * x0_pred + sigma_s * epsilon_pred

所以从 x_tx_{t-100} 的形式就是:

text 复制代码
x_{t-100} = alpha_{t-100} * x0_pred + sigma_{t-100} * epsilon_pred

这里的 x0_predepsilon_pred 是根据当前 x_t、当前 t 和模型输出得到的。

因此 DDIM 的采样过程可以少步数运行。例如训练时有 100 个 diffusion timestep,但推理只跑 10 步:

text 复制代码
100 -> 90 -> 80 -> 70 -> ... -> 0

每一步都使用:

text 复制代码
x_next = alpha_next * x0_pred + sigma_next * epsilon_pred

其中 next 是采样计划里的下一个更低噪声 timestep,不一定是 t-1

8. 带随机性的 DDIM 更新

上面是 eta = 0 的确定性 DDIM。更一般的 DDIM 可以加入随机噪声:

text 复制代码
x_s =
    alpha_s * x0_pred
  + sqrt(sigma_s^2 - eta_noise^2) * epsilon_pred
  + eta_noise * z

其中:

text 复制代码
z ~ N(0, I)

eta_noise 由 DDIM 的 eta 参数和当前/目标 timestep 的 alpha 决定。

当:

text 复制代码
eta = 0

随机项消失,采样变成确定性的。

许多 DDIM 推理默认使用 eta = 0,因为它更快、更稳定,并且同一个初始噪声会得到确定结果。

9. 三种 prediction type 下的 DDIM 更新流程

epsilon prediction

text 复制代码
epsilon_pred = model(xt, t, cond)
x0_pred = (xt - sigma_t * epsilon_pred) / alpha_t
x_s = alpha_s * x0_pred + sigma_s * epsilon_pred

sample prediction

text 复制代码
x0_pred = model(xt, t, cond)
epsilon_pred = (xt - alpha_t * x0_pred) / sigma_t
x_s = alpha_s * x0_pred + sigma_s * epsilon_pred

v prediction

text 复制代码
v_pred = model(xt, t, cond)
x0_pred      = alpha_t * xt - sigma_t * v_pred
epsilon_pred = sigma_t * xt + alpha_t * v_pred
x_s = alpha_s * x0_pred + sigma_s * epsilon_pred

其中 s 可以是:

text 复制代码
s = t - 1

也可以是采样计划中的任意更早 timestep:

text 复制代码
s = t - 10
s = t - 100

只要 s < t 并且 scheduler 有对应的 alpha_ssigma_s

10. 三者优缺点总结

预测方式 模型目标 优点 缺点 适合场景
epsilon 噪声 epsilon 经典稳定,支持广,和 DDPM/DDIM 公式关系直接 和最终数据目标间接;低噪声阶段不一定自然 通用 baseline、图像生成、传统 diffusion
sample 干净样本 x0 直观,直接优化最终样本;适合低维动作轨迹 高噪声阶段难;不同 timestep 难度差异大 动作生成、低维连续控制、强条件生成
v_prediction 速度变量 v 不同噪声强度下更平衡;现代 diffusion 中常更稳定 抽象,依赖 scheduler 正确匹配;调试不直观 大模型、复杂生成、需要更稳定参数化的任务

11. 和 3D Diffusion Policy 的关系

在 3D Diffusion Policy 中:

text 复制代码
x0 = 专家动作轨迹
xt = 加噪后的动作轨迹
condition = 点云和机器人状态编码出的 global condition

默认配置使用:

text 复制代码
prediction_type: sample

也就是:

text 复制代码
输入:
  noisy action trajectory xt
  timestep t
  point_cloud + agent_pos condition

输出:
  clean action trajectory x0_pred

loss:
  MSE(x0_pred, expert_action_trajectory)

推理时:

text 复制代码
1. 从随机动作轨迹噪声开始
2. 用观测 condition 反复去噪
3. 得到 clean action trajectory
4. 取其中一段动作执行

12. 最简记忆

text 复制代码
epsilon prediction:
  预测噪声。
  问题是:噪声是什么?

sample prediction:
  预测干净数据。
  问题是:干净样本是什么?

v prediction:
  预测扩散轨迹上的速度方向。
  问题是:从当前 noisy sample 沿去噪轨迹该往哪个方向走?

三者的最终目的都一样:

text 复制代码
从 xt 得到更干净的 x_s,最后得到 x0。

区别只是模型输出变量不同,scheduler 会根据 prediction_type 把它转换成 DDIM 更新需要的 x0_predepsilon_pred