RL FOR LLM · 算法工程学

GRPO 公式解剖

一条公式,七个可修改的旋钮

RL for LLM 里的目标函数不是定理,而是脚手架——policy gradient 估计器本身方差极大又极脆弱,公式里的每一项都是围绕它搭的稳定化补丁。 GSPO、DAPO、Dr. GRPO、CISPO……每个具名算法都只是动了其中 1~3 个旋钮。本页逐个拆解。

完整公式(含 KL 项的原版 GRPO)

每种颜色对应一个可修改的组件,点击下方卡片查看细节:

$$J(\theta) = \mathbb{E}_{x \sim \mathcal{D},\ \{y_i\}_{i=1}^{\textcolor{#c084fc}{G}} \sim\, \textcolor{#c084fc}{\pi_{\theta_{old}}}}\!\left[ \textcolor{#d6a35c}{\frac{1}{G}\sum_{i=1}^{G} \frac{1}{|y_i|} \sum_{t=1}^{|y_i|}} \min\Big( \textcolor{#f87171}{w_{i,t}}\, \textcolor{#60a5fa}{\hat{A}_{i}},\ \textcolor{#4ade80}{\mathrm{clip}(w_{i,t},\, 1\!-\!\varepsilon,\, 1\!+\!\varepsilon)}\, \textcolor{#60a5fa}{\hat{A}_{i}} \Big) - \textcolor{#fb923c}{\beta\, \mathbb{D}_{KL}(\pi_\theta \| \pi_{ref})} \right]$$
$$\text{其中}\quad \textcolor{#f87171}{w_{i,t} = \frac{\pi_\theta(y_{i,t}\mid\cdot)}{\pi_{\theta_{old}}(y_{i,t}\mid\cdot)}}, \qquad \textcolor{#60a5fa}{\hat{A}_i = \frac{\textcolor{#fbbf24}{r_i} - \mathrm{mean}(\{\textcolor{#fbbf24}{r_j}\})}{\mathrm{std}(\{\textcolor{#fbbf24}{r_j}\})}}$$
① 重要性比 w
② Clip 机制
③ Advantage Â
④ 聚合结构
⑤ KL 正则项
⑥ 组与采样
⑦ 奖励 r
骨架(不可动)

符号速查表 —— 先认符号,再看拆解

按公式从左到右的出现顺序排列。一句话记住整条公式:"抽一道题 → 让旧模型答 G 遍 → 组内比出好坏 (Â) → 按新旧模型概率变化 (w) 加权更新,变化太大就截断 (clip),最后按 token 平均"

\(\mathbb{E}[\,\cdot\,]\)

期望(平均值)。下标注明随机性来自哪里:题目 \(x\) 从数据集抽、回答从旧策略采样。实际训练中就是"对一个 batch 取平均"。

\(x \sim \mathcal{D}\)

prompt(题目),从训练数据集 \(\mathcal{D}\) 中随机抽取。"\(\sim\)" 读作"采样自"。

\(\pi_\theta\ /\ \pi_{\theta_{old}}\ /\ \pi_{ref}\)

三个策略(模型):\(\pi_\theta\) 是正在更新的新模型;\(\pi_{\theta_{old}}\) 是负责采样回答的旧模型(几步更新前的快照);\(\pi_{ref}\) 是 KL 项的参照锚点(通常为 SFT 初始模型)。\(\pi(y_t \mid \cdot)\) 表示模型给某 token 分配的概率。

\(\{y_i\}_{i=1}^{G}\)

一组回答:对同一道题 \(x\),让旧模型独立采样 \(G\) 条完整回答(\(G\) 常取 8~16)。\(y_i\) 是第 \(i\) 条回答,\(y_{i,t}\) 是它的第 \(t\) 个 token,\(y_{i,

\(\sum_{i=1}^{G}\ /\ \sum_{t=1}^{|y_i|}\)

两层求和:外层 \(\sum_{i}\) 遍历组内的 \(G\) 条回答(第 1 条到第 \(G\) 条);内层 \(\sum_{t}\) 遍历第 \(i\) 条回答里的每个 token(第 1 个到最后 1 个)。

\(|y_i|\)

第 \(i\) 条回答的长度(token 数)。\(\frac{1}{G}\) 和 \(\frac{1}{|y_i|}\) 就是"先在回答内对 token 平均,再对 G 条回答平均"——这个顺序本身就是可改的旋钮④。

\(w_{i,t}\)

重要性比:第 \(i\) 条回答第 \(t\) 个 token 上,新模型概率 ÷ 旧模型概率。=1 表示策略没变;偏离 1 越远表示模型对这个 token 的看法变化越大。旋钮①。

\(\hat{A}_i\)

优势(advantage):第 \(i\) 条回答"比组内平均好多少",经均值/标准差归一化。正 → 鼓励,负 → 抑制。整条回答共用一个标量,这正是与 token 级 \(w\) 粒度错位的根源。旋钮③。

\(\mathrm{clip}(w,\, 1\!-\!\varepsilon,\, 1\!+\!\varepsilon)\)

截断函数:把 \(w\) 强行限制在 \([1-\varepsilon,\ 1+\varepsilon]\) 内(小于下界取下界,大于上界取上界)。\(\varepsilon\) 常取 0.2,即只允许 ±20% 的偏离。旋钮②。

\(\min(\,\cdot\,,\,\cdot\,)\)

取两项中较小者(PPO 的悲观原则):在"未截断"与"截断"两个目标里选更保守的那个,防止模型靠虚增比值骗取大更新。注意它对 Â 的正负行为不对称——见 ② 的 2×2 矩阵。

\(r_i\)

奖励分数:第 \(i\) 条回答的得分(规则打分或 reward model),整条回答一个数。mean / std 都是在这一组 G 个 \(r\) 上算的。旋钮⑦。

\(\beta\,\mathbb{D}_{KL}(\pi_\theta \| \pi_{ref})\)

KL 散度惩罚:衡量新模型偏离参照模型的距离,\(\beta\) 是惩罚力度。防止模型跑得离初始点太远;长 CoT 训练中常被直接删掉。旋钮⑤。

重要性比 \(w\) —— 比值的粒度与形态

本对话的主线,但选项远不止 GSPO 一种。核心自由度 = 粒度(token / 序列 / 混合)× 处理方式(clip / 截断 / 平滑 / 删除)

变体改法代表算法
token 级(原版)每 token 一个 \(w_{i,t}\)GRPO
序列级几何平均\(s_i = \big(\prod_t w_{i,t}\big)^{1/|y_i|}\) —— 路由噪声被整句平均掉GSPO
混合粒度序列级比值做 clip 门控 + token 级做梯度加权GSPO-token(论文附录,为 token 级 advantage 留口)
不 clip,只截断比值\(\mathrm{stop\_grad}(\min(w_{i,t}, c))\cdot\hat{A}_i\log\pi_\theta\) —— 比值退化为纯权重,梯度永不归零CISPO(MiniMax-M1)
修正双引擎失配把 \(\pi_{old}\) 换成 vLLM 实际采样分布,补一层截断 IS 比值TIS
直接删掉\(w \equiv 1\),退化为 REINFORCE,靠严格 on-policy 保证正确性RLOO / 严格同步训练

Clip 机制 —— 信任域的形状

clip 是一个不对称、有洞的保险丝:对「坏回答 + 比值暴涨」完全不设防,对区间内累积噪声完全不设防,触发时的代价是丢弃而非修正

clip 的真实行为(min 外套,ε=0.2)

w = 5 暴涨w = 0.1 暴跌
 > 0 好回答clip 生效
梯度归零 ✂️
不触发!
0.1 倍畸形通过
 < 0 坏回答不触发!
5 倍放大通过 ⚠️
clip 生效
梯度归零 ✂️

四格中只有对角线两格被保护——噪声对称随机,保护却不对称,净效果系统性偏坏。GRPO 崩溃正是在带 clip 的前提下发生的。

变体解决什么
不对称区间 \([1\!-\!\varepsilon_{low},\ 1\!+\!\varepsilon_{high}]\)低概率 token 被对称上界压死 → 熵坍缩(DAPO Clip-Higher)
Dual-Clip:给 Â<0 且 w≫1 补上界左下角那个"不设防的格子"
区间尺度整体换挡(ε ≈ 3e-4)GSPO 的 \(s_i\) 天然贴近 1,信任域尺度必须跟着换
软化 clip(sigmoid/tanh 惩罚)硬 clip 梯度突变为零的问题
换回 KL 约束回到 TRPO / PPO-penalty 路线

但先别急着说它烂:那两个"洞"是刻意设计

clip 的本质是一个基于「谁在偏离、往哪偏」的放行策略——重要性采样给出 w 之后,min+clip 回答的问题是:"这个样本的梯度,让它以多大力度通过?"。规则表背后只有两条理念:

不许刷分(anti-exploitation)

凡是「策略已朝有利方向移动很远」的情形(\(\hat{A}\!>\!0, w\!\uparrow\) 和 \(\hat{A}\!<\!0, w\!\downarrow\),即对角线两格),一律截断停止发放奖励——你已经赚到了,不许再从同一批旧数据里反复套利。这保证目标是真实收益的悲观下界

不拦纠错(full correction)

凡是「策略朝危险方向跑了」的情形(\(\hat{A}\!<\!0, w\!\uparrow\):坏 token 概率反被推高),敞开放行、惩罚不设上限——回头的路永远畅通。这个"无上界惩罚"正是让钻 clip 区间空子变得无利可图的威慑机制

一句话:对「继续获利」保守,对「悬崖勒马」激进。这是价值判断而非数学必然——所以"补齐四格"并不是修 bug:给惩罚封顶会拆掉威慑(Dual-Clip 只敢封在 c≈3 而非 1+ε),把 w=0.1 抬回 1 是伪造 IS 权重。每补一格都是用偏差换方差。

补格子派

接受 w 有噪声,在 clip 形状上打补丁 —— Dual-Clip Clip-Higher CISPO。代价:每个补丁引入新偏差 + 新超参,治标。

洗信号派

让 w 恢复「真实策略移动」的语义,clip 原封不动 —— GSPO(几何平均降方差)、TIS(修引擎失配)。修上游,一次到位。

Advantage 估计 \(\hat{A}\) —— 组内归一化的每一步都可改

\(\hat{A}_i = (r_i - \mathrm{mean})/\mathrm{std}\) 看着简单,三个环节都有争议

变体改法理由
删掉 std 归一化\(\hat{A}_i = r_i - \mathrm{mean}\)std 小的「简单题/难题」被隐性放大权重,是 difficulty bias(Dr. GRPO)
换 baselinemean 换成 leave-one-out 均值 \(\frac{1}{G-1}\sum_{j\neq i} r_j\)无偏 baseline(RLOO)
跨 batch / 全局归一化组内统计换成 batch 级或滑动全局统计组太小时统计不稳
token 级 advantage引回 critic 或用过程奖励模型(PRM)逐步打分组相对分数没有 credit assignment——这是 GRPO 砍掉 critic 换来的原生缺陷
非线性变换对 r 先做 rank / sigmoid 再算 advantage抗 reward 异常值

聚合与归一化结构 —— 求和平均的顺序

\(\frac{1}{G}\sum_i \frac{1}{|y_i|}\sum_t\) 这个看似无害的结构藏着长度偏差——「答错时越说越长」就是它的产物

变体改法效应
序列内平均后再组平均(原版)每条序列权重相等长序列里单个 token 梯度被稀释 → 错误回答倾向变长(Dr. GRPO 指出的 length bias)
token 级全局平均\(\frac{1}{\sum_i |y_i|}\sum_i\sum_t\)每个token 权重相等,长序列话语权更大(DAPO)
固定分母除以常数 \(L_{max}\) 而非 \(|y_i|\)彻底切断长度与梯度尺度的耦合(Dr. GRPO)

KL 正则项 —— 位置、形式、存废

四个独立的自由度,每个都被人动过

自由度选项
存废长 CoT RL 中直接 \(\beta = 0\) 删掉(DAPOGSPO 实践)——策略本来就要大幅偏离初始点,锚着反而碍事
位置加在 loss 里(GRPO 原版)vs 折进 reward:\(r - \beta\log\frac{\pi_\theta}{\pi_{ref}}\)(RLHF 经典做法,但会污染 advantage)
估计器形式\(k_1 = \log\frac{\pi_\theta}{\pi_{ref}}\)(无偏但可负)/ \(k_2 = \frac{1}{2}\big(\log\frac{\pi_\theta}{\pi_{ref}}\big)^2\) / \(k_3 = \frac{\pi_{ref}}{\pi_\theta} - 1 - \log\frac{\pi_{ref}}{\pi_\theta}\)(GRPO 原版,保证非负)——三者方差与偏差特性完全不同
参照点\(\pi_{ref}\) 固定为 SFT 模型 vs 周期性重置为当前策略

组与采样 —— G、πold 和数据的进出规则

期望符号底下的东西同样是设计空间

自由度选项与代表
组大小 G4~64 都有人用;越大 baseline 越准但越贵
零方差组过滤组内全对或全错 → \(\hat{A}\equiv 0\)、纯浪费算力 → 动态重采样直到组内有对有错(DAPO Dynamic Sampling)
off-policy 程度一批 rollout 更新几次(μ)、\(\pi_{old}\) 多久同步、是否 partial rollout——直接决定 w 偏离 1 的程度,与①②强耦合
超长处理截断序列给不给惩罚 / 直接 mask 掉不参与 loss(DAPO Overlong Filtering)
采样分布温度、top-p,甚至对难题定向加采

奖励 r 本身 —— 公式的最上游

严格说在公式之外,但它决定了 \(\hat{A}\) 的一切

规则奖励 vs Reward Model 结果奖励 vs 过程奖励(PRM) 长度惩罚 格式奖励 多奖励加权

任何下游公式调整都救不了坏奖励(reward hacking)。

全景图:一条公式,七个旋钮

组与采样:决定数据从哪来、w 会偏离多远(在整条管线的上游兜底)

具名算法 ≈ 动了哪些旋钮

  • GSPO②尺度
  • DAPO
  • Dr. GRPO
  • CISPO
  • RLOO

没有谁重写了骨架。唯一没人敢动的是最里面的 score function 估计器 \(\mathbb{E}[\text{权重}\times\nabla\log\pi_\theta]\)。

诊断指标 → 该查哪个旋钮

  • 熵坍缩② clip(上界压死探索)
  • 长度失控 (归一化偏差)
  • 训练崩溃① w ⑥ off-policy(比值失真)
  • reward 涨但能力没涨⑦ 奖励(reward hacking)

工作流:看指标 → 定位病灶 → 改对应的项。不是盲试,是带诊断的试。

换一个模型架构(dense → MoE)、换一个任务形态(短答 → 长 CoT)、换一套基础设施(同步 → 异步 rollout),最优的补丁组合就会变。 所以实践中「调公式」不是不严谨,恰恰是这个领域目前的正规工作方式——前提是每次修改都要有指标支撑和明确的病因假设,否则就真成炼丹了。