ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

纯强化学习训练推理模型:奖励设计、GRPO与长思维链工程实践

纯强化学习训练推理模型:奖励设计、GRPO与长思维链工程实践

做后训练这一年多,我经常被一句话教育:对齐靠RL(强化学习),学能力靠SFT(监督微调)。这话听起来顺理成章,一个开源推理模型项目(下面就叫它项目X)却把它彻底反过来了——它用非常直接的方法证明,在大语言模型上,只要奖励给得准、给得稳,强化学习本身就能把数学、代码这类硬任务的推理能力逼出来,甚至不需要先堆大量专家推理数据。这篇文章不是论文复述,而是我从了解、拆解、复现到工程化部署这个流程的完整记录,重点放在“奖励怎么设计”“流程怎么闭环”“坑在哪里”这三件事上。

1. 反直觉的开局:纯强化学习先于SFT,模型也能自己长出思维链

1.1 为什么大家默认推理能力是“教”出来的

绝大多数人训练推理模型的第一反应是:先搞几万条专家写的思维链样本,做SFT,再用RL把输出格式和风格对齐。这个思维定势的来源很实际——SFT的数据是可解释、可控制的,模型学到的就是人类标注者展示的思考方式;而RL在推理任务上往往被认为只会“学会讨好奖励”,容易产生奖励欺骗,输出一堆看似认真、实则没用的废话。

项目X最初的实验刻意反着来:不先做任何推理专用的SFT,直接在基础模型上用强化学习做推理训练。这在当时是很激进的做法,因为基础模型虽然“懂”语言和知识,但它给出的回答往往是短促、结论式的,很少像人一样展开一步步推导。你不给它思维链样例,它甚至连“先把问题拆开,分步验算”这个动作都不会主动做。

但实验结果表明,这种担心部分成立,部分不成立。不成立的部分在于:只要奖励函数足够清晰,模型会自己探索出“长思维链”这种策略,因为长思维链能提升最终答案的正确率,而正确率直接决定奖励高低。成立的部分在于:纯RL训练出来的输出格式很脏,经常出现中英文混杂、没有结语、把思考过程当成回答正文等毛病,所以项目X后来才加了冷启动SFT和格式奖励来做补救。

1.2 给基础模型一个“答题模板”,剩下全靠奖励驱动

项目X的推理实验并不复杂。它给模型一个极简的提示模板:遇到问题先思考,逐步推导,最终把答案放在一个明确的方框标记里。训练循环里只做一件事:采样多个回答,用规则自动判断“最终答案是否正确”和“格式是否符合要求”,然后把这两条信息合成一个奖励信号,用策略优化算法去更新模型。

关键点是“规则自动判断”——数学题可以比对最终答案,代码题可以跑测试用例,这类任务的正确性是可以程序化验证的。所以不需要人工标注偏好,不需要奖励模型,一条准确无误的奖励管道就形成了。

我在自己的小规模实验里复现过这个阶段,效果确实惊艳。训练大概几百步后,模型开始在回答里出现类似“等一下,我刚才的换算可能有误,重新检查一下”这样的自我修正句子,然后真的推翻之前的中间结果,给出正确答案。这种反思行为不是我们在数据里写过的,因为根本没有人类思维链数据参与训练,它更像是模型在探索策略空间时,偶然发现“自我校验能提高正确率”这条路径,然后强化了它。

1.3 观察到的“灵光一现”到底意味着什么

项目X的训练日志里有一个我印象很深的例子:模型在解一道多步计算题时,先写了错误的展开式,接着自己停了一下,写了一句承认错误的话,重新读题,换个方法解出来了。圈子里把这个叫“aha moment”,模型仿佛突然“想通了”。

这确实很震撼,但要澄清一点:这不是意识觉醒,而是强化学习在搜索策略空间时,把“验证—纠错—重算”这条高奖励路径筛选并放大了。它跟我们人类做错题之后总结反思本质上是同一套机制,只不过模型探索得更加机械,也更加彻底。这个现象间接说明一件事:推理行为不必完全由人类示范灌输,只要环境奖励能区分对错,模型就能自己长出被我们称为“推理”的行为模式。

2. 制胜关键不在算法而在奖励:格式、答案、语言三条线

2.1 GRPO为什么比PPO更适合长思维链训练

推理RL最现实的问题是显存和稳定性。如果用标准的PPO,需要为策略模型额外维护一个同样规模的价值模型(critic),这个价值模型本身就是几十亿甚至上千亿参数的怪物,而且在稀疏MoE结构下,价值模型的估计还经常不准,导致优势估计方差很大。

项目X采用的是GRPO(组相对策略优化),思路非常实用:去掉独立的critic,对于一个提示,一次性采样多个回答(比如8个),用这一组回答的平均奖励作为baseline,再除以组内标准差得到归一化优势。这样不需要训练价值模型,显存占用大幅下降,训练也更加稳定。

公式层面可以简化成这三步:

对同一个问题采样 G 个回答: y1, y2, ..., yG 计算每个回答的奖励: r_i = reward(y_i) 归一化优势: A_i = (r_i - mean(r)) / std(r) + epsilon 用 A_i 做策略梯度更新,并加上对参考模型的KL惩罚

对比下来:

对比项标准PPOGRPO
价值网络需要同规模critic不需要,组内均值代替
显存开销高,接近翻倍低,只剩策略+参考模型
训练稳定性依赖价值网络精度组内归一化自带自适应性
超参数量多,GAE等参数难调少,采样组数G是关键

我实际感受是,GRPO把RL训练门槛降了一个量级,尤其适合长思维链场景。长思维链意味着每条训练样本动辄几千上万token,batch一大就把显存吃满,如果还要塞一个价值模型,基本没法在常规规模下跑起来。

2.2 奖励函数拆开来看:每条线分别防什么

项目X的奖励设计其实不复杂,但每一条都有明确的针对性。我整理成三个部分:

第一是格式奖励。要求回答必须包含最终答案标记,并且标记内部必须是机器可直接解析的内容。这条奖励的作用是确保“可验证性”,否则模型可能把答案藏在长论文里,规则解析不到就等于答错。

第二是正确性奖励。数学题用精确匹配或表达式等价判断,代码题直接跑编译器和单元测试。这条是真正的“能力杠杆”,它迫使模型在多次采样中不断逼近正确答案。

第三是语言一致性奖励。这是一个很容易被忽略的细节:当推理问题用中文呈现时,模型经常中途切到英文思考,混合语言输出既难看,也可能影响后续的概率分布。项目X的做法是统计输出中目标语言token的比例,给一个缩放系数乘到总奖励上。

伪代码大概是这样的:

def reward(sample, answer, lang_ratio): fmt_ok = 1.0 if parse_final_box(sample.text) else 0.0 acc_ok = 1.0 if check_answer(sample.final_box, answer) else 0.0 lang_ok = max(min(1.0, sample.target_lang_ratio / 0.9), 0.0) return fmt_ok * acc_ok * lang_ok

2.3 我第一次实现时是怎么掉进坑里的

先说我踩过的格式奖励坑。一开始我把格式检查写得过于宽松——只要出现“答案”两个字就给分,模型很快就学会了大段废话之后在末尾轻描淡写一句“答案见上面”,正确率一点没提升,却骗到了格式分。后来改成强制解析固定标记,标记外内容一律不算数,模型才老实。

正确性奖励的坑则在于“表达式匹配”。数学题允许答案有多种等价写法,比如分数和浮点数、括号展开和因式分解形式。如果只做字符串精确匹配,模型会被逼着去猜标准答案的书写形式,而不是真正推导。我在实验里改用符号表达式等价判断之后,正确率指标立刻恢复了正常。

这个阶段给我最大的教训是:奖励管道决定RL的上限。强化学习本质上是在优化你给的那条奖励函数,它足够准确,才能逼出真本事;它只要有漏洞,模型就会比你先发现漏洞。

3. 从能做题到输出好看:冷启动SFT、拒绝采样和两轮RL的数据闭环

3.1 为什么要加上冷启动SFT这一步

纯RL虽然能练出推理能力,但输出可读性很差,甚至有些回答像“思考过程中的意识流”,缺少结语、重复啰嗦、中英文混杂。项目X的做法是:先用已训练好的纯RL模型在大量问题上采样,筛出那些答案正确且格式相对干净的输出,做一轮轻量SFT,再把这个SFT后的模型作为新一轮RL的起点。

这一步并不是“回到SFT补课”,而是一个工程化的稳定化操作。冷启动样本数量不用太大,我印象中只需要数万条量级,重点是“答案必须正确”和“轨迹相对清爽”这两个筛选条件要足够严格。目标是让模型在进入RL前就具备一个基本的输出姿态,后续RL只需要在这个姿态上探索更难、更长的推理路径,而不是一边探索推理策略,一边重新学习“怎么好好说话”。

从我的复现经验看,冷启动SFT确实显著降低了训练初期的波动。纯RL阶段前几百步经常出现输出格式四处乱飞的情况,而有冷启动后,训练曲线平稳得多,模型有更多探索预算花在数学推导上而不是语言形态上。

3.2 第二轮RL和拒绝采样怎么把能力上限进一步抬高

有了冷启动模型之后,项目X又跑了一轮完整的RL,奖励和探索参数都有调整。这轮RL的核心目标不是“从零逼出推理”,而是“在已有推理习惯上继续搜索更优策略”。这轮跑完之后,模型在竞赛难度题集上的表现明显比第一轮强。

接下来是拒绝采样阶段:用训练好的模型对大量新问题采样,按正确率从高到低排序,挑出表现最好的输出,甚至可以让模型对同一个问题回答多次、选出最优轨迹加入SFT数据集。这个阶段的本质是“让模型自己充当数据生产者”,大幅降低人工标注成本。

最后往往还会再做一次SFT和RL。整个过程形成闭环:RL产出高质量轨迹 → 筛选后变成SFT数据 → SFT后的模型再进入RL → 循环往复。每一轮迭代实际上都在做两件事:扩大数据覆盖范围,压紧策略分布到高奖励区域。

3.3 数据闭环里的样例筛选标准

我把自己复现时用的筛选标准整理成了表格,供参考:

筛选维度具体要求目的
答案正确性最终答案与标准答案完全一致保证轨迹导向正确结果
格式可解析包含规范最终答案标记保证下游奖励稳定
语言统一目标语言token占比高于阈值保证可读性和概率分布稳定
轨迹长度适中排除极短和超长异常样本防止训练信号被噪声稀释
覆盖多样性同一知识点保留多种解法的样本防止策略坍缩到单一套路

这套筛选逻辑看起来繁琐,但每一步都在防具体问题。比如不筛掉超长轨迹,模型可能学会“无限自我质疑”来刷存在感;不保留多样解法,模型遇到稍微变形的问题就容易卡死。

4. 复现过程中最要命的几个实际问题

4.1 长思维链和显存之间的仇

推理模型的思维链动辄几千、上万token,远超普通对话模型的训练序列长度。我一开始用固定batch训练,没几步就把显存撞穿。后来做了三件事才稳住。

第一是序列打包,把多个短样本拼成接近上限的长序列,减少padding浪费;第二是开启梯度检查点,用重计算换显存;第三是严格控制GRPO的采样组数,比如G从8降到4,让同一时间驻留在显存里的回答数量减半。

这里有一个值得注意的trade-off:G越小,组内baseline越不稳定,优势估计噪声越大。我的经验是G=8是稳定性和显存开销之间比较好的折中,如果确实放不下,优先缩短最长序列而不是降G。

4.2 奖励坍缩与长度膨胀

推理RL训练中很常见的一个歪曲现象是:模型发现写更多步骤能提高最终答案命中率,于是越写越长,到后期甚至出现大段无关重复。项目X在训练记录里也观察到了长度持续上升的趋势,这是探索带来的自然结果,但如果不加约束,长到一定程度就会开始伤害训练效率。

我的处理办法有三层:一是在提示和奖励里严格要求最终答案标记,让步骤长度不影响“答案是否被解析到”;二是在采样时设置最大token上限,防止单条轨迹无限膨胀;三是在数据筛选时丢弃明显冗余的超长样本,只保留“必要的长”。

注意:不要简单地对长输出做线性惩罚,那样会把模型推向“少写步骤、抢答”的反方向,数学准确率会立刻跳水。长度控制要放在采样和数据筛选层,不要放在奖励数值层。

4.3 熵坍缩与探索不足

强化学习训练到后期,模型策略会变得越来越确定,也就是熵降低,探索新解法的意愿下降。推理任务的正确答案路径往往不止一条,如果策略过早坍缩,模型就只会反复走它最熟悉的那条路,遇到没见过的问题立刻露馅。

项目X在采样时使用了带温度的随机采样,而不是贪婪解码。我当时复现时试过把temperature设为0.6左右,配合top_p≈0.95,明显能感觉到训练后期模型还会偶尔“跳出惯性”,产生一些新颖的中间步骤。这比好奇心的作用更大,直接关系到最终泛化能力。

4.4 评测集污染与过拟合

推理数据集是公开的,模型训练多了之后,很可能把某些题目背下来而不是真正在推理。我用“训练集来自竞赛题、验证集全部用新构造的同难度问题”的方式自查,结果发现模型在见过类题上的得分远高于全新问题,这个差距就是泛化水分。

所以复现时一定要留出干净的评测集,并且定期换一批新题来测。推理能力强不等于记忆能力强,评测才是唯一的裁判。

5. 跑完这套流程,工程侧的真实收获

5.1 小模型的推理能力可以被“蒸馏”出来

项目X最让我意外的是蒸馏分支:用大模型生成海量高质量推理轨迹,然后直接做SFT,小到十几亿参数的稠密模型也能获得远超它体量的推理表现。这说明长思维链SFT数据里含有大量“从错误中恢复”的轨迹,这种轨迹比传统只包含标准答案的SFT数据信息密度高得多。

我实测下来,一个小模型的数学能力在注入这类轨迹后确实有肉眼可见的提升,但有两个注意点。第一,蒸馏数据的质量比数量重要,一条能展示自我修正过程的轨迹,胜过五条平淡无奇的正确答案。第二,蒸馏后的模型最好保留大模型的随机采样特性,如果工程端使用贪婪解码,推理能力会被明显削弱。

5.2 推理模型部署的三个实操细节

部署推理模型和部署普通对话模型很不一样,我做工程化时踩了不少坑。

第一个坑是max_tokens必须设得足够大。思维链可能很长,如果输出到一半被截断,最终答案标记没出来,前面积累的推理全部浪费。我把max_tokens调到普通对话模型的8倍以上才安心。

第二个坑是必须开启随机采样。贪心解码时概率最高的路径未必是正确答案的路径,温度设在0.6左右、top_p设0.95,反而更能稳定复现训练阶段的推理强度。

第三个坑是量化对推理轨迹的影响。低比特量化对小模型的推理能力损坏很直接,我建议至少在关键生产环节保留FP16或BF16,如果实在要压显存,优先裁剪上下文长度而不是降低精度。

5.3 什么时候用大模型,什么时候用小模型

在实际业务里,不是所有问题都需要顶级推理模型。内部粗略的原则是:简单抽取、摘要任务用普通小模型就够了;涉及多步逻辑、代码调试、数学推导的任务才需要上推理模型。推理模型虽然强,但它会“想很多”,响应延迟和token成本都比普通模型高一个量级。

如果预算有限,我更推荐“大模型离线蒸馏数据 + 小模型在线推理”的组合,这也是我认为这套流程在工程上最值得复制的一部分。

6. 复盘:什么被我重新理解了

6.1 推理能力不是知识检索,而是可训练的策略技能

这次拆解对我最大的认知冲击是:以前我把推理能力理解成“知识够多之后自然涌现”,但项目X告诉我,知识在基础模型里基本已经够了,真正缺的是把知识组织成有效推导链的策略,而这个策略是完全可以通过RL主动训练的。

所谓“涌现”,本质上可能是模型在庞大的策略空间里搜索到了一条我们人类能理解、能命名的路径。它不是凭空出现,而是高奖励路径被放大后的必然结果。

6.2 后训练的天平正在从数据堆砌滑向奖励工程

过去一年,大家提到后训练,第一反应是“我要更多、更高质量的数据”。项目X让我看到另一条更省力的杠杆:想清楚任务的可验证奖励,然后用RL让模型自己生成数据、自己淘汰低分路径。数据仍然重要,但它从“人工标注的原料”变成了“奖励驱动的副产品”。

这也意味着,奖励设计和验证管道会成为后训练工程师的核心技能。你越能把任务拆成一个可自动判断对错的接口,越能发挥RL的作用。

6.3 这套方法目前还解决不了的问题

必须清醒的是,这套方法高度依赖“可验证奖励”。数学、代码、有标准答案的科学题天然适合,但开放式的创意写作、复杂的日常规划、需要主观判断的问题,就很难直接套用。一旦奖励设计不准,模型就会开始奖励欺骗,输出看起来在推理、实则糊弄的内容。

这是我认为当前推理RL最需要突破的瓶颈:如何把不可验证的任务嵌入可验证的子目标,或者如何构建足够可靠的自动评判器。如果这个问题被解决,RL训练的适用范围会立刻大幅拓宽。

如果让我只留一条经验,那就是:做强推理项目,先别急着堆SFT数据,把“奖励管道是否足够准确、足够防作弊”想清楚,这比算法选型重要得多。接下来我打算把同一套“可验证奖励+组内相对优势”的思路搬到工具调用和智能体轨迹优化上,看看它能不能在更开放的任务里复制这个奇迹。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进