返回 AICAP-180
B11 · Day 102GRPO/后训练机理 + 首跑

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]

逐步算:

  1. mean = (1+0+1+1+0+0+1+0)/8 = 4/8 = 0.5
  2. 各偏差平方 (r_i − 0.5)²:每项都是 0.25(因为奖励只取 0/1,离均值都差 0.5)。
  3. variance = (8 × 0.25)/8 = 0.25;std = √0.25 = 0.5
  4. Â_i = (r_i − 0.5)/(0.5 + ε),ε=1e-8 可忽略 → 奖励=1 的样本 Â ≈ +1.0,奖励=0 的样本 Â ≈ −1.0

8 行 advantage 表:

ir_iÂ_ireinforce
11+1.0
20−1.0
31+1.0
41+1.0
50−1.0
60−1.0
71+1.0
80−1.0

对拍代码走读:本仓 src/agent/train/grpo.tsgroupRelativeAdvantage(rewards, eps = 1e-8)(grpo.ts:7)实现与上面逐字一致:

  • mean = rewards.reduce(...) / n(grpo.ts:10);
  • variance = Σ(r−mean)² / nstd = 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]。

  1. 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
  2. 各 (r−mean)²:约 [0.170, 0.0826, 0.000156, 0.0452, 0.150, 0.0352, 0.0976, 0.00766],Σ ≈ 0.5886。
  3. variance = 0.5886/8 ≈ 0.0736;std ≈ 0.2713
  4. Â_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. 今日实战

  1. 打开 src/agent/train/grpo.ts,定位 groupRelativeAdvantage(grpo.ts:7)。
  2. 在 notebook(或临时 *.test.ts)单元里,对 G=8 的奖励组手算 mean/std/advantage,逐行填表(如上)。
  3. groupRelativeAdvantage([1,0,1,1,0,0,1,0]),断言输出与手算的 ±1.0 在浮点容差内一致;再调 grpoScore 验证 reinforce 标记。
  4. 试一组非二值奖励(如 [0.9, 0.2, 0.5, 0.7, 0.1, 0.3, 0.8, 0.4])再手算一遍,确认 std≠0.5 时归一化仍正确。
  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——对拍 grpoScorereinforce 列。
  • 退化情形:全相同奖励 [0.5,0.5,...] → advantage 全 ≈0、reinforce 全 false(std→0,ε 兜底不报 NaN)。

4. 今日实测 / 产出

  • docs/aipa/day102-grpo-paper.md + 8 行 advantage 手算表
  • src/agent/train/grpo.tsgroupRelativeAdvantage 已建为纯函数并通过单测,可直接对拍手算结果。
  • 状态如实:本日为确定性数学对拍,无需 key、无需 GPU;产出即手算表 + 代码一致性验证。

5. 常见误区 / 陷阱

  • 方差除 n 还是 n−1:GRPO 论文与本仓实现用总体方差(除 n)。若改成样本方差(除 n−1),小 G 时 advantage 尺度会偏移——对拍前先对齐口径。
  • 忘了 ε 防除零:组内奖励全相同(std=0)时,若不加 ε 会得到 NaN/Inf。groupRelativeAdvantagestd + 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 道算术样本打分统计准确率