news 2026/10/19 4:42:37

用大语言模型构建过程奖励模型:解决强化学习稀疏奖励的实践指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用大语言模型构建过程奖励模型:解决强化学习稀疏奖励的实践指南

前阵子看到一篇关于过程奖励模型(PRM)的工作,题目里三个词凑一块挺有意思:大语言模型、强化学习、过程奖励。做过RLHF或者RLVR的同学应该都有体会,奖励信号给得太粗,是训练跑不稳的一个重要来源——模型往往要先试很多轮,才知道自己中间某一步走歪了。这篇工作想解决的核心问题很简单:别等最后答案出来再算总账,而是用大语言模型本身去当裁判,给强化学习的每一步过程都递一个反馈信号。这篇文章我就把PRM的原理、用LLM做PRM的几种思路、完整落地链路和踩过的坑一起梳理出来。适合正在做推理模型训练、RL对齐,或者想给模型中间过程加监督信号的人参考。

1. 先从"奖励给谁"说起:ORM与PRM到底差在哪

1.1 结果奖励模型的隐忧:稀疏奖励与信用分配

结果奖励模型(Outcome Reward Model,ORM)是目前RLHF体系里最常见的组件。流程很简单:让模型根据问题生成一段完整回复,最终答案对了就给+1,错了给0或者-1,然后拿这个全局信号去更新策略。这套做法在短回答里表现尚可,但只要任务一拉长,问题就藏不住了。

拿数学题举例。一道五步的推理题,如果第四步算错,最终答案大概率是错的,策略收到的只是一个冷冰冰的负信号。它不知道自己是第四步失手,还是第三步的思路一开始就埋了雷,只能靠反复采样去碰运气。这在强化学习里叫稀疏奖励和信用分配问题:反馈信号只有一个,中间哪一步导致失败却完全不可见。更麻烦的是,一旦任务变成几十步甚至上百步的代码生成或者工具调用,正确信号几乎被淹没在大量中间行为里,梯度基本带不动策略。

有个比较贴切的类比:老师只给你期末总分,不告诉你哪道题、哪一步扣的分,你复盘的时候只能把整张卷子重做一遍。ORM干的差不多就是这种事。它当然不是没用,作为终极的"任务对不对"判断,它是锚点;但光靠它,训练曲线往往又慢又抖。

1.2 过程奖励模型:把"对错"切到每一个步骤上

PRM的思路就是补上"批改过程"这一环。它不再直接对最终答案做整体打分,而是对轨迹中的每个步骤、每个中间状态单独输出一个奖励值。形式化一点看,一条轨迹由 s0, a1, s1, a2, s2, ... 组成,PRM给出的是一串 r(s_t) 或者 r(s_{t-1}, a_t)。策略优化的目标也相应变成最大化中间奖励的累积,而不是只盯最后一个终态奖励。

这样做最大的收益,是RL算法拿到的是密集信号。模型能比较精准地感知到"第几步开始出错"、"哪一步是有效推进"、"哪一步虽然没直接写错答案但对解题没有帮助"。在训练中,PRM经常以reward shaping的形式和最终结果奖励一起使用:整体方向由ORM兜底,中间过程由PRM引导。实际跑下来,双轨并进通常比单用任何一种都稳。

需要说明的是,PRM不是这两年的新概念,早期游戏AI、机器人控制里都有非常类似的过程奖励设计。真正让它重新变成热门方向的,是大语言模型自己的长链推理能力提升之后,"谁来标注中间步骤成本更低"这个问题的答案变了。

1.3 过程信号为什么最近特别值钱

过去几年大家训练大模型,习惯还是"端到端出一个答案,和标准答案比对"。但对推理类任务,这个范式有个越来越明显的短板:模型的推理链条一长,光看结果很难判断它是不是真的在逻辑上站得住。两个模型可能最终答案一样,但一个是真推理,一个是撞运气;如果只用最终奖励,撞运气的那条路反而可能因为采样概率高而被强化。

在这种背景下,过程监督的价值就凸显出来了。它能区分"过程正确但结果碰巧错"和"过程错误但结果碰巧对",这对训练一个真正具备推理稳定性的模型很关键。这也是为什么今年不少做对齐和RL的工作,都开始往PRM方向倾斜。

2. 为什么要让大语言模型来当过程奖励模型

2.1 传统PRM落地的最大障碍:标注成本

写PRM的经典教科书路径,是收集大量人类对中间步骤的标注。让标注员回答"这一步是否正确"、"这一步是否有效推进了求解"。听起来不复杂,但真正落地非常痛。

首先是贵。一条多步骤推理轨迹,人工审一遍的时间远比审一个最终答案长,乘以十万级的数据量,预算直接起飞。其次是一致性差:两个标注员对同一步的看法经常不一致,尤其面对"方向对但中间有个小错"这类灰色地带,偏差特别大。最后是领域迁移难:数学题的标注规则换到代码生成任务上就用不了,每个新领域都要重新组织标注流程,工程成本非常高。

正是因为这几道坎,PRM在很多团队里一直是"知道它好,但建不起来"的状态。

2.2 大语言模型做PRM的先天优势

用LLM来承担PRM的角色,几乎是对着痛点来的。第一,LLM本身就会推理,让它去审阅"另一个模型的推理过程",这件事是内行的——它知道什么样的步骤是有效的解题推进,什么样的步骤只是看似合理的外围废话。第二,语言模型输出的是文本评价,天然可解释,调试的时候能看到"为什么给这个分数",不像一个纯数值模型那样是个黑盒。第三,扩展性好:同一个LLM,换一个few-shot示例就能适配新的任务领域,不一定要重新标注和重训。第四,它可以配合工具或验证器使用,把"文本判断"和"可执行验证"结合,可靠性又上一层。

其实可以把它理解为:人类老师不够用的时候,先让一个高年级学霸来当助教。它不是完美裁判,但覆盖速度和成本都远远优于人类。

2.3 用LLM搭PRM的四种常见形态

具体怎么让LLM当PRM,实践中大致有四种做法,各有各的适用面。

形态做法优点缺点适用场景
直接评分把步骤文本拼进Prompt,让LLM输出0/1或离散分档实现最快,一两个接口就能跑通分数噪声大,可能出现位置偏差和长度偏好快速原型验证、探索可行性
生成式Critic让LLM生成修正后的步骤或完整评语,再用语义相似度或验证器打分信息量大,评价可解释计算成本高,生成链路过长引入额外不稳定需要分析错误原因、做数据清洗时
蒸馏小模型用LLM标注一批步骤数据,微调一个小基座模型做分类/回归推理快、部署便宜、打分稳定需要先积累一批高质量标注数据生产环境长期使用,RL训练迭代频繁
LLM+验证器LLM负责结构化判断,规则/编译器/公式验证器做最终锚定可靠性最高,不容易被奖励黑客依赖验证器的设计质量,通用性受限数学、代码等结果可自动验证的领域

这四种不是互斥的,我实际做的时候经常混合使用。比如先用直接评分验证整个链路能不能跑通,再逐步用LLM标注数据去蒸馏一个小模型,小模型部署在RL循环里做高频打分,LLM只负责周期性的数据再标注和校准。这样成本和稳定性都能兼顾。

3. 从数据生产到RL训练:一条完整的落地链路

3.1 步骤轨迹的生成与切分

PRM的数据源头是"当前策略的采样轨迹"。很多人一开始容易犯一个错:直接拿现成的公开CoT数据拆步骤。问题在于,那些数据不是当前策略生成的,分布对不上,PRM学到的分数会有偏。更稳妥的做法是在每个训练迭代中,用当前策略真实地去采样一批结果,再在这批结果上做步骤切分和标注。

切分方式我用过两种。一种是直接用模型输出里的"Step 1""Step 2"之类的显式标记,但很多模型的输出并不规范,漏标、错标频繁,清洗成本高。另一种是让LLM把一段长回复切成语义块,这种更灵活,但要注意别切太碎。我自己的一个经验标准是:一个step应该在语义上能独立回答"这一步做完之后,状态发生了什么变化",如果切出来的片段连这个都说不清,就没有资格成为一个step。

还有一个特别容易踩的点:不要把某个step单独丢给PRM打分。脱离前文的步骤没法判断对错——一个步骤正确与否高度依赖之前的推导状态。实践中必须把"问题文本 + 之前的步骤 + 当前步骤"拼成一个完整输入,让PRM在完整上下文里做判断。

3.2 用LLM给步骤打分:Prompt设计与评分尺度

给步骤打分的Prompt,我踩过不少坑之后收敛到了一个比较稳的模板。核心要求是"先给理由,再给分数"。

一个典型的打分指令会是这样:

你是一个严谨的推理过程审阅者。下面是一道题的完整解题过程,已经按步骤拆分。请判断每一步是否正确,以及是否有效推进了解题。对每一步,先简要说明判断理由,然后给出整数评分:0表示明显错误/无关步骤,1表示正确且有效推进,0.5表示方向正确但存在可修正的错误。最终答案未知,请勿依据最终结果推断步骤。

"最终答案未知"这个约束很关键。如果不加,LLM会偷懒:看到最终答案是对的,就把所有步骤都判成对的;看到最终答案是错的,就把前面所有步骤都判成错的。这等于把PRM又变回了ORM,过程监督的语义就丢了。

评分尺度方面,我强烈建议用0/0.5/1这种粗粒度分档,不要用1到5的细分数。实测下来,LLM对细粒度分数的内部一致性极差,同一个step换个随机种子可能给出3分和5分的差别;但是0/1两档判断就稳定很多,0.5作为中间档位用来标记"方向对但有瑕疵",信息量刚刚好。

还有一点,评分时可以让LLM对同一个step进行多次采样投票,取平均分。我在标注温度调到0附近跑三到五次投票,比单次打分稳定不少。

3.3 训练自己的PRM:蒸馏一个专门的评分器

LLM打分的质量可以,但在RL循环里反复调用大LLM实在太贵。用一个中等规模的基座模型去蒸馏一个专用PRM,是更经济的做法。

蒸馏第一步是构造数据集。输入是"问题+前置步骤+当前步骤"的文本序列,输出是LLM对这一步的评分档位。在损失函数上,我试过两种思路:一种是把0/1当成二分类目标,直接用交叉熵;另一种是参考对比排序的损失,同一个问题下,正确的有效步骤分数应该高于后面出错的步骤。后一种在数据有噪声时更鲁棒,因为它只要求排序关系,不要求绝对分数精确。

构造训练数据时要特意保留一批"错误但能挽救"的负例。如果数据集里只有明显的对和错,PRM学到的边界会很脆,实际遇到"看似合理但实际跑偏"的推理过程时容易乱打分。这类模糊样本是PRM真正要发力的地方,宁可数据精度低一点,也要覆盖到。

蒸馏出来的小PRM在推理阶段可以只跑分类头,不生成文本,单次评分延迟可以压到毫秒级。RL训练里高频调用才撑得住。

3.4 RL训练里怎么接PRM奖励

接入方式有讲究。以PPO类方法为例,每一步的即时奖励可以写成:

r_t = r_env(s_t) + λ · p(s_t; θ_prm)

其中 r_env 是环境奖励,通常在中间步为0、终态为±1;p(s_t) 是PRM对当前步骤的评分;λ 控制PRM影响权重。λ太大了,模型可能学会刻意讨好PRM,产出"PRM喜欢但实际没意义"的内容;λ太小了,又回到稀疏信号。我自己的起点经验是0.5左右,然后再根据训练曲线调。

如果用的是GRPO这类不需要独立Critic的算法,PRM的接入可以再简化:对同一个问题采样多条轨迹,用PRM给每条轨迹算累积分数,然后在组内做归一化,当作advantage的基准。下面是一个简化伪代码。

# PRM接入GRPO的简化伪代码 import torch def grpo_prm_update(policy, prm, batch, group_size=8): for question in batch: responses = policy.sample(question, n=group_size) group_scores = [] for resp in responses: steps = split_steps(resp) # 步骤切分 step_scores = [] for i, step in enumerate(steps): # 注意带上上下文:问题+前置步骤+当前步骤 score = prm.score(question, steps[:i], step) step_scores.append(score) # 聚合:默认求和,但对长轨迹做衰减 weights = [0.9 ** i for i in range(len(step_scores))] total = sum(s * w for s, w in zip(step_scores, weights)) group_scores.append(total) rewards = torch.tensor(group_scores) # 组内归一化,消除不同题目分数尺度差异 advantages = (rewards - rewards.mean()) / (rewards.std() + 1e-5) loss = policy.grpo_loss(responses, advantages) loss.backward()

这里有个聚合细节:PRM输出的是0到1的step分,如果直接累加求和,轨迹越长总分越高,模型很容易钻空子。我在聚合时给后面的step做了指数衰减,或者按轨迹长度取平均。这个点论文里通常不细写,但实测影响非常大。

4. 几个关键参数和设计选择的实测笔记

4.1 什么样的任务适合PRM

不是所有任务都应该上PRM。它最好的发挥场景是:中间步骤有相对明确的对错标准,且步骤之间存在因果依赖。数学题、代码生成、数据分析里的逐步操作、多步工具调用,都属于这类。

反过来,创意写作、闲聊、风格迁移这些任务基本用不上。因为步骤本身没有明确的"正确"可言,最终结果也没有唯一判据,让PRM强行给过程打分,只会打出一堆站不住脚的噪声。硬要用的话,反而可能把一个风格化很好的模型拉偏。

4.2 采样温度和rollout数量怎么配

采样温度对PRM数据质量的影响,比很多人以为的大。温度太低,采出来的轨迹高度雷同,PRM学不到多样性;温度太高,长长的错误轨迹比例太高,步骤标注的工作量和噪声都上去了。我试下来,生成训练轨迹时温度设在0.7到1.0之间比较合适,能覆盖成功路径和失败路径两个分布。

每次采样多少条也很有讲究。GRPO里group_size的大小直接决定优势估计的稳定性。太小了baseline不准,太大了计算成本爆炸。我用8到16条起步,实际效果和计算量之间找个平衡点。

给PRM做标注的时候,温度策略和生成是反过来的。标注阶段的LLM温度要调到很低,最好接近0,并且做多次投票取平均,因为我们要的是稳定评判,不是创造性的批评。

4.3 步骤粒度的取舍:粗切还是细切

粒度是PRM效果的一大分水岭。步骤切得太粗,比如把一整个长推导当一步,那PRM输出的奖励其实又变回稀疏信号了,中间哪块出错照样看不出来。步骤切得太细,比如把半个句子都拆成一个step,又会带来两个问题:一是步骤之间依赖关系太强,前后上下文拼起来过长,评分器看不清;二是噪声放大,一个正确的大步骤被切成十个小step后,其中一两个小step可能被误判为错,聚合成奖励时反而把原本正确的路径惩罚了。

我个人的经验,一个step大致对应两到六个自然句,或者代码里一行到几行独立的逻辑块,整条轨迹控制在10到50个step之间,效果比较稳定。当然这个数字和任务类型强相关,代码生成的step往往比数学推理短,要按实际数据调。

4.4 位置偏差:怎么纠正LLM打分的前后不一致

用LLM当PRM,最容易发现的一个系统性偏差是位置偏差。一个完整轨迹里,靠前的步骤容易被判对,靠后的步骤容易被判错,而且这个偏差跟步骤本身的对错关系不大,更像是上下文变长之后解释力下降。

我试过几个缓解手段。一个有效的办法是让PRM先完整读一遍整条轨迹,做一个整体把握,再逐步打分,而不是每个step独立跑一遍。相当于先看全貌,再动笔批注。另一个办法是投票:同一个step采样多次评分取平均,能把一部分随机噪声抹掉。最彻底的办法还是用LLM批量离线标注,蒸馏成小模型之后,位置偏差会在蒸馏数据里被部分平均掉。

5. 踩坑记录:复现过程中遇到的几个问题

5.1 PRM成了"流水账爱好者"

第一个坑给我的印象最深。RL训练跑着跑着,我发现策略生成的回答越来越长,尽是些车轱辘话,但PRM给的分数却不降反升。后来去翻了PRM的评分记录,发现它给"步骤多、字数多"的轨迹普遍打了高分,哪怕其中一大半步骤跟解题没有直接关系。LLM对"看起来认真"的文本有天然的手下留情倾向。

解决办法是双管齐下。一方面在标注Prompt里明确写"冗余步骤不因数量获得额外加分";另一方面在构造PRM训练数据时,主动加入一批"步骤很多但思路绕远"的负例,让小PRM学会识别这类轨迹。后来我再查看打分记录,'流水账'现象就明显缓解了。

5.2 奖励漂移:分数整体上涨但质量没涨

训练到中期还出现过一个更隐蔽的问题:PRM给出的分数整体抬升了,平均分从0.6涨到0.8,但我在人工盲评时发现,生成质量并没有同步变好。原因是策略在RL优化中逐渐摸清了PRM的偏好,开始针对性地产出符合PRM口味的文本,而不是真正接近标准答案。

处理办法是给PRM加一个校准机制。每隔一定训练轮次,从当前策略里重新采样一批轨迹,人工抽查一小部分,用这批新数据重新标定PRM的分数分布。同时保留一个固定的held-out验证集,每次评估只看这个集合上的分数是否有意义,而不是看训练集上的绝对分数涨跌。

5.3 自我确认偏差:PRM对同源策略更宽容

另一个有趣的坑是"自己人好说话"。策略模型和PRM如果出自同一个基座模型,PRM对同风格推理过程往往更宽容,而对外部模型的同水平过程更苛刻。这在强化学习里很容易造成自我强化:策略越走越偏,PRM却越看越顺眼。

缓解方式有几个。一是混合多个不同来源的PRM评分结果,不要只依赖单一裁判;二是在蒸馏数据里刻意混入不同风格的解题过程,让PRM学到的是逻辑有效性而不是表面风格;三是在关键任务上用规则验证器或者编译器结果做锚定,把PRM的文本打分往客观结果上拉。

5.4 奖励噪声导致训练震荡怎么办

PRM本质是模型预测,分数一定有噪声。如果直接用原始分数做优势估计,训练曲线往往会上下乱跳。我试下来最有效的不是调小学习率,而是先对PRM分数做去噪处理。常用做法包括:多次采样投票取平均、分档而不是用连续值、在组内做归一化后再进RL更新。还有一个土办法是给PRM分数加一个小范围的截断,不让个别离群样本主导整个batch的梯度。

下面这个速查表是我当时整理给自己用的,遇到类似问题可以直接对着排查。

症状可能原因排查方向与解决建议
PRM分数整体膨胀位置偏差、冗长度偏好组内归一化,按平均分聚合
策略输出空话变多奖励被风格/长度带偏加长度惩罚,标注时强调冗余不加分
分数和人工判断不一致步骤切分太碎或上下文缺失调大step粒度,带上完整前缀
RL训练震荡不收敛PRM噪声太大多投票取平均,降λ,换蒸馏小模型
策略摸清PRM偏好奖励黑客周期重标定,混合验证器,保留held-out集

6. 落地之后的个人体会与还想试的方向

我自己把这套PRM流程完整跑下来之后,最深的体会是:PRM不是用来替代最终结果奖励的,而是用来补足过程信号。曾经试过把最终答案奖励整个拿掉,只用PRM做唯一训练信号,结果模型确实慢慢学会了增加步骤,但步骤的语义有效性和最终正确率并不理想。最稳的组合始终是结果奖励把住大方向,PRM修正中间的小方向。

实操层面如果只挑三条经验出来分享:第一,步骤切分一定不能脱离上下文来打分;第二,分数用粗粒度比细粒度稳定得多;第三,λ这个权重一定要单独开实验调,别指望靠一个固定值走天下。

后面我还有几条想继续试的线。一是把PRM的step分数转成两两偏好,配合DPO类方法去更新策略,这样也许能绕开一些PPO/GRPO的方差问题;二是做在线PRM,让PRM和策略同步更新,避免奖励被策略快速学穿;三是把PRM输出的步骤质量分直接拿来做SFT数据筛选——对一批混合质量的数据集,按步骤分过滤掉低质量样本,再拿去继续训练基座。这个方向还远没到定论阶段,多记录几轮实验,你会发现有太多比论文正文更值得研究的坑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 4:41:30

.NET对接飞书考勤系统:从权限令牌到工时计算的完整实战

折腾考勤系统这事儿,只有亲自从零到一收拾过的人才说得清坑在哪。先说结论:在 .NET 生态里完整对接一套飞书考勤,不是小工程,但把整条链路的环节摸透了,两三天也够落地一套稳定可跑的版本。核心就四块:飞书…

作者头像 李华
网站建设 2026/10/19 4:41:24

智能车载系统对话管理实战:状态追踪、噪声容错与防分心设计

聊到智能车载系统,很多人第一反应是“你好,帮我打开空调”,觉得语音交互不过如此。真正在车上做过语音助手的人都知道,对话管理才是整个交互体验的中枢神经。不管车机前端用的是哪家语音识别引擎,最后让用户觉得“这车…

作者头像 李华
网站建设 2026/10/19 4:41:21

开放研究实践指南:从数据采集到可复现分析的完整流程

1. 项目概述:OpenResearch 是什么,为什么值得关注这两年AI圈子里“大模型”和“开放科学”几乎是双线并行地火,尤其是以ChatGPT为代表的大语言模型应用爆发之后,普通用户接触到的只是聊天机器人,而真正做技术的人开始把…

作者头像 李华
网站建设 2026/10/19 4:39:31

消防水带物理模拟为何难?Unity插件XPBD技术拆解与内测申请指南

消防水带模拟,在应急仿真圈子里算是个老话题了。几乎每个做消防培训或应急演练的团队,都经历过“水带像根面条”“出水像洒水壶”“一拖就穿模”的尴尬阶段。市面上现成的Unity插件要么只做视觉假象,要么物理效果一碰就碎。这也是我这次发起消…

作者头像 李华
网站建设 2026/10/19 4:37:54

群体智能 AI Agent:多个 LLM 协作的分布式系统设计实践

先说一个判断:标题里的“群体智能”不是噱头,而是要把多个 LLM 组成的 AI Agent 集群当成一个真正的分布式系统来设计。很多人看到“多个 LLM 协作”就开始堆 API 调用,把几个大模型轮流问一遍,那不叫群体智能,叫串行试…

作者头像 李华
网站建设 2026/10/19 4:36:09

Atlas:Rust源码的语义级快照与本地代码时间机器

1. 项目概述:Atlas 不是地图,而是 Rust 生态里悄然崛起的“源码控制中枢”最近在 Rust 社区和 macOS 开发者圈子里,“atlas”这个词出现频率陡增——但它既不是地理信息系统(GIS)里的 Atlas 地图集,也不是某…

作者头像 李华