GRPO“第一背锅侠”Token Level X:DAPO/DrGRPO与GSPO/GMPO的殊途同归

关于GRPO的优化,我们已经介绍过多篇文章(可以看这里[1]的小汇总)了。其中,比较有名的是DAPO[2]DrGRPO[3],而且,后者的两个发现(长度偏差和难度偏差)与前者的其中两个发现(Token级别损失和动态采样)是比较类似的,只是做法稍微不同。我们不妨看一下最终的损失函数。

DAPO的s.t.和DrGRPO的where处对应,当然我们特别想提的是大括号前面的部分——Token Level的计算逻辑。

机理分析

接下来,我们看一下DAPO和DrGRPO关于Token Level的分析。GRPO的Loss计算方式(先在每个样本内按Token对损失进行平均,然后在样本之间聚合损失)下,每个样本对Loss是等权的。

DAPO发现较长回复中的Token可能对总体损失的贡献较低,其原因是,每个样本都被平均到Token级别了,和长度无关,导致长样本的影响被“稀释”,对总Loss的贡献和短样本相同。所以就可能导致高质量的长样本学习的较差,而低质量的长文本又无法得到惩罚。于是,他们的做法是在Token级别进行平均,让每个Token的的贡献从计算上看相当。简单来说,出发点是长回复的影响被稀释(无论好坏)。

DrGRPO发现长度偏差:对积极的advantage,较短的回复获得更大的梯度更新,从而使策略倾向于在正确答案中优先选择更简洁的表达。相反,对消极的advantage,由于较长的回复具有更大的|oi|,因此受到的惩罚较小,导致策略在错误答案中倾向于选择较长的回复。这个发现其实和DAPO是一样的,都是“长回复”作用被缩小。不过,DrGRPO的做法是直接去掉Token层面的平均,这样贡献就变成样本级别了,自然就避免了该问题。

之前在DrGRPO[3]还说非常相似,其实这么一对比看,这几乎都没啥区别了!果然,大家都注意到了这一点,只是处理方式略微不同罢了。

DAPO和DrGRPO的做法其实是对GRPO的“微调”,接下来要介绍的两位则要更进一步,基于同样的出发点,但改动的更加彻底。

GSPO

来自Qwen团队,全称是Group Sequence Policy Optimization[4],看名字就能大概猜到,Level变了。与GRPO的Token级别计算重要性采样不同,GSPO基于序列级别来定义重要性比率,并在序列级别执行裁剪、奖励和优化。

出发点当然是GRPO的训练不稳定问题,GSPO认为根本原因是“重要性采样权重的错误使用和失效”引入了高方差的训练噪声,且随着生成响应长度的增加不断累积,并被裁剪机制进一步放大,最终导致模型崩溃。因此,他们以序列概率为基础重新定义重要性比率计算。更为关键的是,GSPO天然地解决了MoE的稳定性难题。

动机分析

我们在GRPO优化在继续——CISPO和熵 | Yam[5]中提到过,GRPO虽然整体上是on-policy的,但更新过程有off-policy的成分。这也是为什么PPO和GRPO都有clip机制,其主要作用是避免偏离当前策略过远的样本参与梯度估计,从而维持训练的稳定性。

但本文发现GRPO的目标函数本身就是病态的,其本质是对重要性采样权重的不当使用,Token级别的重要性权重计算方式在训练中引入了高方差的噪声。如前面所言,这种噪声在长序列中不断累积,并被clip机制进一步放大。实证结果表明,这种现象可能导致模型的灾难性崩溃,而且往往是不可逆的。也就是说,一旦崩溃发生,即便回退到之前的 checkpoint、精细调整超参数(如clip区间)、延长生成长度,或更换 RL query,训练也难以恢复。这些现象说明了GRPO设计存在问题——Token 级重要性权重失败——优化目标的单位应该与奖励的单位一致(应该都是序列级别)

值得一提的是,虽然原始的GRPO(首发于DeepSeek-Math[6])是Token级别的,但在DeepSeek-R1[7]中,它的公式是序列级别的:

论文里没有写更多细节。不过,GRPO的R本来也不是Token,而是Relative。

算法设计

简单来说,就是把重要性权重变成序列级别。不过引入了「长度归一化」,以降低方差并将其控制在一个统一的数值范围内。具体如下式所示:

si(θ)=(πθ(yix)πθold (yix))1yi=exp(1yit=1yilogπθ(yi,tx,yi,<t)πθold (yi,tx,yi,<t))(1)s_i(\theta)=\left(\frac{\pi_\theta\left(y_i \mid x\right)}{\pi_{\theta_{\text {old }}}\left(y_i \mid x\right)}\right)^{\frac{1}{\left|y_i\right|}}=\exp \left(\frac{1}{\left|y_i\right|} \sum_{t=1}^{\left|y_i\right|} \log \frac{\pi_\theta\left(y_{i, t} \mid x, y_{i,<t}\right)}{\pi_{\theta_{\text {old }}}\left(y_{i, t} \mid x, y_{i,<t}\right)}\right) \tag{1}

损失函数为:

JGSPO(θ)=ExD,{yi}i=1Gπθ old (x)[1Gi=1Gmin(si(θ)A^i,clip(si(θ),1ε,1+ε)A^i)](2)\mathcal{J}_{\mathrm{GSPO}}(\theta)=\mathbb{E}_{x \sim \mathcal{D},\left\{y_i\right\}_{i=1}^G \sim \pi_{\theta \text { old }}(\cdot \mid x)}\left[\frac{1}{G} \sum_{i=1}^G \min \left(s_i(\theta) \widehat{A}_i, \operatorname{clip}\left(s_i(\theta), 1-\varepsilon, 1+\varepsilon\right) \widehat{A}_i\right)\right] \tag{2}

Advantage的计算与GRPO一样,不多说了。由于重要性比率定义方式的不同,GSPO与GRPO的clip范围在数量级上通常存在差异。

分析梯度(简单起见不考虑clip),GSPO梯度如下:

GRPO梯度如下:

注意,上面的求导利用了对数导数技巧(log-derivative trick):概率的导数等于它自己乘以log的导数。

ddθlogπ(o)=1π(o)ddθπ(o)ddθπ(o)=π(o)ddθlogπ(o)\frac{d}{d \theta} \log \pi(o)=\frac{1}{\pi(o)} \cdot \frac{d}{d \theta} \pi(o) \\ \Rightarrow \frac{d}{d \theta} \pi(o) = \pi(o) \cdot \frac{d}{d \theta} \log \pi(o)

根据梯度看,GSPO与GRPO的根本区别在于它们对 token 的对数似然梯度进行加权的方式,在GRPO中,token 的梯度是根据其「各自的重要性权重」进行加权的。这些不均等的权重并非可以忽略,它们可能分布在 (0, 1+ε] (A>0)[1-ε, +∞) (A<0)区间内, 随着训练的进行,这些差异会不断累积,最终可能导致不可预测的后果。相比之下,GSPO 对一个响应中的所有 token 赋予相等的权重,从而消除了 GRPO 中这一不稳定因素。

Token级别变种

为了适配多轮场景,引入比序列级别更细的token粒度损失。

JGSPOtoken(θ)=ExD,{yi}i=1Gπθ old (x)[1Gi=1G1yit=1yimin(si,t(θ)A^i,t,clip(si,t(θ),1ε,1+ε)A^i,t)](3)\mathcal{J}_{\mathrm{GSPO-token}}(\theta)=\mathbb{E}_{x \sim \mathcal{D},\left\{y_i\right\}_{i=1}^G \sim \pi_{\theta \text { old }}(\cdot \mid x)}\left[\frac{1}{G} \sum_{i=1}^G \frac{1}{\mid y_i \mid} \sum_{t=1}^{\mid y_i \mid} \min \left(s_{i,t}(\theta) \widehat{A}_{i,t}, \operatorname{clip}\left(s_{i,t}(\theta), 1-\varepsilon, 1+\varepsilon\right) \widehat{A}_{i,t}\right)\right] \tag{3}

s自然也需要相应调整。

si,t(θ)=sg[si(θ)]πθ(yi,tx,yi,<t)sg[πθ(yi,tx,yi,<t)](4)s_{i, t}(\theta)=\operatorname{sg}\left[s_i(\theta)\right] \cdot \frac{\pi_\theta\left(y_{i, t} \mid x, y_{i,<t}\right)}{\operatorname{sg}\left[\pi_\theta\left(y_{i, t} \mid x, y_{i,<t}\right)\right]^{\prime}} \tag{4}

sg表示停止梯度只取数值,这个和GRPO优化在继续——CISPO和熵 | Yam[5]中的做法一致。梯度如下:

注意看,这个形式和序列级别的梯度是等价的。考虑到式(4)右边的分式恒等于1,si,t(θ)在数值上与si(θ)相等,它们的损失函数也是等价的(式2和式3)。

进一步,当我们将响应 y_i 中所有 token 的优势值设为相同(即 A_{bi,t} = A_{bi})时,GSPO-token 与 GSPO 在目标函数、剪枝条件和理论梯度上在数值上是相同的;而 GSPO-token 具有更高的灵活性,可以对每个 token 的优势值进行单独调整。

MoE模型

论文发现,采用 GRPO 时,MoE 中专家的激活波动性可能会导致强化学习训练无法正常收敛。具体来说,在一次或多次梯度更新之后,对同一个响应,所激活的专家可能会发生显著变化。这一现象在更深层的 MoE 模型中表现更加明显,导致 token 级别的重要性比率出现剧烈波动,进一步使这些比值失效,从而阻碍了RL训练的正常收敛。

一个Naive的策略就是采用 Routing Replay 策略。具体来说,缓存旧策略中激活的专家,并在计算重要性比值时,在新策略中“重放”这些路由方式。从而保证激活专家的一致性。效果如下:

重用路由方式的做法会带来额外的内存和通信开销,同时也可能限制 MoE 模型的实际容量。GSPO消除了对 Routing Replay 的依赖,能够直接计算重要性比值si(θ),实现正常收敛并保持稳定优化。效果如下:

这里的关键原因是:GSPO 仅关注序列级的似然(πθ(yi|x)),对单个 token 的似然(πθ(yi,t|x, yi,<t))不敏感。由于 MoE 模型始终保持其语言建模能力,序列级的似然不会出现剧烈波动。

GMPO

GRPO 在处理具有异常重要性加权奖励的 token 时,容易出现策略更新不稳定的问题。这种不稳定表现为训练过程中出现极端的重要性采样权重(新旧策略为某 token 分配的采样概率比)。GMPO全称Geometric-Mean Policy Optimization[8],来自UCAS,它采用几何平均值保持重要性采样权重的稳定性。两者对比如下:

其中,sgn的意思是,A为正时取1,为负时取-1。

看起来就是把算术平均改为几何平均,因为几何平均对边界异常值不敏感。同时,还有个好处是:可以使用更大的裁剪范围(ε1、ε2)进行更大的策略探索。所以,GMPO的核心=「稳定(对极端值鲁棒)+更好的策略探索(更小的KL背离和更高的熵)」。

算法设计

训练目标如下:

和GRPO的梯度分别如下:

可以看到,GRPO中,权重是包含重要性比率的,极端的重要性比率将导致token梯度过大或过小,从而导致激进的策略更新。但是GMPO中,包含的是所有重要性比率的几何平均值,为策略更新提供了整体视图,并且对极值具有鲁棒性。

注意,上面梯度的计算和前面一样,使用了对数导数技巧,这里GRPO的导数和前面其实是等价的。当然,简单起见都没有考虑clip。可以发现,GMPO和GSPO有异曲同工之妙呀!其实,不能说很像了,从梯度看只能说一样了;)而且两篇发表时间也是相当接近,也是挺有意思的,相信两方作者都会不由自主地会心一笑吧。

算法分析

Token级别clip

前面提过,与原始DeepSeek-math中的GRPO不同,DeepSeek-R1最大化序列Reward,clip也是序列级别。这其实是和前面GMPO的损失函数中连乘的重要性比率是等价的(等价于序列级别),但clip时采用了token级别。原因如下:

  • token级别的clip更稳定(如上图指数为0.4的和带seqclip的两条曲线对比)。
  • 序列级别的clip过于激进。一旦触发,就会将序列中所有token的梯度设置为零。

Clipping wider

DAPO通过clip-higher来扩大clip范围,进而鼓励探索。根据本节开头处右边的重要性比率图显示:

  • 随着训练的进行,重要性比率的范围扩大,表明policy更新更加积极,不稳定性增加。
  • 相比GRPO,GMPO 保持更稳定的重要性比率范围,说明更新更稳定。
  • 如上图所示,clip的范围可以或达到e^±0.4(0.67, 1.49)区间,比GRPO和DAPO(0.2, 0.28)都要大,鼓励更多探索。

代码实现

代码实现也不复杂,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def gmpo_loss(new_probs, old_probs, mask, advantage, epsilon=0.4):
"""
new_probs [L, 1]: Token probabilities from the current model
old_probs [L, 1]: Token probabilities from the old model
mask [L, 1]: Indicates valid (non-padded) tokens
advantage [1]: Advantage or normalized reward for the sequence
epsilon [1]: Controls the clipping range
"""
# Clipping at token-level & Clipping wider
new_log_probs, old_log_probs = torch.log(new_probs), torch.log(old_probs)
sgn_A = 1 if advantage > 0 else -1
sgn_A_log_probs_diff = sgn_A * (new_log_probs - old_log_probs)
sgn_A_log_probs_diff2 = torch.clamp(sgn_A_log_probs_diff, -epsilon, epsilon)
sgn_A_log_probs_diff_min = torch.min(sgn_A_log_probs_diff, sgn_A_log_probs_diff2)
log_probs_diff_min = sgn_A * sgn_A_log_probs_diff_min

# Geometric-Mean Policy Optimization
importance_sampling_ratio = torch.exp(log_probs_diff_min[mask].sum()/mask.sum())
loss = -advantage * importance_sampling_ratio
return loss

对着GMPO的损失函数公式即可,注意最后的负号,别忘记了。

相关工作

这篇论文提到不少相关工作,正好也一起罗列一下(补了一点新的)。

算法名称 核心方法 补充说明
SRPO[9] (Sample Reweighted Policy Optimization) 利用历史重采样机制,保留关键问题(关键样本),以便在后续训练阶段中继续使用。 提高样本利用率。
DAPO[10] (Dynamic Adaptive Policy Optimization) 采用动态采样机制,从中筛选出极端样本(极高或极低奖励),保证训练效果的有效性。 本博客介绍[11]过,还有其他方法。动态采样为其中之一,避免极端样本噪声干扰。
Dr.GRPO[12] (Dynamic Reward GRPO) 直接除以G解决长度偏差问题。 本博客介绍[13]过,还有难度偏差。
OPO[14] (Optimal baseline Policy Optimization) 采用了最优奖励基线设计,从而最小化梯度方差,提高训练稳定性。 处理梯度提高稳定性。
EMPO[15] (Entropy-guided Model-based Policy Optimization) 将语义熵引入优化目标,以此评估不确定性,并将其纳入“优势值”计算中。 语义熵,看起来和这里[1]的熵不太一样。
AAPO[16] (Advantage Accumulation Policy Optimization) 提出融合优势动量的优势估计方法。 改进优势估计方法,使策略更新更平滑、更有效。
BNPO[17] (Beta Normalized Policy Optimization) 使用具有动态更新参数的 Beta 分布对奖励进行自适应归一化。 动态地正则化Reward,适应不同任务与样本分布,增强训练鲁棒性。
COPO[18] (Consistency-Aware Policy Optimization) 基于结果一致性引入了结构化的全局奖励;引入基于熵的软融合机制。 解决多个回答收敛到相同结果导致优势为0的问题;自适应地平衡局部优势估计与全局优化。

只能说,优化工作太多了!方方面面,公式上每个部分都被动过了;)

小结

本文从Token Level角度对GRPO的优化出发,引出GSPO和GMPO——两个在Token粒度改动更彻底的、且非常相似的优化算法。为啥这么多优化算法都瞄准“Token Level”呢?看下来应该是序列级别粒度“太大”,正如GMPO所言,序列级别过于激进。其实原始的GRPO是Token粒度的,但DeepSeek-R1不是搞了个纯规则的序列级别的Reward么,也就是只看最终结果。效果自然是有的,但确实看起来有一点“粗”,于是就有了这么一些优化方案。另外,我们经过分析也发现,DAPO和DrGRPO在Token级别的损失计算优化上其实是等价的;而GSPO和GMPO虽然出发点不同,但解决重要性采样权重(重要性比率)问题的设计也是等价的。最后,GSPO没有最终效果的实验对比,但GMPO有,根据实验结果,最终的改进相比GRPO其实是有限的(1个多点)。不过话说回来,分析问题和设计优化方案这个过程看起来还是相当有意思的。

References

[1] 这里: https://yam.gift/2025/06/19/NLP/LLM-Training/2025-06-19-CISPO-and-Entropy/
[2] DAPO: https://yam.gift/2025/03/19/NLP/LLM-Training/2025-03-19-LLM-PostTrain-DAPO/
[3] DrGRPO: https://yam.gift/2025/03/28/NLP/LLM-Training/2025-03-28-LLM-PostTrain-DrGRPO/
[4] Group Sequence Policy Optimization: https://arxiv.org/abs/2507.18071
[5] GRPO优化在继续——CISPO和熵 | Yam: https://yam.gift/2025/06/19/NLP/LLM-Training/2025-06-19-CISPO-and-Entropy/
[6] DeepSeek-Math: https://arxiv.org/abs/2402.03300
[7] DeepSeek-R1: https://arxiv.org/abs/2501.12948
[8] Geometric-Mean Policy Optimization: https://arxiv.org/abs/2507.20673
[9] SRPO: https://arxiv.org/abs/2504.14286
[10] DAPO: https://arxiv.org/abs/2503.14476
[11] 介绍: https://yam.gift/2025/03/19/NLP/LLM-Training/2025-03-19-LLM-PostTrain-DAPO/
[12] Dr.GRPO: https://arxiv.org/abs/2503.20783
[13] 介绍: https://yam.gift/2025/03/28/NLP/LLM-Training/2025-03-28-LLM-PostTrain-DrGRPO/
[14] OPO: https://arxiv.org/abs/2505.23585
[15] EMPO: https://arxiv.org/abs/2504.05812
[16] AAPO: https://arxiv.org/abs/2505.14264
[17] BNPO: https://arxiv.org/abs/2506.02864
[18] COPO: https://arxiv.org/abs/2508.04138