GRPO“第一背锅侠”Token Level X2:GTPO双“T”傍地走

上一篇 GRPO“第一背锅侠”Token Level X:DAPO/DrGRPO与GSPO/GMPO的殊途同归 | Yam[1] 中,我们重点分析了 GSPO 和 GMPO 这两个非常相似的与 token 级别有关的优化算法,它们瞄准的是重要性比率。本文要介绍的 GTPO 和 GTPO(哈哈,两个撞名了)则是瞄准了 token 粒度有关的的梯度和优势/奖励,而且两者都重点关注了“熵”的作用。值得注意的是,虽然瞄准的是梯度和优势/奖励,但与OPO[2]AAPO[3]BNPO[4] 不同,关注到 token 粒度。

解决共享 token 梯度冲突和策略坍塌的 GTPO

这篇论文是:GTPO: Trajectory-Based Policy Optimization in Large Language Models[5],它的出发点是GRPO的两个局限:

  • 不期望的梯度冲突:某些 token 经常出现在既有正奖励又有负奖励的生成结果中,这会导致梯度更新相互冲突,从而降低它们的输出概率,即便这些 token 对于保持正确结构可能是必不可少的。简单来说,就是重要的 token 没被重视。这个问题主要影响格式类token
  • 策略坍塌现象:在训练达到一定步数后,大语言模型性能下降,得到负奖励的生成结果可能会惩罚模型的自信输出,并将模型决策偏向不太可能的 token,从而逐步平坦化输出分布,降低学习效果。简单来说,就是输出分散到更多token,不重要的token会乱入导致训练不稳定。

Group-relative Trajectory-based Policy Optimization (GTPO),核心思想是防止同一组内部轨迹之间出现不期望的分歧,从而在保持稳定性的同时提升奖励。为此,引入冲突感知的梯度校正机制,用于缓解共享 token 上的梯度冲突,尤其是在 completion 的首尾部分,从而保持不同轨迹之间的格式一致性。此外,虽然 GRPO 中的 KL 散度在防止策略坍塌时往往反应过慢,但监测 LLM 输出的熵能够提供更清晰的策略不稳定信号。在此基础上,GTPO 引入了基于熵的正则化项,用于控制同组轨迹的探索过程。

背景知识

GRPO 的梯度如下(不含KL,懒得写了,从这里[6]粘过来):

根据论文Improving LLM Reasoning for Vulnerability Detection via Group Relative Policy Optimization[7],采用简化版损失函数。具体来说,就是每个训练步骤只执行一次迭代(然后这批数据就不用了,下一批数据重新采样),此时新旧策略一致,重要性比率恒等于1。

此时,梯度可以写为:

θJGRPO(θ)=1Gi=1GA^ioit=1oigi,tβθDKL(πθπref)(1)\nabla_\theta \mathcal{J}_{\mathrm{GRPO}}(\theta)=\frac{1}{G} \sum_{i=1}^G \frac{\hat{A}_i}{\left|o_i\right|} \sum_{t=1}^{\left|o_i\right|} g_{i, t}-\beta \cdot \nabla_\theta \mathrm{D}_{\mathrm{KL}}\left(\pi_\theta \| \pi_{\mathrm{ref}}\right) \tag{1}

其中,

gi,t=θlogπθ(oi,tsi,t)(2)g_{i, t} = \nabla_\theta \log \pi_{\theta}(o_{i,t} | s_{i,t}) \tag{2}

πθ 是个 softmax,将其展开到 token 粒度:

gi,t=(θfθj(1πθj)kjπθkθfθk)(3)g_{i, t}=\left(\nabla_\theta f_\theta^j\left(1-\pi_\theta^j\right)-\sum_{k \neq j} \pi_\theta^k \nabla_\theta f_\theta^k\right) \tag{3}

j 是概率 πθ 最大的 logit 的索引。当 A>0 时,会按 1-πj 成比例地提升所选 token 的 logit,同时降低其他所有 token 的 logit。相反,当 A<0 时,则会反转这一行为,惩罚该 token 并提升其他候选 token 的 logit。

推导过程如下,首先有:

πθj=efθjmefθm=efθjZ, 其中 Z=mefθm(4)\pi_\theta^j=\frac{e^{f_\theta^j}}{\sum_m e^{f_\theta^m}}=\frac{e^{f_\theta^j}}{Z}, \quad \text { 其中 } Z=\sum_m e^{f_\theta^m} \tag{4}

fθj 是第 j 个 token 的 logit(未归一化的输出),πθj 是选择第 j 个 token 的概率。于是有:

logπθj=log(efθjZ)=fθjlogZ=fθjlogmefθm(5)\log \pi_{\theta}^j = \log (\frac{e^{f_\theta^j}}{Z}) = f_\theta^j - \log Z = f_\theta^j - \log \sum_m e^{f_\theta^m} \tag{5}

两边分别求梯度:

θlogπθj=θfθjθlog(mefθm)(6)\nabla_\theta \log \pi_{\theta}^j = \nabla_\theta f_\theta^j - \nabla_\theta \log \left( \sum_m e^{f_\theta^m} \right) \tag{6}

因为:

θlog(mefθm)=1mefθmmefθmθfθm=mefθmkefθkθfθm=mπθmθfθm(7)\nabla_\theta \log \left(\sum_m e^{f_\theta^m}\right)=\frac{1}{\sum_m e^{f_\theta^m}} \cdot \sum_m e^{f_\theta^m} \nabla_\theta f_\theta^m=\sum_m \frac{e^{f_\theta^m}}{\sum_k e^{f_\theta^k}} \nabla_\theta f_\theta^m=\sum_m \pi_\theta^m \nabla_\theta f_\theta^m \tag{7}

于是就有:

θlogπθj=θfθjkπθkθfθk(8)\nabla_\theta \log \pi_{\theta}^j = \nabla_\theta f_\theta^j - \sum_k \pi_\theta^k \nabla_\theta f_\theta^k \tag{8}

k=j从求和中拆出来,就得到:

θlogπθj=θfθjπθjθfθjkjπθkθfθk(9)\nabla_\theta \log \pi_{\theta}^j = \nabla_\theta f_\theta^j - \pi_\theta^j \nabla_\theta f_\theta^j - \sum_{k \neq j} \pi_\theta^k \nabla_\theta f_\theta^k \tag{9}

这就是式(3)。

Token-level 惩罚

问题分析

LLM在生成时,前面的 token 可能会一样,将 G 个响应分成前缀相同的K个小组,每个小组都共享相同的前缀。前缀中的 token 会受到该组所有生成结果的综合优势影响,而其他 token 仅依赖于其各自生成结果的优势。

此时,GRPO 的梯度可以改写为由一个前缀项和一组单独项构成。去除 KL 项后,梯度可表示为:

θJGRPO(θ)=1Gk=1K[iGkA^ioitSpfx(k)gi,tΔpfx(k)+iGkA^ioijSpfx(k)gi,j](10)\nabla_\theta \mathcal{J}_{\mathrm{GRPO}}(\theta)=\frac{1}{G} \sum_{k=1}^K[\underbrace{\sum_{i \in \mathcal{G}_k} \frac{\hat{\mathcal{A}}_i}{\left|o_i\right|} \sum_{t \in S_{\mathrm{pfx}}^{(k)}} g_{i, t}}_{\Delta_{\mathrm{pfx}}^{(k)}}+\sum_{i \in \mathcal{G}_k} \frac{\hat{\mathcal{A}}_i}{\left|o_i\right|} \sum_{j \notin S_{\mathrm{pfx}}^{(k)}} g_{i, j}] \tag{10}

S 表示 Gk 中的前缀,Δ 表示与 Gk 共享前缀相关的梯度更新。由于gi,t 是相同且保持不变的,Δ 主要由归一化的优势驱动,意味着前缀的更新主要取决于组k内所有生成结果优势之间的相对平衡。比如,当正确的响应(具有正优势)普遍比错误的更长时,该和可能为负。此时,正确生成结果的分母 |o_i| 会更大,从而减弱它们对整体梯度的贡献。结果就是,模型可能会因为生成了理想且有益的前缀 token 而受到惩罚。这引入了一种对共享起始 token 的偏差,如格式化 token 或推理标签(如 <reasoning>),因为它们往往出现在前面。

特别需要特别注意,DeepSeek-R1 中的 GRPO 其实是用 sequence 级别的 A 代替 token 级别的。

在这种情况下,其实受影响的是所有 token。这和GRPO“第一背锅侠”Token Level X:DAPO/DrGRPO与GSPO/GMPO的殊途同归 | Yam[1]中提到的现象是类似的(对,就是 DrGRPO 中的长度偏差)。

即便格式化 token 没有出现在前缀,它们可能会在多个响应中以不同的位置和上下文出现,其中一些是正确的,另一些是错误的,这使得它们更容易受到不一致甚至有害的更新影响,从而在更新中引发潜在问题。

文中举了个例子,如果某个 token τ 经常出现在具有负优势的生成结果中,即使该 token 在语法上是正确且必要的,它的概率也可能被降低。进一步的问题是,当一个生成结果只部分遵循预期格式时,也会出现类似情况。比如,一个生成结果正确地用格式化 token τ </reasoning> 关闭了第一部分,但随后却遗漏了 <answer>,那么 τ 可能会得到较低甚至负的奖励。这样一来,</reasoning> 就会受到惩罚,尽管它在生成结果中本身是正确的。

从这个例子可以看出,虽然和 DrGRPO 类似,但其实是站在 token 粒度分析的。归根结底是因为每个 token 的更新主要依赖于其所在整个生成结果的优势,而不会直接考虑该 token 的单独贡献是否有益。这种现象在格式化 token 以及构成多个生成结果共享后缀的最终 token 情形下尤其显著。

解决策略

为了缓解共享 token 的梯度冲突,有选择地屏蔽参与冲突更新的 token 的梯度贡献。具体做法是,先识别所谓冲突 token,即那些在相同位置(无论是序列的开头还是结尾)同时出现在具有正优势和负优势的生成结果中的 token,然后对它们的梯度更新进行相应修正。

实际上选择了从前向后第一段冲突 token 和从后向前第一段冲突 token,然后将这些 token 的区域定义为 mask 区域。然后通过下式对选中的冲突 token 进行不一致梯度更新的修正,而保持其他 token 的更新不变。

J=1Gi=1GAioit=1oiλi,t(11)\mathcal{J}^*=\frac{1}{G} \sum_{i=1}^G \frac{\mathcal{A}_i}{\left|o_i\right|} \sum_{t=1}^{\left|o_i\right|} \lambda_{i, t} \tag{11}

λi,t根据每个 token 的冲突位置以及其优势 Ai 的符号来控制该 token 的更新:

λi,t={1 if Mi,t=00 if Mi,t=1 and Ai<02 if Mi,t=1 and Ai>0(12)\lambda_{i, t}= \begin{cases}1 & \text { if } \mathcal{M}_{i, t}=0 \\ 0 & \text { if } \mathcal{M}_{i, t}=1 \text { and } \mathcal{A}_i \lt 0 \\ 2 & \text { if } \mathcal{M}_{i, t}=1 \text { and } \mathcal{A}_i \gt 0\end{cases} \tag{12}

该 mask 会屏蔽冲突 token 上的负梯度,只有当它们出现在带有正奖励的生成结果中时才会被强化。

个人感觉这里搞的有点复杂,结果都错了,说某个 token 正确的意义在哪里呢?如果 LLM 是弱能力模型,这样考虑可能还有点用处,Base 都那么强了,这种细节影响其实不大。不过分析过程还是有点意思,不妨了解一下。

显然,论文也意识到了这点,mask 仅针对开头和结尾的连续冲突 token,以保持生成结果的语义结构。事实上,如果在中间位置屏蔽单个冲突 token,可能会损害稳定性和学习效果,因为这些 token 的含义通常依赖于上下文,改变它们的梯度可能适得其反。所以,本文也只是将修正聚焦在主要冲突来源的格式化标签上。

怎么说呢,实在有点牵强,合着简单理解就是不计算 A<0 的响应中的正确格式标签梯度。这真的是好大的雷,好小的雨。

策略坍塌

问题分析

为了进一步理解 advantage 如何影响学习,在训练过程中,针对生成结果 i 和 token t,分析输出分布 πθ 的平均香农熵。给定 p 为概率向量,熵定义为:

H(p)=j=1npjlnpj(13)H(p) = - \sum_{j=1}^n p_j \ln p_j \tag{13}

对于输出 oi,给定 token 位置 t,

p=πθ(oi,tsi,t)(14)p = \pi_\theta (o_{i,t} | s_{i,t}) \tag{14}

将 ⟨H⟩ᵢ 定义为在生成结果 oᵢ 中的平均熵。

在一个生成步骤上,考虑低熵情况,比如 ⟨H⟩i ≪ ln 2(二分类最大熵),意味着模型对输出有很高的置信度,大部分概率会被分到某一个token 上,即 πj ≈ 1,πk ≈ ε ≪ 1,其中k≠j。如果该token导致负面结果(Ai<0),GRPO 会对其进行严厉惩罚,因为在第i个生成结果的索引 τ 处,GRPO 损失的梯度变为:

θJGRPO(i,τ)(θ){A^ioiθfθj(1ϵ) for jA^ioiθfθkϵ for kj(15)\nabla_\theta \mathcal{J}_{\mathrm{GRPO}}^{(i, \tau)}(\theta) \approx \begin{cases}-\frac{\left|\hat{\mathcal{A}}_i\right|}{\left|o_i\right|} \cdot \nabla_\theta f_\theta^j \cdot(1-\epsilon) & \text { for } j \\ \frac{\left|\hat{\mathcal{A}}_i\right|}{\left|o_i\right|} \cdot \nabla_\theta f_\theta^k \cdot \epsilon & \text { for } k \neq j\end{cases} \tag{15}

来源于式(3),只是把 A 放了进来。式(15)的意思是,被选中的 token j 得到一次负向更新,而其他所有 token(即使在语法或语义上可能不正确的)k ≠ j 都会得到一些微小的正向更新。

其实就是负优势可能导致不稳定性,按文中的说法:

虽然这些正向更新单独来看非常小,但它们会随着时间的推移逐渐累积,从而提升那些最初不合理 token 的概率。

这一效应因 GRPO 的 零均值约束 而被进一步放大:当大多数生成结果获得正向奖励时,那些少数得到负向奖励的结果必须承担过大的负优势,以维持整体的平衡。这种惩罚可能抑制正确预测,并在无意间放大错误候选的出现概率,从而提升熵并引入不稳定性。

个人感觉貌似有些牵强,大家看看就行了。关于这个稳定性,论文发现,KL 散度作为纠正信号具有滞后性,仅在策略坍塌之后才上升;而熵则能实时追踪策略坍塌,当策略结构丧失时熵值会随之增加。

解决策略

基于前面的发现,引入了基于熵的正则化项,这个策略和 GRPO优化在继续——CISPO和熵 | Yam[8] 中的《熵》有点类似。该正则化包含两个关键部分:

  • 一个筛选机制,用于丢弃不稳定的生成结果。
  • 一个正则化项,用于惩罚高熵行为。

筛选机制是考虑到高熵不稳定,可能加速坍塌,所以过滤掉初始熵比较低,后面比较高的:

δi={1, if Hini>ln2,0, if Hini<ln2 and Hi>ln2,1, if Hini<ln2 and Hiln2.(16)\delta_i= \begin{cases}1, & \text { if }\langle H\rangle_{i n i} \gt \ln 2, \\ 0, & \text { if }\langle H\rangle_{i n i} \lt \ln 2 \text { and }\langle H\rangle_i \gt \ln 2, \\ 1, & \text { if }\langle H\rangle_{i n i} \lt \ln 2 \text { and }\langle H\rangle_i \leq \ln 2 .\end{cases} \tag{16}

正则化项则受 PPO 启发,在损失中增加一个基于每个生成结果平均 token 熵 <Hi> 的正则化项,最终损失如下:

JGTPO=1Gi=1GδiAioit=1oiλi,tγHi(17)\mathcal{J}_{\mathrm{GTPO}}=\frac{1}{G} \sum_{i=1}^G \frac{\delta_i \cdot \mathcal{A}_i}{\left|o_i\right|} \sum_{t=1}^{\left|o_i\right|} \lambda_{i, t}-\gamma \cdot\langle H\rangle_i \tag{17}

消融结果表明,δ、H 都比较关键,γ 可以取 0.1。效果看起来也有 3-4 个点的提升。

总的来说,这篇文章的设计有点复杂,当然也很细,论文本身也写的非常细致,还附带有代码实现,感兴趣的读者不妨进一步阅读原文。

解决细粒度 token 级别奖励问题的 GTPO

这篇论文是 GTPO and GRPO-S: Token and Sequence-Level Reward Shaping with Policy Entropy[9],它的出发点是:GRPO 所有 token相同的奖励,这种做法不合理(要么全对,要么全错),尤其是长链推理任务。

真的不合理吗?感觉好像并没有那么不合理。错了就重来,好像也不是特别难接受。

本文核心思想源于一个关键点:正确回答中的高熵 token 可以引导策略迈向更高的性能上限。具体来说,高熵的 token 位置往往对应于推理路径中的关键决策点,或是模型在多个合理选项之间进行探索的不确定时刻。

于是,很自然地,可以将这种不确定性用作信用分配的启发式依据。通过利用 token 级熵 动态调整奖励权重,将策略梯度的更新更多地集中在那些对最终结果至关重要的时刻,从而提供更有效且更具指导性的学习信号。这种方法被称为 “不确定性利用(Harnessing Uncertainty)”

基于此,本文提出 Group Token Policy Optimization(GTPO),该方法为每个 token 引入动态的、基于熵加权的奖励,在 GRPO 框架内首次实现了真正意义上的 token 级信用分配。扩展到序列层面,进一步提出 GRPO-S,根据序列的平均 token 熵,为每个序列分配一个熵加权的奖励。

和 DAPO 的 token-level 损失类似,但 DAPO 优化的是如何计算损失,本文优化的是损失项本身的内容。

背景知识

标准 GRPO 的一个理论缺陷是对 advantage 的估计方式。当序列长度 |oi| 不相等时,对所有 token 做一次整体平均(逐 token 的均值)比序列内部求均值再在序列之间求均值(逐序列的均值),其方差更低。方差低意味着更稳定的梯度和更高效的训练。

我们可以从统计学角度理解,前者用了更多样本(所有 token 独立看作样本),相当于有效 sample size 更大 → 方差更低;后者先压缩成长短不一的均值,再去平均,等于减少了样本数量 → 方差更高。举个例子,假设2个序列,每个 token 的 advantage 分别如下:

1
2
s1 = 1
s2 = 1 2 3 4 5

假设 token-level advantage 服从同一分布,均值为 μ,方差为 σ²,逐 token 的平均方差为 σ²/6=0.167σ²,逐序列的平均方差为 (σ² + σ²/5)/4=0.3σ²。

这一理论洞见为本文转向 token 级别的目标函数 提供了数学基础,也与 DAPO 的 token 级别策略梯度损失保持一致。 然而,本文认为仅仅改变损失的归一化方式还不够,必须进一步重塑奖励本身

GTPO

目标:为每个 token 设置独特的奖励。设计一个动态、熵加权的 token 级奖励:

r~i,t=α1ri+α2Hi,tk=1nHk,tdt(18)\tilde{r}_{i, t}= \alpha_1 r_i+\alpha_2 \frac{H_{i, t}}{\sum_{k=1}^n H_{k, t}} \cdot d_t \tag{18}

其中:

Hi,t=vVπθold (vq,oi,<t)logπθold (vq,oi,<t)(19)\begin{aligned} H_{i, t}= -\sum_{v \in \mathcal{V}} \pi_{\theta_{\text {old }}}\left(v \mid q, o_{i, \lt t}\right) \log \pi_{\theta_{\text {old }}}\left(v \mid q, o_{i, \lt t}\right) \end{aligned} \tag{19}

是生成 token o_i,t 时的熵。Hkt 是在同一时间步 t 上,所有成功序列中对应 token 的熵的总和。这个归一化项使得奖励具有相对性,即在某个具体位置上,不确定性更高的 token 会比其他成功路径得到更多奖励。

dt 表示在时间步 t 仍在生成的序列数量(即序列长度不少于 t),这是一个必要的缩放因子。

α1>0 和 α2>0 是超参数,α1 + α2 = 1,用于控制熵奖励的权重。可以通过调整 α1 和 α2 的权重,来控制不同 token 之间动态奖励的相对大小。

对于奖励为 0 的序列,定义其所有 token 的奖励均为 0,即 r ̃it = 0。

作为替换,r ̃_it 也可以被定义为:

r~i,t=α1ri+α2Hi,t(k=1oiHi,t)1oi(20)\tilde{r}_{i, t}= \alpha_1 r_i+\alpha_2 \frac{H_{i, t}} {\left( \prod_{k=1}^{|o_i|} H_{i,t} \right)^{\frac{1}{|o_i|}}} \tag{20}

在实际训练中,所有与熵相关的项都被视为常数,它们的梯度不会被反向传播。

Advantage 定义为:

A~i,t=ri,t~mean(R~)std(R~)(21)\tilde{A}_{i,t} = \frac{\tilde{r_{i,t}} - \text{mean}(\tilde{R}) }{\text{std}(\tilde{R})} \tag{21}

目标函数为:

JGTPO(θ)=E{oi}πθold[1i=1Goii=1Gt=1oimin(wi,t(θ)A~i,t,clip(wi,t(θ),1ϵlow,1+ϵhigh)A~i,t)](22)\mathcal{J}_{\mathrm{GTPO}}(\theta)=\mathbb{E}_{\{o_i\} \sim \pi\theta_{old}} \left[ \frac{1}{\sum_{i=1}^G | o_i|} \sum_{i=1}^G \sum_{t=1}^{|o_i|} \min ( w_{i,t} (\theta) \tilde{A}_{i,t}, \text{clip} (w_{i,t}(\theta), 1-\epsilon_{low}, 1+\epsilon_{high}) \tilde{A}_{i,t} ) \right] \tag{22}

Advantage 的计算方式同 GRPO,核心不同是 r。

这个版本在训练后提高了难题的准确率,但简单数学题的准确率有所下降。原因是过于依赖熵权重来获得奖励。因此,就有了第二个版本,对熵加权奖励做一个 clip,并额外考虑了对响应长度的惩罚

L1 和 L2 是两个正整数,L2 > L1,令 L = L2 - L1,惩罚如下:

R(i)={0 if yLLoiL2 if L<oiL21 if L2<oi(23)R(i)= \begin{cases}0 & \text { if }|y| \leq L \\ \frac{L-\left|o_i\right|}{L_2} & \text { if } L \lt \left|o_i\right| \leq L_2 \\ -1 & \text { if } L_2 \lt \left|o_i\right|\end{cases} \tag{23}

clip 定义如下:

R~i,t=clip(α1+α2Hi,tk=1nHk,tdt,1,α1+α1κ)(24)\tilde{R}_{i, t}=\operatorname{clip}\left(\alpha_1+\alpha_2 \frac{H_{i, t}}{\sum_{k=1}^n H_{k, t}} d_t, 1, \alpha_1+\frac{\alpha_1}{\kappa}\right) \tag{24}

α1 + α2 = 1,κ > 1。于是,

r~i,t=R~i,t+R(i)(25)\tilde{r}_{i, t}= \tilde{R}_{i,t} + R(i) \tag{25}

此外,通过对实验中回答错误样本的观察,注意到模型在生成正确答案时仍需要投入大量的训练工作。因此,文章重新设计错误回答(reward=0)的奖励结构,从而得到另一个版本的 GTPO,它能够提升训练效率,进一步提高性能上限。

对于奖励为 1 的序列,记为 oj,定义 r−jt = 0,对于奖励为 i 的序列,记为 oi,定义:

ri,t=1Hi,ti=1m1Hi,tht(1)(26)r_{i, t}^{-}=\frac{\frac{1}{H_{i, t}}}{\sum_{i=1}^m \frac{1}{H_{i, t}}} \cdot h_t \cdot(-1) \tag{26}

其中,ht 表示 reward 为 0 的、在 t 步依然还在生成的序列数(序列长度 > t)。

作为替换,r−_it 也可以被定义为:

ri,t=1Hi,t(k=1oi1Hi,k)1oi(1)(27)r_{i, t}^{-}=\frac{\frac{1}{H_{i, t}}}{ \left( \prod_{k=1}^{|o_i|} \frac{1}{H_{i,k}} \right)^{\frac{1}{|o_i|}} } \cdot (-1) \tag{27}

定义:

mean(R)=mean({rk,t}1kG,1tok)(28)\operatorname{mean}\left(R^{-}\right)=\operatorname{mean}\left(\left\{r_{k, t}^{-}\right\}_{1 \leq k \leq G, 1 \leq t \leq\left|o_k\right|}\right) \tag{28}

Advantage 定义和 GRPO 一样:

Ak,t=ri,tmean(R)std(R)(29)A^{-}_{k,t} = \frac {r_{i,t}^- - \text{mean}(R^{-})} {\text{std} (R^{-})} \tag{29}

o_1 ... o_n 是 reward 为 1 的序列,o_n+1 ... o_n+m 是 reward 为 0 的序列。损失函数定义为:

JGTPO_2(θ)=E{ok}πθold [1k=1Gok(i=1nt=1oimin(wi,t(θ)A~i,tclip(wi,t(θ),1ϵlow ,1+ϵhigh )A~i,t)+j=n+1Gt=1ojmin(wj,t(θ)Aj,tclip(wj,t(θ),1ϵlow ,1+ϵhigh )Aj,t))].(30)\begin{gathered} \mathcal{J}_{\mathrm{GTPO} \_2}(\theta)= \\ \mathbb{E}_{\left\{o_k\right\} \sim \pi_{\theta_{\text {old }}}}\left[\frac { 1 } { \sum _ { k = 1 } ^ { G } | o _ { k } | } \left(\sum _ { i = 1 } ^ { n } \sum _ { t = 1 } ^ { | o _ { i } | } \operatorname { m i n } \left(w_{i, t}(\theta) \tilde{A}_{i, t}\right.\right.\right. \\ \left.\operatorname{clip}\left(w_{i, t}(\theta), 1-\epsilon_{\text {low }}, 1+\epsilon_{\text {high }}\right) \tilde{A}_{i, t}\right)+ \\ \sum_{j=n+1}^G \sum_{t=1}^{\left|o_j\right|} \min \left(w_{j, t}(\theta) A_{j, t}^{-}\right. \\ \left.\left.\left.\operatorname{clip}\left(w_{j, t}(\theta), 1-\epsilon_{\text {low }}, 1+\epsilon_{\text {high }}\right) A_{j, t}^{-}\right)\right)\right] . \end{gathered} \tag{30}

即把 Loss 分成 reward=1 和 reward=0 两部分计算,以增加错误答案中高熵 token 的权重,从而促进探索以找到正确解。

看起来比较复杂,其实仔细一看还是比较清楚的,有一点需要特别说明,reward=0 时,为啥要用 1/H 呢?这是因为 H 表示不确定性,越大说明模型在该 token 上越「不确定」;1/H 越大说明该 token 熵小,模型在这里其实很确定却选错了;这比「本来就不确定的地方选错」更严重,因此要给予更大的惩罚。简单来说,就是 H 小,1/H 大,则惩罚大。最后乘的 -1 表示惩罚是反向的,和惩罚大小无关。

总的来说,reward=1 时,熵越大,模型在该 token 上不确定,表示模型还有探索空间,训练希望保留这种不确定性,鼓励它继续学习更丰富的分布,所以对应的奖励越大;reward=0 时,熵越小,模型在该 token 上非常确定,结果却错了,应该给予更大的惩罚,尽快修正错误,因此需要用 1/H。一句话概况:正样本鼓励探索,负样本惩罚自信错误。

GRPO-S

接下来是 GRPO-S,其核心思想是利用序列的平均熵来调整整个序列的奖励。

对一个成功的序列 oi,Sequence-Level Reward 定义如下:

r^i=β1ri+β2H^ik=1nH^kn(31)\hat{r}_{i}=\beta_1r_i + \beta_2 \frac{\hat{H}_{i}}{\sum_{k=1}^n \hat{H}_{k}} \cdot n \tag{31}

其中,

H^i=1oik=1oiHi,t(32)\hat{H}_i = \frac{1}{\mid o_i \mid} \sum_{k=1}^{\mid o_i \mid} H_{i,t} \tag{32}

H_it 表示序列 oi 的平均熵。与GTPO类似,只不过在序列级别。当然也可以采用几何平均(无论是 Hi 还是 ri),其对极端值不敏感,整体方差较低。

重要性比率也需要调整为序列级别:

w^i(θ)=t=1oiπθ(oi,tq,oi,<t)πθold(oi,tq,oi,<t)oi(33)\widehat{w}_i(\theta)=\frac{\sum_{t=1}^{\left|o_i\right|} \frac{\pi_\theta\left(o_{i, t} \mid q, o_{i,\lt t}\right)}{\pi_{\theta_{o l d}}\left(o_{i, t} \mid q, o_{i,\lt t}\right)}}{\left|o_i\right|} \tag{33}

嗯,就是 token 粒度的均值,很自然地,也可以换为几何平均。

算法平均比几何平均算的快,省资源;几何平均比算术平均方差小,更稳定。

损失函数为:

JGRPOS(θ)=E{oi}πθold[1Gi=1Gmin(w^i(θ)A^i,clip(w^i(θ),1ϵlow,1+ϵhigh)A^i)](34)\mathcal{J}_{\mathrm{GRPO-S}}(\theta)=\mathbb{E}_{\{o_i\} \sim \pi\theta_{old}} \left[ \frac{1}{G} \sum_{i=1}^G \min ( \hat{w}_{i}(\theta) \hat{A}_{i}, \text{clip} (\hat{w}_{i}(\theta), 1-\epsilon_{low}, 1+\epsilon_{high}) \hat{A}_{i} ) \right] \tag{34}

其中:

A^i=r^imean({r^k}k=1G)std({r^k}k=1G)(35)\hat{A}_i = \frac{\hat{r}_i - \text{mean}(\{ \hat{r}_k \}_{k=1}^{G} ) }{\text{std}(\{ \hat{r}_k \}_{k=1}^{G} ) } \tag{35}

这和 DeepSeek-R1 给出的 GRPO 的损失(序列级别)是一样的(偷懒了,直接从这里[6]粘过来):

当然,依然是 r 不同,哦还有,重要性比率计算也不同。

和 GTPO 对应,也把序列分成 reward=0 和 reward=1 两个组。对于 reward=0 的序列 oi,定义:

ri=1H^ii=1m1H^im(1)(36)r_{i}^{-}=\frac{\frac{1}{\hat{H}_{i}}}{\sum_{i=1}^m \frac{1}{\hat{H}_{i}}} \cdot m \cdot(-1) \tag{36}

同样,也可以换成几何平均。对于 reward=1 的序列 oj,定义r−j = 0

Advantage 也类似,定义为:

Ai=rimean({rk}k=1G)std({rk}k=1G)(37)A^{-}_{i} = \frac {r_{i}^- - \text{mean}( \{r_k^{-}\}_{k=1}^{G} )} {\text{std} ( \{r_k^{-}\}_{k=1}^{G} )} \tag{37}

最终损失函数为:

JGRPOS_2(θ)=E{oi}πθθold[1G(i=1nmin(w^i(θ)A^iclip(w^i(θ),1ϵlow,1+ϵhigh)A^i)+j=n+1Gmin(w^j(θ)Ajclip(w^j(θ),1ϵlow,1+ϵhigh)Aj))](38)\begin{array}{r} \mathcal{J}_{\mathrm{GRPO}-\mathrm{S} \_2}(\theta)=\mathbb{E}_{\left\{o_i\right\} \sim \pi_\theta \theta_{\mathrm{old}}}\left[\frac { 1 } { G } \left(\sum _ { i = 1 } ^ { n } \operatorname { m i n } \left(\widehat{w}_i(\theta) \widehat{A}_i\right.\right.\right. \\ \left.\operatorname{clip}\left(\widehat{w}_i(\theta), 1-\epsilon_{\mathrm{low}}, 1+\epsilon_{\mathrm{high}}\right) \widehat{A}_i\right)+ \\ \sum_{j=n+1}^G \min \left(\widehat{w}_j(\theta) A_j^{-}\right. \\ \left.\left.\left.\operatorname{clip}\left(\widehat{w}_j(\theta), 1-\epsilon_{\mathrm{low}}, 1+\epsilon_{\mathrm{high}}\right) A_j^{-}\right)\right)\right] \end{array} \tag{38}

实验结果表明,在长链推理中,准确识别并奖励关键的、高不确定性的决策点,比单纯给予整体最终结果奖励是一种更有效的学习范式。

最后,本文最大的局限是:熵仅仅是对推理重要性的一种启发式度量,并非在所有情况下都完美(并不等于标准答案)。比如,一些简单的模板化推理步骤也可能由于词汇多样性而表现出较高的熵。

小结

本文继续 Token Level 角度对 GRPO 进行优化,介绍了两篇 GTPO,第一篇的 T 是 Trajectory-Based,核心思想是防止同一组内部轨迹之间出现不期望的分歧。为此,引入冲突感知的梯度校正机制,用于缓解共享 token 上的梯度冲突;第二篇的 T 是 Token,直接为每个 token 加入基于熵的奖励,让每个 token 奖励根据熵动态调整,设计的确很漂亮。两篇的 T 其实是没有关系的,虽然它们都下到更细的 token 粒度了。另外,感觉两篇都有点麻烦(并不是复杂),不像 GSPO 和 GMPO 那么简洁,总给人一种在打补丁的感觉(虽然确实是在打补丁)。总的来说,虽然读起来还是很爽,但缺乏那种让人眼前一亮的感觉。当然,如果非要说,个人觉得 GRPO-S 更加优雅一些。最后,不得不再次感慨一句,DeepSeek-R1 之后,RL(尤其是 GRPO 相关)真是越来越广泛和深入了,相关文章实在是有点多,类似这样的“补丁”后面可能没时间再细品了,得抓紧时间填其他坑了……

References

[1] GRPO“第一背锅侠”Token Level X:DAPO/DrGRPO与GSPO/GMPO的殊途同归 | Yam: https://yam.gift/2025/08/14/NLP/LLM-Training/2025-08-14-Token-Level-GSPO-GMPO/
[2] OPO: https://arxiv.org/abs/2505.23585
[3] AAPO: https://arxiv.org/abs/2505.14264
[4] BNPO: https://arxiv.org/abs/2506.02864
[5] GTPO: Trajectory-Based Policy Optimization in Large Language Models: https://arxiv.org/abs/2508.03772
[6] 这里: https://yam.gift/2025/08/14/NLP/LLM-Training/2025-08-14-Token-Level-GSPO-GMPO/
[7] Improving LLM Reasoning for Vulnerability Detection via Group Relative Policy Optimization: https://arxiv.org/abs/2507.03051
[8] GRPO优化在继续——CISPO和熵 | Yam: https://yam.gift/2025/06/19/NLP/LLM-Training/2025-06-19-CISPO-and-Entropy/
[9] GTPO and GRPO-S: Token and Sequence-Level Reward Shaping with Policy Entropy: https://arxiv.org/abs/2508.04349