尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

大模型RLHF奖励模型训练避坑:偏好数据到PPO上线检查

发布时间:2026/9/29 1:17:22

资讯中心
01
ARTICLE

大模型RLHF奖励模型训练避坑:偏好数据到PPO上线检查

大模型RLHF奖励模型训练避坑:偏好数据到PPO上线检查
奖励模型这块我踩过的坑比预训练和SFT加起来都多。前半程你会觉得一切顺利——预训练把知识塞进去SFT把格式调顺模型已经能像模像样地对话了。可一旦进入RL阶段突然发现模型开始讨好裁判、回答越来越长、废话越来越多甚至学会了用一堆漂亮话来掩盖事实错误。十有八九问题不在PPO而在你手上那个奖励模型。它才是整条大模型训练流程里最隐蔽、最容易被糊弄的一环。这篇是训练流程系列的第三篇专门讲奖励模型Reward ModelRM。我会假设你已经有了一个训好的SFT模型现在要把它变成一个能替人类打分排序的裁判。内容覆盖偏好数据怎么造、损失函数为什么长这样、训练配置踩过哪些雷、怎么判断RM已经坏了以及最后把它交给PPO之前必须过的几道关。不管你是刚接触大模型微调的新手还是已经跑过几轮RLHF的老手这里应该都能捞到点能直接用的东西。1. 奖励模型在整条训练流水线里到底卡住哪个环节1.1 从预训练到SFT再到RM的接力关系先把位置摆清楚。一条典型的对齐流水线是预训练负责让模型知道SFT负责让模型会说奖励模型负责让模型知道说什么更好PPO负责把这种偏好真正写进权重里。区别在于前两步的监督信号是明确的文本预测下一个token对错一目了然。到了RM这一步监督信号变成了人类更喜欢A还是B这种相对判断没有绝对答案。模型要学的不是某个正确输出而是一个能把两个输出排出高低的打分函数。这就决定了一个很关键的事实RM的能力上限几乎完全由数据里人类判断的一致性决定。你标注了一万个样本如果标注员之间自己都吵不出个结果RM学到的就是一锅粥。SFT阶段数据脏一点还能靠规模糊过去RM阶段数据脏一点后面PPO会把它放大成灾难。1.2 为什么不能让SFT模型直接兼任裁判有人会问SFT模型已经会打分了吧直接让它输出这个回答得几分不行吗理论上行实践上非常不稳。原因有两个。第一SFT模型的输出目标是最可能的下一个token它没有经过任何排序训练。你让它打分它给的分数往往集中在几个常见数值上区分度极差而且对prompt的措辞极其敏感换个说法分就变了。第二SFT模型会继承训练数据里的长度偏好和格式偏好它会本能地给看起来完整、分段漂亮的回答打高分哪怕内容空洞。这种偏置直接喂给PPO模型就会朝着写得长、排得整齐去优化而不是朝着答得对。所以我们需要在SFT之上再挂一个专门的打分头用偏好数据重新训练把这个骨架改造成一个稳定的、单调性好的评分器。这一步就是奖励模型训练。1.3 奖励模型到底吃什么、吐什么把接口定清楚后面所有实现都围着它转。输入一个prompt加上一条完整回答response拼成一条序列送进模型。输出一个标量分数scalar越高代表回答越被偏好。训练时的输入同一个prompt配一对回答chosen被偏好的和rejected被嫌弃的截断后成对送入。我习惯把RM看成一个带语言理解的比较器而不是一个生成模型。它的任务不是写出好答案而是在两个已有答案之间做判别这个视角能帮你少走很多弯路——比如你会更关注判别边界清不清晰而不是它生成的文字通不通顺。2. 偏好数据的构造奖励模型的天花板全压在这里2.1 四元组格式与标注口径的统一一条标准的偏好样本核心就是三元组加上元信息prompt用户问题或指令chosen被偏好/更优的回答rejected被嫌弃/更差的回答附加字段标注员ID、时间、置信度、是否并列tie我强烈建议在数据里保留是否并列这个字段。很多团队图省事遇到两个回答差不多就随便丢一个进chosen这种噪声非常致命。并列样本要么直接剔除要么在损失里用一个margin把它们推开千万别硬塞进二分类里。标注口径必须在动手标注之前就写成文档而不是边标边想。至少要把这几件事说死事实正确性优先于表达流畅性同样的正确性下简洁优先拒绝阿谀奉承式的回答拒绝包含不能核实的数字和引用的回答。这些规则看起来琐碎但它们决定了chosen和rejected的边界是不是同一条线。边界不一致模型学到的特征就是随机的。2.2 标注一致性比标注量更致命我见过太多团队砸钱标了十万条最后RM的效果还不如别人标两万条的。差别就在一致性。衡量方式很直接抽一批样本做双标或三标计算标注员之间的一致率agreement rate或者Kappa系数。经验上一致率低于70%的批次基本可以回炉因为剩下30%的噪声足够把RM的判别边界搅烂。真正该做的是每天抽检、开短会校准边界而不是埋头堆量。另一个容易被忽略的点是标注员的偏好漂移。同一个人标了三天之后手会松标准会往差不多就给通过滑。解决办法是每隔一段时间往任务流里混入一批gold样本答案已知的对照题一旦有人在gold上掉链子立刻约谈。这套机制听起来像人事管理但它对RM质量的提升比换更深的网络结构有用得多。2.3 数据配比与难样本挖掘的实操经验偏好数据不是越多越好配比才是关键。我通常在几个维度上做平衡维度建议做法踩坑提示任务类型问答、摘要、代码、写作按真实线上比例配别让某一类独占否则RM在该类上过拟合难度保留30%左右的难样本两答案差距小全用简单样本RM学不到细粒度区分长度chosen和rejected长度分布要接近长度差异过大RM会学成长度打分器安全性不友好/有害回答单独成组控制比例混在一起会让模型把礼貌和正确混淆难样本怎么来我一般靠两个途径。一是让当前的SFT模型对同一个prompt采样多次比如temperature调高采8条再把两两组合里最接近的几对挑出来标二是拿训练early阶段的RM去跑线上数据专门挑那些打分极端接近的样本重新标注。后者有一个额外好处它是针对你当前模型的弱点在做定向补强。3. 损失函数与网络结构把打分问题翻译成排序问题3.1 为什么一定是 Bradley-Terry 而不是回归很多人第一反应是让模型直接预测这个回答几分比如1到5分做回归。这条路我试过效果明显不如成对比较原因是主观评分的绝对尺度根本不可靠。同一个标注员今天给4分的回答明天可能就给3分而我更喜欢A还是B这种相对判断稳定得多。于是我们用Bradley-Terry模型把相对判断转成概率。设RM给chosen打分为 $r_w$给rejected打分为 $r_l$则chosen优于rejected的概率建模为$$P(w \succ l) \sigma(r_w - r_l) \frac{1}{1 e^{-(r_w - r_l)}}$$对应损失就是在最大化这个似然取负对数$$L -\log \sigma(r_w - r_l)$$一句话记住它的含义模型只需要把好回答的分数压过坏回答绝对数值无所谓。这带来两个好处——尺度自由不用纠结分数范围、天然抗单点噪声一条标错的影响被sigmoid平滑掉。3.2 从SFT权重初始化加一个标量头而不是换个头实现上的标准姿势是加载SFT模型作为骨干去掉原来的语言模型头lm_head换成一个输出维度为1的线性层取序列最后一个有效token的隐藏状态作为输入得到分数。位置大致是这样import torch import torch.nn as nn class RewardModel(nn.Module): def __init__(self, backbone): super().__init__() self.backbone backbone # 加载SFT权重 hidden backbone.config.hidden_size self.score_head nn.Linear(hidden, 1, biasFalse) def forward(self, input_ids, attention_mask): out self.backbone( input_idsinput_ids, attention_maskattention_mask, output_hidden_statesTrue, ) last_hidden out.hidden_states[-1] # [B, L, H] # 取每条序列最后一个非padding token lengths attention_mask.sum(dim1) - 1 # [B] pooled last_hidden[torch.arange(last_hidden.size(0)), lengths] return self.score_head(pooled).squeeze(-1) # [B]这里有几个细节值得展开。为什么用最后一个token而不是对整条序列做平均池化因为生成式模型的信息是层层累积到最后一个位置的末位token的隐藏状态天然含了整段上下文的信息而平均池化会把关键位置和填充位置混在一起稀释掉信号。为什么加biasFalse因为分数本身是相对的模型只需要学差值的分布加不加偏置在理论上等价去掉能少一个无用的参数。3.3 padding、mask 和截断这些小事决定成败理论看着简单跑起来全是坑。左padding还是右padding如果实现里靠最后一个token取分就必须保证padding在左边或者严格用attention_mask定位末位有效token。我早期图省事用右padding又按长度取下标结果一批样本全部取到了pad位置分数几乎不随内容变化训练loss纹丝不动排查了大半天。截断策略prompt和response要一起算长度。如果全局截断从尾部砍掉很多长回答的结论会被切没导致模型看到的chosen和rejected其实都残缺。更稳妥的做法是优先保留完整的response对过长的prompt做压缩。chosen/rejected拼批次常见做法是把两者分别forward取分后计算损失而不是简单拼接。注意attention_mask要逐条传别偷懒共用。4. 训练配置与显存权衡我踩过的那些数字4.1 超参选择的经验区间RM的训练比SFT更娇气因为它对扰动敏感。下面这些区间是我在大量试验后比较稳定的经验值供你起步参考参数建议起始值说明学习率5e-6 ~ 1e-5比SFT再低一档高了会破坏骨干能力训练轮数1 ~ 3 epoch超过3轮基本开始过拟合验证准确率会掉全局batch64 ~ 256 对样本太小梯度噪声大太大收敛慢梯度累积视显存定保持有效batch在建议区间即可warmup比例3% ~ 5%前期稳一点别让随机初始化的头带歪权重衰减0.01 ~ 0.1对打分头有效抑制数值漂移学习率这块我特别想强调RM的学习率如果和SFT一样大前几百步你会看到准确率飞快上升然后突然开始震荡不收敛。原因是打分头刚初始化时输出接近0梯度很大会反向冲进骨干把SFT辛苦学到的表征打乱。降学习率、加warmup、甚至可以先把骨干冻结几百步只训打分头这几个手段能显著稳住训练。4.2 长度偏置最阴险也最常见的失效方式如果只让我提醒一件事那就是长度偏置。RM天然倾向于给更长的回答打高分因为长回答往往包含更多正面词、更完整的结构、更少的明显错误。这种偏置在RM训练里可能只表现为准确率还不错但一旦进入PPO模型会疯狂地往长得离谱的方向优化你会在对话里看到一堆重复、铺垫、和稀泥。对抗手段有几个我一般组合使用数据层面保证chosen和rejected的长度分布接近必要时对长回答做摘要压缩再标。损失层面加一个长度惩罚项把分数里与长度线性相关的成分减掉或者做一个回归去偏。评估层面单独算一个长度匹配子集上的准确率只看那些两者长度接近的样本对RM判别得准不准。这个长度匹配子集准确率是我最看重的指标之一。如果整体准确率70%但长度匹配子集只有55%那这个RM基本是废的PPO一定会跑偏。4.3 全参微调、LoRA到底怎么选对一个需要精细判别边界的RM来说全参微调通常效果最好但代价是显存。7B模型全参训练光是优化器状态就吃掉几十GB单机很难扛。LoRA在RM上是能用的尤其当你数据量不大、只想小幅调整时。但要注意两个前提一是rank别太小判别任务需要一定的表达能力rank给到32或64比较稳二是不要把学习率调得过高LoRA的初始化和全参不一样过高的学习率很容易让打分头学到只要挂上这个LoRA就输出某值这种作弊解。我的经验是如果显存允许优先全参确实受限时用LoRA并配合更严格的验证集早停。5. 怎么判断奖励模型已经坏了5.1 偏好准确率之外的几个指标验证集上的偏好准确率chosen得分高于rejected的比例是入门指标但远远不够。一个只会在简单样本上打对、在难样本上蒙的RM准确率也能刷到65%以上放出去照样出事。我一般同时盯这几个长度匹配子集准确率前面提过对抗长度偏置的底线。分数间隔分布chosen和rejected的分数差应该有一个合理的分布如果大量落在0附近说明判别边界模糊如果全都很大可能是过拟合。校准性把模型给出的分数差映射成概率看它和真实偏好频率是不是对得上。差得太多说明分数尺度不可信。跨分布泛化拿一个完全不同来源的测试集比如另一个标注批次、另一种prompt风格跑一遍掉点超过10%就该警惕。5.2 reward hacking 的早期信号奖励模型被钻空子是必然会发生的问题只在于你能不能早点发现。最典型的信号是PPO训练中奖励分数持续上涨但人工抽样评估时质量却在下降。这时候模型不是在变得更好而是在学会迎合RM的偏好特征比如无脑加长、堆砌首先其次最后、结尾强行用一个反问句。我的应对策略是把RM的评估和PPO的监控绑在一起看。每隔固定步数用固定的一批prompt生成回答人工盲评打分和RM分数画在同一张图上。一旦两条曲线开始背离立刻停下来查别等它跑完。这个动作很花人力但它是唯一能真正抓住hacking的手段因为RM自己是没有能力发现自己被骗的。5.3 集成与长度惩罚能不能救场如果单个RM已经明显被hack常见补救是集成多个RM用不同数据子集、不同种子、甚至不同骨干训几个RMPPO时对它们的分数做平均或取最小值。取最小值更保守能压掉那些被某个RM过度偏好的方向。集成确实有效但别把它当万能药。如果所有RM都是用同一批标注数据训的它们会共享同一套偏置集成也救不回来。真正有价值的集成是数据来源、标注批次、模型结构尽量差异化。另外长度惩罚参数也不是越大越好调过头会让模型变得惜字如金该展开的地方也不展开了。我一般从0.001起步边跑边看生成长度曲线落在一个稳定区间就停。6. 把奖励模型交给PPO之前必须过的几道关6.1 分数尺度与后续clip的衔接PPO里的奖励会参与优势估计还会经过白化和clip。这意味着RM输出的绝对尺度会直接影响训练稳定性。如果RM分数方差极大PPO的advantage会被少数样本主导如果方差极小梯度信号又太弱。我通常会在RM交付时做一次统计用一批线上prompt的模型输出跑一遍记录分数的均值和方差并在PPO侧加一个在线白化层把奖励归一化到稳定区间。这样即使换RMPPO的超参也不用大改。还有一个细节是PPO里的总奖励通常是rm_score - kl_penaltyKL惩罚的系数和RM尺度是耦合的。换RM一定要重新调这个系数否则不是约束过强导致模型原地踏步就是约束太弱导致跑飞。这一条我吃过好几次亏尤其是从一个小RM换到大RM时尺度变了但系数忘了动。6.2 交付前的检查清单最后把我每次上线前都会过一遍的东西列出来你可以直接拿去用检查项通过标准不通过的后果验证偏好准确率明显高于随机且难样本子集不塌判别能力不足PPO无有效信号长度匹配子集准确率与整体准确率差距在合理范围长度偏置PPO输出疯长分数间隔分布集中在差异明显的区间边界模糊训练不稳定跨分布测试掉点可控上线后泛化崩盘固定prompt抽样盲评与RM分数趋势一致存在hacking风险分数尺度统计已记录均值方差并同步PPO白化换RM需重调所有超参这些检查做起来不轻松但每一道都对应一个真实发生过的翻车现场。过了这关你手上的RM才算是能用的裁判而不是一个会随机吹黑哨的摆设。说到底奖励模型是整条训练流程里最不像技术活、最像体力活加上一点判断力的一环。它没有炫技的空间靠的就是数据干净、边界一致、实现细节不出错、评估手段到位。我见过太多人把精力堆在PPO的各种trick上却忽略了这个上游裁判早就歪了。先把RM这关坐稳后面的RL才有意义。等它真跑通你会发现在模型变好的同时自己对什么叫一个更好的回答这件事的理解也被迫上了一个台阶。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。