GRPO 原论文精读 (arXiv:2402.03300)
昨天 Day 101 画了后训练全局地图,把 GRPO 定位成「去掉 critic、用组内相对得分估 advantage」的那一支。但「组内相对得分」到底怎么算、为什么这样就能替掉 value 网络,地图层面没展开。今天精读 GRPO 原论文(DeepSeekMath, arXiv:2402.03300)的核心公式,手算一组 8 样本的 mean/std/advantage,再用本仓 groupR
阶段: B11 · GRPO/后训练机理 + 首跑(Day 101-110) 标签: #grpo #group-relative-advantage #no-critic #ppo
今日导引(由浅入深)
昨天 Day 101 画了后训练全局地图,把 GRPO 定位成「去掉 critic、用组内相对得分估 advantage」的那一支。但「组内相对得分」到底怎么算、为什么这样就能替掉 value 网络,地图层面没展开。今天精读 GRPO 原论文(DeepSeekMath, arXiv:2402.03300)的核心公式,手算一组 8 样本的 mean/std/advantage,再用本仓 groupRelativeAdvantage 对拍——这是从「知道有这个东西」到「能逐行复现它」的关键一步,也是 B1→B18 曲线上「会改模型」必须先迈过的数学门槛。今天的「最小可判定产出」:一张 8 行 advantage 手算表,且代码输出与手算逐行一致(确定性,无需 key)。
为什么先手算再读论文公式?因为 GRPO 的核心就一个归一化式子,手算一遍比读十遍公式更牢;而且本仓已有
groupRelativeAdvantage可即时对拍,手算错了立刻暴露——这是「确定性内核 + 可对拍」带来的学习杠杆。
1. 机理精读
GRPO 的中心思想:用「同一道题采样一组答案,组内互相比较」来替代「训一个 critic 估每个 token 的优势」。 对同一 prompt 采样一组 G 个输出 {o_1, …, o_G}(论文里常取 G=8 或更大),每个输出经 reward 函数得到标量奖励 r_i。GRPO 用组内奖励的均值和标准差把奖励归一化成 group-relative advantage:
Â_i = (r_i − mean(r)) / (std(r) + ε)
直觉极简:比组内平均好的输出,advantage > 0,被强化;比平均差的,advantage < 0,被抑制。 整组的相对排序就是优势信号本身。
为什么这能省掉 critic? PPO 用 GAE + 一个独立的 value 网络逐 token 估 advantage——value 网络要额外训练、要占显存、训不好就引入偏差,是 PPO 不稳定的主要来源之一。GRPO 把「优势」重新定义为「相对于同组其他采样的好坏」,用采样本身的统计量代替了 value 网络的预测。组内归一化天然提供了一个 baseline(组均值就是 baseline),方差归一化又让不同难度的 prompt 之间梯度尺度可比。代价是:每步要对每个 prompt 采样 G 个 rollout,算力随 G 线性增长(Day 104 会和 DPO 的「无采样」对比)。
目标函数结构。 GRPO 保留 PPO 式的 clip ratio:用新旧策略概率比 r_t(θ) = π_θ/π_old,按 advantage 符号做 min(r·Â, clip(r, 1−ε, 1+ε)·Â),防止单步更新过大;并加 KL 正则项约束与参考策略 π_ref 的偏离,防止策略跑飞、保持语言能力。所以 GRPO ≈「PPO 的 clip + KL 框架」减去「critic/GAE」,换成「组相对 advantage」。
为什么「去掉 critic」不会导致 advantage 估计崩? 因为 GRPO 换了 advantage 的定义。PPO 的 critic 是在估「这个 token 之后的期望回报」,需要时间维度上的信用分配(GAE);GRPO 用的是序列级(outcome-level)奖励——一整个答案对/错给一个标量,再在组内相对化。对可验证任务,序列级 0/1 奖励本就是最干净的信号,不需要 token 级信用分配,所以 critic 是多余的。代价是 GRPO 对「过程奖励/中间步骤奖励」天然弱(一整条答案只有一个分),这也是为什么 PRM(过程奖励模型)路线在某些场景仍有价值——但那是另一条线。
关键边界与权衡。 组内归一化对绝对奖励噪声较鲁棒(整体加个常数不改相对排序),但对系统性偏置仍敏感——比如 reward 隐含偏好长答案,组内长样本会系统性拿高分,advantage 就被长度污染(Day 105 的去偏主题)。此外 std 归一化在「组内奖励几乎相同」时会放大噪声(std→0),这正是 2025-2026 衍生工作 Dr.GRPO 要修的点之一。资源:GRPO 原论文(arXiv:2402.03300,2024-02)。
GRPO 与 PPO 的三点对照(钉死边界):
- advantage 来源:PPO=critic 预测(学出来);GRPO=组内均值/标准差(采出来)。
- 信用分配粒度:PPO 可做 token 级(GAE);GRPO 通常 outcome 级(整序列一个分)。
- 失败模式:PPO 多因 critic 不准/value 崩;GRPO 多因 grader 漏洞(reward hacking)或 G 太小方差大。
2. 推导 / 手算 / 代码走读
手算一组 G=8 的 advantage(演示用奖励,非实测训练值)。设 8 个 rollout 的奖励为:
r = [1, 0, 1, 1, 0, 0, 1, 0]
逐步算:
- mean = (1+0+1+1+0+0+1+0)/8 = 4/8 = 0.5
- 各偏差平方 (r_i − 0.5)²:每项都是 0.25(因为奖励只取 0/1,离均值都差 0.5)。
- variance = (8 × 0.25)/8 = 0.25;std = √0.25 = 0.5。
- Â_i = (r_i − 0.5)/(0.5 + ε),ε=1e-8 可忽略 → 奖励=1 的样本 Â ≈ +1.0,奖励=0 的样本 Â ≈ −1.0。
8 行 advantage 表:
| i | r_i | Â_i | reinforce |
|---|---|---|---|
| 1 | 1 | +1.0 | ✓ |
| 2 | 0 | −1.0 | ✗ |
| 3 | 1 | +1.0 | ✓ |
| 4 | 1 | +1.0 | ✓ |
| 5 | 0 | −1.0 | ✗ |
| 6 | 0 | −1.0 | ✗ |
| 7 | 1 | +1.0 | ✓ |
| 8 | 0 | −1.0 | ✗ |
对拍代码走读:本仓 src/agent/train/grpo.ts 的 groupRelativeAdvantage(rewards, eps = 1e-8)(grpo.ts:7)实现与上面逐字一致:
- 先
mean = rewards.reduce(...) / n(grpo.ts:10); - 再
variance = Σ(r−mean)² / n、std = Math.sqrt(variance)(grpo.ts:11-12)——注意是总体方差(除 n,非 n−1),与论文一致; - 返回
rewards.map(r => (r − mean) / (std + eps))(grpo.ts:13),ε 防 std=0 时除零。 grpoScore(group)(grpo.ts:38)在此基础上附advantage并打reinforce: adv > 0——正好对应上表「reinforce」列。
把 r=[1,0,1,1,0,0,1,0] 喂进去,输出应与手算的 ±1.0(差一个 ε 量级)逐行吻合——这就是今日「代码输出与手算一致」的对拍点。
第二个手算(非二值,验证 std≠0.5 的一般情形):r = [0.9, 0.2, 0.5, 0.7, 0.1, 0.3, 0.8, 0.4]。
- sum = 0.9+0.2+0.5+0.7+0.1+0.3+0.8+0.4 = 3.9;mean = 3.9/8 = 0.4875。
- 各 (r−mean)²:约 [0.170, 0.0826, 0.000156, 0.0452, 0.150, 0.0352, 0.0976, 0.00766],Σ ≈ 0.5886。
- variance = 0.5886/8 ≈ 0.0736;std ≈ 0.2713。
- Â_i = (r_i − 0.4875)/0.2713:例如 r=0.9 → Â ≈ +1.52;r=0.1 → Â ≈ −1.43;r=0.5 → Â ≈ +0.046(几乎踩在均值上,advantage≈0,强化信号极弱)。
这个例子说明一个实战要点:接近组均值的样本几乎不提供梯度——GRPO 的学习信号集中在「明显比平均好/差」的样本上,所以采样要有足够区分度(温度/G 调节,Day 106/108)。
clip 与 KL 的直觉(不展开公式):
- clip ratio:限制单步 π_θ/π_old 落在 [1−ε, 1+ε],防止某个高 advantage 样本把策略一步推太远(更新过冲会崩)。
- KL 正则:拉住策略别离参考模型 π_ref 太远,保住语言流畅度与通用能力——RL 只优化 reward,不加 KL 会「为拿分不择手段」地退化语言。
- 二者合起来 = 「敢更新但不敢跑飞」,是把 RL 训练稳住的两条缰绳。
3. 今日实战
- 打开
src/agent/train/grpo.ts,定位groupRelativeAdvantage(grpo.ts:7)。 - 在 notebook(或临时
*.test.ts)单元里,对 G=8 的奖励组手算 mean/std/advantage,逐行填表(如上)。 - 调
groupRelativeAdvantage([1,0,1,1,0,0,1,0]),断言输出与手算的 ±1.0 在浮点容差内一致;再调grpoScore验证reinforce标记。 - 试一组非二值奖励(如
[0.9, 0.2, 0.5, 0.7, 0.1, 0.3, 0.8, 0.4])再手算一遍,确认 std≠0.5 时归一化仍正确。 - 写入
docs/aipa/day102-grpo-paper.md,附 8 行 advantage 手算表与对拍结论。
对拍单测的三条断言(确定性,可进 CI):
- 零均值:
groupRelativeAdvantage输出之和应 ≈0(归一化后均值为 0)——浮点容差内Math.abs(sum) < 1e-6。 - 单位标准差:输出的总体标准差应 ≈1(除去 ε 影响)——验证 std 归一化生效。
- 符号一致:奖励高于组均值的样本 advantage>0、
reinforce=true,反之 false——对拍grpoScore的reinforce列。 - 退化情形:全相同奖励
[0.5,0.5,...]→ advantage 全 ≈0、reinforce全 false(std→0,ε 兜底不报 NaN)。
4. 今日实测 / 产出
docs/aipa/day102-grpo-paper.md+ 8 行 advantage 手算表。src/agent/train/grpo.ts的groupRelativeAdvantage已建为纯函数并通过单测,可直接对拍手算结果。- 状态如实:本日为确定性数学对拍,无需 key、无需 GPU;产出即手算表 + 代码一致性验证。
5. 常见误区 / 陷阱
- 方差除 n 还是 n−1:GRPO 论文与本仓实现用总体方差(除 n)。若改成样本方差(除 n−1),小 G 时 advantage 尺度会偏移——对拍前先对齐口径。
- 忘了 ε 防除零:组内奖励全相同(std=0)时,若不加 ε 会得到 NaN/Inf。
groupRelativeAdvantage用std + eps规避,但此时 advantage 全 ≈0(无梯度信号),说明这组采样没区分度,应调温度或 reward。 - 把 advantage 当绝对奖励:advantage 是「相对组均值」的,跨组不可比绝对值;它只决定组内谁被强化谁被抑制。
- 照搬未做 length-bias 修正的早期实现:原始 GRPO 对长度偏置敏感,2025-2026 的 DAPO/Dr.GRPO 已改进,复现时要确认用的是哪版。
- G 太小就下结论:G=2 时组内只有「一好一坏」,std 估计极不稳,advantage 噪声大;论文常取 G≥8。手算用 G=8 不是随意,是为了让 mean/std 有意义。
- 以为 advantage>0 就一定更新:还要过 clip 和 KL;高 advantage 但 ratio 已超 clip 边界时,梯度被截断——
grpoScore只标reinforce,不代表实际更新幅度。 - 把组相对 advantage 跨 prompt 比较:每个 prompt 自成一组、各自归一化;A 组的 +1.5 和 B 组的 +1.5 不代表「一样好」,只代表「各自组内排第一档」。跨组比绝对值无意义。
- 忽略 reference 策略漂移:KL 是相对 π_ref 算的,若训练中误更新了 reference,KL 约束失效、策略会悄悄跑飞——reference 必须冻结。
6. 学习资源(每条带 YYYY-MM)
- DeepSeekMath《GRPO》原论文(arXiv:2402.03300,2024-02)——group-relative advantage + clip + KL 的权威源。
- DeepSeek-R1(arXiv:2501.12948,2025-01)——GRPO 在大规模可验证 RL 上的落地。
- 《DAPO: An Open-Source LLM Reinforcement Learning System at Scale》(arXiv:2503.14476,2025-03)——长度偏置 + clip 改进,再验是否成新主线。
- Dr.GRPO 相关工作(2025,再验当周)——std 归一化偏置修正。
- 项目源码
src/agent/train/grpo.ts(本仓,grpo.ts:7-41)——groupRelativeAdvantage/grpoScore对拍对象。
一句话总结今天:GRPO 把 PPO 的「critic 估优势」换成「组内统计估优势」,公式只有一行归一化,本仓 groupRelativeAdvantage 与之逐行一致——能手算+对拍这一行,就抓住了 2026 开源 RL 后训练的数学核心。
SOTA检查 (2026-06 更新)
- 当前主流:arXiv:2402.03300 仍是 GRPO 的权威源,组相对 advantage + 无 critic 是 2026 RL 后训练共识做法。
- 过时黑名单:照搬未做 length-bias 修正的早期 GRPO 实现;2025-2026 的 DAPO/Dr.GRPO 改进了长度偏置与 std 归一化,再验时对比项目是否已采纳。
- 下次复查点:DAPO/Dr.GRPO 是否已取代原始 GRPO 成为开源主线(与 Day 108 训练诊断一并复查 std 归一化开关)。
衔接
- 昨天:Day 101 — 后训练地图(M5):SFT→RM→PPO→DPO→GRPO 三轴对齐
- 今天:精读 GRPO 公式,手算 G=8 的组相对 advantage,对拍
groupRelativeAdvantage做到逐行一致 - 明天:Day 103 — R1 训练范式(arXiv:2501.12948):RLVR 用确定性 grader 替 RM,对 10 道算术样本打分统计准确率