后 GRPO 时代:长 CoT 的爆发与“对齐”新挑战
当你第一次跑通 GRPO 的闭环,你会以为自己掌握了“无 Critic RL”的终极奥义:不用 Value 网络、不用重 RM 架构,只靠同题多采样的相对比较,就能把推理能力硬拔起来。
但当你把 CoT 从 512 token 拉到 10k+,当你把模型换成 MoE,再把 rollout 做成异步 off-policy……你会发现:
GRPO 不是“开始不稳定”,而是开始报复你——长度黑客、方差爆炸、路由崩溃、熵坍塌轮番上阵。
今天我们就按“拳谱”的方式,把 GRPO 之后最主流的改法拆到:
- 它想解决什么“原罪”(Motivation)
- 它在数学上动了哪一刀(Objective / 公式)
- 它为什么在工程里更稳(深度解析)
- 最小改动:你在现有 GRPO 代码里到底换哪几行 loss(Diff 清单)
贯穿全文的直观比喻:假设 Prompt 是一道 AIME 数学题:“求解某多项式的整数根”。
y_w(好回答 / Win):步骤不多,但关键推导全对,最后答案正确。(短、准、有效信息密度高)
y_l(坏回答 / Lose):输出 8000 token 的“深度思考”,但中间第 3 步开始就错了,后面全是建立在错误之上的长篇大论。(长、错、废话文学)
GRPO clip 家族交互图
0. 统一符号(后面所有算法都用这一套)
- 问题 / Prompt:
- 同一 下采样 个回答:
- 可验证终局奖励:(对/错、或规则打分)
- 旧策略(rollout/behavior):,新策略:
- token 级重要性比率:
- group advantage(常见 Z-score):
注:实际工程里还会加 KL/entropy 正则、length penalty、mask、packing 等,这里先剥离掉,只看“主刀”。
1. GRPO:无 Critic 的优雅,和两宗“原罪”(长度偏置 + 方差爆炸)
Motivation(核心动机)
Critic(Value)太费显存、太难训、太容易震荡?那就别猜 baseline 了——直接在同题多答案里比高下。
解法(GRPO 的核心目标)
先做 group advantage,再把一个序列级标量 “广播”到每个 token 上,用 PPO-style clip surrogate:
深度解析(为什么长 CoT 会把它逼疯)
- 长度偏置(Length Bias)
看似公平,实际上会导致“错而长”的轨迹被稀释惩罚:
- y_l 如果很长,每个 token 分到的负优势更小,模型反而学会“错也要长”。
(这点在 Dr.GRPO 的分析里被直接点名为 optimization bias。)
- 方差爆炸(Variance Explosion)
token 级 在长序列里会出现极端 outlier;clip 会频繁触发,更新变得“又硬又噪”。
MoE 还会把这种高频 token 噪声放大成 router 不稳定,最终“训练突然崩”。
最小改动(你能动的旋钮在哪里?)
GRPO 的所有后继,几乎都在改四个东西:
- clip 的形状(对称→不对称;硬剪→软门控)
- ratio 的粒度(token→sequence→prefix)
- 聚合几何(算术均值→几何/幂均值)
- off-policy 的可控性(stale data、MoE routing、replay)
2. DAPO:给探索开绿灯(不对称截断 + 动态采样 + 长 CoT 清噪)
Motivation(核心动机)
标准 GRPO 的对称 clip 会把“灵机一动的低概率正确 token”也锁死在上限里,探索被憋死;此外还会浪费大量 std=0 的无信息 batch(全对/全错)。
解法(DAPO 的主刀)
(1) Clip-Higher:不对称截断
(2) Dynamic Sampling:拒收“全对/全错”组
用“组内必须有分歧”的约束,把 的 batch 直接踢出训练集(不够就重采样):
(3)(常配套)Overlong 处理
对超长回答过滤或软惩罚,专治“为了长而长”。
深度解析
- 对 y_w:如果某一步突然走出正确但低概率的关键推导,clip-higher 允许你更大幅度拉高该 token 的概率,避免系统熵坍塌。
- 对 y_l:动态采样保证 batch 里一定有“高下之分”,梯度不会因为 std=0 直接消失。
最小改动(Diff 清单)
clip(r, 1-ε, 1+ε)→clip(r, 1-ε_low, 1+ε_high)- rollout 端加入过滤:
if all_correct or all_wrong: resample - (可选)加 overlong filter / penalty
3. GSPO:降维打击(把 token ratio 升级成 sequence ratio)
Motivation(核心动机)
token 级 ratio 是长序列方差爆炸的罪魁祸首。尤其 MoE:token 噪声 → router 抖动 → 训练崩。
解法(序列级重要性比率 + 序列级截断)
先定义序列级 ratio(工程上常用 log-domain + 长度归一化避免数值下溢):
然后把 clip 从 token 级挪到 sequence 级:
深度解析
GSPO 的哲学很“武侠”:抛弃微观噪声,约束宏观步幅。
不管你输出 1k 还是 10k token,整条轨迹的更新幅度被锁在一个安全的序列级 trust region 里——MoE 的训练稳定性往往立竿见影。
最小改动(Diff 清单)
- 保留 rollout 时计算的 token logprob diff:
Δℓ_t = logπθ - logπold - 新增:
s_i = exp(mean_t Δℓ_t) - surrogate:把
r_{i,t}全换成s_i(每个 token 共享一个比率)
4. LUSPO:修复 GSPO 的长度塌缩(把“长度旋钮”拨回无偏)
Motivation(核心动机)
GSPO 在某些设定下会出现 response length collapse / 偏置:训练过程中长度变化模式异常,影响性能。
解法(最小但致命的一刀:按自身长度缩放)
在 GSPO 的每条轨迹 loss 外面乘回自己的长度:
深度解析
你可以把它理解成:
GSPO 让每条轨迹“按序列”更新,但序列级目标里长度会悄悄改变梯度的相对权重;LUSPO 用 把这个偏置抵消掉,让“长短”不再是隐藏奖励。
最小改动(Diff 清单)
- 在 GSPO 的 per-sample loss 上
* len(y_i)(就这一行)
5. Dr.GRPO:把 GRPO 做对(去掉两大 bias:长度稀释 + 题级 std 放大)
Motivation(核心动机)
Dr.GRPO 的观点很直接:GRPO 的两个“看似合理的归一化”在 RLVR 里是 bias 源:
- 会让“错而长”被稀释惩罚(长度黑客)
/std(rewards)会引入 difficulty-level bias(某些题被异常放大权重)
解法(极简修复)
- advantage 用去均值但不除 std(或用更稳健的归一化)
- token 归一化不要用 ,改成常数预算(例如 MAX_TOKENS)
深度解析
对 y_l(长且错):原 GRPO 会把负优势摊薄,让模型“错得越长越不疼”。
Dr.GRPO 等价于加了一句规矩:错就要痛,不许用长度逃税。
最小改动(Diff 清单)
A = (R-mean)/std→A = R-mean(或稳健缩放)loss /= len(y)→loss /= MAX_TOKENS
6. GMPO:专治 outlier(算术均值→几何均值)
Motivation(核心动机)
长序列下,真正搞崩训练的往往不是“大多数 token”,而是极少数 ratio 极端的 outlier token。
算术均值会被 outlier 拉飞;几何均值天生抗离群。
解法(把 GRPO 的 token 聚合几何换掉)
先定义 token 级的“贡献项”(省略 KL 等正则):
GRPO 做算术均值:
GMPO 用几何均值(工程实现通常需要保证正数,可加一个小常数 做平移):
最终优化:
深度解析
几何均值的直觉:
“任何一个 token 想当训练的皇帝?不行。你可以重要,但你不能一票否决。”
最小改动(Diff 清单)
- 你不需要改采样,不需要改 advantage
- 只把 per-sample 的
mean(u_t)换成exp(mean(log(δ+u_t)))
7. PMPO:一枚指数 ,把 GRPO↔GMPO 连成连续谱
Motivation(核心动机)
固定用算术(太激进)或固定用几何(太保守)都不理想。不同阶段/不同题目,信号可靠性在变。
PMPO 的野心是:让聚合几何 可连续调节。
解法(power-mean geometry)
仍然用上面的 token 贡献项 ,定义幂均值聚合:
- → 算术均值(GRPO-like)
- → 几何均值(GMPO-like)
目标:
深度解析
PMPO 的精髓不是“又一个公式”,而是一个控制旋钮:
- 信号干净、ratio 不乱飞 → 往 1 靠,更新更快
- 信号嘈杂、outlier 多 → 往 0 靠,更新更稳
最小改动(Diff 清单)
- 把聚合从
mean()/geo-mean()换成power-mean(p) - (可选)按训练阶段或 ESS/clip 触发率动态调
8. SAPO:硬剪刀太粗暴?换成“软门控”(smooth trust region)
Motivation(核心动机)
PPO/GRPO 的 hard clip 是不连续操作:
- 触发 clip 的 token 梯度突然变形甚至消失
- 长序列里 clip 触发比例高 → 学习信号变得碎片化 → 不稳定
解法(用平滑门控替代 hard clip)
SAPO 用一个平滑的缩放函数 替代 min(·, clip(·)):
一个常见门控形式(温度控制的 sigmoid 缩放):
深度解析
hard clip 像“断崖式刹车”;SAPO 像“连续刹车”。
离 on-policy 越远,梯度越被平滑衰减,而不是突然砍断。
最小改动(Diff 清单)
- 把 PPO-style
min(rA, clip(r)A)换成f(r)*A - 新增超参:(或正负 advantage 不同温度)
9. SSPO:把“软门控”升级成“序列一致”的软权重
Motivation(核心动机)
token 级门控虽然平滑,但序列级奖励/信用分配的一致性仍然可能受损。
SSPO 想要的是:软、稳、还要序列 coherent。
解法(token 门控 → 序列级几何聚合)
先算每个 token 的门控 ,再做几何均值聚合为序列权重:
目标:
深度解析
你可以把 SSPO 理解成:
“token 级我允许你软调,但最终裁决必须是序列级的一致规矩。”
最小改动(Diff 清单)
- 你已有 SAPO 的
f(r_t) - 再加一层:
w_i = exp(mean(log f(r_t))),然后用w_i*A_i
10. CISPO:不剪“更新”,只剪“权重”(clip IS weights, 保留梯度流))
Motivation(核心动机)
PPO/GRPO 的 hard clip 会让大量 token 的学习信号被砍掉。
CISPO 的思路:权重可以剪,但梯度流别断。
解法(clip importance weights + stop-gradient)
先 clip 权重:
再用 stop-grad 的权重去乘 logprob:
深度解析
一句话:“所有 token 都要交学费,但谁都不许当暴君。”
最小改动(Diff 清单)
- 删除 PPO 的 two-branch
min(·, clip(·)) - 用
sg(clip(r))*A*logπ替代
11. DHPO:把 GRPO(token)与 GSPO(sequence)混合插值
Motivation(核心动机)
GRPO token 级信用分配细,但方差大;GSPO 稳,但牺牲 token-wise credit。
DHPO:两头都要。
解法(混合 ratio + 分支剪裁)
DHPO: token-to-sequence ratio 交互图
- token ratio:
- sequence ratio:(同 GSPO)
混合:
分支剪裁(先分别 clip 再混合,防止任一分支 outlier 统治更新):
目标:
深度解析
DHPO 像“师傅带徒弟”:
- token 级负责细节(哪里对、哪里错)
- sequence 级负责稳态(别让训练崩)
- 权重 (例如按熵/不确定性)决定“这一步听谁的”。
最小改动(Diff 清单)
- 你保留 GRPO 的 token ratio
- 新增 GSPO 的 sequence ratio
- 新增 mixing 权重(常数或 entropy-guided)
- clip 改成“分支 clip → 再混合”
12. DPPO:把 ratio clip 换成 divergence trust region(更“正统”的安全带)
Motivation(核心动机)
ratio clipping 是用“单样本 token”去近似“真实分布散度”,在大词表下结构性不适配:
- 低概率 token 被过度惩罚
- 高概率 token 的灾难性漂移反而可能约束不足
解法(约束真实散度而非 token ratio)
把目标写成一个带约束的优化:
其中 可用 TV / KL,并用 Binary / Top-K 近似来做可计算的 divergence 估计与 mask。
深度解析
DPPO 的核心不是“换一个 clip”,而是把安全带从“token 层启发式”换成“分布层约束”。
如果你训练跑久了总是“要么 reward 上天要么直接崩”,DPPO 属于那种“换底盘”的改法。
最小改动(Diff 清单)
- 你需要实现 divergence 估计(Binary / Top-K)
- 用 divergence 触发 mask/缩放,替代 token ratio clip
13. TRM:长时序的真相——只要有一个 token 越界,整条轨迹都不该信
Motivation(核心动机)
长序列 off-policy mismatch 的误差会累积,经典 trust region 误差界随 增长会变得“无意义”。
TRM 的观点:token-independent 的 PPO clip 控不住序列级最大 KL。
解法(序列级 mask:任何 token 越界,整条轨迹梯度归零)
定义序列 mask:
masked surrogate:
深度解析
TRM 的规矩非常冷酷:
“你这条推理链里只要有一步跑偏到信任域外,后面再正确也不能用来更新——因为它已经不再是目标策略的好估计器。”
最小改动(Diff 清单)
- 计算(或估计)每条序列的
max_token_KL if max_token_KL > δ: skip whole sequence
14. MinPRO:off-policy 大漂移的解药(prefix ratio,而不是 token ratio)
Motivation(核心动机)
off-policy 下严格的校正项其实是 prefix importance ratio:
但它在长序列里数值非常不稳定。token ratio 只是一个“偷懒近似”,漂移大时会直接训崩。
解法(Minimum Prefix Ratio surrogate)
MinPRO 用一个非累乘、但能反映“前缀里是否出现过大跑偏”的 surrogate:
然后在 surrogate 里用 替代 。
深度解析
直觉:
“如果你在第 17 步已经严重 off-policy,那么第 3000 步的 token 再漂亮也不能给你加权加太大。”
最小改动(Diff 清单)
- 在计算 token ratio 时,额外维护
prefix_min_ratio - surrogate 中用
prefix_min_ratio替代r_t
15. M2PO:stale data 还能训?用二阶矩信任域只压 outlier
Motivation(核心动机)
异步 RL 需要 stale rollouts(陈旧 256 updates+)——但 stale 让 importance weights 出现极端 outlier,训练要么崩要么全在 clip。
解法(Second-Moment Trust Region)
用“重要性权重二阶矩”来定义信任域:只压极端 token,不误杀大部分有效梯度。
一个典型的约束写法:
或等价的惩罚/自适应缩放,使得高方差 token 的权重被抑制。
深度解析
M2PO 的审美是:
“我不需要你所有 token 都保守,我只需要你把那 0.0X% 的疯子关进笼子。”
最小改动(Diff 清单)
- 引入对 的监控/约束(可做成自适应阈值或缩放)
- 用它替代单纯的 ratio clip 触发逻辑(或叠加)
16. Off-policy GRPO:把 GRPO 正式搬进 off-policy 体制内
Motivation(核心动机)
rollout 与训练解耦是规模化的必经之路。问题是:GRPO 的 advantage 估计和 clip surrogate 如何在 off-policy 下成立?
解法(在 off-policy regime 下重写/对比 GRPO 目标)
核心结论是:在合理的 clipped surrogate 设置下,off-policy GRPO 可以与 on-policy 相比不逊色,甚至更优(更高采样效率、更易扩展)。
最小改动(Diff 清单)
- 训练端允许使用“旧策略”生成的 rollouts
- 控制 staleness,并用更强的 trust region(常见搭配:MinPRO / M2PO / TRM)
17. R3:MoE 稳定器(训练-推理路由一致性 = 生死线)
Motivation(核心动机)
MoE 的训练崩溃往往来自一个根因:训练端与推理端的 routing 不一致,甚至同条件重复 forward 都可能选不同专家。
解法(Rollout Routing Replay)
记录推理引擎中的 routing 分布/决策 ,训练时回放:
深度解析
R3 的哲学:
“你要优化的策略是推理时会发生的那一个,不是训练时偶然抽到的那一个。”
最小改动(Diff 清单)
- rollout 端保存 routing(或 router logits / expert ids)
- 训练端 forward 强制使用回放 routing
18. RSPO:不用回放整套路由,也能稳——对“路由漂移大的 token”降权
Motivation(核心动机)
并非所有路由变化都需要“完全重放”。更精细的做法是:识别路由漂移大的 token,让它们不要主导更新。
解法(router-shift trust weight 乘到 ratio 上)
定义 router-shift 产生的信任权重 ,然后:
再走原本的 clip / 聚合流程(通常还会 stop-grad + flooring)。
深度解析
R3 是“强一致性”,RSPO 是“软一致性”:
“我不要求路由完全一样,但谁变得太离谱,谁就少说话。”
最小改动(Diff 清单)
- 额外计算 router shift(基于旧激活专家的 router scores)
r_t <- w_router * r_t然后照常 GRPO/DAPO
19. STAPO:稳定性塌掉,往往是 0.01% 的“稀有疯 token”造成的
Motivation(核心动机)
训练崩溃往往由极少数低概率、但继承了大优势的 spurious tokens 驱动。
你剪掉一堆正常 token 不如静音这极少数“疯子”。
解法(Silencing Rare Spurious Tokens)
用规则识别/打分这些 spurious tokens,然后 mask 或降权,再做归一化保证估计不偏:
最小改动(Diff 清单)
- 监控 token-level 极端项(低概率+高权重)
- 对这些 token 做 mask/降权,再做 renorm
20. RiskPO:均值目标太贪婪?换成“风险度量”防熵坍塌
Motivation(核心动机)
mean-based(GRPO/很多变体)容易过度强化高概率路径,忽略稀有但信息量大的推理分支 → 熵坍塌、探索枯竭。
解法(Mixed Value-at-Risk, MVaR)
用混合分位风险度量替代简单均值(示意写法):
目标从“最大化均值奖励”变成“最大化风险度量下的奖励”,并配套 bundling 让反馈更稳定。
最小改动(Diff 清单)
- 你需要在每个 batch 内估计 reward 分布的分位点
- 用 MVaR 替代 mean 来计算“优势/目标权重”
21. RePO:把 off-policy 知识“翻译成 on-policy 轨迹”再喂回去
Motivation(核心动机)
SFT 能灌知识但伤泛化;on-policy RL 保泛化但吃不动 hard samples;off-policy RL 吃 hard samples 但不稳。
RePO:硬样本要吃,但必须按 on-policy 的消化系统来吃。
解法(Comprehend → Rephrase → Replace)
- 先让模型理解 off-policy 轨迹(专家解)
- 再把它 rephrase 成“符合当前策略分布风格”的轨迹
- 用这些 rephrased 轨迹替换低 reward rollouts,保持 on-policy 动力学
最小改动(Diff 清单)
- 新增一条数据闭环:hard sample → rephrase → replacement buffer
- loss 本体可以仍用你现有的 GRPO/DAPO/GSPO(这是它最香的地方)
22. SPO:不想要 group?那就 single-stream(彻底避免 degenerate groups)
Motivation(核心动机)
group-based 方法的现实痛点:
- degenerate groups(全对/全错)反复出现 → 学习信号被抹掉
- 不同样本生成耗时差异大 → 同步 barrier 降吞吐
解法(persistent value tracker + global normalization)
SPO 用一个持续更新的、KL 自适应的 value tracker 提供 baseline,并对全 batch 做 advantage 归一化,让每个样本都能贡献稳定梯度(不再依赖 group)。
最小改动(Diff 清单)
- 去掉 group 结构(采样不必固定 G)
- 引入 persistent baseline/trackers(轻量、持续更新)
- 训练吞吐通常会更好
最小改动 Loss:从 GRPO 出发的“替换清单”(工程师版)
下面这张清单的目标是:你不换基础设施,只换 loss 的关键几行,就能切到对应算法。
- GRPO → DAPO
clip(r, 1-ε, 1+ε)→clip(r, 1-ε_low, 1+ε_high)- rollout 加
reject degenerate group(全对/全错重采样)
- GRPO → GSPO
r_{t}→s_i = exp(mean_t log r_t)clip从 token 挪到 sequence
- GSPO → LUSPO
loss_i *= len(y_i)(一行)
- GRPO → Dr.GRPO
A=(R-mean)/std→A=R-mean(或稳健缩放)loss/=len(y)→loss/=MAX_TOKENS
- GRPO → GMPO / PMPO
- 不动采样、不动 A
- 把 token 聚合从算术均值换成几何/幂均值(替换聚合器)
- GRPO → SAPO
- 把
min(rA, clip(r)A)换成f(r)*A(新增温度超参)
- SAPO → SSPO
w_i = geo_mean_t f(r_t)loss_i = - w_i * A_i
- GRPO/GSPO → DHPO
- 同时算
r_t与s_i - 混合
m = w r + (1-w) s,并做分支 clip
- 任何方法 + MoE 崩
- 优先叠 R3(强一致)或 RSPO(软一致)
- off-policy drift 大 / stale 很高
- 优先用 MinPRO / M2PO / TRM 加强 trust region
终极速查表:Objective Functions 大赏(含“一行改动”)
| Method | Objective(核心形式,省略正则项) | 一句话核心优势 | 最小改动(你改哪一行) |
|---|---|---|---|
| GRPO | 无 Critic 的相对反馈基石 | baseline | |
| DAPO | + 动态采样 | 给探索开绿灯 + 拒收无信息 batch | 不对称 clip + reject degenerate group |
| GSPO | , | 序列级稳定,MoE 更稳 | token ratio → sequence ratio |
| LUSPO | $ | y | \cdot \min(sA,\mathrm{clip}(s)A)$ |
| Dr.GRPO | ;token 归一化用常数预算 | 砍掉长度/题级 std 的 bias | 去 std + 去 len(y) 归一化 |
| GMPO | 抗 outlier,稳定 ratio | mean(u) → geo_mean(u) | |
| PMPO | 动态调“激进/保守” | geo_mean → power_mean(p) | |
| SAPO | 硬剪刀→软门控,更平滑 | min/clip → f(r) | |
| SSPO | $w=\left(\prod_t f(r_t)\right)^{1/ | y | }-wA$ |
| CISPO | clip 权重不剪梯度流 | 用 sg(clip(r)) 乘 logprob | |
| DHPO | + 分支 clip | token credit + seq 稳定 | 同时算 与 并混合 |
| DPPO | 用真实散度做 trust region | 实现 divergence 估计 + mask | |
| TRM | 任一 token 越界 → 整条丢弃 | if max_token_KL>δ: skip | |
| MinPRO | 大 off-policy drift 下更稳 | token ratio → prefix-min ratio | |
| M2PO | 约束 / 抑制 outlier | stale data 仍可训 | second-moment trust control |
| R3 | 回放 inference routing | MoE 防崩底座 | 保存并回放 routing |
| RSPO | 不回放也能稳 | 额外乘 router trust weight | |
| STAPO | mask/降权 spurious tokens | 静音极少数“疯 token” | token mask + renorm |
| RiskPO | 防熵塌缩、增强探索 | 用风险度量替代均值 | |
| RePO | rephrase + replace 轨迹闭环 | 吃 hard samples 但保持 on-policy | 新增 rephrase/replacement 流水线 |
| SPO | single-stream baseline + global norm | 彻底避免 degenerate group | 去 group,改 baseline/归一化 |
参考资料(按上文出现顺序)
- DAPO: https://arxiv.org/abs/2503.14476
- GSPO: https://arxiv.org/abs/2507.18071
- SAPO: https://arxiv.org/abs/2511.20347
- Dr.GRPO: https://arxiv.org/abs/2503.20783
- GMPO: https://arxiv.org/abs/2507.20673
- PMPO: https://arxiv.org/abs/2601.22521
- DHPO: https://arxiv.org/abs/2601.05607
- DPPO: https://arxiv.org/abs/2602.04879
- TRM: https://arxiv.org/abs/2512.23075
- MinPRO: https://arxiv.org/abs/2601.22718
- M2PO: https://arxiv.org/abs/2510.01161
- R3: https://arxiv.org/abs/2510.11370
- RSPO: https://arxiv.org/abs/2510.23027
- STAPO: https://arxiv.org/abs/2602.15620
- RiskPO: https://arxiv.org/abs/2510.00911
- RePO(Rephrasing): https://arxiv.org/abs/2602.10819
- SPO(Single-stream): https://arxiv.org/abs/2509.13232