4. 奖励模型训练:损失函数设计、训练流程与泛化问题
好,咱们进入奖励模型训练这个环节。说实话,这是整个RLHF流程里最容易被低估的一步。很多人觉得,不就是训练一个打分器吗?其实没那么简单。我当年在第一个RLHF项目里,就因为在奖励模型上偷了懒,结果后面策略模型怎么调都不对劲。
4.1 损失函数设计:Pairwise Ranking Loss
奖励模型的核心任务,是学会给不同的输出排序。你想想看,人类标注员做的是「选A还是选B」,而不是「给A打8分,给B打3分」。所以,我们的损失函数也得跟这个对齐。
最常用的就是 Pairwise Ranking Loss,也叫对比损失。它的思路很简单:
- 给定一个输入 prompt,以及两个输出 y_w(好的)和 y_l(差的)
- 让奖励模型给 y_w 打高分,给 y_l 打低分
- 如果它搞反了,就惩罚它
公式长这样:
Loss = -E[ log( σ( r(x, y_w) - r(x, y_l) ) ) ]
其中 σ 是 sigmoid 函数,r 是奖励模型的输出。说白了,就是让好回答和差回答的分数差距尽量大。
核心要点:这个损失函数只关心「相对排序」,不关心「绝对分数」。所以奖励模型的输出值本身没有意义,有意义的是不同输出之间的差值。
我在项目中遇到过一个问题:如果两个回答质量差不多,标注员也分不清好坏,那这对样本反而会引入噪声。所以我建议,训练时最好过滤掉那些「标注一致性低」的样本。
4.2 训练流程:从数据到模型
训练流程其实不复杂,但有几个坑。我按步骤拆开说:
- 数据准备:从人类反馈数据中,构造 (prompt, y_w, y_l) 三元组。注意,同一个 prompt 下可以有多个对比对。
- 模型初始化:通常用预训练的语言模型作为 backbone,去掉语言模型头,换成回归头(输出一个标量分数)。
- 前向传播:把 y_w 和 y_l 分别输入模型,得到两个分数 r_w 和 r_l。
- 计算损失:用 Pairwise Ranking Loss 计算梯度。
- 反向传播:更新模型参数。
嗯,这里要注意一个细节:batch 内对比。有些实现会把同一个 batch 里的所有样本混在一起做对比,但我不推荐这么做。因为不同 prompt 下的输出没有可比性——你想想看,写代码的回答和写诗的回答,怎么比?
我的习惯:每个 batch 只包含同一个 prompt 下的对比对。这样模型学到的排序才是「针对同一个问题的偏好」,而不是跨问题的绝对分数。
训练时的超参数也值得聊两句。我一般用很小的学习率,比如 1e-5 到 5e-5。因为奖励模型是在预训练模型上微调,学习率大了容易把预训练知识冲掉。
4.3 过拟合问题:奖励模型的「死穴」
过拟合在奖励模型训练里特别常见。为什么会这样?因为人类反馈数据通常很少——几千到几万条对比对,对于一个大模型来说,太容易记住了。
我见过最典型的例子:奖励模型学会了「只要回答里出现某个关键词就给高分」。比如在某个数据集里,好的回答经常以「首先」开头,结果奖励模型就变成了「首先检测器」。
怎么防?我分享几个实战经验:
- 数据增强:对同一个回答做轻微改写(同义词替换、句式变换),生成更多对比对。但注意别改变原意。
- 正则化:在损失函数里加 L2 正则项,或者用 dropout。我习惯在回归头前面加一个 dropout 层,概率设 0.1 左右。
- 早停:在验证集上监控准确率(即奖励模型正确排序的比例),一旦开始下降就停止训练。
警告:千万不要在训练集上追求 100% 的排序准确率。那几乎一定是过拟合的信号。我一般看到训练准确率超过 95%,就开始警惕了。
4.4 泛化问题:奖励模型能「举一反三」吗?
泛化能力,说白了就是奖励模型能不能在没见过的 prompt 上也能给出合理的排序。这比过拟合更难搞。
我踩过一个坑:训练时用的 prompt 都是英文的,结果上线后用户输入中文,奖励模型直接乱打分。后来我才意识到,奖励模型的 backbone 虽然支持多语言,但训练数据里没有中文对比对,它自然学不会中文的偏好。
提升泛化能力的方法:
- 多样化的训练数据:覆盖不同的领域、风格、语言。别只盯着一个数据集。
- 使用更大的 backbone:模型越大,泛化能力通常越强。但代价是训练和推理成本更高。
- 集成学习:训练多个奖励模型,取平均分数。这能有效减少单个模型的偏差。
我曾经试过用 5 个不同的随机种子训练奖励模型,然后取它们的平均输出。效果确实比单个模型稳定,但推理时间也变成了 5 倍。嗯,这是个 trade-off。
4.5 知识体系总览
下面这张图总结了奖励模型训练的核心逻辑,我画出来方便你对照着看:
你看,整个流程其实是个闭环。数据质量决定了上限,损失函数决定了优化方向,而过拟合和泛化问题则决定了最终效果的上限。
一句话总结:奖励模型训练的本质,是让模型学会「人类的排序偏好」,而不是「记住训练数据」。时刻问自己:我的模型是真的理解了偏好,还是只是在死记硬背?
公众号:蓝海资料掘金营,微信deep3321