Diffusion Post-Training
DDPO、DPOK、DRaFT、AlignProp、Diffusion-DPO、Flow-GRPO 等生成后训练。
Diffusion/flow 后训练仍在发展,奖励建模、偏好优化和高效微调部分适合做本地更新。
§0 TL;DR
💡 9 句话搞定 Diffusion Post-Training — 一页拿下 RL/DPO/Flow-RL 全家桶(详见 §1–§10 推导)。
-
为什么难:diffusion 是多步 步生成(典型 20–50 步),reward 只在终态 给一次 —— 稀疏 terminal reward + 长 denoising trajectory + credit assignment 三件事叠加,比 LLM RLHF 多一个"轨迹积分"维度。
-
三条主线:(i) RL on denoising MDP(DDPO / DPOK,把 步 denoising 当 MDP);(ii) Direct reward backprop(DRaFT / AlignProp / ReFL,把 reward 当 differentiable loss 沿 步反传);(iii) Preference optimization(Diffusion-DPO / D3PO / SPO / Diffusion-KTO / MaPO,把 LLM DPO 家族搬到 diffusion)。
-
DDPO (Black et al. 2024 ICLR, arXiv 2305.13301):denoising 视为 -步 MDP,state ,action ,per-trajectory reward ;用 REINFORCE 或 PPO-clip 更新 。
-
AlignProp (Prabhudesai et al. 2024 ICLR, arXiv 2310.03739) & DRaFT (Clark et al. 2024 ICLR, arXiv 2309.17400):reward 关于 可导时,直接把 沿 步 sampler 反传到 。关键工程问题:显存 ;DRaFT-K / AlignProp 只回传最后 步(典型 ),配合 gradient checkpointing 把显存压到 。
-
Diffusion-DPO (Wallace et al. 2024 CVPR, arXiv 2311.12908):把 LLM 的 换成 diffusion 的 per-step ELBO surrogate——具体地,用 作为 的一个 lower bound 项,对 拼成 DPO contrastive。
-
D3PO (Yang et al. 2024 CVPR, arXiv 2311.13231):完全免 RM——直接把人类对生成图片的 thumbs up/down 信号代入 KL-regularized 最优解的 implicit reward;推导上与 DPO 平行,但放到 diffusion per-step Markov chain 上。
-
SPO (Liang et al. 2024, arXiv 2406.04314):观察到不同 denoising step 偏好不同(高噪 step 学构图,低噪 step 学细节),把 DPO 推广为 step-aware——每个 单独采 in-step pair ,loss 在 step 维度上加权。
-
Flow-GRPO (Liu et al. 2025, arXiv 2505.05470):第一个把 GRPO 搬到 Flow Matching 的工作。两个关键 trick:ODE→SDE 等价转换让确定性 flow 变可探索的随机过程;denoising reduction 训练时减步、推理时全步。RL-tuned SD3.5-M 把 GenEval 从 63% 拉到 95%。
-
Reward hacking is the real boss:过饱和颜色、构图单调、风格收敛、PickScore 高但人眼丑 —— 缓解靠 reward ensemble (HPSv2 + PickScore + ImageReward + CLIP-Score)、KL anchor (Diffusion-DPO 的 )、early stop on reward plateau。SD3 / FLUX 几乎不公开 post-training 细节,但社区主流认为 SD3.5 Turbo 系列、FLUX.1 dev 走的是 DPO + 蒸馏混合路线。
✅ vs LLM RLHF 一句话对比 — LLM RLHF 关心 "token-level credit assignment + KL anchor";diffusion post-training 关心 "denoising-step credit assignment + 显存爆炸 (backprop) 或 sample 爆炸 (RL)"。本质相同问题——稀疏 reward + 长轨迹——只是轨迹的物理含义换了。
§1 直觉:为何 diffusion post-training 难
1.1 单步 vs 多步生成的本质差异
LLM 的 reward 一般也是 sequence-level,但 token 是离散、轨迹长 、词表中等大。diffusion 的"轨迹"是 步 denoising,每步操作的是连续高维张量 (SDXL latent 是 维), 典型 20–50。
| 维度 | LLM RLHF | Diffusion Post-Training |
|---|---|---|
| 轨迹长度 | (response token 数) | (denoising step 数,典型 20–50) |
| 单步动作 | 离散 token | 连续向量(–) |
| Reward 频率 | 通常只在终态 | 通常只在终态 |
| 探索性 | sampling temperature / top-p | DDIM 是 deterministic,需要"加噪"才能探索(DDPO 用 stochastic DDPM;Flow-GRPO 用 ODE→SDE) |
| Reward 来源 | trained RM (BT) / rule | trained image RM (ImageReward / HPSv2 / PickScore) / rule (object count / OCR) |
| 显存瓶颈 | 4 副本 (policy + ref + RM + V) | 1 副本 UNet/DiT,但直接反传时需存 步 activation |
1.2 三条主线分类
- Line A (RL on denoising MDP):把 diffusion 当成 RL 环境,不要求 reward 可导。代表:DDPO、DPOK、Flow-GRPO。
- Line B (Direct reward backprop):reward 关于 可导时直接梯度下降,类似把 reward 当一个新 loss。代表:DRaFT、AlignProp、ReFL。
- Line C (Preference optimization, DPO-style):把 LLM DPO 系移植到 diffusion,不再 sample on-policy。代表:Diffusion-DPO、D3PO、SPO、Diffusion-KTO、MaPO。
偏好/奖励信号
│
┌───────────────────────┼───────────────────────┐
│ │ │
reward 不可导 reward 可导 偏好对 (offline)
│ │ │
Line A: RL Line B: backprop Line C: DPO 家族
DDPO, DPOK, DRaFT, AlignProp, Diffusion-DPO,
Flow-GRPO ReFL D3PO, SPO, KTO, MaPO
│ │ │
最通用 显存友好 (K-step) off-policy 快
但 sample 贵 但要求可导 但需偏好数据
1.3 一句话直觉
💡 核心直觉 —
- Line A 把 步 denoising 当 RL 轨迹:每步是一个 stochastic policy 输出。
- Line B 把 reward 当 differentiable loss:用 步反传,但显存 把人压垮。
- Line C 把 reward 完全 bypass:用偏好对的 implicit reward = 。
1.4 Convention(全文统一)
| 符号 | 含义 |
|---|---|
| 干净图像(latent 或 pixel) | |
| 加噪样本; | |
| UNet/DiT 预测的噪声(DDPM 参数化) | |
| Flow Matching 的 vector field | |
| 条件(text embedding / class) | |
| reverse process 的单步条件分布 | |
| 终态 reward(scalar,可来自 RM 或 rule) | |
| / | 参考模型(一般是 SFT 后的 base) |
| KL/温度超参(与 LLM DPO 同义) |
§2 RL for Diffusion:DDPO 与 DPOK
2.1 把 denoising 当 MDP(DDPO 视角)
Black et al. 2024 ICLR Training Diffusion Models with Reinforcement Learning(arXiv 2305.13301)的关键观察:DDPM/DDIM 的 reverse process 本身就是一个有限 horizon MDP。
定义:
- State: ,时间反向
- Action: (从 采样得到)
- Transition: 确定性——
- Reward: for ,(terminal-only)
- Policy:
策略梯度定理:
核心: 在 DDPM 中是 Gaussian,log-prob 可解析写出,所以梯度可直接算。
2.2 DDPO-SF (Score Function) 算法
最朴素的版本(DDPO-SF, score function estimator):
- 采样阶段 — 从 prompt 出发跑 步 DDPM reverse,得到 trajectory ;计算 。
- 更新阶段 — 用 REINFORCE-style 梯度估计:
其中 是 baseline(典型用 batch mean reward)。
2.3 DDPO-IS (Importance Sampling, PPO-style)
DDPO 的实际推荐变体用 PPO-clip 在每步上做重要性比:
⚠️ Per-step ratio 而非 trajectory ratio — diffusion PPO 用 per-step importance ratio,不是把 步乘起来。因为整条 trajectory 的 ratio 是 个比值的积,方差爆炸;per-step clip 在每步独立 clamp 才稳。
2.4 DDPO 的两个 reward 实验
Black et al. 用 DDPO + SD-1.5 在四个 reward 上跑:
| Reward 类型 | 例子 | 信号性质 |
|---|---|---|
| Compressibility | JPEG file size | rule-based scalar |
| Aesthetic | LAION aesthetic predictor | trained MLP |
| Prompt-image alignment | CLIP-Score / LLaVA judge | VLM-based |
| Object presence | DETR / OWL-ViT count | rule-based |
实测在所有四个 reward 上,DDPO 比 reward-weighted regression(RWR baseline)涨幅明显,且能从 emoji 风格漂移到油画风格——证明 RL 真的在 explore 而不是简单 mode-seeking。
2.5 DPOK:KL-regularized RL for diffusion
Fan et al. 2023 NeurIPS DPOK: Reinforcement Learning for Fine-tuning Text-to-Image Diffusion Models(arXiv 2305.16381)和 DDPO 几乎同期,差别在显式 KL anchor:
KL 项展开到 per-step:
由于 DDPM 的 是 Gaussian,两个 Gaussian 的 KL 有闭式,per-step KL 直接算。DPOK 用 policy gradient + 这个 KL penalty,等价于 RLHF 的 "" 的 diffusion 版本。
💡 DPOK vs DDPO —
- DDPO:纯 RL(REINFORCE 或 PPO-clip),KL 隐式(通过 ratio clip)。
- DPOK:显式 KL 项,与 LLM RLHF 的"reward 上加 KL"对应。
- 实测 DPOK 在 reward-prompt alignment(ImageReward)上稳一些;DDPO 在 compressibility 等 rule-based reward 上更激进。
2.6 DDPO 失败模式与缓解
| 现象 | 原因 | 缓解 |
|---|---|---|
| Reward 上升但 FID 暴跌 | over-optimization on RM 盲点 | KL penalty / LoRA fine-tune(防 base 漂移) |
| 同一 prompt 收敛到单一构图 | mode collapse,policy 找到 RM 高分 mode | reward ensemble / early stop |
| 高 reward 但人眼丑 | RM scale 与 human 不对齐 | 多 RM 加权 + human eval 校准 |
| Training 不稳 | per-step ratio 在 步上累计 | per-step PPO-clip 比 LLM 的 更稳 |
§3 Direct Reward Fine-Tuning:DRaFT / AlignProp / ReFL
3.1 核心 idea:reward 当 differentiable loss
若 reward 关于 可导(一般 CNN/ViT RM 都满足),且 diffusion sampler 是 differentiable,则可以直接对 反传:
其中 表示从 出发跑 步 reverse 得到 。这是把 diffusion 整条 reverse trajectory 当成一个 giant differentiable computation graph,end-to-end 优化 reward。
✅ 优势 — 无需 sample variance;梯度信号方差远小于 REINFORCE-style RL。
❌ 代价 — 存 步 activation;vanilla 实现下显存 ,对 SDXL UNet 数百 GB,完全不可训练。
3.2 DRaFT (Clark et al. 2024 ICLR, arXiv 2309.17400)
Directly Fine-Tuning Diffusion Models on Differentiable Rewards。两个核心 trick:
Trick 1:DRaFT-K,只回传最后 步。
完整的 chain rule(denoise step 既影响下一步 又直接依赖 ):
其中 是 step- 通过 直接对 的偏导(不经过 的间接路径), 是 backward 时的 Jacobian product propagation。前 步用 torch.no_grad() 跑,只在最后 步保留 graph;K=1 (DRaFT-1) 已能给出极强信号——最后一步对 直接影响最大。autograd 自动累加所有 步的 ,所以代码只要 loss.backward() 即可。
Trick 2:LoRA fine-tune + 高学习率。
只训 LoRA adapter(1% 参数),base UNet 冻结。配合 gradient checkpointing 把显存压到单卡 24GB 内可训。
伪代码:
# DRaFT-K 一步训练 x_t = torch.randn(B, C, H, W).to(device) # x_T with torch.no_grad(): for t in range(T-1, K, -1): # 前 T-K 步无梯度 x_t = ddim_step(unet_lora, x_t, t, cond) for t in range(K, 0, -1): # 最后 K 步要梯度 x_t = ddim_step(unet_lora, x_t, t, cond) x_0 = x_t reward = image_rm(x_0, prompt) # ImageReward / HPSv2 loss = -reward.mean() # 注意负号——最大化 reward loss.backward() # 显存 O(K) optimizer.step()
⚠️ DRaFT-1 等价于 REINFORCE 吗? — 不等价。DRaFT-1 是真实 reparameterized gradient(pathwise estimator),REINFORCE 是 score function estimator。前者方差极小但只在 reward 可导时可用;后者通用但方差大。 vs 是两类不同的梯度估计。
3.3 AlignProp (Prabhudesai et al. arXiv 2310.03739, 2023-10;ICLR 2024 venue; arXiv 后被 superseded/withdrawn)
Aligning Text-to-Image Diffusion Models with Reward Backpropagation——和 DRaFT 几乎并行的工作(2023 年底先后挂 arXiv),核心 idea 相同:reward backprop through denoising。差别:
| 维度 | DRaFT | AlignProp |
|---|---|---|
| 截断 | DRaFT-K,最后 步保留梯度 | 随机选 步保留梯度(randomized truncated BPTT) |
| 显存优化 | gradient checkpointing | gradient checkpointing + LoRA |
| 主推 reward | HPSv1, PickScore, Aesthetic | ImageReward, HPSv2, PickScore |
| Mode collapse 缓解 | 简单 KL anchor | 退火 + early stop |
AlignProp 的关键贡献是把"为什么 reward backprop 可以工作"理论化——证明在 fixed-point 假设下,截断 BPTT 的梯度是真实梯度的有偏但低方差估计。
3.4 ReFL (Xu et al. 2023 NeurIPS, arXiv 2304.05977)
ImageReward: Learning and Evaluating Human Preferences for Text-to-Image Generation。这篇是 ImageReward 的原始论文,同时也提出了 ReFL (Reward Feedback Learning) 算法。
ReFL 与 DRaFT 思想接近,但发表更早。它把 reward 直接当 loss,并且只在一个随机选定的中间 step 用 reward 监督,相当于 DRaFT 思想的最早期实现:
其中 是从单步 -prediction 估的 (Tweedie 一步 unfold)。
关键差异:ReFL 是"单步反传 + 同时训",DRaFT/AlignProp 是"多步反传 + 纯 reward loss"。ReFL 训练更稳但 reward 涨幅小,因为只看了 的一步估计而非真实采样轨迹。
3.5 三者对比
| 算法 | 反传策略 | 显存 | reward 涨幅 | 稳定性 |
|---|---|---|---|---|
| ReFL (Xu 2023) | 单步 + 混合 | 小 | 高 | |
| DRaFT-K (Clark 2024) | 最后 步 BPTT | 大 | 中( 大易过优化) | |
| AlignProp (Prabhudesai 2024) | 随机选 步 BPTT | 大 | 中 |
💡 显存粗算 — SDXL UNet 约 2.6B 参数,单 forward 在 fp16 下需要约 6–8 GB activation; 时 30–40 GB; 时 300 GB,只能多机分片。这就是为什么 实测最常用——精度损失可忽略但工程友好。
3.6 Reward hacking in direct reward backprop
直接反传比 RL 更容易 hacking,因为梯度信号"太精确":
| 现象 | 例子 |
|---|---|
| Over-saturation | HPSv2 偏好高对比度 → 训练后图像饱和度爆表 |
| Style monotonicity | ImageReward 训练数据有偏 → 所有 prompt 输出同一风格 |
| Trypophobia patterns | 某些 RM 偏好"细密纹理",model 学到密恐图案 |
| Mode collapse | 同一 prompt 的多次采样几乎一样 |
缓解:reward ensemble (HPSv2 + PickScore + ImageReward 取 mean 或 min)、KL anchor、early stop、small LoRA scale。
§4 Preference Optimization:Diffusion-DPO 家族
4.1 Diffusion-DPO (Wallace et al. 2024 CVPR, arXiv 2311.12908)
Diffusion Model Alignment Using Direct Preference Optimization。把 LLM DPO 移植到 diffusion 的关键挑战:diffusion 的 没有闭式,要用 ELBO 代替。
4.1.1 推导(关键步骤)
LLM DPO 的核心是 KL-regularized RL 最优解:
反解 ,代入 Bradley-Terry, 消掉。
对 diffusion,把"sample "替换为"sample trajectory ",最优解形式相同但 用整条 trajectory 的 likelihood:
这个 trajectory log-likelihood 是可解析的(每项都是 Gaussian log-prob)。但是:训练时若每个 update 都要跑完整 trajectory,计算成本爆炸。
Wallace et al. 的 trick:用 ELBO surrogate。
DDPM 的 是 的 (negative) ELBO 项之一,具体地:
用 作为 的单 sample 估计(Jensen 不等式严格意义上给的是 lower bound,但作为 DPO 的 implicit reward 数值代理可用),代入 DPO 框架:
💡 直觉读法 — sigmoid 内部是"对 ,policy 比 ref 更会去噪"减去"对 ,policy 比 ref 更会去噪"。如果 policy 在 上更准、在 上更不准,差值正,loss 下降。
4.1.2 实现细节
- 来自一个 prompt 下的人类偏好对(Pick-a-Pic 数据集是主力)。
- 训练时每步随机采 和 ,构造 (同样的 用在 和 上,做 paired noise)。
- 是冻结的 base UNet(一般用 SDXL 原始 checkpoint)。
⚠️ 共享 noise 的关键性 — 论文强调 和 必须用同一个 (即 paired noise),否则 不再可比,loss 方差爆炸。这是 Diffusion-DPO 最容易踩的坑。
4.1.3 结果(SDXL 上)
- 在 PickScore / HPSv2 上稳定优于 SDXL base。
- 训练成本约 SFT 的 1.5–2x(要算两次 UNet:policy + ref)。
- 比 DDPO 简单:完全 offline,不需要 sample。
4.2 D3PO (Yang et al. 2024 CVPR, arXiv 2311.13231)
Using Human Feedback to Fine-tune Diffusion Models without Any Reward Model。和 Diffusion-DPO 几乎同时挂 arXiv(2023-11),差别在推导路径:
- Diffusion-DPO:先 KL-regularized RL → ELBO surrogate → DPO loss。
- D3PO:直接把 LLM DPO 的推导逐步搬到 diffusion 的 Markov chain——每个 denoising step 看作一个 MDP step,用相同的"反解 implicit reward + 代入 BT"框架。
D3PO 最终 loss 形式与 Diffusion-DPO 几乎相同:
需要的是完整 trajectory pair ;如果偏好对只有 final image ,需先用 重构 trajectory(用 DDPM 的 forward q-sample)。
💡 Diffusion-DPO vs D3PO 实际差异 — 二者数学等价(在 ELBO surrogate 下,D3PO 的 trajectory log-ratio 退化为 Diffusion-DPO 的单步 距离差)。实践中:
- Diffusion-DPO 用 single- 估计(更省),D3PO 用全 trajectory 求和(更精但贵)。
- Diffusion-DPO 在 Pick-a-Pic 上稳,D3PO 在自采集 thumbs up/down 数据上稳。
- 工业部署主流用 Diffusion-DPO(计算简单)。
4.3 SPO (Liang et al. 2024, arXiv 2406.04314)
Step-aware Preference Optimization: Aligning Preference with Denoising Performance at Each Step。关键观察:不同 denoising step 对图像的不同方面负责:
- 高噪 step ():决定 global 结构(构图、物体位置)。
- 低噪 step ():决定 local 细节(纹理、边缘)。
如果用 Diffusion-DPO 的"单 采样",相当于把所有 step 同等对待——但人类偏好在不同 step 上的"重要性"不同。
4.3.1 SPO 的两个修改
修改 1:In-step preference——对同一 ,独立采两个 ,由一个 step-wise reward model 判断"哪个 在 step 上更好"。
修改 2:Step-aware weighting——SPO loss 在 step 维度上加权:
其中 是 step 采样分布(典型 uniform 或更偏向中等 )。
4.3.2 In-step reward model
为了得到 in-step preference ,SPO 训了一个step-wise reward model ,判断"给定 , 在 step 上是好的过渡吗"。它不是直接打分 的像素质量,而是估计在 step 上这个过渡是否会通向高质量 。
✅ SPO 的关键收益 — 同一份偏好数据,SPO 的有效信号量 × 倍(每个 prompt 在 个 step 上都产生 pair)。实测在 PickScore / HPSv2 上比 Diffusion-DPO 涨 1–3 点。
4.4 Diffusion-KTO (Li et al. 2024 NeurIPS, arXiv 2404.04465)
Aligning Diffusion Models by Optimizing Human Utility。LLM KTO (Ethayarajh 2024, arXiv 2402.01306) 的 diffusion 版。
LLM KTO 核心 idea:用 Kahneman-Tversky prospect theory 替换 BT preference model,只需要 per-sample binary feedback(thumbs up/down),不需要 pair:
其中 是 prospect-theoretic 价值函数(thumbs up 用 ,thumbs down 用 ), 是 reference utility。
Diffusion-KTO 把 替换为 Diffusion-DPO 的 -distance ELBO surrogate:
💡 Diffusion-KTO 的实用价值 — 工业场景大量 binary feedback(喜欢/不喜欢)远多于 paired comparison;KTO 让这部分数据可直接用。
4.5 MaPO (Hong et al. 2024, arXiv 2406.06424)
Margin-aware Preference Optimization for Aligning Diffusion Models without Reference。核心 idea:完全去掉 reference model——类似 LLM 的 SimPO 思想。
MaPO loss 同时优化两件事:
- Likelihood margin:(用 ELBO surrogate 估计)。
- Likelihood of preferred: 本身要高(防止"两边都降")。
其中 是 likelihood surrogate, 是 margin, 是 likelihood term 权重。
优势:
- 不需要 ref UNet:显存省一半(从 到 )。
- 解决 reference mismatch:当 fine-tune 到新风格(reference 与目标分布差距大)时 Diffusion-DPO 训练崩溃,MaPO 稳定。
- 训练快 15%(论文报告,5 domains 上验证)。
4.6 DPO 家族总览表
| 方法 | 需要 ref? | 偏好类型 | 显存 | 适用 |
|---|---|---|---|---|
| Diffusion-DPO (Wallace 2024) | ✅ | paired | 2x | 一般 alignment |
| D3PO (Yang 2024) | ✅ | paired or thumbs | 2x | 没 RM 时 |
| SPO (Liang 2024) | ✅ + step-RM | per-step paired | 2x + 小 step-RM | 想榨干 step 信号 |
| Diffusion-KTO (Li 2024) | ✅ | unpaired binary | 2x | 大量 thumbs 数据 |
| MaPO (Hong 2024) | ❌ | paired | 1x | 风格 fine-tune / 显存紧 |
§5 Flow-GRPO:Flow Matching 的 RL
5.1 为什么 Flow Matching 也要 post-training
SD3 / FLUX / Lumina 全部转向 Flow Matching(Rectified Flow),post-training 需求一样:
- 提升 GenEval / DPG 等组合性 benchmark(颜色、计数、空间关系)。
- 提升 OCR / 文字渲染准确率。
- 提升 prompt-image alignment(VLM judge)。
但 Flow Matching 是确定性 ODE(),DDPO/DPOK 假设的 stochastic transition 不存在——直接套 RL 框架会失败。
5.2 Flow-GRPO 的两个核心 trick
Liu et al. 2025 Flow-GRPO: Training Flow Matching Models via Online RL(arXiv 2505.05470)解决了 Flow + RL 的两个根本问题:
Trick 1:ODE → SDE 等价转换
对 Rectified Flow 的 ODE ,构造一个等价的 SDE:
关键性质(Song et al. 2021 score SDE 框架):这条 SDE 的 marginal 与原 ODE 完全相同。区别是 SDE 提供了随机探索( 噪声项),让 RL 可以 sample 不同 trajectory。
对 Flow Matching,(在 Gaussian path 下),可以从 推得 score。把 设为 schedule(典型 ),就得到 Flow-GRPO 训练用的 SDE sampler。
💡 物理意义 — 加 让粒子在 marginal 不变的前提下"抖动"出多条 trajectory,于是同一 prompt 的 次 sample 是真正不同的 → GRPO 的组内统计可算。
Trick 2:Denoising reduction
GRPO 需要 sample 一组 个 trajectory, 典型 16–32。Flow Matching 推理一般 25–50 步,训练时 sample 一次 次 forward,太贵。
Flow-GRPO 训练时用 fewer steps(如 10 步),推理时仍用 25–50 步。SDE 在 schedule 上更均匀,少步训练的"探索质量"够用。具体地:
实测在 GenEval / OCR / Aesthetic 上不掉点。
5.3 Flow-GRPO 的 advantage 计算
和 GRPO for LLM 完全平行——对同一 prompt sample 个 final image ,每个打 reward ,组内归一化:
整条 trajectory 内所有 step 共享 (同 LLM GRPO 的 per-token 共享)。
5.4 Flow-GRPO 的 loss
记 SDE Euler step 的 transition log-prob (Gaussian),importance ratio ,PPO-clip:
KL 仍用 K3 estimator(同 GRPO for LLM)。
5.5 vector field 的 advantage 几何意义
✅ L3 级理解 —
- LLM GRPO 的 advantage 在 token logit 空间上做 reweight;
- Flow-GRPO 的 advantage 直接 reweight 的方向修正——具体地, 时把 推向 trajectory 实际经过的方向 。
- 这是 空间的"方向梯度",等价于在 Gaussian path 下的 -prediction 重要性加权。
5.6 Flow-GRPO 实测结果
论文报告 SD3.5-M 上:
| Benchmark | SD3.5-M base | Flow-GRPO |
|---|---|---|
| GenEval overall | 63% | 95% |
| Visual text rendering | 59% | 92% |
| Aesthetic (Schuhmann) | 5.8 | 6.1 |
⚠️ GenEval 95% 看起来过于完美 — 论文确实主张这个数字,但需注意 GenEval 测的是规则可验证的对象计数/颜色/空间关系,本身就是 RL 友好任务(reward 极规则化)。在更主观的 PartiPrompt / DPG 上涨幅是 5–10 点,更现实。
§6 Code Patterns(可读伪代码)
6.1 DDPO REINFORCE-style update
import torch import torch.nn.functional as F def ddpo_step(unet, ref_unet, scheduler, prompts, reward_fn, T=20, B=4, lr=1e-5, beta=0.0): """ DDPO-SF 一步训练(REINFORCE + 可选 KL anchor)。 prompts: list of B text prompts reward_fn: callable (x0_batch, prompts) -> [B] scalar """ # ── 1. Rollout: sample G=B trajectories ── x = torch.randn(B, 4, 64, 64, device=device) traj_log_probs = [] with torch.set_grad_enabled(False): # rollout 不需要梯度 x_t = x for t in reversed(range(T)): # predict noise + sample x_{t-1} eps_pred = unet(x_t, t, prompts) mean, std = scheduler.step_mean_std(x_t, eps_pred, t) x_tm1 = mean + std * torch.randn_like(mean) # stochastic transition traj_log_probs.append((mean.detach(), std.detach(), x_tm1.detach())) x_t = x_tm1 x_0 = x_t # ── 2. Reward ── R = reward_fn(x_0, prompts) # [B] A = (R - R.mean()) / (R.std() + 1e-8) # batch baseline # ── 3. Policy gradient: 重新 forward 取 log p_θ ── x_t = x.detach() loss_pg = 0.0 for t, (mean_old, std_old, x_tm1) in zip(reversed(range(T)), traj_log_probs): eps_pred = unet(x_t, t, prompts) # 要梯度 mean, std = scheduler.step_mean_std(x_t, eps_pred, t) # Gaussian log-prob log_p = -0.5 * (((x_tm1 - mean) / std) ** 2).sum([1, 2, 3]) log_p -= std.log().sum([1, 2, 3]) loss_pg = loss_pg - (log_p * A).mean() # REINFORCE if beta > 0: ref_eps = ref_unet(x_t, t, prompts).detach() mean_ref, std_ref = scheduler.step_mean_std(x_t, ref_eps, t) # Gaussian-Gaussian KL closed form kl = ((mean - mean_ref) ** 2 / (2 * std_ref ** 2) + (std / std_ref) ** 2 / 2 - 0.5 - (std / std_ref).log()).sum([1, 2, 3]) loss_pg = loss_pg + beta * kl.mean() x_t = x_tm1.detach() return loss_pg
⚠️ DDPO 实现踩坑 —
- Rollout 用
set_grad_enabled(False),policy gradient pass 再开梯度,避免显存 。 - DDPM stochastic transition 是关键:DDIM 是 deterministic,没有 维度可优化,DDPO 必须用 DDPM 或 DDIM-eta=1。
- Batch baseline 比无 baseline 稳得多。
- LoRA 训而非 full fine-tune,否则 base 漂移很快。
6.2 Diffusion-DPO loss
def diffusion_dpo_loss(unet, ref_unet, scheduler, x0_w, x0_l, prompt_embeds, beta=2000.0): """ Diffusion-DPO (Wallace 2024) 单步训练。 x0_w, x0_l: [B, 4, H, W] preferred / dispreferred latents beta: 论文用 2000~5000(注意是 β·T 的合并系数,比 LLM DPO 大) """ B = x0_w.shape[0] t = torch.randint(0, scheduler.num_train_timesteps, (B,), device=x0_w.device) noise = torch.randn_like(x0_w) # paired noise! xt_w = scheduler.add_noise(x0_w, noise, t) xt_l = scheduler.add_noise(x0_l, noise, t) # ── policy ε-prediction ── eps_w = unet(xt_w, t, prompt_embeds) eps_l = unet(xt_l, t, prompt_embeds) # ── reference ε-prediction (frozen) ── with torch.no_grad(): ref_eps_w = ref_unet(xt_w, t, prompt_embeds) ref_eps_l = ref_unet(xt_l, t, prompt_embeds) # ── ELBO surrogate: -‖ε - ε_θ‖² 是 log p_θ 的代理 ── err_w_pol = ((noise - eps_w) ** 2).mean([1, 2, 3]) # [B] err_w_ref = ((noise - ref_eps_w) ** 2).mean([1, 2, 3]) err_l_pol = ((noise - eps_l) ** 2).mean([1, 2, 3]) err_l_ref = ((noise - ref_eps_l) ** 2).mean([1, 2, 3]) # DPO log-ratio: smaller err = better likelihood # log(π_θ/π_ref)(y_w) ≈ -(err_w_pol - err_w_ref) diff_w = -(err_w_pol - err_w_ref) diff_l = -(err_l_pol - err_l_ref) inner = beta * (diff_w - diff_l) loss = -F.logsigmoid(inner).mean() with torch.no_grad(): margin = inner.mean() accuracy = (inner > 0).float().mean() return loss, {"margin": margin.item(), "acc": accuracy.item()}
⚠️ β 量级注意 — Diffusion-DPO 的 比 LLM DPO 大几个数量级,因为它吸收了 倍的累积项( 才是真正的"温度")。论文用 ;LLM DPO 用 。
6.3 AlignProp / DRaFT 反传 with checkpointing
def alignprop_step(unet_lora, scheduler, prompts, reward_fn, T=50, K=1, B=4, lr=1e-5): """ DRaFT-K / AlignProp 一步训练。 K: 最后 K 步保留梯度 显存 O(K),K=1 时与 SDXL 单步 forward 同量级 """ x = torch.randn(B, 4, 64, 64, device=device) # ── 前 T - K 步无梯度 ── with torch.no_grad(): for t in reversed(range(K, T)): eps = unet_lora(x, t, prompts) x = scheduler.step_ddim(x, eps, t) # deterministic DDIM # ── 最后 K 步要梯度 ── for t in reversed(range(K)): eps = unet_lora(x, t, prompts) # gradient ON x = scheduler.step_ddim(x, eps, t) x_0 = x # ── 反传 ── reward = reward_fn(x_0, prompts) # [B] loss = -reward.mean() # 最大化 reward = 最小化 -reward return loss # 显存分析: # K=1: ~24 GB on SDXL (single forward + grad) # K=5: ~60 GB # K=10: ~120 GB (需要 multi-GPU) # K=T=50: ~600 GB (完全不可行)
💡 K=1 已经够用? — 是的。直觉:最后一步 对 的影响最大(前面 49 步的方差被压缩),所以反传 1 步的信号已经主导。Clark 2024 也实测 与 差距极小。
6.4 SPO step-aware preference loss
def spo_loss(unet, ref_unet, scheduler, step_rm, x_t, t, prompt_embeds, beta=500.0): """ SPO (Liang 2024) in-step preference. 给定 x_t 和 t,独立采两个 x_{t-1},让 step_rm 判断 winner. """ # ── 1. 用 policy 采两个 x_{t-1} candidate(采样过程必须 no_grad,否则后续 DPO log-prob 会传梯度回到 sample)── with torch.no_grad(): eps_sample = unet(x_t, t, prompt_embeds) mean_s, std_s = scheduler.step_mean_std(x_t, eps_sample, t) noise_a, noise_b = torch.randn_like(mean_s), torch.randn_like(mean_s) x_a = mean_s + std_s * noise_a x_b = mean_s + std_s * noise_b # ── 2. step-wise reward model 判断 winner ── with torch.no_grad(): r_a = step_rm(x_a, x_t, t, prompt_embeds) # [B] r_b = step_rm(x_b, x_t, t, prompt_embeds) winner = (r_a > r_b).long() # [B], 1 if a wins x_w = torch.where(winner.bool()[:, None, None, None], x_a, x_b).detach() x_l = torch.where(winner.bool()[:, None, None, None], x_b, x_a).detach() # ── 3. compute log p_θ / log p_ref 对 x_w, x_l(grad-aware forward)── eps = unet(x_t, t, prompt_embeds) mean, std = scheduler.step_mean_std(x_t, eps, t) log_p_w = -0.5 * ((x_w - mean) / std).pow(2).sum([1, 2, 3]) log_p_l = -0.5 * ((x_l - mean) / std).pow(2).sum([1, 2, 3]) with torch.no_grad(): ref_eps = ref_unet(x_t, t, prompt_embeds) ref_mean, ref_std = scheduler.step_mean_std(x_t, ref_eps, t) log_pref_w = -0.5 * ((x_w - ref_mean) / ref_std).pow(2).sum([1, 2, 3]) log_pref_l = -0.5 * ((x_l - ref_mean) / ref_std).pow(2).sum([1, 2, 3]) inner = beta * ((log_p_w - log_pref_w) - (log_p_l - log_pref_l)) return -F.logsigmoid(inner).mean()
6.5 Flow-GRPO group-relative advantage
def flow_grpo_step(flow_net, ref_flow, prompts, reward_fn, G=16, T_train=10, sigma_fn=lambda t: (1 - t) ** 0.5, eps_clip=0.2, beta=0.04): """ Flow-GRPO 一步训练。 G: 每个 prompt sample G 个 trajectory. T_train: 训练用 SDE 步数(推理时另外用 28-50 步). """ P = len(prompts) # 每个 prompt 重复 G 次 prompts_rep = sum([[p] * G for p in prompts], []) # [P*G] # ── 1. SDE rollout: ODE→SDE 等价转换 ── x_t = torch.randn(P * G, 4, 64, 64, device=device) log_probs_old = [] # for PPO importance ratio trajectory = [x_t.clone()] with torch.no_grad(): for i in range(T_train): t_now = 1.0 - i / T_train t_next = 1.0 - (i + 1) / T_train dt = t_next - t_now sigma = sigma_fn(t_now) v = flow_net(x_t, t_now, prompts_rep) # SDE Euler: drift = v + 0.5 σ² ∇log p (PF-ODE → SDE 转换, Song 2021) # !!! 重要:以下 drift 是简化教学版(placeholder),生产实现要按 Flow-GRPO 论文 Eq.(6) # 正确地从 score = (data_pred - x_t)/σ_t² 推导,包含具体 Rectified Flow / EDM schedule. # 真实部署请参考论文 + 官方 repo;此处 -v/σ 仅作 illustrative. drift = v + 0.5 * sigma ** 2 * (-v / (sigma + 1e-6)) # placeholder, see paper Eq.(6) noise = torch.randn_like(x_t) x_next = x_t + drift * dt + sigma * noise * abs(dt) ** 0.5 # Gaussian log-prob (transition) mean = x_t + drift * dt std = sigma * abs(dt) ** 0.5 log_p = -0.5 * ((x_next - mean) / std).pow(2).sum([1, 2, 3]) log_probs_old.append(log_p) x_t = x_next trajectory.append(x_t.clone()) x_0 = x_t # ── 2. Group-relative advantage ── R = reward_fn(x_0, prompts_rep) # [P*G] R = R.view(P, G) mean_R = R.mean(dim=1, keepdim=True) std_R = R.std(dim=1, keepdim=True) + 1e-8 A = ((R - mean_R) / std_R).view(P * G) # [P*G] # ── 3. PPO-clip loss with KL ── loss = 0.0 x_t = trajectory[0] for i in range(T_train): t_now = 1.0 - i / T_train v = flow_net(x_t, t_now, prompts_rep) # grad ON sigma = sigma_fn(t_now) drift = v + 0.5 * sigma ** 2 * (-v / (sigma + 1e-6)) dt = -1.0 / T_train mean = x_t + drift * dt std = sigma * abs(dt) ** 0.5 log_p_new = -0.5 * ((trajectory[i+1] - mean) / std).pow(2).sum([1, 2, 3]) ratio = (log_p_new - log_probs_old[i]).exp() surr1 = ratio * A surr2 = ratio.clamp(1 - eps_clip, 1 + eps_clip) * A loss = loss - torch.min(surr1, surr2).mean() # K3 KL estimator with torch.no_grad(): v_ref = ref_flow(x_t, t_now, prompts_rep) drift_ref = v_ref + 0.5 * sigma ** 2 * (-v_ref / (sigma + 1e-6)) mean_ref = x_t + drift_ref * dt log_p_ref = -0.5 * ((trajectory[i+1] - mean_ref) / std).pow(2).sum([1,2,3]) delta = log_p_ref - log_p_new kl_k3 = (delta.exp() - delta - 1) loss = loss + beta * kl_k3.mean() x_t = trajectory[i + 1].detach() return loss
6.6 Combined reward signal
def combined_reward(images, prompts, weights=None): """ 多 reward 加权组合 — 缓解单 RM hacking. """ weights = weights or {"image_reward": 0.4, "hps_v2": 0.3, "pickscore": 0.2, "clip_score": 0.1} rewards = {} rewards["image_reward"] = image_reward_model(images, prompts) # [-1, 4] rewards["hps_v2"] = hps_v2(images, prompts) # [0, 1] rewards["pickscore"] = pickscore(images, prompts) # logits rewards["clip_score"] = clip_cosine(images, prompts) # [-1, 1] # ── 各自 z-score 归一化(不同 reward scale 差异巨大)── normed = {k: (v - v.mean()) / (v.std() + 1e-8) for k, v in rewards.items()} # ── 加权 + length / safety penalty ── R = sum(weights[k] * normed[k] for k in weights) # NSFW penalty (rule-based) nsfw_score = nsfw_detector(images) # [0, 1] R = R - 5.0 * nsfw_score return R
⚠️ 多 reward 实操经验 —
- 每个 reward 单独 z-score:尺度差异巨大(HPSv2 ~0.25, ImageReward ~1.5, CLIP-Score ~0.3),不归一化等于让 ImageReward 主导。
- min 比 mean 更稳:
R = min(normed.values())能强制所有 RM 都满意,hacking 风险显著降低(reward ensemble 经典策略)。 - 保留 rule-based safety override:NSFW / 政治敏感 / 版权 reward 不能被 RL 优化掉。
§7 Reward Design & 失败模式
7.1 Reward model 选择
| RM | 来源 | 数据 | scale | 偏好特点 |
|---|---|---|---|---|
| CLIP-Score | OpenAI/LAION | 4B image-text pair | cosine | text-image alignment 弱信号;倾向 caption 字面匹配 |
| ImageReward (Xu 2023 NeurIPS) | 137K human pair | 真实 prompt | aesthetic + alignment 综合;偏好高对比度 | |
| HPSv2 (Wu 2023 arXiv 2306.09341) | 798K human pair | DiffusionDB-style | 综合 human preference;偏好饱和颜色 | |
| PickScore (Kirstain 2023 NeurIPS) | Pick-a-Pic 1M pair | 真实用户 | logits | 综合;倾向 trained-on-SDXL 风格 |
| PiCaR (rule) | OpenAI | counting/OCR | binary | rule-based, 不可 hack |
7.2 Reward hacking gallery(diffusion 特色)
| 现象 | 视觉特征 | 原因 |
|---|---|---|
| Over-saturation | 颜色饱和度 >100% | HPSv2 / aesthetic 偏好鲜艳 |
| Center bias | 主体永远居中 | RM 训练数据多为 centered subject |
| Monotone composition | 不同 prompt 都用同一构图 | mode collapse to RM 高分 mode |
| Tryphobia-like patterns | 密集点状/孔状纹理 | 某些 RM 偏好"texture richness" |
| Watermark hallucination | 角落出现 fake watermark | RM 训练数据含水印 → 学到"水印 = 真照片" |
| Cartoon shift | 真实风格 prompt 输出动漫 | RM 标注者偏好 anime |
| Lighting overcooked | 后期 HDR 过强 | aesthetic predictor 偏好后期重 |
7.3 Step-level vs trajectory-level reward
| 维度 | Trajectory-level | Step-level |
|---|---|---|
| 信号位置 | 只在 | 每个 都有 |
| 数据获取 | 易(一张图) | 难(需要 step-wise RM 或 rollout) |
| 学习效率 | 低(稀疏) | 高(dense) |
| 代表 | DDPO, Diffusion-DPO | SPO (Liang 2024) |
| 工程难度 | 低 | 高(要么训 step-RM,要么 PRM-shepherd 式 rollout) |
💡 step-RM 怎么训 — SPO 用一个 "given at step , is a good transition?" 的 binary RM。训练数据:从 base UNet 跑多条 trajectory,用最终 的 reward 反推每步的 step-reward (类似 Math-Shepherd 的 rollout-based PRM)。
7.4 缓解 reward hacking 的核心机制
- Reward ensemble:多 RM 取 min 或 mean(HPSv2 + PickScore + ImageReward 是主流组合)。
- KL anchor:DPO 的 、DPOK 的显式 KL、Flow-GRPO 的 K3 KL term。
- LoRA scale:full fine-tune 漂移快,LoRA scale 限制 reward hacking 上限。
- Early stop on reward plateau:reward 涨 + FID 涨 = hacking 信号。
- Composite reward:rule-based (object count, OCR) + neural RM (aesthetic, alignment) 加权。
- Adversarial RM:训 RM 时加 hacking 样本作为 negative。
§8 Production Landscape:SD3 / FLUX 用了什么
8.1 公开论文 / 报告说了什么
| 模型 | Post-training? | 公开内容 |
|---|---|---|
| SD 1.5 | 部分社区 DPO / DDPO LoRA | base 是纯 LDM;社区 fine-tune 多 |
| SDXL | Stability AI 没明确 post-training | base + refiner; Pick-a-Pic + Diffusion-DPO 社区 LoRA 流行 |
| SDXL Turbo / ADD | 蒸馏为主 | Adversarial Diffusion Distillation (2311.17042);本质是 1-step distill,不属 RL post-training |
| SD3 (Stable Diffusion 3, Esser et al. 2024 ICML) | base 用 Rectified Flow + MM-DiT | 论文未公开 post-training;社区猜测有内部 DPO |
| SD3.5 / SD3.5 Turbo | 有 distill,post-training 未公开 | 推测有 DPO + distill 混合 |
| FLUX.1 dev / pro (Black Forest Labs 2024) | 未公开 | 社区猜测 DPO + distill;pro 走 API 闭源 |
| DALL-E 3 (OpenAI 2023) | "recaptioning + RLHF" | 公开报告强调 prompt-faithful RLHF |
| Imagen 3 (Google 2024) | 未公开 | 内部 alignment 流程 |
| DeepFloyd IF | 无 post-training | 学术 base model |
8.2 SD3 / FLUX 是否用了 post-training?
⚠️ 诚实回答 — 公开论文 / 技术报告都没有明说用 RL / DPO post-training。但有以下间接证据:
- SD3 论文 (arXiv 2403.03206) 的 "Improving Rectified Flow Transformers" 章节讨论 sampling + reflow,没提 reward fine-tune。
- FLUX 完全没发论文,社区从 model card 推测有 distillation(FLUX schnell 是 4-step 蒸馏版)。
- Stability AI 在 SD3.5-Large 发布时提到 "fine-tuned with improved aesthetics",可能是 SFT 而非 RL。
- DALL-E 3 论文 (OpenAI 2023) 明确说用了 caption-faithful RLHF。
业界共识(来自 HuggingFace 社区 + Reddit r/StableDiffusion):闭源大模型(FLUX pro, DALL-E 3, Midjourney v6+)有 reward-based fine-tune,但具体方法不公开;开源 base(SD3.5 base, FLUX dev base)公开训练 pipeline 不含 RL,但 Stability AI 内部 dev 版可能有。
8.3 工业级 pipeline 假说
┌─────────────────┐
│ LDM Pretrain │ 几百 M / B images, $L_simple$
└────────┬────────┘
│
┌────────▼────────┐
│ SFT on Curated │ 高质量 prompt-image pair
│ dataset │ (Aesthetic > 6.0, no watermark)
└────────┬────────┘
│
┌────────────────┼────────────────┐
│ │
┌────────▼────────┐ ┌─────────▼────────┐
│ Diffusion-DPO │ │ DRaFT / AlignProp│
│ on Pick-a-Pic │ │ on multi-RM │
└────────┬────────┘ └─────────┬────────┘
│ │
└────────────────┬─────────────────┘
│
┌────────▼────────┐
│ Distillation │ 4-step / 1-step turbo
│ (ADD / LCM) │
└────────┬────────┘
│
Production
💡 结论 — Post-training 大概率发生在"SFT → distill"之间;具体方法工业界倾向 Diffusion-DPO(offline、稳定、不需要 sample),DDPO/DPOK 学术影响大但工程部署少。
§9 vs LLM RLHF 对比
9.1 一表看完
| 维度 | LLM RLHF (RLHF + DPO + GRPO) | Diffusion Post-Training |
|---|---|---|
| 轨迹 | 个 token | 个 denoising step |
| 动作空间 | 离散 vocab | 连续 |
| Reward 来源 | trained BT-RM / rule (math, code) | trained image RM (HPSv2/PickScore/ImageReward) / rule (count, OCR) |
| Reward 稀疏度 | terminal only (response 末尾) | terminal only () |
| On-policy 成本 | 次 forward | 次 forward + image RM forward |
| Offline 方法 | DPO / IPO / KTO / SimPO / ORPO | Diffusion-DPO / D3PO / SPO / KTO / MaPO |
| On-policy 方法 | PPO / GRPO / RLOO | DDPO / DPOK / Flow-GRPO |
| 直接 reward 反传 | ❌(token 不可导) | ✅(DRaFT / AlignProp / ReFL) |
| 显存瓶颈 | 4 副本 (policy + ref + RM + V) | 1 副本(DPO)/ (DRaFT-K)/ (vanilla backprop) |
| 典型 | (吸收 倍系数) | |
| 典型 trajectory length | token | – step |
| Mode collapse 严重度 | 中(vocab 大) | 高(连续空间易陷局部 mode) |
| Reward hacking 难度 | 中(依赖 RM 质量) | 高(视觉 RM 比 BT-RM 更易被 hack) |
9.2 共同 lesson
- KL anchor 是必须的:无 ref policy 的纯 RL 一定 reward hack(LLM 是变长无内容,diffusion 是过饱和单一构图)。
- DPO 家族 >> on-policy RL(在工程性上):no sampling, no value model, offline——LLM 和 diffusion 都成立。
- Reward ensemble 反 hacking:min-of-K RMs 是两个领域通用的缓解。
- Group-based advantage:LLM 的 GRPO/RLOO 和 diffusion 的 Flow-GRPO 都通过组内统计绕过 value model。
9.3 独有差异
- Diffusion 有"反传"选项:reward 可导让 DRaFT/AlignProp 成立——LLM 因为 sampling 是离散的没有对应方法。
- Diffusion 有 "step-aware" preference:denoising step 有明确语义(高噪管构图、低噪管细节),SPO 利用了这点;LLM token 没有这种自然分层。
- Diffusion 的 scale 大 1000x:因为 ELBO surrogate 吸收了 倍 trajectory term。
§10 25 高频面试题
按难度分 3 档:L1 = 多模态/diffusion 岗常问;L2 = research/alignment 方向会问;L3 = 顶级 lab 的硬核题。
L1 必会题(10 题)
Q1. 为什么 diffusion 模型需要 post-training?SFT 不够吗?
- SFT 只能模仿正例("做得好的样子"),学不到对比信号(A 比 B 好)。
- Post-training 通过 reward / preference 提供对比信号,让模型在 alignment、aesthetic、prompt-faithful 维度都涨。
- 实测 Diffusion-DPO 在 PickScore 上 +5-10 点,远超继续 SFT。
只说"提升画质"是浅;要说清"对比信号 vs 模仿信号"的差异。
Q2. DDPO 把 diffusion 当成什么 MDP?state/action/reward 怎么定义?
- State:
- Action: (从 采)
- Transition: 确定性
- Reward: for ,(terminal-only)
说成"per-step reward"(错,只在终态);或不知道 transition 是确定性的(noise 是 action 自带的)。
Q3. Diffusion-DPO 用什么代替 $\log \pi_\theta(y|x)$?
- 用 ELBO surrogate:(DDPM 的 )作为 的代理。
- 这是 的(negative)下界项,方向正确。
- 配上 paired noise ( 和 共享同一 )才稳。
说用 解析式(错,diffusion 没闭式);忘记 paired noise。
Q4. AlignProp 和 DRaFT 的核心 idea?显存为什么是 $\mathcal{O}(K)$?
- 核心:reward 可导 → 直接对 反传,跳过 RL。
- 步 sampler 是 differentiable computation graph,vanilla 反传需存 步 activation → 。
- DRaFT-K / AlignProp:前 步用
no_grad,只在最后 步保留梯度,显存压到 。 - 典型 已能给强信号。
说 K=1 等于 REINFORCE(错,K=1 是 reparameterized gradient,方差远低于 REINFORCE)。
Q5. 为什么 Diffusion-DPO 的 $\beta$ 比 LLM DPO 大 1000 倍?
- LLM DPO:
- Diffusion-DPO:
- 原因:diffusion 的"trajectory log-likelihood"是 个 Gaussian log-prob 之和,单步 距离差吸收了 倍系数。实际有效温度是 。
- 也有 implementation 把 显式分离,那时 看起来与 LLM 同量级。
说"diffusion 噪声大所以 β 大"(错,是 trajectory 长度的累计效应)。
Q6. ImageReward / HPSv2 / PickScore 三者区别?
| ImageReward | HPSv2 | PickScore | |
|---|---|---|---|
| 数据规模 | 137K pair | 798K pair | 1M pair (Pick-a-Pic) |
| backbone | BLIP fine-tuned | CLIP fine-tuned | CLIP fine-tuned |
| scale | logits | ||
| 偏好 | aesthetic + alignment | 高对比度 + alignment | SDXL 风格 |
工业上取 ensemble(最少两个)。
说三者都一样(错,scale 和偏好差异大)。
Q7. DDPO 用 DDPM 还是 DDIM 采样?为什么?
- DDPM(或 DDIM-eta=1)—— 需要 stochastic transition。
- DDIM-eta=0 是 deterministic,没有 noise term,没有 action 可优化 → policy gradient 等于 0。
- 类比:LLM RL 必须用 sampling(temperature > 0),不能用 greedy.
说 DDIM 也行(错,要 eta > 0);不知道 stochasticity 是 RL 前提。
Q8. Reward hacking 在 diffusion 上典型症状有哪些?
- Over-saturation(颜色饱和度暴增)—— HPSv2/aesthetic 偏好鲜艳。
- Center bias(主体永远居中)—— RM 训练数据偏 centered。
- Monotone composition(不同 prompt 同一构图)—— mode collapse。
- Watermark hallucination(角落 fake 水印)—— RM 训练数据含水印。
- Cartoon shift(写实 prompt 输出 anime)—— RM 标注者偏好。
只说"过度优化"不具体;要能举至少 3 种具体视觉症状。
Q9. Flow-GRPO 的 ODE→SDE 转换为什么必要?
- Flow Matching 的 ODE 是确定性的,给定 → 唯一。
- RL 需要 stochastic policy 来 explore;ODE 没有 sampling 维度。
- ODE→SDE 加 噪声项,marginal 不变(Anderson 1982),但每次 sample 路径不同 → 可 explore。
不知道 marginal 不变(错,会以为 SDE 改变了 distribution)。
Q10. Diffusion-DPO 训练时 $y_w$ 和 $y_l$ 的 noise 怎么处理?
- paired noise: 和 用同一个 (即 , 同理用同一 )。
- 不 paired 时 的尺度不再可比,loss 方差大幅上升,训练不稳。
- 这是 Diffusion-DPO 最容易忽视的实现细节。
不知道 paired noise(错);或以为 是 的预测(错,这里 是 q-sample 的 noise)。
L2 进阶题(10 题)
Q11. 推导 Diffusion-DPO loss(从 KL-regularized 最优解出发)。
- KL-regularized 目标:,最优解 。
- 反解 implicit reward:。
- 代入 BT:; 在差中消掉。
- 替换 ; 用 ELBO surrogate:(在 处)。
- 期望对 取,loss 变成 ,。
直接背公式答不上来 为什么消掉;或不知道 ELBO surrogate 的来源。
Q12. AlignProp 反传 $K$ 步显存 vs 性能怎么 trade-off?
- 显存:。SDXL 单 forward 8 GB activation; GB(含 weights + grad); GB; GB。
- 性能: 实测已达 的 95%; 在大多数 reward 上无显著提升。
- 直觉:最后一步 对终态影响最大,前面 49 步的方差被压缩。
- 工业上 是标准选择(24GB 单卡可训)。
只说" 越大越好"(错,性能曲线 saturate);不知道显存量级。
Q13. DDPO 用 REINFORCE 和 PPO 区别?哪个 prod 常用?
- DDPO-SF (REINFORCE):,简单但方差大。
- DDPO-IS (PPO-clip):用 importance ratio ,多次 update 同 batch,clip 。
- per-step ratio 而非 trajectory ratio(避免 个 ratio 累乘的方差爆炸)。
- Prod 常用 PPO 形式:稳一些,sample efficiency 更高。
说"trajectory-level ratio"(错,per-step);或不知道两个都是 DDPO。
Q14. SPO 怎么得到 in-step preference pair?为什么需要 step-RM?
- In-step:给定 ,独立采两个 (用 policy 的 stochastic transition 采两次)。
- 用step-wise reward model 判 winner。
- step-RM 训练数据:base UNet rollout 多 trajectory,每步的 step-reward 由终态 reward 反推(类似 Math-Shepherd 的 rollout-based PRM)。
- 不用 step-RM 用终态 RM 也行,但要 rollout 到 才能打分,贵 倍。
不知道 in-step pair 怎么得(错,要采两次);或不知道 step-RM 是 SPO 独有。
Q15. Diffusion-DPO vs D3PO 实质差异?
- 推导路径:Diffusion-DPO 用 ELBO surrogate(单步 -distance),D3PO 用完整 trajectory log-ratio。
- 数学等价性:在 ELBO 下界 + 期望 over 下,D3PO 的 trajectory 形式退化为 Diffusion-DPO 的单步形式。
- 实践差异:
- Diffusion-DPO 每步只算一次 UNet forward(policy + ref),便宜。
- D3PO 严格意义上要算完整 trajectory 次 forward。
- 工业部署主流用 Diffusion-DPO(便宜 + 稳)。
说"完全不同"(错,理论等价);或不知道 D3PO 也是 DPO 家族。
Q16. Flow-GRPO 的 denoising reduction 是什么?为什么不掉点?
- 训练时 SDE 用少步(),推理时仍用全步(–)。
- 经验上不大掉点的理由(注意:这是经验观察 + approximation,不是严格等价):
- SDE 的 连续 marginal 与离散步数无关;但 离散 sampler 的实际分布 与 step 数有关——少步是 discretization-error 较大的近似。所以严格说 "same marginal" 只在 continuous limit 成立。
- RL 学的是 的方向修正,方向信号与具体步数耦合较弱(这是经验观察)。
- 在 GenEval/OCR 这类 rule-based reward 上不掉点;在更主观 reward 上略掉但可接受。
- 省 sample 成本:训练每 prompt 次 forward → 1/3 成本。
不知道 marginal 不变(错);或以为 train/infer 必须同步数。
Q17. MaPO 怎么去掉 reference model?loss 长什么样?
- 不用 ,直接用绝对 likelihood margin:
- 是 likelihood surrogate。
- 是 margin(类似 SimPO), 项防止"两边都降"。
- 显存省一半(无 ref UNet),训练快 15%,且解决 reference mismatch 问题(fine-tune 到风格差异大的目标时稳)。
说去 ref 就完事(错,要加 likelihood term 防 degenerate);不知道 reference mismatch。
Q18. Reward ensemble 为什么用 min 比 mean 好?
- mean:被一个高分 RM 主导可能仍 hack。
- min:要所有 RM 都同意"好"才给高 reward → hacking 必须同时骗过所有 RM,难度指数级上升。
- 等价于 conservative aggregation (Coste 2024 ICLR for LLM),diffusion 上同理。
- 代价:reward 偏保守,涨幅小。
- 工业上常用
R = mean - k * std(含 uncertainty penalty)作折中。
只说"防 hacking"不知道为啥 min;或不知道这是 LLM 也用的 ensemble 策略。
Q19. Diffusion-KTO 比 Diffusion-DPO 有什么独特优势?
- 只需 per-image binary feedback(thumbs up/down),不需要 paired comparison。
- 工业场景大量用户 reaction(喜欢/不喜欢)远多于 paired comparison → KTO 让这部分数据可用。
- prospect-theoretic 价值函数 对正负 feedback 不对称(loss aversion)。
- 不需要"哪个更好"的标注成本。
不知道 KTO 是 unpaired(错,这是 KTO 全部 idea);或不知道 prospect theory 来源。
Q20. 为什么 diffusion 没有 token-level KL anchor,而是 trajectory-level?
- LLM 的 KL 是 per-token:。
- Diffusion 的 KL 是 per-step(per-denoising-step),不是 per-pixel:。
- 两个 Gaussian KL 有闭式:。
- 像素之间不独立(卷积/attention),所以 KL 是整张图 level 而非 per-pixel。
说"per-pixel KL"(错,per-step);不知道 Gaussian KL 闭式。
L3 顶级 lab 题(5 题)
Q21. 推 Diffusion-DPO loss 从 reverse ELBO 出发,说清 ELBO surrogate 为何有效。
- DDPM ELBO:
- 化简(Ho 2020):,。
- KL-regularized 最优 ,反解 。
- 代入 BT, 消掉。
- 用 ELBO surrogate 代 :(注意:这是上界的取负,作为单 sample 估计 — 严格意义上是 lower bound 的一个项,而非 本身,但作为 DPO 的 implicit reward proxy 数值有效)。
- 期望对 取,得到最终 loss。
为什么 ELBO surrogate 有效的更深一层:DPO 的 implicit reward 是 ,它只依赖相对 likelihood。ELBO surrogate 的常数项()在 和 之间相消(两个模型用同一架构),只剩 的差。所以即使 ELBO 不是 的紧 bound,差异是可消的。
只能写出最终公式背不出推导链;或不知道常数项相消是关键。
Q22. AlignProp 反传 $K$ 步显存 $\mathcal{O}(K)$ 是否真的无法绕过?
理论上可以,工程上很贵:
- Gradient checkpointing:把 activation 的存储换成重算。每步 forward 不存 activation,反传时重新 forward 算 grad。
- 显存:从 降到 + 。
- 代价:反传速度慢 2-3x。
- Reversible ResNet:如果 UNet 用 reversible 架构(i-RevNet 风格),反传时从 output 反推 input,不存 activation。
- 但 Stable Diffusion / SDXL UNet 不是 reversible。
- Implicit gradient:通过 fixed-point 假设把 写成 implicit function theorem。
- 需要 sampler 收敛到 fixed point,diffusion 不满足。
- Truncated backprop with control variates:DRaFT-K 已是这个方向;理论上加 control variates 可进一步降方差但不降内存。
实践答案: + gradient checkpointing + LoRA 是工程最优解。 不可绕过的本质是 — sampler 不是 reversible computation。
只说 gradient checkpointing 不到位;不知道 reversibility 假设。
Q23. Flow-GRPO 中 vector field $v_\theta$ 的 advantage 几何意义?
GRPO 的 advantage 在 vector field 空间作用如下:
- Group statistics:对同一 prompt sample 条 SDE trajectory,每条得到不同 ;reward 给整条 trajectory 同一 advantage 。
- 沿 trajectory 的梯度:。在 Gaussian transition 下,,所以 。
- 的物理含义:在 Flow Matching SDE 下,;(忽略 score 项)。
- 几何意义:advantage 时,把 朝 方向推(即 trajectory 实际经过的方向);advantage 时,朝相反方向推。
- vs ODE 视角:等价于在 vector field 空间做"组相对方向 reweight"——好的 trajectory 让 在那个 上指向它经过的方向,坏的反之。
这是 vector field 上的 "reward-weighted importance sampling":每条 SDE trajectory 是 的一次"提议方向",advantage 决定要不要 follow。
完全说不出几何就 0 分;说"reweighting"但不能说清在哪个空间也只值半分。
Q24. SD3 / FLUX 是否真的用了 RL post-training?怎么判断?
诚实回答:公开论文 / 技术报告都没明说用 RL / DPO。但有以下线索:
- SD3 论文 (arXiv 2403.03206):只讨论 Rectified Flow + MM-DiT + reflow;没提 reward fine-tune。
- FLUX:完全没发论文,model card 只提"trained on a large image-text dataset"。
- DALL-E 3 (OpenAI 2023):明确说用了 caption-faithful RLHF(rewrite caption + RM)。
- 业界共识:闭源大模型(FLUX pro, DALL-E 3, Midjourney v6+)几乎确定有 reward-based fine-tune,但具体方法不公开。
判断标准(black-box test):
- 给同一 prompt 让模型生成 100 张,FID-100 / multi-mode 多样性低 → 可能是 RL/DPO(mode collapse 信号)。
- prompt-image alignment 在 GenEval 高分但 portrait 风格单一 → reward over-optimization 信号。
- 同一 model 对 "vibrant"/"colorful" prompt 反应过强 → HPSv2/aesthetic RM 痕迹。
结论:FLUX 大概率有内部 DPO + distill 混合;SD3.5 推测有 SFT + 可能的 DPO。但没有公开证据——这道题的关键是答出"不公开但有间接证据",避免胡编技术细节。
如果直接答"SD3 用了 Diffusion-DPO"是错的(论文没说);要答"未公开但社区推测 + 列举证据"。
Q25. 如果让你设计一个 diffusion post-training pipeline,从 $0$ 开始,你怎么选?
取决于约束。给一个 generic 推荐:
Phase 1: 偏好数据收集
- 收集 paired preference (Pick-a-Pic 风格):成本高但 DPO 直接可用。
- 收集 binary feedback (thumbs up/down):成本低,用 Diffusion-KTO。
- 收集 rule-based ground truth (GenEval 类型 prompt + 自动 verifier):成本低,用 Flow-GRPO。
Phase 2: 算法选择
- 首选 Diffusion-DPO:offline、稳、便宜、社区代码成熟(HuggingFace
diffusers直接支持)。 - 如果 base 是 Flow Matching (SD3/FLUX):用 Flow-GRPO,rule-based reward 优先。
- 如果 fine-tune 到新风格 / 显存紧:用 MaPO(去 ref,省一半显存)。
- 如果 reward 可导且想榨干信号:DRaFT-1 + LoRA,配 HPSv2 + PickScore ensemble。
- NOT 首选 DDPO:on-policy sampling 太贵,工程复杂度高,性能 vs DPO 无显著优势。
Phase 3: Reward 设计
- Multi-RM ensemble(min 或 mean - k·std):HPSv2 + PickScore + ImageReward。
- 加 rule-based safety:NSFW detector hard penalty。
- 加 rule-based alignment:GenEval 自动 verifier(object count, OCR)。
- 每个 RM 独立 z-score 归一化。
Phase 4: 监控与 early stop
- 每 N 步算 reward + FID-100k;reward 涨 + FID 涨 = hacking 信号。
- KL budget 监控: 时 stop。
- Human eval blind A/B (base vs RL) 每 1000 steps。
Phase 5: distill 衔接
- Post-training 完后做 ADD / LCM 蒸馏到 4-step / 1-step。
- 注意 distill 可能消除部分 RL 增益,需要 distill-aware 后训。
只答"用 Diffusion-DPO" 是浅;要答出"phase 分解 + 多 reward + 监控 + distill 衔接"才完整。
§A 附录
A.1 关键论文清单(含 arXiv ID)
| 论文 | 一句话 | arXiv | 发表 |
|---|---|---|---|
| DDPO | Diffusion 当 MDP,REINFORCE/PPO 训 | 2305.13301 | ICLR 2024 |
| DPOK | KL-regularized RL for diffusion | 2305.16381 | NeurIPS 2023 |
| DRaFT | 直接 reward 反传 步 | 2309.17400 | ICLR 2024 |
| AlignProp | reward backprop with randomized truncation | 2310.03739 | ICLR 2024 |
| ImageReward / ReFL | 137K human pair RM + 单步 reward fine-tune | 2304.05977 | NeurIPS 2023 |
| HPSv2 | 798K human pair RM | 2306.09341 | arXiv 2023 |
| PickScore (Pick-a-Pic) | 1M user pair, CLIP RM | 2305.01569 | NeurIPS 2023 |
| Diffusion-DPO | ELBO surrogate + DPO loss | 2311.12908 | CVPR 2024 |
| D3PO | trajectory-level DPO for diffusion | 2311.13231 | CVPR 2024 |
| SPO | step-aware preference + step-RM | 2406.04314 | arXiv 2024 |
| Diffusion-KTO | unpaired binary feedback (KTO for diffusion) | 2404.04465 | NeurIPS 2024 |
| MaPO | margin-aware, no ref | 2406.06424 | arXiv 2024 |
| Flow-GRPO | GRPO for Flow Matching via ODE→SDE | 2505.05470 | arXiv 2025 |
| SD3 (Rectified Flow + MM-DiT) | base model | 2403.03206 | ICML 2024 |
| Constitutional AI (RLAIF 起源) | AI feedback 替代 human | 2212.08073 | arXiv 2022 |
| KTO (LLM) | prospect theory alignment | 2402.01306 | arXiv 2024 |
A.2 常用 reward model 资源
- ImageReward:https://github.com/THUDM/ImageReward
- HPSv2:https://github.com/tgxs002/HPSv2
- PickScore:https://github.com/yuvalkirstain/PickScore
- CLIP:OpenAI / OpenCLIP,多 backbone 可选
A.3 开源训练代码
- TRL (HuggingFace):
diffusers+DPO Trainerfor Diffusion-DPO(最成熟) - DDPO 原始仓库:https://github.com/kvablack/ddpo-pytorch
- AlignProp:https://github.com/mihirp1998/AlignProp
- DRaFT (Google research):https://github.com/clarkjkr/draft(Clark et al. 2024 ICLR)
- MaPO:https://github.com/mapo-t2i/mapo
- Flow-GRPO:通过论文 arXiv 2505.05470 找官方实现
A.4 工程踩坑清单
| 坑 | 解 |
|---|---|
| Diffusion-DPO 没 paired noise | for 和 必须共享 |
| DDPO 用 DDIM-eta=0 | 必须 eta>0 或 DDPM,否则梯度为 0 |
| AlignProp 显存爆炸 | + gradient checkpoint + LoRA |
| Reward scale 不归一化 | 每个 RM 单独 z-score |
| RL 后 FID 暴跌 | 加 KL anchor 或 reward ensemble |
| 调不动 | Diffusion-DPO 用 ,不是 LLM 的 0.1 |
| Flow-GRPO 训练慢 | 用 denoising reduction () |
| MaPO 训崩 | 项必须够大防 likelihood 一起降 |
| Step-RM 训不起来 | 用 rollout-based 自动标注(类 Math-Shepherd) |
| reward hacking 检测不到 | 同时监控 reward + FID + human blind A/B |
A.5 与 §0 TL;DR 的呼应
| TL;DR 条 | 详见章节 |
|---|---|
| 1. 为什么难 | §1 |
| 2. 三条主线 | §1.2 |
| 3. DDPO | §2.1–2.4 |
| 4. DRaFT / AlignProp | §3.2–3.3 |
| 5. Diffusion-DPO | §4.1 |
| 6. D3PO | §4.2 |
| 7. SPO | §4.3 |
| 8. Flow-GRPO | §5 |
| 9. Reward hacking | §3.6 + §7 |
✅ 学完 checkpoint —
- 能口述 Diffusion-DPO loss 形式 + paired noise 细节
- 能解释 AlignProp 为什么 够用 + 显存
- 能写 DDPO 的 state/action/reward + per-step ratio
- 能讲 Flow-GRPO 的 ODE→SDE 转换为什么必要 + denoising reduction
- 知道 SD3/FLUX 是否用 RL 的诚实答案(公开未明说)