核心摘要
RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)把人类判断转化为模型策略可优化的训练信号。在经典 InstructGPT 流程中,团队先得到能遵循指令的初始策略,再收集回答排序、训练奖励模型,并用 PPO 优化策略,同时约束它与参考模型的偏移。奖励仍然只是代理:分数升高不能证明回答真实、安全,也不能代表所有用户的价值判断。因此,生产级 RLHF 的核心不只是优化算法,还包括数据契约、独立评测、发布门禁和回滚能力。
核心要点
- RLHF 是一类从人类反馈优化行为的方法;SFT、奖励建模和 PPO 只是其中影响最广的一种实现。
- 成对奖励模型学习的是“评审者更偏好 A 还是 B”的概率,并没有恢复一个普适的人类效用函数。
- PPO Clipping 与 KL 惩罚作用不同:前者约束相对采样策略的单次更新,后者限制策略偏离冻结参考模型。
- 奖励模型准确率只是起点,还要检查校准、标注分歧、分布漂移和奖励过度优化。
- 发布前必须让候选策略与 SFT 基线在独立的能力、安全、事实性和业务切片上同口径比较。
RLHF 是什么
RLHF 是一种利用人类判断构建奖励信号,再用强化学习优化模型策略的训练方法。它适合“目标很难直接写成损失函数,但人能比较候选行为”的问题,例如判断两段回答哪一段更切题、更谨慎,或更符合明确的产品策略。
业界经常把所有偏好优化都称为 RLHF,容易混淆数据、算法和风险边界。更准确的区分如下:
| 方法 | 训练信号 | 策略更新 | 名称能证明什么 |
|---|---|---|---|
| SFT | 目标回答 | 最大似然训练 | 模型学习模仿示范 |
| 基于 PPO 的 RLHF | 由奖励模型表示的人工比较 | On-policy 强化学习 | 策略优化的是既定偏好的代理 |
| DPO | 通常是 chosen-rejected 样本对 | 离线偏好损失 | 不需要独立奖励模型和 PPO 循环 |
| RLAIF | AI 生成或 AI 辅助的反馈 | RL 或直接偏好优化 | 反馈提供方发生变化,评分规则仍可能来自人 |
| RLVR | 程序或其他可验证结果 | 强化学习 | 奖励可验证,不是学习得到的人类偏好代理 |
三阶段流程不是 RLHF 的定义。2017 年的 Deep Reinforcement Learning from Human Preferences 用轨迹片段的人工比较学习控制任务奖励;后续的 Learning to Summarize from Human Feedback 与 InstructGPT 才把这一路径系统应用到文本生成。
更关键的边界是:RLHF 只会把模型推向某个提示词分布、标注政策和评审群体表达出来的偏好。InstructGPT 论文也明确说明,其结果是对齐到标注者与研究人员表达的偏好,而不是抽象的“全人类价值观”。
一套完整的 RLHF 系统
RLHF 不是单次训练任务,而是由数据、模型、优化和评测组成的闭环。任何一个环节改变,最终奖励分数的含义都可能变化。
工程上要明确四份契约:
- 行为契约: 哪些提示词、用户、语言和失败场景属于目标范围。
- 反馈契约: 谁负责评审,按什么规则判断,怎样处理平局、跳过和升级复核。
- 优化契约: 使用哪个奖励、参考策略、约束和停止条件。
- 发布契约: 哪些独立指标可以阻断发布并触发回滚。
只要其中一份契约没有版本化,持续上涨的 Reward Curve 就可能掩盖产品质量下降。
阶段零:先定义目标与基线
收集偏好前必须先说明“偏好优化要修复什么”。“让模型更好”无法被评测,也无法判断 RLHF 是否值得投入。
一份可执行的行为规范至少要写清:
- 目标 Prompt 分布和明确排除的场景;
- 评审需要判断的回答维度;
- 多个维度冲突时的优先级;
- 可接受的拒答与不确定性表达;
- 受保护人群与高影响场景;
- 能力、安全、隐私、延迟和成本约束。
随后用同一评测协议记录 Base Model、Prompt-only 方案和 SFT 基线。只有更简单的方法仍留下可量化的偏好问题时,RLHF 才有充分理由。
SFT 常被用作初始策略,是因为原始的 Next-token Prediction 不一定能稳定生成适合评审的交互格式。但它不是理论上的强制步骤。真正的要求是:初始策略能在目标域生成可比较的候选回答,而且发布评测中的基线必须冻结。
阶段一:把偏好数据当作版本化契约
偏好数据 记录候选回答之间的判断,但一个 chosen-rejected 标签不足以还原判断发生的条件。可用记录应保留下列上下文:
| 字段 | 工程价值 |
|---|---|
| Prompt 与对话状态 | 说明回答针对的真实任务 |
| 候选文本与生成策略版本 | 识别分布漂移和模型专属特征 |
| Rubric 与版本 | 说明采集时“更好”的确切含义 |
| 标注者或 Cohort 标识 | 支持可靠性、分歧与人群分析 |
| 选择、平局、跳过和置信度 | 保留歧义,不强迫每组比较产生赢家 |
| 展示顺序与随机化信息 | 检测位置偏差和界面偏差 |
| 数据来源、Consent 与 License | 证明数据是否可以合法使用 |
| Split Group | 防止 Prompt、会话、用户或模板泄漏 |
成对比较只表达相对偏好
Pairwise Comparison 往往比绝对打分更容易校准,但它只说明:在当前上下文和评分准则下,某位评审更偏好其中一个回答。它没有说明差距多大、两个回答是否都合格,也没有保证其他评审会同意。
候选回答的生成方式同样会改变学习结果。如果所有 rejected 都是明显错误,模型只能学到表面区分;如果某个来源模型总是更长,奖励模型可能学到篇幅或模型身份,而不是质量。正式采集前应随机展示顺序、混合候选来源、删除完全重复,并先检查长度、格式、拒答率等简单特征。
标注分歧不是纯噪声
不要把所有分歧都压成多数票。2026 年修订的 Diverging Preferences 在两个偏好数据集中观察到大量标注分歧,其中很多来自任务描述不完整、篇幅、回答风格和拒答选择。标准标量奖励模型却可能把分裂的判断转化为一个看似确定的分数。
因此,要按评分维度、Prompt 切片、语言和标注者群体报告一致性,并保留 Tie 与 Skip 原因。对于强主观任务,更合理的方案可能是按用户偏好条件化生成,或把歧义请求路由到澄清流程,而不是训练一个全局唯一答案。
必须先分组,再划分数据集
如果同一 Prompt 派生出多组比较,随机按行切分会导致泄漏。一个 Prompt 的全部候选回答和派生 Pair 必须进入同一 Split;条件允许时,还要独立留出用户、时间、领域和标注者。
InstructGPT 的实际处理说明了这个问题:每个 Prompt 会展示 4 到 9 个回答,最多派生 K choose 2 个高度相关的 Pair。论文发现,若把这些 Pair 独立打乱,一轮训练就可能让奖励模型过拟合,因此按 Prompt 聚合为一个 Batch Element。
阶段二:训练并审计奖励模型
奖励模型 把 Prompt 与回答映射到一个标量:
r_theta(x, y) -> 实数分数
常见的 Bradley-Terry 偏好模型用分数差计算成对偏好概率:
P(y_chosen > y_rejected | x)
= sigmoid(r_theta(x, y_chosen) - r_theta(x, y_rejected))
L_RM
= -E[log sigmoid(r_theta(x, y_chosen) - r_theta(x, y_rejected))]
成对偏好只识别分数差。给所有 Reward 同时加上相同常数,不会改变比较概率。因此,除非系统定义并验证了独立校准流程,否则一个绝对奖励值没有跨模型、跨版本的通用含义。
奖励模型指标分别能证明什么
| 指标 | 有效信号 | 不能证明 |
|---|---|---|
| Pairwise Accuracy | 偏好回答通常是否排在更前 | 概率是否校准、产品质量是否提高 |
| Pairwise Log Loss | 是否惩罚“高置信度但判断错误” | 分布外行为是否正确 |
| Brier Score / Calibration Curve | 预测概率与实际频率是否接近 | 一个标量足以表达多元偏好 |
| Slice Accuracy | 哪些领域、语言、策略或回答类型较弱 | 未覆盖攻击上的安全性 |
| Reward 与长度、风格关系 | 是否存在篇幅或格式捷径 | 不存在其他隐藏捷径 |
| Cross-policy Evaluation | 能否判断更新后策略生成的新回答 | 激进优化后的持续鲁棒性 |
验证集必须来自未参与训练的人工判断,并覆盖预期生产分布。一个能正确排序旧候选的奖励模型,未必能判断它随后训练出来的新策略。
用 Go 审计冻结的 Reward 输出
深度学习框架负责训练奖励模型,但发布流水线仍需要独立、可复核的冻结分数审计。下面的 Go 程序不依赖第三方库,计算整体和各切片的 Pairwise Accuracy、Log Loss 与 Brier Score,并拒绝非法数值。
package main
import (
"fmt"
"math"
"os"
"sort"
)
type pair struct {
slice string
chosenReward float64
rejectedReward float64
}
type metrics struct {
count int
correct int
logLoss float64
brier float64
}
func softplus(x float64) float64 {
switch {
case x > 30:
return x
case x < -30:
return math.Exp(x)
default:
return math.Log1p(math.Exp(x))
}
}
func (m *metrics) add(chosenReward, rejectedReward float64) error {
if math.IsNaN(chosenReward) || math.IsNaN(rejectedReward) ||
math.IsInf(chosenReward, 0) || math.IsInf(rejectedReward, 0) {
return fmt.Errorf("reward must be finite")
}
margin := chosenReward - rejectedReward
probability := 1 / (1 + math.Exp(-margin))
m.count++
if margin > 0 {
m.correct++
}
m.logLoss += softplus(-margin)
m.brier += math.Pow(1-probability, 2)
return nil
}
func (m metrics) report(name string) {
fmt.Printf(
"%s n=%d accuracy=%.1f%% log_loss=%.3f brier=%.3f\n",
name,
m.count,
100*float64(m.correct)/float64(m.count),
m.logLoss/float64(m.count),
m.brier/float64(m.count),
)
}
func main() {
pairs := []pair{
{slice: "coding", chosenReward: 2.4, rejectedReward: 0.3},
{slice: "coding", chosenReward: 0.2, rejectedReward: 0.7},
{slice: "coding", chosenReward: -0.1, rejectedReward: -0.4},
{slice: "safety", chosenReward: 1.1, rejectedReward: 0.8},
{slice: "safety", chosenReward: 0.4, rejectedReward: 1.2},
{slice: "safety", chosenReward: 1.6, rejectedReward: 0.2},
}
overall := &metrics{}
bySlice := map[string]*metrics{}
for _, item := range pairs {
if bySlice[item.slice] == nil {
bySlice[item.slice] = &metrics{}
}
if err := overall.add(item.chosenReward, item.rejectedReward); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if err := bySlice[item.slice].add(item.chosenReward, item.rejectedReward); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
overall.report("overall")
names := make([]string, 0, len(bySlice))
for name := range bySlice {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
bySlice[name].report(name)
}
}
预期输出:
overall n=6 accuracy=66.7% log_loss=0.598 brier=0.213
coding n=3 accuracy=66.7% log_loss=0.548 brier=0.193
safety n=3 accuracy=66.7% log_loss=0.649 brier=0.232
整体平均值不能掩盖关键切片回退。正式评测还应为结果提供置信区间,并比较多个 Seed 或 Checkpoint;如果 Safety Slice 低于门槛,即使大量简单样本把总体分数抬高,也必须阻断发布。
Bandit 方法在 RLHF 中适用于哪里
在一个决策边界内,系统选择一种回答策略或模型方案,并且只观察所选方案的反馈,这与多臂老虎机相似;当 Prompt、用户或请求特征会改变最佳方案时,更接近上下文老虎机。上置信界与 Thompson Sampling 可以服务于显式路由或实验选择,但不能直接替代 PPO:自回归生成包含巨大的结构化动作空间、由 Token 条件化的状态,以及延迟到序列结束的奖励。
有模拟器或可信 Oracle 提供反事实价值时,可以用 Regret比较探索策略;普通生产日志却看不到未选回答的奖励。离策略评估只有在决策时上下文、动作 Propensity、Outcome Timing 与 Support 都有效时,才能用另一条策略的日志估计冻结 Target Policy。确定性偏好日志即使同时保存 Chosen 与 Rejected 文本,也不能据此证明任意反事实策略价值。
阶段三:用 PPO 优化策略
PPO 是一种 On-policy Policy Gradient 方法:当前策略生成回答,系统计算奖励和 Advantage,再用这批 Rollout 更新策略。
面向 LLM 的实现通常包含四个逻辑角色:
| 组件 | 职责 | PPO 阶段通常是否更新 |
|---|---|---|
| Policy / Actor | 生成回答并接收梯度 | 是 |
| Reference Policy | 提供 KL 参照 | 否 |
| Reward Model | 为完整回答生成偏好分数 | 否 |
| Value Function / Critic | 估计 Return,降低梯度方差 | 是 |
四个角色不等于必须同时驻留四份完整模型。框架可以共享 Backbone、挂载 Value Head、做模型切分或 Offload。评估工程成本时应记录真实拓扑、精度、序列长度、Batch 和检查点策略,不能把参数量简单乘四当成通用显存要求。
PPO Clipping 不等于 KL 惩罚
这两个约束经常被混为一谈:
- PPO Clipping 约束一次参数更新相对生成当前 Rollout 的 Behavior Policy 变化过大。
- Reference-policy KL Regularization 惩罚策略偏离一个冻结参考模型,参考模型通常来自 SFT。
简化后的 PPO Clipped Surrogate 为:
L_clip(theta)
= E[min(r_t(theta) * A_t,
clip(r_t(theta), 1-epsilon, 1+epsilon) * A_t)]
r_t(theta)
= pi_theta(a_t | s_t) / pi_old(a_t | s_t)
常见的奖励塑形还会加入独立的参考策略项:
R(x, y)
= r_phi(x, y)
- beta * sum_t(
log pi_theta(y_t | x, y_<t)
- log pi_ref(y_t | x, y_<t)
)
PPO 原始论文 定义的是 Clipped Policy Update。RLHF 系统在此基础上加入 Reward Model、参考策略约束与语言模型 Rollout。Reward Aggregation、KL Estimator、Value Target、Generation Policy 和 Stale Rollout 处理都属于需要版本化的实现选择。
奖励模型通常只为完成后的整段回答给出一个 Scalar Reward,并不是独立评价每个 Token。实现可以把 Terminal Reward 分配到 Token-level Return,再叠加逐 Token 的 KL Reward Shaping,最后计算 Advantage。
监控完整优化路径
每个 Checkpoint 至少要记录:
- Proxy Reward 与独立人工或任务指标;
- 在固定测量协议下相对 Reference 的 KL;
- 回答长度、Entropy、Truncation 与 Repetition;
- Advantage 均值和方差、Value Loss 与 Explained Variance;
- PPO Clip Fraction、Ratio Distribution 与 Gradient Norm;
- 拒答、事实性、策略遵循与能力切片;
- Rollout Policy、Reward Model、Tokenizer、Prompt Template 与代码版本。
停止条件必须引用独立质量门禁,而不是 Reward 是否收敛。真实质量达到峰值后,策略仍可能继续提高代理奖励。
奖励过度优化与其他失败模式
只要被测偏好与真实目标存在差异,RLHF 就可能失败,而且问题可以在训练前、训练中或上线后出现。
| 失败层 | 例子 | 如何检测 | 主要缓解方法 |
|---|---|---|---|
| 目标定义 | 规则奖励自信回答,但正确行为应是承认不确定 | Rubric 评审与对抗样本 | 定义维度优先级和可接受的不确定性 |
| 数据采样 | 候选只覆盖简单中文问答 | 覆盖率与 Cohort 报告 | 分层采样和困难样本挖掘 |
| 人工标注 | 评审对篇幅或拒答分歧 | 按切片统计 Tie 与 Agreement | 保留分歧、澄清 Prompt、细分偏好 |
| 奖励建模 | Reward 追随长度或生成模型身份 | Counterfactual 与简单特征探针 | 平衡数据、去除伪特征、按切片校准 |
| 策略优化 | Proxy Reward 上升但独立质量下降 | Reward-Human Checkpoint Curve | Early Stop、限制偏移、刷新反馈 |
| 生产部署 | 线上用户和 Prompt 偏离采集分布 | 灰度与上线后切片指标 | 路由、补采标签或回滚 |
Scaling Laws for Reward Model Overoptimization 在受控的合成实验中展示了典型 Goodhart 现象:持续优化学习得到的代理奖励时,更大的 Gold Reward 会先上升再下降,而 Proxy Reward 仍继续上升。论文中的具体曲线依赖该实验设置,只能证明这种机制存在,不能当作所有系统的通用停止阈值。
KL Regularization 能限制策略移动范围,但不能证明 Reward 有效。策略可能在很小的 KL 距离内利用局部捷径,过强约束也可能压制真实改进。Reward Ensemble 与 Uncertainty Penalty 同样只能缓解特定失败;产品是否改善,最终仍需独立评测。
InstructGPT 研究真正证明了什么
InstructGPT 是重要的 RLHF 案例,但不是可以直接复制的生产配方。它的实验细节恰好说明结果有多依赖数据和评测设计:
- 研究通过筛选招募了 40 名 Contractor。
- SFT、Reward Model 和 PPO 分别使用约 1.3 万、3.3 万和 3.1 万个训练 Prompt;这些数字是 Prompt 数量,不能与派生出的 Pairwise Comparison 数量混用。
- 每个 RM Prompt 展示 4 到 9 个回答,因此一份 Ranking 会产生多组高度相关的 Pair。
- 一个 6B Reward Model 被用于优化 1.3B、6B 和 175B 三种规模的策略。
- 数据中超过 96% 的 Prompt 是英文。
- 主测试集来自未出现在训练数据中的 API Customer Prompt,论文还单独分析了公共 NLP 任务和 Held-out Labeler。
在这项研究的 Prompt、标注者、模型和协议下,评审更偏好 1.3B InstructGPT 的回答,而不是 175B GPT-3 的回答。论文也报告了特定真实性和毒性测试上的改善,同时明确保留了简单错误、两个偏见基准没有显著改善,以及公共 NLP 能力回退等限制;后者促使研究加入 Pretraining Gradient。
这些结果不能证明通用数据量、模型拓扑、超参数或“RLHF 会让所有模型更安全”。它们证明的是:一条经过严格测量的偏好训练链路,可以显著改变目标分布上的模型行为。
RLHF、SFT、DPO、RLAIF 与 RLVR 如何选择
选型应从“你能信任什么反馈、需要改变什么行为”出发,而不是从方法热度出发。
| 方法 | 适用条件 | 主要工程风险 |
|---|---|---|
| SFT | 能直接示范期望回答 | 模仿数据伪特征,难表达相对取舍 |
| 基于 PPO 的 RLHF | 需要围绕学习得到的偏好做 On-policy 探索,并能承担持续评测 | 奖励过度优化与多组件训练复杂度 |
| DPO | 已有固定且有代表性的成对数据,希望先建立较简单的离线基线 | 偏好过拟合、参考策略敏感、无法自动覆盖数据集之外行为 |
| RLAIF | 人工评审是瓶颈,且可用书面规则约束 AI Judge | 评审模型偏差和相关性盲区 |
| RLVR | 正确性可以由 Test、Solver 或 Environment Outcome 验证 | Verifier Bug、奖励漏洞与稀疏奖励 |
DPO 与 RLHF 对比 详细推导了目标函数和选型矩阵;LLM 微调指南 则回答更上层的 Prompt、RAG、SFT、参数高效微调与偏好优化选型问题。
这些方法可以串联,但阶段更多不等于模型更好。每增加一个阶段,都应绑定一项被独立评测证实的问题,并保留同口径基线。
生产评测与发布门禁
可信的 RLHF 评测必须把“用于优化的指标”和“批准发布的指标”分开。
数据门禁
- 固定 Prompt、Candidate Policy、Rubric、Annotator Cohort 与 Sampling Weight 版本。
- 报告 Agreement、Tie、Skip、Adjudication、Duplicate、Leakage、语言覆盖和敏感数据处理。
- 条件允许时,测试 Prompt 和评审者都应与训练独立。
奖励模型门禁
- 与回答长度、来源模型等简单基线比较。
- 按关键切片报告 Pairwise Accuracy、Log Loss、Calibration 与置信区间。
- 测试更新后 Policy 的回答、对抗 Pair、候选顺序变化和只改变风格的 Counterfactual。
- 总体收益掩盖 Safety 或关键人群回退时,拒绝该 Reward Model。
策略门禁
- 在相同 Decoding 参数下比较 Base、SFT 和候选策略。
- 同时使用 Blind Human Comparison 与任务可用的确定性指标。
- 分开报告事实性、Groundedness、拒答 Precision / Recall、隐私、偏见、鲁棒性和能力回退。
- 追踪篇幅和格式,暴露只迎合风格的偏好捷径。
运行门禁
- 固定 Model、Dataset、Tokenizer、Prompt Template、Reward 与 Evaluation 版本。
- 灰度发布,监控分布漂移,并保留上一版本的快速回滚能力。
- 用户反馈是新的数据源,必须重新处理 Consent、Provenance、滥用防护与质量审核。
- 运行时 Guardrails、Authorization 与副作用控制必须独立于模型训练。
RLHF 只能改变行为概率,不能执行 Tenant Isolation、批准转账、验证医疗事实,也不能保证 Agent 操作获得授权。
常见问题
RLHF 是什么?
RLHF 利用人类判断学习奖励信号,再用强化学习优化模型策略。它最适合“人能稳定比较候选结果,但目标很难写成固定规则”的行为问题。
RLHF 一定要经过 SFT、奖励模型和 PPO 三个阶段吗?
不一定。这是 InstructGPT 推广的经典流程。其他系统可以采用不同初始策略、反馈格式、奖励表示或 RL Optimizer。DPO 等直接偏好方法会使用相似的比较数据,但通常不归入狭义 RLHF,因为它们没有独立的 Reward Model 与 RL Loop。
RLHF 和 DPO 有什么区别?
基于 PPO 的 RLHF 会训练显式 Reward Model,并在优化过程中从当前策略采样。DPO 则在 Reference-policy 公式下直接对 chosen-rejected Pair 使用离线偏好损失。DPO 通常减少了在线训练组件,但没有消除标注偏差、分布漂移、过拟合与独立安全评测。
RLHF 能消除幻觉或保证模型安全吗?
不能。评审可能偏好听起来更自信但未经验证的回答,Reward Model 还可能放大这类捷径。产品必须独立评测事实性与策略遵循,需要证据时强制 Grounding,并把权限与高影响操作交给模型外部的可信控制。
训练 RLHF 需要多少偏好数据?
没有可靠的通用门槛。先用有代表性的小规模试验建立真正未触碰的评测集,再相对 SFT 基线绘制 Learning Curve。应该在分歧、校准或关键切片显示覆盖不足时增加数据,而不是用记录总量宣称已经对齐。
总结
RLHF 的本质是优化“人类判断的学习代理”。真正困难的部分不只是运行 PPO,而是说明谁的偏好有效、保留判断发生的条件、验证奖励模型能否迁移到新策略,并在代理分数取代真实质量前停止优化。
把 SFT 作为强基线,只为已经测量的偏好问题引入 RLHF,并让独立产品指标、安全评测和运行时控制始终留在发布链路中。
一手来源
- Deep Reinforcement Learning from Human Preferences
- Proximal Policy Optimization Algorithms
- Learning to Summarize from Human Feedback
- Training Language Models to Follow Instructions with Human Feedback
- Scaling Laws for Reward Model Overoptimization
- Direct Preference Optimization
- Diverging Preferences: When Do Annotators Disagree and Do Models Know?
- Reinforcement Learning from Human Feedback