类PPO强化学习三部曲:GRPO简化→DAPO修正→GSPO全面进化

B站影视 港台电影 2025-09-12 07:08 1

摘要:本文虽然标题中提到“类 PPO 算法”,但更准确地说,DAPO 和 GSPO 都可以视作在 GRPO 框架下,针对不同任务场景的一系列演进方案。它们并非简单的替代,而是通过改进策略更新与约束机制,逐步修正了 GRPO 在实践中暴露出的若干缺陷。

本文约10000字,建议阅读10分钟

本文介绍了类PPO强化学习三部曲。

本文虽然标题中提到“类 PPO 算法”,但更准确地说,DAPO 和 GSPO 都可以视作在 GRPO 框架下,针对不同任务场景的一系列演进方案。它们并非简单的替代,而是通过改进策略更新与约束机制,逐步修正了 GRPO 在实践中暴露出的若干缺陷。

这一脉络不仅揭示了算法间的继承关系,也能帮助我们更清晰地理解 PPO 系列方法在强化学习中的演化逻辑。

那么,GRPO 究竟存在哪些问题?DAPO 与 GSPO 又分别从哪些角度切入,提出了怎样的改进?接下来,我们就沿着这一条演进主线,逐步拆解背后的动机与机制。

01 PPO简单说明

为了后文内容连贯性,这里再简单介绍一下 PPO 算法,PPO 算法在 LLM 上的初始应用是作为模型输出内容的一种偏好调节,旨在使得模型输出更贴合人类偏好的回答内容。

在这个过程中需要让人类去针对问题进行排序标注,使用排序标注好的模型来训练奖励(RM)模型以及价值(Value)模型,一般初始的奖励模型和价值模型是同一个模型(也有使用不同模型的情况),区别在于 RLHF(人类偏好强化训练)过程中价值模型会进行参数更新,而奖励模型则仅进行推理输出奖励值。

下面是 PPO 中 Actor 模型,也就是我们目标主模型的强化学习训练目标函数:

优势函数

其中优势函数计算方式有很多种,其公式为:

需要注意优势函数中 是可以展开的,根据展开的方式不同也会存在非常多类型的优势函数,如果是 1 步展开即 TD(时序差分),如果全部展开到序列结束,则为 MC(蒙特卡洛),介于两者中间的为 GAE(广义优势估计)。不同展开方式各有优劣,具体可看上文连接(主要是方差与偏差)。

在 PPO 算法应用在 LLM 的 RLHF 训练过程中一般是存在 4 个模型,Actor 模型也就是训练的主模型,其训练的目标函数也就是上面的目标函数。

在对其训练中可以看到会计算优势函数 ,优势函数的简单理解就是在当前状态(LLM 上下文)情况下选择特定动作(选择哪个 token)相比较其他动作(vocab 中其他 token)带来的优势。

这里的 代表当前状态下具体选择的动作(action), 则代表当前状态选择具体价值后会带来多少潜在价值,而 则代表当前状态下所有动作潜在价值的期望,也代表了当前状态的潜在价值。二者差值则代表在当前状态下选择该动作相较其他所有动作均值的价值优势,因此也称为优势函数。

如果使用 TD(时序差分)方法来展开 ,则 ,这里的 代表状态 下选择动作 带来的价值收益(单步价值), 为奖励衰减因子,马尔科夫链的基础知识,这里不再解释。 代表执行动作后下一个状态的潜在价值。

优势函数中奖励值 需要使用提前训练的奖励模型来生成,因此奖励模型也就是 RLHF 算法中的第二个模型。

状态价值 及 需要一个价值模型来生成,因此价值模型也就是 RLHF 算法中的第三个模型。

第四个模型是参考模型,也是初始的 Actor 模型,在 RLHF 训练过程中参考模型不进行训练,仅作为 KL 散度约束 Actor 模型的输出分布不要离开初始的权重太多。这个模型的 KL 散度约束没有中主函数中进行体现。

以 GRPO 论文中的示意图来理解更准确(可以将上面文字与下图 PPO 算法示意图对照理解):

可以看到 PPO 算法涉及到了 4 个模型,更主要的是奖励模型需要提前进行训练,而价值模型也是一个 LLM,这就造成两个问题。

首先奖励模型的训练工作很复杂,虽然 DPO 算法可以通过绕过奖励模型的方案来训练,但 DPO 需要构造负样本,负样本与正样本的质量会影响训练的结果。

其次状态价值是由一个 LLM 给出的,这个值具备不确定性,也就是说价值模型提供的状态价值可能不准确,这样也就使得 PPO 训练过程变得极其脆弱。我们的目标是来最大化目标函数,价值模型预估偏差会使得 Actor 模型参数梯度往错误方向走一大步,很容易造成训练崩溃。

另外还有一点考虑,我们之前是对 LLM 输出内容进行人类偏好的强化学习训练,人类偏好本身是没有固定规则的,因此才需要去训练奖励模型来进行 LLM 输出内容是否符合人类偏好的打分。

但对于程序,数学等任务是具备规则特性的,对于一个程序任务或者数学任务,LLM 输出结果是可以使用规则来判断正确性的,这也是 GRPO 提出的一个前提。

02 GRPO

GRPO 中一般存在两个模型,主模型 Actor 模型以及参考模型,这两个模型初始时是同一个模型,但训练过程中参考模型只作为 KL 散度约束项来防止主模型训练中权重偏离原始模型权重太多。

PPO 中奖励模型更换成了特定的规则函数来进行奖励值打分,PPO 中的价值模型则直接取消,优势函数的计算更换成了 LLM 一组输出的奖励值标准化的形式。

GRPO 目标函数:

从公式中可以看到,对于一个输入 ,GRPO 会产生一组 个输出,对于这些输出会使用规则函数分别计算奖励值,即 ,使用这一组不同输出来计算优势函数 。

可以看到优势函数的计算只依赖于每个输出的结果奖励(结果奖励的意思是对整个输出序列即多个 token 进行整体的奖励值计算,但注意此时动作的粒度仍是单个 token,而不是整个输出序列)。

计算完每个输出的优势值,即 后,会将这个整体优势值均匀分配给该序列的每个 token,这么做还是因为 GRPO 的动作粒度是 token,后面进行重要性采样时是以 token 为粒度来进行计算的(重要性采样稍后会说)。也就是为什么优势值下标会带着时间步 t,实际上在计算时,同一个序列的每个 token 优势值是相同的。

GRPO 公式里也带上了 Actor 模型与参考模型的 KL 散度,KL 散度直观理解上十分简单,就是两个不同离散数据分布的相似程度,两个分布越相近则 KL 散度值越小,两个分布越大则 KL 散度值越大。

我们强化训练目标是最大化目标函数,因此需要减去这个 KL 散度值,如果目标模型训练过程造成与原始权重偏差较大,这时 KL 散度值变大,目标函数计算时会减去较大的 KL 值,因此使得整体目标值变小,来达到约束模型训练不过分偏移原权重的目的,反之亦然。

PPO 中目标函数也有这个 KL 约束,只不过省略掉了。

GRPO的问题与思考

GRPO 使得强化训练变得简单易行,但大家也能发现一些问题,每次训练时组的规模 取多大合适?如果该组内输出全错或全对怎么办?如果使得组内 个输出尽可能不一样?

这也是强化学习一直强调的“探索”与“利用”中的“探索”,“探索”在强化学习训练中是十分重要的,如果模型想获得更有的策略决策能力,也就是在不同状态下需要去选择更优的动作就需要去“探索”新的动作带来的收益。

因为强化学习训练本身就是一个通过不断试错来找到最优解的过程,如果在强化学习训练过程中让策略模型(也就是 Actor 模型)没有足够的“探索”能力(也就是模型输出不够多样)那模型就不会找的更好的路径,就会造成所谓的“熵坍塌”。

“熵坍塌”理解起来很容易,就是模型只在少量的输出中训练,这样使得模型输出分布变得越来越尖锐,模型分布会变得集中,分布的熵会变小。

因此 GRPO 训练中 应该更大一些(当然也需要分任务来说,有的输出范围本身就很小,分组规模也没必要大)。 中多样性也是通过不同的采样方法,不同温度超参数来进行采样控制。而如果同一组内模型输出都是错误的情况,那这个 step 训练过程来说也就变得没有意义。

其实 GRPO 还有个问题,就是极度依赖奖励函数,这也是对 PPO 精简后带来的一个显而易见的问题,去掉价值函数来对状态价值进行预估,仅使用奖励值来计算优势,那么就需要奖励值尽可能的公平公正。

对于简单任务来说不是很困难,但对于大多数实际任务来说,奖励函数是需要多方面权衡的,很难找到一个标准化的奖励函数去做奖励判断,如智能体任务中如果只将智能体任务完成与否来作为奖励值,那就没办法权衡智能体中间状态是否合理有效,是否有冗余轨迹等。

GRPO 训练甚至转变为去拟合奖励函数,换句话说会去钻奖励函数的空子,模型会为了获得高的奖励值生成与实际需要不符合的结果,因此奖励函数一定要综合权衡考虑。

GRPO 的奖励是序列级别,而动作是 token 级别,前面介绍了这是为了简化 PPO 算法带来的,但是这种动作与奖励粒度的不一致性其实会带来一些影响,后面 GSPO 会重点针对这个问题阐述方案。另外插个眼,GRPO 中的重要性采样是有问题的,具体的 GSPO 中会详细说。

关于重要性采样修正项在这里重点系统解释一下,方便后面说明,就是上述目标函数公式中的 ,重要性采样修正项的分母是旧策略模型产生的每个 token 的概率,分子则是经过几轮训练后新策略 prefill 旧策略输出得到的该策略中对应 token 上的概率值。

之所以使用重要性采样是因为强化训练轨迹是很珍贵的,一般情况下是需要多轮训练来提升利用率,这就使得当训练当前策略模型时会使用之前旧策略模型产生的轨迹。

而这两个模型实际上输出分布是不同的,那么如何对当前策略使用旧策略的分布,这就是重要性采样修正项的作用,注意重要性采样和重要性采样修正项不是一个概念,下面来介绍重要性采样。

重要性采样

假设存在两个数据分布, 和 ,可以使用下面等式将两个分布的期望连接起来,里面 称为重要性权重修正项,做为两个分布之间的修正项。

上式中 代表旧策略的分布,也就是 Actor 模型做 Rollout 的分布,而 代表训练中新策略模型的分布,我们当前仅知道旧策略分布情况(即之前 Rollout 过程),但我们目标是使得当前训练策略模型目标函数更高,但我们又不知道新策略模型的分布情况(因为没有 Rollout),听起来很绕,可以多读几遍。

因此需要使用旧策略分布来表示新策略分布,即使用 来表示 。看公式的期望下标,经过重要性采样成功使用旧策略的分布来表示新策略。返回 PPO 和 GRPO 目标函数公式也可以看到,最外层的期望是旧策略模型的分布,不是新策略模型分布。

但是有一点,重要性采样只是让两个分布在期望上达到了统一,但没有在方差上统一。

根据方差计算公式:

即使两个分布期望相同也只是上面公式的后面一项相同,两个分布的方差还是不同的。

这也是为什么从 PPO 或者更早 TRPO 开始需要增加 clip 项和 min 来控制这个重要性采样修正项,实际上是在控制两个分布的方差不要差距太大。

上面几个问题实际上是后面几个想要解决的,当然新算法也有其他的创新前提。

重要性采样的补充思考

在这里再额外补充一个概念,就是 on policy 和 off policy,在 LLM 的 RL 训练可以这样理解:当生成采样数据的模型与使用采样数据进行训练的模型是有相同权重(也就是同一个模型)时,换句话说就是自己产生数据来训练自己,这样叫做 on policy。

相反,如果使用其他模型或者非目标模型产生的数据来训练就属于 off policy。如果是 on policy 的话,上面的重要性修正项的值就为 1,因为相同模型会具有相同的数据分布,只有 off policy 情况下才会提现出重要性采样的价值。

一般在 LLM 的 RL 训练中不会使用 on policy,这一点主要从训练效率出发的,一般会使用 Actor 模型 Rollout 一大批的样本出来,将这一大批样本分为几个训练批次来进行训练。

这个过程中只有第一个批次样本进行训练时是 on policy 的,这个时候重要性采样修正项的比值大概为 1(考虑随机性波动),也就不起作用,但后面几个批次的目标模型权重已经发生了变化,再使用之前采样的数据进行RL训练就属于 off policy 了。

从算法理论上来说,如果不计较训练损耗,一直使用 on policy 来训练,GRPO 结论可能也未必会好,因为 GRPO 的问题在于动作粒度与奖励粒度的不均衡,在对 GRPO 目标函数计算梯度时每个 token 具有相同的优势值。

GRPO 梯度公式:

这时候主要的梯度贡献其实是重要性采样修正项的值,如果这个值为 1 的话,GRPO 每个 token 就只剩下了相同的优势值,其实这样就退化成了 SFT 训练的交叉熵梯度。

也就是每个 token 是具有相同奖励的行为克隆,因为从强化学习策略梯度定理角度来看,RL 相对于 SFT 梯度公式最大的区别在于每个动作(token)是具备不同优势值的。

03 DAPO

DAPO 引言部分就提到了其训练 GRPO 时出现了熵坍塌、训练不稳定、奖励噪声的问题,这也对应了上面我们分析的几个 GRPO 固有缺陷,这一点 DeepSeek 应该是有应对的 Trick,但论文中并没有提到。

DAPO 是字节的工作,因此开源代码也就使用的 verl,其针对 GRPO 存在的问题提出来解耦裁剪和动态采样策略优化(Dynamic sAmpling Policy Optimization DAPO)。

另外 DAPO 应对的场景是长 COT 场景, 也就是带思考模式的输出情况(上面也提到,当生成序列如果很长,重要性采样修正项会造成方差偏移的累积)。

下面是 DAPO 针对 GRPO 做的修正工作:

移除KL散度

上面的 PPO 及 GRPO 目标函数中都存在 Actor 模型与参考模型的 KL 散度,KL 散度的意义也说过了,就是不想让训练的模型与最初始模型分布差距太大。

但 DAPO 的训练方案应对场景是有长思维链输出(带思考过程)情况,长输出也就代表着对于输出 token 分布调整更大,那么训练后的模型就必然会与原始模型存在很大差异,因为目标就是让他们有差异,因此KL散度的约束反而不是必需的了,所以可以移除。

DAPO公式及创新点

从公式上看与 GRPO 整体相差不大,但有一些小细节的改动。

提高上限——Clip-Higher

首先改动是 clip 函数中的 ,在 PPO 及 GRPO 中都使用一个固定的超参数(一般是 0.2),但 DAPO 中分化成了 和 ,DAPO 论文中叫提高上限——Clip-Higher。

可以看到 clip 裁剪的对象是对重要性采样修正项进行裁剪,裁剪函数的图像示意如下:

为了方便理解裁剪函数实际含义可以简化为下面公式:

其中 代表重要性采样修正项, 代表 , 代表 。因此整体含义就十分好理解了。

OK,解释完裁剪函数后来看一下 DAPO 为什么要使用这种非对称的裁剪方案。

首先背景前提是模型根据指令会自回归的生成带思考过程的输出内容,每一个 token 被选择的概率是依赖于之前 token 内容的,而且根据当前主流的采样方式(核采样,top-k,贪心等)在都会去选择概率较高的 token。

而 GRPO 是对整个序列来计算奖励值与优势值的,这就使得在进行目标函数计算时每个 token 的优势值都一样,假设某条序列的优势值是正值,则训练的目标就是对该序列中的每个 token 都要正向的训练。

训练的结果就是要提升每个 token 在前置 token 中被采样的概率,使得模型输出多样性会进一步减小,造成整体输出分布熵的减小,也就是熵坍塌。那么为什么要提高裁剪高值可以缓解这个问题呢?下面展开说一下。

我们裁剪的对象是重要性采样比值,这个比值是新策略模型生成某个 token 与旧策略模型生成某个 token 的比值,当旧策略模型生成某个 token 的概率本身比较高时,其被裁剪的概率就会变低;而如果旧策略模型生成某个 token 的概率本身比较低时,其被裁剪的概率就会变高。

这么说可能有点绕,举个例子,比如旧策略采样到某个 token 的概率是 0.9,按照裁剪上限 1.2 计算(1+),则新策略采样到该 token 的概率是接近于 1(0.91.2 但最大为 1)。

注意新策略是我们训练目标函数期望的概率分布,也就是说旧策略中本身高概率的那些 token 是不容易被上限裁剪的,哪怕新策略下这个 token 采样概率很高了也容易被裁剪。

反之当旧策略采样到某个 token 概率是 0.1 时(一般情况下低概率 token 不容易被采样到,但强化训练 Rollout 会具备一定随机性),如果同样的现在裁剪上限是 1.2,那么新策略下这个 token 最高的采样概率也就是 0.11.2=0.12。

也就是说对于旧策略概率低的 token,即使训练后这个 token 的采样概率也不会有很大提升,因为提升上限被裁剪限制了。这样一对比,(0.99-0.9)>>(0.12-0.1)是不是就很明显的看到差距了。

这也是为什么 DAPO 要提升裁剪上限,因为不这样做的话,本来旧策略模型采样概率高的 token 会随着训练变得采样概率越来越高,而低的 token 只会有很小的提升,那么结果就是模型输出的分布越来越尖锐,也就使得分布的熵变低,造成熵坍塌现象。

上面是论文中的贴图,作者统计了哪些旧策略采样 token 容易被裁剪,可以发现,这些被裁剪的 token 的采样概率集中在 0.1-0.2 范围内,也证明了就是这些本身概率低的 token 容易被上限裁剪。

强化学习的训练过程一直以来的宗旨就是要平衡“探索”与“利用”,既要“利用”好已经有的经验来找到好的策略方案,又要去“探索”新的动作及状态,看是否存在更优的策略,上面的熵坍塌现象就会使得训练过程不能更好的去“探索”,无法找到更优策略。

前段时间忘记在哪里听到了一个座谈会,就是当下的强化训练算法都是使得模型输出的 pass @k 转为 pass@1,也就是没有更好的去探索新的可能性,而是让模型从原来可能的输出序列中去稳定生成最优的那一个。

本质上没有脱离模型能力范围,这其实与强化学习的思想相矛盾,强化学习是让模型去学习能力范围以外的知识来找更优策略,从这一点来说,GRPO 及以此提升的算法其实都没有更好的让模型去“探索”。

动态采样

DAPO 第二个创新点就是动态采样,前面对 GRPO 思考中提到过,如果 GRPO 对某一组输出的结果全是错误,或全是正确的情况下,这样组内的每个样本序列计算后的优势都是 0,因为本身就是每个样本序列奖励值与组内均值的差值最标准化,均值就等于样本奖励值的时候那么就没有优势了。

那就会造成这一组的训练不会对模型梯度变化有任何贡献,就代表本组训练没意义了。但一个问题就是当我们训练到后期就会面临一个组内很可能全正确的情况,这种情况出现的很自然,因为我们训练目标就是让模型输出序列的奖励值更高。这就使得后期的训练中有很多的组是没有意义的,白耗费训练资源。

上图是 DAPO 作者发现训练中一组32个输出全部正确的比例,训练越往后一个组内全部正确的比例越高。

除了耗费训练训练资源之外还会带来一个问题,假设我们有每个批次有 N 个指令来进行 GRPO 训练,这 N 个指令有的容易一些,有的难一些,模型在训练后期很可能在这 N 个指令中有 50% 的指令输出的组内序列全部正确,也就代表有一半的指令训练是没有意义。

随着模型训练到后期,每个批次中全为 1 的指令占比会更高。这会使得强化学习训练方差变大,因为我们输入指令让模型产生组内输出的过程实际是生成旧策略模型输出分布的过程。

只有指令足够多,旧策略模型输出的序列足够多才能更准确的表示旧策略的输出分布,当有效指令变少的时候,旧策略模型输出的分布也就存在一定的偏移,换句话说就是存在方差,也就是说 GRPO 越到训练后期训练的方差偏移越大。

关于解决这个问题 DAPO 也是简单粗暴,对于批次内生成的组内序列全部正确或错误的指令直接剔除掉,使用新的输出组中不全是错误或正确的指令来补充上,直到补全这个批次。

这个方法粗看会影响训练效率,因为你需要让每条指令去生成一个组,再去使用奖励函数判断才能知道输出的组中序列是否全部正确或错误,但是作者实验发现这种方法可以更快的让模型收敛,也就是说可以平衡掉 GRPO 耗费的资源,甚至更优。

下图是对照实验,紫色是使用动态采样的方案,蓝色是不使用动态采样的方案,很明显紫色更快收敛。

重新平衡动作:token级别策略梯度损失

在 GRPO 训练中针对每个指令输出一组的序列样本,这一组训练样本是有长有短的(token 个数),但不管 token 长度多少,组内每个样本是最后求平均值,也就代表每个样本具备相同的权重系数,即每个序列样本对本次训练的重要性是相同的。

这里可以比较一下 GRPO 与 DAPO 的外层求和与均值算法。

GRPO:

DAPO:

举个简单例子,假设 大小为 2,一个序列 token 长度为 100,这个序列的优势值是 1,另一个 token 序列长度为 10,这个序列的优势值为 -1,为简单起见不考虑裁剪,重要性采样修正的操作。

如果使用 GRPO 计算,则最后的结果为 0(此时只代表目标函数值标量为 0,但反向传播是看的梯度,梯度一般不为 0),而如果使用 DAPO 计算则结果为 ,在计算过程中大家就能感受到如果使用 GRPO 的方法是没有考虑 token 粒度的。

也就是说在同一个样本中每个 token 所占的权重系数随着 token 长度的增加而减小,这样的话模型输出序列的长度越长,每个 token 在训练中对应的概率调整的幅度就越小。

如果还是不太懂的话可以从策略梯度定理的角度来看,我们分别对 GRPO 和 DAPO 的目标函数算梯度公式。

GRPO 梯度公式:

DAPO 梯度公式:

从梯度函数中可以更明显的看到 GRPO 中样本级别与 DAPO 中 token 级别计算的区别,从梯度的角度可以更好理解 GRPO 长 token 序列对于每个 token 权重的稀疏化对于梯度计算的实际影响。与上面同样的理解,不再赘述。

另外还有一点是可以从梯度公式上看出来:对于一个每个 token 的梯度贡献来说,由于每个 token 的优势都是相同的,那么主要贡献值其实就来自于这个 token 的重要性采样修正项。

而且从梯度公式后面看到(大括号内)一旦该 token 的重要性采样修正项被 clip 裁剪,那么这个 token 实际上对于梯度更新是没有任何作用的,也就是说被裁剪的 token 实际上对于 GRPO 训练没有任何帮助,从这一点上来重新思考 DAPO 去提升 Clip 裁剪上限也是有意义的。

GRPO 这个问题的影响是长 token 序列的训练中每个 token 的修正幅度慢,比如对于长思维链的输出,假如最终推导结果正确,无论思维的过程很优质还是思维过程很差,该组的训练都不会对中间过程的 token 有较大的修正,比如优质内容的 token 采样概率应该增大,很差的思维过程 token 采样概率应该减小。

而 DAPO 的修正方案是对组内全部 token 赋予相同的权重系数,这样就可以从 token 粒度来进行梯度的更新,解决上述问题。

上图是对照实验,紫色是 DAPO 在 token 级别计算损失,蓝色是样本级别计算损失,可以明显看到紫色曲线无论生成分布的熵值还是输出内容长度都更平稳。

长序列的奖惩

这一部分并不是针对 GRPO 公式的修正,而是对于带思考过程的长序列训练的一个 trick,其背景在于一般情况下在进行训练时考虑到模型输出长度限制会对于很长的内容进行截断。

对于被截断的内容直接粗暴的给一个惩罚分值(负分),但忽略了可能这个长序列推导过程是正确的只是有点啰嗦,这种直接给负分会使得模型误认为这个推理逻辑是错误的。

因此 DAPO 做了个动态的长度奖惩机制,让模型训练有个缓存,可以意识到是长度带来的惩罚而不是逻辑内容错误带来的惩罚,具体动态惩罚函数:

这个函数没有什么可说的,简单明了。

整个 DAPO 是对 GRPO 的修正,提出了 4 个创新点,附上伪代码,读起来一目了然:

04 GSPO

GSPO 全称是 Group Sequence Policy Optimization,组序列策略优化。是qwen3 团队的工作,该工作也是对 GRPO 的改进,不同于 DAPO 是应对带思考的长文本场景,GSPO 应对的场景是 MOE 模型的训练(当然还有对 GRPO 算法的一般性改进,参考前文 GRPO 的思考)。

优化背景

GSPO 提到的一个 GRPO 关键性缺陷在于重要性采样修正项使用的粒度不对,GRPO 中是对序列中每个 token 进行的重要性采样,因为动作的粒度是 token,但是奖励却是对整个序列的奖励,这样会造成一种逻辑冲突的问题。

其实这个问题其他论文中也讨论过(忘记哪篇论文了),我们训练优化的目标是 token 的采样概率,这一点使用 token 作为动作粒度可以理解。但 GRPO 却是对一个序列整体奖惩,优化单元与奖惩单元粒度上不一致时的模型训练就容易出现偏差。

其实上面这个观点如果站在未简化的强化学习算法的角度上来讲(PPO 或者 A2C),优势应该是动作级别的,但是对于 LLM 的自回归输出场景来说动作级别的优势是不太容易计算的,上面介绍 RLHF 的时候也提到了,需要有奖励模型和价值模型。

但 GRPO 的简化方案使得每个 token 共享该序列整体的优势值,那粒度上对不齐也是必然的。从理论上来说带来的结果就是无法从 token 粒度上更快速的让模型提升正确 token 的采样概率。

就比如重要性采样思考中提到的如果使用 GRPO 进行 on policy 训练,当不可以重要性采样修正项时,从目标函数梯度上看 GRPO 的 on policy 训练就成了 SFT 训练,对每个 token 一视同仁。

除了上面问题外还有一个很重要问题是关于重要性采样修正项本身的,在上文中详细介绍了重要性采样的概念,这个概念是围绕两个分布展开的,涉及到分布,在统计学上是使用大数定律来近似一个分布的。

通俗点说就是需要随机采样非常多的样本才能用这些样本的概率分布来近似整体的分布,在传统强化学习中也有蒙特卡洛方法(可以理解成随机采样)来近似模型的策略分布。

但 GRPO 中的重要性采样修正项是如何计算的呢?它是计算新旧两个模型在某个 token 位置输出一个特定 token 的概率,使用这 1 个特定 token 样本的概率来代替该 token 位置的整个动作空间分布的概率,这样就极容易造成方差偏移的问题(这是上面介绍重要性采样方差公式的具体场景)。

这个实际 token 的概率很困难随机性原因偏高或偏低(也就是方差),随着输出序列的增长,这种方差是会累积的(因为自回归的特性,每个 token 的采样概率依赖之前 token),前面有 GRPO 目标函数的梯度公式,对组内每个样本 token 会累加求均值,方差累积后求均值是不会消失的。

除了以上的内容,GSPO 算法的出发点其实源自于 MOE 模型与 Dense 模型的区别,在 Dense 模型上使用 GRPO 训练模型不会有很大训崩的概率,但 MOE 模型上训崩概率很大。从下图示意原因就很明显:

区别在于新旧两个模型在进行序列中每个 token 概率计算时会被专家路由器路由到不同的专家模块,这样的话会造成重要性采样修正项变得极其不稳定,很容易被裁剪,被裁剪就会使得这个 token 在训练中没有任何的梯度贡献。

还有一点使用旧策略模型激活的专家获得的分布来训练当前策略激活的专家梯度,这样训练到最后会使得专家功能混乱,基于以上原因可以得出结论,在 MOE 模型上使用 token 作为优化的动作粒度是不合理的。

GSPO算法

上面的背景中问题的本质就是奖励粒度与优化的动作粒度不一致问题,很自然的想法就是既然无法将奖励粒度细化到 token 的动作粒度,那能不能将动作粒度上升到奖励的序列粒度?

也就是重要性采样修正不再对应 token 级别,而是对应序列级别,这也是 GSPO 做的工作。

GSPO 目标函数公式:

其中:

从 GSPO 目标函数公式可以看到与 GRPO 最大的区别就是在重要性采样修正项的处理上,也就是这里的 。

这里 代表的是一个序列中每个 token 的重要性采样累乘后的值进行几何平均,也就是说括号中的 (注意 的下缀中不再有 )是这个序列中每个 token 的重要性采样修正项的乘积结果,然后按照序列中 token 的个数来求几何平均。后面这一项是一个恒等式,在实际计算时会使用后者进行计算。

GSPO 的关键创新点就是将每个 token 的重要性采样修正改成了序列级别,目的是为了避免单个 token 带来的随机性极值引发较大的方差问题,再进行几何平均后会一定程度上消除这个序列中少量的几个 token 带来的方差偏移,相对于 GRPO 那种将每个 token 的重要性采样修正的形式更优。

上面这段话大家可能还是困惑,这里举两个例子,正确的序列内容,和存在偏差较大的错误序列内容。

正确的序列内容情况下:假设每个 token 的重要性采样修正项为:[1.1, 1.1, 1.2, 1.05, 1.1],因为新旧策略模型没有出现极值概率情况,内容正确,因此优势值为 +1。

此时 GRPO 在 token 粒度上对每个token都进行了鼓励,这没有问题,GSPO 的算数平均值为 1.109,也是对这个序列进行鼓励,在正确序列上二者都没有问题。

错误序列内容情况下:

假设每个 token 的重要性采样修正项为:[1.1, 1.1, 0.1, 0.1, 1.1],第三个和第四个 token 可能是旧策略出现的极值影响造成错误,由于内容错误,优势值为 -1。

此时 GRPO 会对第 1,2,5 个惩罚权重为 -1.1,但对错误的 token 惩罚权重只有 -0.1,这显然对于模型训练不利。

而 GSPO 的粒度是整个序列,这是这个序列几何平均为 0.425,乘 -1 的优势值后是 -0.425,代表了整个序列是错误的,应该惩罚,但惩罚大小是根据训练中错误 token 及 token 错误情况计算的。

综上内容大家应该理解了为什么 GSPO 要使用每个 token 重要性采样修正项的几何平均做完整体序列的重要性采样修正项。

其实到这里 GSPO 的主要内容就已经结束了,后面做了一些补充证明,比如证明 GSPO 在 token 级别上的形式,梯度分析等。

说到梯度分析,可以在这里说一下GSPO公式的梯度,如下图:

我们依然可以看到前面提到的问题,对于 GSPO 来说,当使用序列为单位做重要性采样时会发现序列中每个 token 中梯度上的贡献是一样的,其实对于就弱化成了交叉熵的梯度,相对于对这个序列进行 SFT 训练(前提优势是正值,值越大这个序列梯度重要性越大)

至于 GSPO 后面提到的 GSPO-token,个人感觉没有太大分析的必要,只是又从 token 角度上推导了一下公式,理解上没有什么区别。

来源:数据派THU一点号

相关推荐