ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

GRPO训练技巧实测:从PPO到组相对优势的LLM强化学习避坑指南

GRPO训练技巧实测:从PPO到组相对优势的LLM强化学习避坑指南 过去大半年我基本都泡在LLM的强化学习里尤其是把训练策略从PPO切换到GRPO之后才真正体会到为什么现在推理类任务几乎一边倒奔着GRPO去。围绕GRPO我能找到的各种训练技巧我前后做了三轮成体系的评测复现了3篇论文级别的相关工作叠加自己的消融实验累计烧掉大约40万GPU小时。这篇文章就是把这套实测经验整理出来——那些被反复提到的GRPO训练技巧到底哪些值得抄哪些只是听起来合理、实际往训练里一放就浪费算力。先说清楚我的实验基线文本类推理任务为主覆盖数学、代码、逻辑推理三个方向基座模型从7B到32B都有训练框架基于vLLM做采样、底层用类Megatron的分布式训练管线精度是bf16混合精度参考模型和Actor共享同一套参数但冻结更新。整个评测跨度接近五个月中间还因为显卡驱动和CUDA版本不匹配白烧过两周的机器时间这些坑后面单独说。1. 为什么我这种“老RL”会被GRPO圈粉PPO的Critic是算力黑洞在GRPO出现之前大规模LLM的强化学习基本被PPO垄断。PPO的架构里除了Actor和Reference Model还必须有一个Critic网络去估计状态价值函数V(s)用它来计算优势值。问题在于LLM的token级状态空间极其庞大Critic很难学准。我之前的实际体感是7B模型训练时Critic参数量往往要跟Actor一样大甚至更大训练出的价值估计还是经常飘优势值噪声一大策略更新就跟着抖。GRPO的核心改动是彻底扔掉Critic。它不再估计绝对价值而是用一组采样输出之间的相对优劣来定义优势值。具体做法是对同一个问题采样G条输出按奖励排序然后用组内奖励的均值和标准差做归一化得到一个类似z-score的优势值。这个改动直接把“要训练一个价值网络”这件事变成了“多采几条样本做统计”说白了就是用显存换采样用额外的推理成本换调参稳定性。我评测下来有几个非常直观的感受显存占用肉眼可见地下降。7B模型用PPO至少要塞下四个模型Actor、Critic、Reference、RewardGRPO只需要三个而且Critic那个大头没了。我当时在8卡H800节点上跑7BPPO配G4最多只能塞batch size 512左右GRPO配G8还能扩到batch size 768单位算力能处理的样本量直接翻了一倍多。没有Critic意味着少一个灾难性遗忘源头。Critic学歪的时候会把错误的状态估计反馈到Actor的更新里这种错误是累积的而且很难追查。GRPO的优势值完全由组内相对奖励决定奖励信号是什么样优势值就是什么样行为要透明得多。GRPO不意味着一定比PPO好它的前提是奖励信号本身可比较。如果奖励是稠密且跨样本不可比的比如通用对话场景下用一个大Reward Model打一个总分组内归一化反而会把绝对值信息丢掉这时候PPO的价值函数仍然有意义。所以我的结论很直接如果你的任务能定义出明确的可比较奖励不管是规则奖励还是RLVR可验证奖励GRPO都是更划算的选择如果任务偏开放生成奖励模型给的分只是弱排序GRPO能用的空间就小一些。2. 评测棋盘3篇论文、40万GPU时是怎么花出去的很多朋友看到“10余项技巧评测”会觉得这就是对着技巧清单逐个跑一遍其实没那么简单。单个技巧的收益放到不同基座、不同任务上可能完全相反所以我在设计评测矩阵时参考了三篇比较有代表性的工作基本覆盖了当前GRPO训练的主流流派。2.1 三篇论文对应三条技术路线论文定位核心贡献我在评测里重点复现的部分提出GRPO的数学推理工作用组内相对优势替代Critic并配套了输出长度惩罚组大小G对收敛速度和最终pass1的影响将GRPO推广到通用基础模型的工作把规则奖励扩展到代码/工具调用引入奖励 shaping 和课程采样不同奖励组成在通用任务上的稳定性聚焦过程奖励模型与RLVR分发的工作稀疏奖励下怎样设计密集化信号减少随机探索消耗过程奖励与结果奖励混合时的收益边界这三篇论文对应的是三种非常实际的工程场景单一任务规则奖励、多任务混合、稀疏过程奖励。我在复现时不是照搬它们的超参而是把每个关键模块拆出来在我自己的基座上做消融。比如第一篇的组大小实验我额外补了G6、G12这种非对称档位第二篇的奖励shaping我在三个任务上都做了第三篇的密集奖励我替换成自己的语法树解析器重新实现了一遍。2.2 算力账单的透明度40万GPU小时这个数字听起来吓人拆开算其实很清晰主实验矩阵8个基座×3个任务×10项技巧×每个技巧至少2组对照单组训练大约需要1200到2000 GPU小时这部分占了约60%。超参搜索与失败重跑GRPO对奖励归一化、KL系数、采样温度这些参数比较敏感早期搜索浪费了不少我估算有约15%的算力花在了方向错误的重跑上后面会详细说。采样和评估开销GRPO的组采样是G倍推理开销加上eval、baseline复现、Reward Model验证大概占25%。这个成本分布本身就是一个重要结论**GRPO省下的训练算力很大一部分又被组采样吃回去了。**所以不能只看训练曲线变陡就开心得把采样成本计入总账单。我的建议是跑GRPO消融实验时一定要定义一个“单位有效样本成本”否则很容易被静态训练曲线误导。2.3 评测环境的稳定性Long training runs最怕环境不稳定我第二次大评测时连续遇到vLLM版本升级带来的采样分布变化、CUDA driver和PyTorch不匹配导致半场崩掉的问题。后来固定了完整的环境快照Python 3.10、PyTorch 2.1、vLLM 0.4.x、固定版本CUDA 12.1并且所有对比实验都从同一个seed出发。这里有个容易忽略的细节vLLM的采样并发度会影响随机性不同并发下同一个温度采样出来的分布不完全一致所以评测组数和单组大小都保持一致否则对比结果会带入额外的噪声。2.4 我用什么指标衡量技巧收益单一指标容易被技巧“骗”。比如只看训练集奖励长度奖励很快就能刷爆只看pass1可能牺牲了输出的多样性。我统一用四个指标综合打评训练过程中奖励曲线的收敛速度和震荡幅度测试集pass1 / passkk由输出数量的计算预算决定输出长度变化趋势是否异常膨胀训练稳定性有没有出现loss spike或者优势值集体爆炸3. 十项GRPO训练技巧逐个过秤下面进入重头戏。我按自己的评测顺序把十项主流技巧逐一拆开每个技巧都会给出我实测里的结论、推荐配置以及适用边界。这里的结论来自我的任务分布不一定对所有人通用但方法论可以复用。3.1 组大小G收益有明确的幂律边界GRPO里最核心的超参就是采样组大小G它直接决定了优势估计的稳定性。我做了G2、4、8、16、32的五档实验核心结论是G从2提到8收敛速度提升非常明显。以GSM8K级别的数学题为例同样600步训练G8比G4的测试集pass1高约3个百分点。G从8提到16收益只剩一个点左右但采样成本翻倍。G32在部分任务上反而出现轻微的过拟合倾向训练集上的奖励漂亮测试集持平甚至下降。从理论上看组内样本越多优势值的方差越低但这本质是中心极限定理的体现方差下降速度是1/G的平方根关系。所以收益递减是数学上注定的不是工程可以绕开的。如果你显存有限我建议G8是性价比最高的档位G4也能跑但需要把KL系数调得更保守。实际操作中还有一个沟通成本很低的技巧**不要用固定G而是根据单条样本的奖励噪声动态调整。**奖励噪声大的任务多采样噪声小就少采样。实现上可以每隔几百步统计一次组内奖励的标准差标准差超过阈值就把G调大一档稳定后再降回来。我在一个代码生成任务上做过对比动态G比固定G8省了约20%采样预算最终pass1还高0.8个点。3.2 KL散度控制固定系数和自适应退火差距很大GRPO在更新策略时有一个对参考模型的KL惩罚项防止Actor跑飞。常规做法是设一个固定的KL系数β但我在评测里发现这个β对训练稳定性极其敏感。β太大比如0.05以上策略被牢牢锁在参考模型附近奖励提升非常缓慢训练曲线像条平线。β太小比如0.001以下前几步奖励涨得飞起但不到200步就会出现一次优势值爆炸然后策略快速退化输出出现大量重复token。比较稳妥的策略是自适应退火训练初期用一个中等偏大的β0.01量级保证稳定等奖励曲线进入平台期后逐步调小让策略有空间去钻奖励函数的空子也就是真正优化目标。我参考了论文里类似的外环控制做法做了一个按训练进度线性衰减的schedule前10%用β0后90%线性降到β0/5。对比固定系数同样的步数下测试集准确率高1.2个点训练过程几乎没出现震荡。这里有个很反直觉的发现KL惩罚并不应该只防策略跑飞它还在间接调节输出的信息熵。如果你发现训练后期输出多样性急剧下降先别急着调温度试着把β临时调大一档往往能拉回来。3.3 采样温度与组内多样性采样温度决定组内G条输出彼此有多“不同”。如果温度太低G条输出几乎一模一样组内相对优劣就退化成个体优劣GRPO就失去了统计意义。如果温度太高输出质量整体下降奖励普遍偏低优势值的信噪比反而降低。我做了温度从0.6到1.2的扫描最优区间落在0.8到1.0之间。0.6到0.7这个区间虽然单样本质量高但组内多样性不足训练后期容易出现“奖励竞争停滞”——每个组里最好的样本都是同一个答案其他样本都是陪跑GRPO退化成只对一条样本做策略梯度方差非常大。更精细的做法是动态温度前25%训练步数用偏高的温度1.0扩大探索之后降到0.85左右转为利用。这个做法在很多RL环境里都有类似经验但在GRPO上特别有效因为组内优势估计的质量直接依赖探索初期的多样性积累。如果训练开头就锁死在低温度基本等于自断一臂。3.4 奖励归一化跨任务共享的问题比想象中大GRPO原始论文是在组内做z-score归一化这一点本身没有问题问题出在多任务混合训练时不同任务的奖励天然不在一个量纲上。举个例子数学题的结果匹配奖励只有0和1两个值代码任务的单元测试通过率可能是0到1的连续分而格式奖励可能是一个固定加分项。如果在同一个batch里混合这些任务组内归一化没问题——因为归一化是在每个组内部做的但组的分配方式会严重影响结果。我最开始按任务均衡采样每个micro batch里混合了多个任务的样本后来发现一个任务奖励噪声大的组会“污染”梯度估计。我的解决方案是在构造GRPO组的时候尽量保证每组内部是同质任务或者说把归一化改成“分位数归一化”而不是均值方差归一化。用分位数的好处是对离群值不敏感。我看过那种某个组里有一条输出因为格式加分拿到极高奖励、其他样本都是0分的情况z-score会把优势值拉得特别极端而把那个加分项单独作为规则奖励而不是参与z-score计算效果会稳定非常多。实操建议把所有奖励分成两类——“主奖励”和“shape奖励”只有主奖励参与组内归一化shape奖励作为筛选条件或直接加到回报上但不参与优势计算。这个改动帮我减少了很多次训练崩溃。3.5 长度与格式奖励硬编码的收益陷阱几乎所有复现GRPO的团队都会加一个长度惩罚防止模型通过输出一长串废话来“骗”奖励。第一篇提出GRPO的论文里也明确提到了长度奖励但它本质上是一个约束不是一个优化目标。我在评测中看到的情况要更复杂长度惩罚系数太小时输出长度会逐渐失控。代码任务上尤其明显模型学会了在代码里塞大量注释和空行实测平均输出长度从400 token膨胀到1500 token而单元测试通过率只涨了不到1个点。长度惩罚系数太大时模型会把输出截短到刚好卡住边界牺牲推理步骤的完整性。数学题上能看到模型为了满足长度约束把多步推理压缩成一行步骤缺失直接导致最终答案错误。我自己最终采用的是分段线性长度惩罚输出长度低于预设的合理区间下限不惩罚处于合理区间不惩罚超过上限的部分按超出的token数线性惩罚并且惩罚系数随训练进度逐步衰减。这样既防膨胀也不至于在早期误导策略。格式奖励就更微妙了比如要求输出以特定标签开头结尾如果直接给它一个0/1硬奖励模型会很快学会“只满足格式但输出垃圾”。正确做法是把格式奖励做成mask格式不对的样本直接不参与训练但格式对了也不额外加分让模型把格式内化成一个约束而不是拿去刷分。3.6 参考模型冻结与滚动更新的权衡GRPO里参考模型是用来计算KL散度的锚点最朴素的做法是全程冻结初始模型。但这种做法有个隐性成本随着训练推进Actor的分布和冻结参考模型的分布越离越远KL项会越来越大等效于β被不断放大策略更新越来越“僵硬”。我在评测里试了三种方案方案A全程冻结参考模型。训练前期稳定后期KL项持续增大最终测试集准确率受抑制。方案B每隔N步用当前Actor的权重硬更新参考模型。训练更灵活但KL含义不再指向“初始策略”如果更新太频繁参考模型会跟着跑偏最终退化成没有约束的RL。方案C指数滑动平均EMA更新参考模型。兼顾稳定和灵活是目前我实测下来最稳的方案EMA系数取0.95到0.99之间。方案C还有一个额外好处EMA参考模型的奖励曲线比Actor本身平滑很多我可以直接用它的输出作为评估指标比单独跑eval更早发现训练恶化趋势。3.7 课程学习与任务混比很多团队在GRPO初期都会加课程学习比如先从简单题开始后混入难题。我的评测结论是**课程学习有效但收益来源不是任务难度本身而是混合比例改变了优势值的统计分布。**简单任务奖励噪声低策略早期可以更快建立正确的基本行为直接上难题会让早期优势值方差过高策略还没学会基本格式就开始乱飞。不过在超过20%的评测里我发现显式的课程设计不如动态难度筛选。做法是每个训练step从候选池里按当前策略的表现采样策略在某个任务上奖励低于阈值就多采这个任务高于阈值就减少它的比例。这个自适应课程本质是在控制优势值的信噪比比人为排序难度要鲁棒。需要注意一个副作用自适应课程会让训练分布偏离真实任务分布导致最后几个任务的pass1被牺牲掉。所以我最终采用的做法是“两阶段”前40%用自适应课程让策略快速进入正确区域后60%锁死任务比例保证最终在各任务上的均衡性能。3.8 损失函数权重与Token级掩码GRPO的损失函数一般用policy gradient的变体但计算loss时在token维度上怎么聚合有很多细节。标准做法是对每个token的log prob加权求和但推理任务里提示词部分不应该贡献梯度因为prompt是固定输入更新它没有意义。问题出在“哪些token算有效”上。我见过不少复现代码把整条序列的token log prob都算进去导致模型把大量梯度花在优化“题目文本的生成概率”上——这完全是个伪任务。正确做法是只对输出部分做mask如果是代码任务进一步mask掉非代码token比如markdown标注。这个小改动在7B模型上直接让同样的训练步数下有效loss占比提升约15%收敛速度肉眼可见地加快。还有一点是组内聚合权重有的实现里每条样本的梯度是按它在组内的归一化奖励加权的有的则把归一化奖励当成常数乘在整个序列loss上。前者更接近REINFORCE with baseline的语义后者更像是奖励加权MLE。我实测下来前者更稳定因为它在token级别保持了策略梯度的正确方向。如果工程架构限制只能做后者至少要把奖励归一化到0均值否则梯度方向会被正优势样本主导。3.9 预热阶段与学习率ScheduleGRPO对学习率异常敏感。我在7B模型上试过3e-7到3e-6的区间超过1e-6几乎必炸1e-6以下又太慢。核心原因是GRPO的优势值来自组内采样方差即便归一化后仍然存在太高的学习率会把噪声直接放大到破坏策略的程度。我推荐的做法是前三到五步用一个极小的学习率比如目标学习率的1/5做预热让采样的组内奖励分布先稳定下来再进入正常学习率。这个预热不是为了传统意义上的“warmup the optimizer”而是让vLLM采样分布和训练器之间先“对齐”否则前几步的优势值统计量很可能因为采样并发不稳定而失真。3.10 梯度裁剪与损失裁剪很多GRPO实现里会加一个global gradient norm clipping这个我测下来是必须项但阈值不能照搬PPO经验。PPO里常用0.5到1.0的裁剪阈值GRPO的优势值分布相对更平滑可以把阈值放宽到1.0到2.0。太紧的裁剪会压低有效梯度让训练在平台期磨很久。比梯度裁剪更有效的是loss裁剪对单条样本的优势值做一个绝对值上限比如限制在[-3, 3]之间。GRPO的组内归一化优势值偶尔会出现极端离群尤其是奖励设计早期如果不限制一条离群样本就能让整个batch的策略更新方向偏掉。加了loss裁剪之后训练稳定性好了很多而且几乎不影响最终准确率。4. 单看都有效叠加就翻车技巧之间的交互效应评测进行到中段我意识到一个问题把十项技巧逐个跑一遍几乎每一项单独都能带来一个点的提升但要是有人天真地把它们一起开满训练大概会在三百步内崩给你看。我记录了一个典型的组合失败实验非常值得拿出来讲。4.1 一个让我印象深刻的负交互案例我当时在一个数学推理任务上把六个技巧同时打开G16、动态温度、EMA参考模型、自适应课程、衰减KL、loss裁剪。理论上看每个技巧都有论文支撑结果训练到第250步时奖励曲线突然断崖式下降随后输出开始疯狂重复同一个词组。事后排查下来的交互链路是自适应课程前期把难题比例降得很低模型快速在简单题上过拟合于是简单题奖励阈值上升课程又把简单题比例降得更低形成了正反馈的“逃课循环”。动态温度这时候还在按步数下降探索能力越来越弱策略被困在一个已经偏离基础的分布里。EMA参考模型虽然稳住了KL但因为参考模型也在往同一个错误方向滑动等于没有提供约束。最终所有单点有效的手段互相放大偏差崩得比不调参还快。4.2 真正能叠加的“正交组合”交互效应严重的地方在于这些技巧都在影响同一个东西组内优势值的分布。凡是直接改变优势值分布的技巧组大小、温度、归一化方式、课程采样都不建议同时大改否则等于给整个GRPO的统计根基引入了可控性极差的扰动。相反的那些作用在不同环节的技巧可以放心叠加。我实测下来最稳的组合是固定或EMA的参考模型影响KL约束输出token的label mask影响loss计算分位数归一化加loss裁剪影响优势值鲁棒性分段线性长度惩罚影响奖励 shaping这四个环节互不重叠分别作用在训练目标的四个独立维度叠加后没有出现相互放大的情况最终收益基本等于各自收益的加和。而G、温度、课程三者属于“采样策略”维度我每次只动其中一个另外两个锁死在一个合理默认值上。5. 被浪费的GPU时我踩过的三个大坑这节不是技巧是倒掉的真金白银。很多坑在论文里只会写“we found that……”但到底怎么发现的、花了多少算力才意识到才是对我们有参考价值的。5.1 优势值方差监控缺失导致的反复震荡最开始我没有专门记录组内优势值标准差只看奖励曲线。直到某一次训练奖励曲线一路走低我还以为是学习率问题反反复复调了三轮超参浪费了差不多两万GPU时才发现是奖励归一化时把格式奖励也算进了主奖励导致优势值被一个几乎恒定的加分项抬高真正的任务奖励差异被稀释了。后来我把“组内优势值std”“每条样本被选中的概率”“每组内不同答案种类数”这三个指标都接到了训练日志里。现在只要std突然飙升我第一时间停住多采集一步看一下数据基本能避免再为类似问题白烧算力。5.2 长度奖励被模型系统性刷分有一段时间我在数学任务上加了长度惩罚结果模型学会了在证明题里把同一个引理换着花样写三遍长度达标但信息量没有增加。长度奖励本质上是不能被模型“误解”的因为模型真的会去优化它。我后来做了一组对照用“新增信息量”替代“token长度”作为惩罚依据具体做法是对输出做语义去重重复的推理片段只算一次长度。这个改动让数学任务少了大概12%的无意义输出测试集效果也回升了不少。5.3 组内重复样本让“相对优势”名存实亡还有一次是采样阶段为了省显存把温度和top-p调得很保守最终G条输出里有超过一半是同一个答案。组内奖励扎堆归一化之后优势值基本都落在零附近策略根本学不动。我去看训练日志才发现熵指标异常低。这个问题的隐蔽性在于训练loss在降奖励在涨但真正学到的东西趋近于零。想要发现这个坑最好的办法是统计每个训练step组内unique样本比例低于60%就要警惕了。6. 不同预算下怎么抄这套结论40万GPU小时评测出来的结论不可能所有人都有条件原样复制所以我最后按预算档位给一套可以直接上手的推荐配置。6.1 百卡时以内的轻量实验只有一两天算力的话不要试图复现全量GRPO先聚焦在两件事上调好组大小G和KL系数。我建议G8β取0.01附近其余全部用论文默认值。这时候最值得做的是验证你的奖励信号到底稳不稳把奖励函数里每一项单独在1000条固定样本上算一遍分布看方差和离群值。这一步几乎不花训练算力但对后续训练成功率影响巨大。6.2 千卡时级别的认真评测这个预算能支撑一个7B模型、一个任务、20组以内的消融实验。先固定一组基线G8、固定β0.005、温度0.9、普通z-score归一化、输出token mask然后只动一个变量跑满全程。优先测温度、长度惩罚、loss裁剪这三项因为它们在现有实现里几乎是零成本改动收益却很明显。6.3 万卡时以上的完整复现到了这个量级可以做比较完整的评测矩阵了。我的建议是不要照抄我的组合而是按我前面说的正交原则自己搭先确定采样策略维度的默认值再单独扫奖励归一化和KL退火最后再加EMA参考模型和动态课程。每一步都要保留日志和checkpoint方便事后定位负交互。6.4 迁移到代码生成、工具调用等新场景如果你不是做数学推理而是做代码生成或工具调用有两点需要特别注意。第一代码任务的结果奖励通常是“单元测试通过率”这是一个0到1的连续值组内归一化时要额外照顾一下全组都是0分的情况我建议给这种组一个保底的负优势避免整组样本都不更新。第二工具调用任务里输出长度方差极大长度惩罚几乎必然和奖励产生冲突我更倾向于用“回合数”而不是“token数”作为惩罚维度限制模型来回调用无效工具。根据我个人一贯的做法遇到新场景我不会先调模型而是先拿20条有代表性的问题人工检查GRPO采样的组内多样性——这一步在代码生成任务上救过我太多次了。很多时候模型学不动不是数学上的梯度问题而是采样阶段就已经把解决方案空间锁死了。先保证G条输出覆盖了足够多的不同解题路径再谈KL、再谈奖励顺序反了后面的技巧全都白搭。
返回列表