Skip to content

GRPO

Group Relative Policy Optimization

GRPO 是什么

最直观地说,它是一种给大语言模型做强化学习后训练的方法。它和 PPO 很像,都属于“策略梯度 + importance ratio + clip”的路线;但它把 PPO 里很重的 critic / value model 拿掉了,改成:

对同一个问题,一次采样出一组回答,然后只看这一组回答内部谁更好、谁更差,再据此更新策略。

所以 GRPO 的关键词有两个:

  • group:不是只看单个回答,而是看“同题的一组回答”
  • relative:不是看绝对分数,而是看“相对组均值高还是低”

TIP

GRPO(Group Relative Policy Optimization)是 DeepSeekMath 提出的、后续被 DeepSeek-R1 等 reasoning LLM 采用的一种 PPO 风格强化学习算法。

它的关键改动是去掉 PPO 中昂贵的 critic / value model,不再通过 GAE + value function 估计 advantage,而是对同一个问题一次采样多个回答,在组内用相对奖励构造 advantage。

于是,GRPO 仍然保留了 PPO 的 importance ratio 和 clipped objective,但 advantage 来自“同题多回答的相对好坏”,而不是单独训练出来的 value 网络。

这种做法特别适合数学、代码等可验证任务,因为同题回答之间天然可以比较优劣。

原始 GRPO 的典型优势定义为 A^i=(rimean(r))/std(r),并把同一个回答的 advantage 分配给整条 token 轨迹。

但后续工作也指出,原始 GRPO 在 long-CoT 场景中存在长度偏置和 token 效率问题,因此出现了 Dr. GRPO、DAPO 等改进版本。

从 PPO 到 GRPO

先回忆 PPO。PPO 的核心目标是:

JPPO(θ)=E[min(rt(θ)A^t, clip(rt(θ),1ε,1+ε)A^t)],

其中

rt(θ)=πθ(atst)πθold(atst).

这里的 clip 是为了防止一次策略更新走得太猛;而 A^t 是 advantage,通常要靠 value function 配合 GAE 来估计。

在标准强化学习里这没有问题,但对 LLM 后训练来说会出现两个麻烦:

第一,value model 往往和 policy model 一样大,显存和算力成本都不低。第二,在很多 LLM RL 任务里,奖励往往主要出现在回答结尾,比如“最终答案对不对”,这使得训练一个“每个 token 都准确”的 value function 变得不太自然。

GRPO 最初就是为了解决这两个问题提出的:不用 critic,而是用同题采样组的相对奖励,直接构造 advantage。

从策略梯度的角度看,GRPO 在做什么

设问题是 q,模型生成完整回答 o=(o1,o2,,oT),奖励函数是 R(q,o)。最基本的目标是最大化期望奖励:

J(θ)=EqD, oπθ(q)[R(q,o)].

对它求梯度,可以得到策略梯度的经典形式:

θJ(θ)=E[R(q,o)θlogπθ(oq)].

又因为整段回答的概率可以分解成每个 token 条件概率之积:

logπθ(oq)=t=1Tlogπθ(otq,o<t),

所以

θJ(θ)=E[R(q,o)t=1Tθlogπθ(otq,o<t)].

这条式子很好懂:

  • 如果一整段回答奖励高,就把这段回答里出现过的 token 决策整体往上推
  • 如果奖励低,就整体往下压

但直接用 R(q,o) 方差通常很大,所以大家会减去一个 baseline,写成 advantage 的形式:

θJ(θ)E[A(q,o)t=1Tθlogπθ(otq,o<t)].

PPO 是用 value function 来估 A;GRPO 的思路则是:不学 critic,直接用同题组内的相对好坏来造一个 advantage。

GRPO 的采样方式

对一个问题 q,GRPO 不只采一个回答,而是从旧策略 πθold 一次采样 G 个回答:

{o1,o2,,oG}πθold(q).

然后对每个回答打一个 reward:

ri=R(q,oi),i=1,2,,G.

接着,在这一组内部计算均值和标准差:

μr=mean({ri}i=1G),σr=std({ri}i=1G).

于是第 i 个回答的组相对优势写成:

A^i=riμrσr.

这就是 GRPO 最核心的一步。

它的含义非常直白:

  • 如果某个回答高于组平均分,那么 A^i>0
  • 如果某个回答低于组平均分,那么 A^i<0
  • 如果刚好接近平均,那更新就会很弱

所以它本质上不是在问“这题绝对值几分”,而是在问:

在同一个问题的这组答案里,你这条回答是相对更好,还是相对更差?

GRPO 的目标函数

原始 GRPO 仍然保留了 PPO 风格的 clipped objective。对第 i 个回答的第 t 个 token,定义 importance ratio:

ri,t(θ)=πθ(oi,tq,oi,<t)πθold(oi,tq,oi,<t).

于是原始 GRPO 目标可以写成:

JGRPO(θ)=E[1Gi=1G1|oi|t=1|oi|(min(ri,t(θ)A^i,t, clip(ri,t(θ),1ε,1+ε)A^i,t)βDKL(πθπref))].

如果是最常见的 outcome supervision,整条回答只拿一个最终奖励,那么同一条回答里所有 token 共用同一个 advantage:

A^i,t=A^i=riμrσr.

你可以把它理解成:

这一整段回答最后成绩不错,那么这段回答里整条 token 轨迹都会被整体鼓励;

如果最后成绩差,那么整条轨迹都会被整体压制。

这正是 GRPO 很适合“最终答案可验证”的数学、代码类任务的原因。

这个公式该怎么理解

为什么要有 ri,t(θ)

如果直接拿新策略的概率去乘 reward,训练会不稳定,因为样本其实是旧策略采出来的。importance ratio

ri,t(θ)=πθπθold

就是在做一个 on-policy / near-on-policy 的修正:它衡量“新策略相对旧策略,是否更愿意生成这个 token”。

  • 如果 ri,t(θ)>1,说明新策略更倾向于这个 token
  • 如果 ri,t(θ)<1,说明新策略更不倾向于这个 token

为什么要 clip

如果某个 token 的概率变化过大,那么一次更新就可能把策略推得太远。PPO 和 GRPO 都用

clip(ri,t(θ),1ε,1+ε)

把这个变化限制在一个窗口里,从而稳定训练。

为什么要减 KL

原始 GRPO 还会加一个相对参考策略 πref 的 KL 正则,用来防止策略漂移太快。这样做和 RLHF 里“不要太快偏离初始模型”的想法一致。

不过后续很多 long-CoT RL 工作会弱化或去掉这个 KL 项,因为对推理模型来说,策略往往需要明显偏离初始分布,太强的 KL 反而会束缚探索。


进一步化简:为什么说 GRPO 本质上是在“奖优罚劣”

如果先忽略 clip 和 KL,只保留最核心的一项,那么目标可以近似看成:

J(θ)E[i=1Gt=1|oi|A^ilogπθ(oi,tq,oi,<t)].

这时就很好懂了:

  • A^i>0 时,这条回答所有 token 的 log-prob 都被往上推
  • A^i<0 时,这条回答所有 token 的 log-prob 都被往下压

所以 GRPO 的核心可以概括为:

同题多采样,组内做排序,相对好的回答整条强化,相对差的回答整条抑制。

GRPO 和 PPO 到底差在哪

很多人第一次看 GRPO,会以为它是“完全不同”的算法。其实不是。

更准确地说,GRPO 仍然是 PPO 风格的策略优化,只是把 advantage 的来源从“critic + GAE”换成了“组相对奖励”。

所以它和 PPO 的关系可以压成一句话:

PPO 保留了 actor-critic 结构;GRPO 保留了 PPO 的 clipped policy update,但把 critic 换成了 group-relative advantage。

这也是为什么很多人把 GRPO 理解成“专门为 LLM 后训练场景改造过的 PPO”。

Outcome supervision 和 process supervision

在 DeepSeekMath 里,GRPO 其实不只有一种监督方式。

Outcome supervision

这是最常见的版本。每条完整回答只拿一个最终奖励,比如答案是否正确,然后把这个归一化后的分数分给整条回答的所有 token:

A^i,t=r~i=rimean(r)std(r).

这适合“最终答案可验证”的任务,比如数学题、代码测试。

Process supervision

如果每一步推理都能打分,那么可以更细粒度地给奖励。设第 i 条回答一共有 Ki 个 reasoning steps,某一步结束 token 的奖励为 riindex(j)。先做归一化:

r~iindex(j)=riindex(j)mean(R)std(R).

然后把从当前位置往后的这些 step reward 累加成 token advantage:

A^i,t=index(j)tr~iindex(j).

直觉上,这就更像“哪一步推理做对了,就从那一步开始往前追溯地给信用分配”。

为什么 GRPO 特别适合数学 / 代码 / 可验证推理

GRPO 最适合的场景不是开放式聊天,而是 reward 相对容易判定 的任务。

比如数学题,你可以直接看最终答案是否等价;比如代码题,你可以看测试是否通过。这样一来,同一个题目下采样出多条回答后,组内相对比较就会很自然。

这也是 DeepSeekMath 和 DeepSeek-R1 这类工作选择 GRPO / RLVR 路线的重要原因:在 reasoning 任务里,很多奖励其实不需要人类逐条打偏好,而可以直接用规则验证。

GRPO 的一个重要问题:长度偏置

GRPO 很有效,但不是没有坑。

后续工作发现,原始 GRPO 在 long-CoT 场景下会带来明显的长度相关偏置。问题主要出在两件事上:

第一,原始 GRPO 是 sample-level 的损失归约方式:先把一条回答内部所有 token 的损失平均,再对不同回答求平均。这样会让长回答里的单个 token 对总梯度的影响被稀释。第二,原始版本里常见的 1/|oi| 长度归一化和 std 标准化,在实践中会诱导输出越来越长,尤其是错误回答也会被拉长。

一篇系统分析 R1-Zero-like 训练的工作明确指出:原始 GRPO 存在一种优化偏置,会在训练中人为地增加回复长度,尤其会拉长错误回复;为缓解这个问题,他们提出了 Dr. GRPO,核心修改就是去掉长度归一化项以及标准差归一化项。

与此相呼应,DAPO 也指出 naive GRPO 在长链式推理场景里会遇到熵塌缩、奖励噪声、训练不稳定等问题,并进一步把“sample-level loss”改成更适合长回答的 token-level policy gradient loss

所以今天如果你看到很多复现 R1 风格训练的系统,它们往往不是“原封不动地照搬最早的 GRPO”,而是在它上面继续做了不少工程和目标层面的修正。

总结

GRPO = 不再训练 critic,而是对同一个问题采样一组回答,用组内相对奖励来替代 advantage,然后仍按 PPO 风格做 clipped policy update。

组相对优势:

A^i=rimean({rj})std({rj}).

GRPO 目标:

JGRPO(θ)=E[1Gi=1G1|oi|t=1|oi|min(ri,t(θ)A^i,t, clip(ri,t(θ),1ε,1+ε)A^i,t)βDKL(πθπref)].

同题多采样,组内做相对比较,让好回答更容易再次被生成,让差回答更不容易再次被生成。

INFO

PPO:餐厅每次根据顾客反馈调整菜品,但每次只能小改,但不能一天之内把菜单全换了。

DPO:这两道菜我更喜欢 A,不喜欢 B。”餐厅直接学会以后多做 A 风格、少做 B 风格。

KTO:餐厅不需要你拿 A 和 B 比,只要你告诉它“这道菜值得保留”还是“不值得保留”。

ORPO:餐厅不再先学菜单、再单独做偏好优化,而是在学 A 这道好菜的同时,直接告诉自己“A 要比 B 更值得被点”,于是边模仿好菜,边拉开好菜和差菜的差距。

GRPO:餐厅一次先做一组不同版本,然后只看这组里面谁相对更好、谁相对更差;好的版本以后更常做,差的版本概率压低。

RLHF:先训练一个美食评委,让评委给菜打分;然后餐厅根据评委分数不断试菜、改菜。

RRHF:餐厅一次准备多道候选菜,你给这些菜排顺序;餐厅学习让高排名菜更容易出现,低排名菜更不容易出现。