指令遵循作为对齐信号 本节摘要:本章后面所有对 RLHF(基于人类反馈的强化学习)的批判,都是在反驳这一条流水线。在研究优化压力如何扭曲代理量之前,你必须先看清这个代理量本身。InstructGPT(Ouyang 等,2022)定义了参考架构:在「指令—回复」对上做有监督微调、在成对偏好排序上训练奖励模型、再用 PPO 相对奖励模型做优化并加一道指向 SFT 策略的 KL 罚项。结果是一个 13 亿参数的 InstructGPT,在人类偏好评估中胜过了 1750 亿参数的 GPT-3。正是这一条结果,让 2026 年每一个前沿实验室仍在发布「RLHF 形状」的后训练流水线。本节带你逐段拆解这条三段式流水线,并解释为什么它至今仍是整个对齐领域的参照原点。
本节摘要:本章后面所有对 RLHF(基于人类反馈的强化学习)的批判,都是在反驳这一条流水线。在研究优化压力如何扭曲代理量之前,你必须先看清这个代理量本身。InstructGPT(Ouyang 等,2022)定义了参考架构:在「指令—回复」对上做有监督微调、在成对偏好排序上训练奖励模型、再用 PPO 相对奖励模型做优化并加一道指向 SFT 策略的 KL 罚项。结果是一个 13 亿参数的 InstructGPT,在人类偏好评估中胜过了 1750 亿参数的 GPT-3。正是这一条结果,让 2026 年每一个前沿实验室仍在发布「RLHF 形状」的后训练流水线。本节带你逐段拆解这条三段式流水线,并解释为什么它至今仍是整个对齐领域的参照原点。
对应原课程:Phase 18 · Lesson 01 ·
instruction-following-alignment-signal(原英文phases/18-ethics-safety-alignment/01-instruction-following-alignment-signal/docs/en.md)。前置:Phase 10 · 06(SFT)、07(RLHF)、08(DPO)。
阅读完本节,你应当能够:
预训练语言模型擅长续写文本,却不擅长回答问题。你问 GPT-3「写一个反转列表的 Python 函数」,经常拿回来的又是另一段提示词——因为训练分布里绝大多数是网页文本,网页后面跟着的还是网页。模型在尽职尽责地完成任务,问题是任务本身设错了。
所有严肃实验室用来修复这一点的代理量,都是人类偏好:把两个候选回复交给标注员,标注员挑出更好的那一个;一个奖励模型(reward model)去学习这位标注员;然后用一个 RL 循环把策略往奖励模型打高分的方向推。三句话就是 InstructGPT 的全部主张,论文剩下的部分都是工程细节。
核心洞察有两条,贯穿全章:
⚠️ 为什么这是第 18 章的参照原点:本章后面每一节都在攻击这条流水线的某一段——奖励黑客攻击第 2 阶段、DPO 把第 2、3 阶段合并、CAI(第 05 节)替换掉人类标注员、谄媚(第 04 节)说明标注员本身是带偏的信号、对齐伪装(第 09 节)说明策略可以绕开第 3 阶段。不先把这条流水线刻在脑子里,后面任何一条批判都读不进去。
原课程 code/main.py 在玩具偏好数据上模拟了这三个阶段。「基座策略」是对动作集合 {A, B, C} 的一个有偏硬币。下面是各阶段的简化伪代码,完整逻辑见原课程代码文件。
收集一批「提示—回复」对,其中的回复是一个善意的标注员会写出的内容(Ouyang 等用了 1.3 万条来自标注员和 OpenAI API 的提示),对基座模型做标准交叉熵微调。
# Stage 1:在 (prompt, response) 对上做交叉熵微调 def sft_step(policy, prompt, response): logits = policy(prompt) loss = cross_entropy(logits, response) # 教模型「回答」而非「续写」 return loss
SFT 给你的是「模型现在会回答问题了」,没给你的是「当多个回答都合理时,标注员更偏好哪一个」这个信号。
对每个提示,从 SFT 模型采样 K 个回复,让标注员排序;训练一个奖励模型,使它对任意 (提示, 回复) 打出一个标量分,且对「胜出回复 y_w 优于落败回复 y_l」的成对样本满足:
L_RM = -log sigmoid( r(x, y_w) - r(x, y_l) )
这就是 Bradley-Terry 成对偏好损失:把排序问题降成二分类。奖励模型通常用 SFT 模型初始化、把语言建模头换成一个标量头。它很小(1750 亿参数的 InstructGPT 用了 60 亿参数的奖励模型就够),也很脆——论文第 5 节大半篇幅在讲小规模下就出现的奖励黑客行为。
J(pi) = E[ r(x, y) ] - beta * KL( pi(.|x) || pi_SFT(.|x) )
用 PPO 最大化。KL 项把 pi 拽住、不让它离 SFT 策略太远。移除它,优化器会找到对抗样本——那些在奖励模型上得高分的字符串,是因为奖励模型从没见过它们,而不是因为人类真的偏好它们。系数 beta 是 RLHF 最重要的单一超参:太低 → 奖励黑客;太高 → 相比 SFT 毫无提升。
# Stage 3:简化版 PPO 更新(玩具版) def ppo_step(policy, sft_policy, reward_model, prompt, beta): y = policy.sample(prompt) r = reward_model(prompt, y) kl = KL(policy(prompt), sft_policy(prompt)) objective = r - beta * kl # beta=0 即关闭 KL 罚项 ppo_update(policy, objective) return r, kl
💡 可观察的现象:把
beta从 0.1 调到 0.0,你会在大约 50 个更新步内亲眼看到奖励黑客浮现——策略塌缩到某个单一动作上,奖励曲线飙升,而真实人类偏好实际在下降。
RLHF 之后,模型更受人类欢迎,但在标准基准(SQuAD、HellaSwag、DROP)上回落。Ouyang 等称之为对齐税,并用 PPO-ptx 对冲:把预训练梯度混进 RL 目标,让模型别忘记那些从未被奖励过的下游能力。
J_ptx(pi) = J(pi) + gamma * E[ log pi(x) ] # x ~ 预训练分布
PPO-ptx 成了标准做法,Anthropic、DeepMind、Meta 都在用某种变体。
不同后训练栈对这条流水线的取舍:
| 方案 | 第 2 阶段 | 第 3 阶段 | KL 锚点 |
|---|---|---|---|
| InstructGPT(PPO-ptx) | 独立 Bradley-Terry 奖励模型 | PPO 显式优化 | KL 到 SFT,显式 beta |
| Anthropic HH-RLHF | 同上,但偏好来自「有用+无害」双轴 | PPO | 同上 |
| DPO(第 03 节) | 合并进第 3 阶段 | 无奖励模型,直接在偏好对上做对比损失 | 隐式正则(参考策略) |
| Constitutional AI(第 05 节) | 标注员换成「模型自我批判」 | RLAIF,仍用 PPO | 同上 |
设计要点:显式 KL 罚项是 InstructGPT 的命门——它把「在奖励模型上拿高分」和「不偏离 SFT 太远」做了显式权衡;DPO 把这道权衡隐式塞进了对比损失,代价是你失去了像
beta这样可直接调的旋钮。
本节产出 outputs/skill-instructgpt-explainer.md:给它一段 RLHF 流水线描述或论文摘要,它能识别出三阶段中哪一段被改了、每段用的是什么损失、是否存在 KL 罚项或等价正则项。这是读懂本章后续 29 节任意一篇论文的通用解码器。
Python 代码(code/main.py)是独立玩具流水线,把里面模拟的「有偏硬币」换成真实策略、把模拟奖励模型换成真实标量头,即可用于教学复现,三阶段骨架无需改动。
Easy:运行 code/main.py,设 beta = 0.0,报告 200 步 PPO 后的动作分布,用一段话解释观察到的 mode-seeking 行为。
Medium:给奖励模型植入一个「对动作 B 有 +0.5 偏置」的模拟 bug,在 beta = 0.1 下跑 PPO。KL 罚项能阻止策略利用这个 bug 吗?在哪个 beta 下利用行为开始可见?
Medium:读 Ouyang 等(arXiv:2203.02155)Figure 1,用「PPO 跑 1、5、20、100 步」对 SFT 模型测量偏好,复现这条偏好曲线。
Hard:论文 4.3 节报告 13 亿 InstructGPT 约 70% 的时间胜过 1750 亿 GPT-3。为什么在隐藏的生产环境提示上这个比例会比在标注员自己的提示上更高?
Hard:把 PPO 损失换成 DPO(Phase 10 · 08),用同一批偏好数据,比较最终策略漂移(到 SFT 的 KL)和最终奖励。在奖励相近时,哪种方法漂移更远?
beta * KL(pi || pi_SFT) 是 RLHF 最重要的单一超参:防策略漂移成对抗样本;太低→奖励黑客,太高→毫无提升。下一节,我们直击这条流水线最致命的弱点——奖励黑客与古德哈特定律:当优化压力加在一个代理量上,这个代理量迟早会与你真正想要的目标脱钩。