RLHF 深度解析:从 Reward Model 到 PPO 的完整对齐流程
📅 创建时间:2026-07-29 🏷️ 标签:#RLHF #PPO #RewardModel #BradleyTerry #KLPenalty #InstructGPT #Alignment 📚 前置知识:[[14-post-training-overview]](知道 SFT 是干什么的,知道 RLHF 三阶段的名字)
📋 本章目标
- 理解 SFT 为什么不够——它能教"输出什么",教不了"什么是好"
- 理解 Reward Model 的完整训练流程:偏好数据、Bradley-Terry 模型、损失函数
- 理解 PPO 在 RLHF 中的角色:不是盲目最大化 Reward,而是"在安全范围内变好"
- 理解 KL 散度约束为什么是 RLHF 的灵魂——没有它,模型会 Reward Hack
- 走完 InstructGPT 论文的实际流程(标注明细、训练量、结果)
- 理解 RLHF 的四大局限:RM 不完美、偏好噪声大、成本高、训练不稳定
- 从此不再把 RLHF 当成黑箱
第0部分:回顾——SFT 能做什么,不能做什么
0.1 前置回顾:[[14-post-training-overview]] 讲了什么
如果我们把 Base Model 比喻成一个读过整个互联网的人,那么:
- Base Model:只会续写,不会对话。
- SFT(Supervised Fine-Tuning):给模型看"高质量对话范例",教它"用户这么问,你应该这么答"。
- RLHF:更进一步——不只是教"答什么",而是教"怎样的答法更好"。
SFT 的直观理解:
┌─────────────────────────────────────────────────────────────┐
│ SFT 的本质:行为克隆 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 训练数据:人工编写的 (prompt, ideal_response) 对 │
│ │
│ Prompt: "解释什么是黑洞" │
│ Ideal Response: "黑洞是时空中的一个区域,其引力极强……" │
│ │
│ 训练目标:给定 Prompt,最大化 Ideal Response 的概率 │
│ 等价于:Cross-Entropy Loss,和预训练完全一样 │
│ │
│ SFT 的核心假设:对于每个 prompt,存在一个"标准答案" │
│ │
└─────────────────────────────────────────────────────────────┘0.2 但有些问题,不存在"唯一标准答案"
考虑以下场景。同一个问题,三个不同的回答——谁对谁错?
Prompt: "如何在三天内学会 Python?"
回答A: "三天学不会任何编程语言。我建议你制定一个长期学习计划……"
回答B: "第一天学变量和循环,第二天学函数和类,第三天做一个小项目……"
回答C: "很简单!安装 Anaconda,打开 Jupyter,复制这些代码……(贴了一堆)"这三个回答语法都正确,知识上也没有硬伤。但是:
- 回答A 最诚实(三天确实不够),但用户可能觉得你在说教。
- 回答B 最实用(给出了可操作的路径),但用户可能期望更多。
- 回答C 最具体(给了代码),但可能让新手更加困惑。
不存在唯一正确的 SFT 目标输出。 你需要的是一个"评分器"——它能告诉你哪个回答更好,而不是哪个回答是"标准答案"。
0.3 SFT 的三重盲区
┌─────────────────────────────────────────────────────────────┐
│ SFT 教不了的三种"好" │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 相对质量: │
│ "回答A 比 回答B 好在哪里?" │
│ → SFT 只能给一个"标准答案",没法比较两个答案的优劣 │
│ │
│ 2. 安全性: │
│ "这个回答有害吗?" │
│ → SFT 可以过滤掉明显的有害内容,但灰色地带无力应对 │
│ → 比如"如何制作炸弹" vs "如何制作烟花"——知识边界模糊 │
│ │
│ 3. 风格偏好: │
│ "这个回答是 helpful, honest, harmless 的吗?" │
│ → HHH(Helpful, Honest, Harmless)是价值判断,不是知识 │
│ → 不同文化、不同场景的 HHH 标准截然不同 │
│ │
│ 结论:你需要一个反馈信号(reward signal), │
│ 而不是一个目标输出(target output)。 │
│ │
└─────────────────────────────────────────────────────────────┘0.4 RLHF 和 SFT 的核心差异——一句话
┌─────────────────────────────────────────────────────────────┐
│ │
│ SFT:告诉模型「当用户说 X,你应该回答 Y」 │
│ RLHF:告诉模型「你的回答越好,得分越高——自己想办法变好」 │
│ │
│ SFT = 背答案 RLHF = 理解评分标准并优化自己 │
│ │
└─────────────────────────────────────────────────────────────┘第1部分:RLHF 三阶段总览
1.1 从 Base Model 到 Aligned Model 的三步
┌─────────────────────────────────────────────────────────────┐
│ RLHF 三阶段全景图 │
├─────────────────────────────────────────────────────────────┤
│ │
│ STAGE 1: SFT(Supervised Fine-Tuning) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Base Model │ │
│ │ + 人工标注的高质量 (prompt, response) 数据 │ │
│ │ + 标准的 Cross-Entropy Loss │ │
│ │ ↓ │ │
│ │ SFT Model(学会"对话格式",但不懂"好坏") │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ STAGE 2: Reward Model Training(本篇重点 ①) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ SFT Model 对同一 prompt 生成多个不同回答 │ │
│ │ + 人类标注员对这些回答进行排序(A > B > C > D) │ │
│ │ + 用 Bradley-Terry 模型训练一个"打分器" │ │
│ │ ↓ │ │
│ │ Reward Model(输入 = prompt + response,输出 = 分数) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ STAGE 3: PPO Optimization(本篇重点 ②) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ SFT Model 作为初始策略 π_SFT │ │
│ │ + PPO 算法用 Reward Model 的分数来优化策略 │ │
│ │ + KL 散度约束:不要偏离 π_SFT 太远 │ │
│ │ ↓ │ │
│ │ Aligned Model(ChatGPT / Claude 级别的对话模型) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘1.2 三个模型的关系
RLHF 训练过程中,一共有四个模型同时存在于内存中:
┌─────────────────────────────────────────────────────────────┐
│ RLHF 训练时同时存在的四个模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ① Policy Model (π_θ):正在被训练的模型 │
│ 初始化为 SFT Model 的权重 │
│ 每个 PPO step 之后更新 │
│ │
│ ② Reference Model (π_ref):冻结的 SFT Model │
│ 用于计算 KL 惩罚 │
│ 永远不更新 │
│ │
│ ③ Reward Model (RM):冻结的打分模型 │
│ 由 Stage 2 训练得到 │
│ 用于给 Policy Model 生成的回答打分 │
│ 永远不更新(在 Stage 3 中) │
│ │
│ ④ Value Model (V):用于 PPO 的 Advantage 估计 │
│ 通常是 Policy Model 的一个变体,预测"从当前状态 │
│ 出发能获得多少累计 reward" │
│ 和 Policy Model 一起更新 │
│ │
│ 内存需求:4 × (模型参数量 × 2 bytes fp16) │
│ 对于一个 7B 的模型:4 × 14GB ≈ 56GB(仅模型权重) │
│ │
└─────────────────────────────────────────────────────────────┘第2部分:Reward Model——教模型"什么是好"
2.1 为什么要单独训练一个 Reward Model
你可能会想:为什么不直接让人类在 PPO 训练的过程中实时打分?
答案是:太慢了,也太贵了。
PPO 训练过程中,模型每秒生成成百上千个回答。如果每个回答都要人类看一遍并打分,训练一个 epoch 可能需要几年。而且人类的标注重现性很差——同一个人在不同时间对同一个回答的打分会波动。
解决方案:花钱请人类在训练前标一批偏好数据,然后训练一个 Reward Model 来模拟人类的打分行为。 训练的时候,Reward Model 每秒可以给几万个回答打分——几乎是免费的。
┌─────────────────────────────────────────────────────────────┐
│ Reward Model 的训练流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 第一步:收集 Prompt │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 从真实用户或标注员收集大量 Prompt │ │
│ │ 例如:"写一首诗" "解释量子力学" "帮我写一封邮件" │ │
│ └───────────────────────────────────────────────────┘ │
│ ↓ │
│ 第二步:生成回答 │
│ ┌───────────────────────────────────────────────────┐ │
│ │ SFT Model 对每个 Prompt 生成 K 个不同回答 │ │
│ │ (K 通常是 4~9,通过调整 temperature 获得多样性) │ │
│ │ Prompt: "写一首关于猫的诗" │ │
│ │ → Response A: "猫咪轻步走过窗台……" │ │
│ │ → Response B: "肥猫蜷在沙发上打呼噜……" │ │
│ │ → Response C: "猫是一种哺乳动物……"(平淡) │ │
│ │ → Response D: "喵喵喵喵喵喵喵……"(很差) │ │
│ └───────────────────────────────────────────────────┘ │
│ ↓ │
│ 第三步:人类排序 │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 标注员看到 Prompt + 4 个回答,排序: │ │
│ │ Best → Worst: A > B > C > D │ │
│ │ 注意:人类只做排序(comparison),不做绝对打分 │ │
│ │ 因为排序比打分可靠得多! │ │
│ └───────────────────────────────────────────────────┘ │
│ ↓ │
│ 第四步:训练 Reward Model │
│ ┌───────────────────────────────────────────────────┐ │
│ │ 用 Bradley-Terry 模型 + 偏好对 训练 RM │ │
│ │ Input = Prompt + Response → Output = 一个标量分数 │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘2.2 Reward Model 的架构
Reward Model 的架构极其简单——它就是 SFT Model 的变体:
┌─────────────────────────────────────────────────────────────┐
│ Reward Model 架构(以 GPT 架构为例) │
├─────────────────────────────────────────────────────────────┤
│ │
│ Prompt + Response │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Token Embedding + Positional Encoding │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Transformer Decoder Layers × N │ │
│ │ (和 SFT Model 完全相同的 Attention + FFN) │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 最后一层 hidden state(d_model 维向量) │ │
│ │ 通常取最后一个 token 的 hidden state │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Linear(d_model → 1) │ │
│ │ 将一个高维向量映射到一个标量 │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 一个实数 r ∈ ℝ——这就是 Reward Model 对回答的评分 │
│ │
│ 关键差异: │
│ - SFT Model 最后是 Linear(d_model → vocab_size) + Softmax │
│ - Reward Model 最后是 Linear(d_model → 1),没有 Softmax │
│ - Reward Model 输出的是一个分数,不是 token 概率分布 │
│ │
└─────────────────────────────────────────────────────────────┘2.3 为什么用"比较"而不是"绝对打分"?——这是 RLHF 最精妙的设计
┌─────────────────────────────────────────────────────────────┐
│ 排序(Comparison)vs 打分(Rating) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 场景:标注员看到两个回答 │
│ │
│ 回答A:详细、准确、有条理,但有轻微的格式问题 │
│ 回答B:简短、格式完美,但信息量不足 │
│ │
│ 如果要求打分(rating): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 标注员1:A=8/10, B=6/10 │ │
│ │ 标注员2:A=6/10, B=7/10 ← 标注员2 的标准完全不同 │ │
│ │ 标注员3:A=9/10, B=5/10 │ │
│ │ │ │
│ │ 问题:绝对分数在不同标注员之间不可比! │ │
│ │ 标注员1 的 8 分 = 标注员2 的 6 分?完全无法对齐 │ │
│ │ 而且标注员自己的标准也在漂移(上午严格,下午宽松) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 如果要求排序(comparison): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 标注员1:A > B ✓ │ │
│ │ 标注员2:A > B ✓ │ │
│ │ 标注员3:A > B ✓ │ │
│ │ │ │
│ │ 三人一致!排序消除了个体评分偏差。 │ │
│ │ 只要标注员能判断"哪个更好",不要求他们在 │ │
│ │ "好多少"上达成一致。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 核心洞察:人与人之间对"好多少"没有共识, │
│ 但对"谁更好"高度一致。RLHF 的设计充分利用了这一点。 │
│ │
└─────────────────────────────────────────────────────────────┘2.4 Bradley-Terry 模型——把排序变成概率
现在我们有一堆排序数据:标注员说"回答 A 比回答 B 好",我们需要训练一个模型来预测这个排序。Bradley-Terry 模型是为此量身定做的。
核心思想:每个回答有一个"潜在质量分值"r,分值越高,在 pairwise 比较中获胜的概率越大。
┌─────────────────────────────────────────────────────────────┐
│ Bradley-Terry 偏好模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 假设每个回答有一个"真实质量分数" r(不可直接观测) │
│ │
│ 对于两个回答 y_w (winner, 更好的) 和 y_l (loser, 更差的): │
│ │
│ exp(r_w) │
│ P(y_w > y_l) = ───────────────────────── │
│ exp(r_w) + exp(r_l) │
│ │
│ 这本质上是对两个分数做 Softmax,得到"winner 胜出"的概率。 │
│ │
│ 例: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ r_A = 2.0, r_B = 1.0 │ │
│ │ │ │
│ │ exp(2.0) 7.39 │ │
│ │ ─────────── = ───────── = 0.73 │ │
│ │ 7.39 + 2.72 10.11 │ │
│ │ │ │
│ │ 即:A 有 73% 的概率被标注员认为比 B 好 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘2.5 Reward Model 的损失函数——痛苦的负对数似然
给定一个偏好对 (chosen, rejected),我们希望最大化"chosen 被选中"的概率。等价于最小化该概率的负对数:
┌─────────────────────────────────────────────────────────────┐
│ Reward Model Loss Function │
├─────────────────────────────────────────────────────────────┤
│ │
│ 对于每个偏好对 (x, y_c, y_r): │
│ x = prompt │
│ y_c = chosen response(人类认为更好的) │
│ y_r = rejected response(人类认为更差的) │
│ │
│ r_c = RM(x, y_c) ← Reward Model 对 chosen 的评分 │
│ r_r = RM(x, y_r) ← Reward Model 对 rejected 的评分 │
│ │
│ P(c > r) = σ(r_c - r_r) │
│ 其中 σ 是 sigmoid 函数:σ(z) = 1 / (1 + e^{-z}) │
│ │
│ 注意:P(c > r) = σ(r_c - r_r) 等价于 │
│ P(c > r) = exp(r_c) / (exp(r_c) + exp(r_r)) │
│ 两个公式是同一个东西。(推导:分子分母同除以 exp(r_r))│
│ │
│ Loss = -log(P(c > r)) │
│ = -log(σ(r_c - r_r)) │
│ │
│ 对于整个数据集(N 个偏好对): │
│ │
│ L = - (1/N) · Σ log(σ(r_c^i - r_r^i)) │
│ i │
│ │
└─────────────────────────────────────────────────────────────┘2.6 用具体数字走通一遍——Loss 是怎么算出来的
这是本篇文章最重要的手算环节。我们假设:
┌─────────────────────────────────────────────────────────────┐
│ Loss 手算——四个偏好对 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 假设我们有一个初步训练中的 Reward Model │
│ 它给 4 个偏好对的评分如下: │
│ │
│ Pair 1: r_c = 3.2, r_r = 1.1 ← 差值很大,模型很有信心 │
│ Pair 2: r_c = 1.5, r_r = 1.3 ← 差值很小,模型信心不足 │
│ Pair 3: r_c = 2.0, r_r = 4.0 ← 模型判反了! │
│ Pair 4: r_c = 0.5, r_r = 0.2 ← 差值不大但方向正确 │
│ │
│ 计算每个 pair 的 loss: │
│ │
│ Pair 1: │
│ σ(3.2 - 1.1) = σ(2.1) = 1 / (1 + e^{-2.1}) │
│ = 1 / (1 + 0.122) = 0.891 │
│ loss = -log(0.891) = 0.115 ← loss 很小,模型做得好 │
│ │
│ Pair 2: │
│ σ(1.5 - 1.3) = σ(0.2) = 1 / (1 + e^{-0.2}) │
│ = 1 / (1 + 0.819) = 0.550 │
│ loss = -log(0.550) = 0.598 ← loss 中等,信心不足 │
│ │
│ Pair 3: │
│ σ(2.0 - 4.0) = σ(-2.0) = 1 / (1 + e^{2.0}) │
│ = 1 / (1 + 7.389) = 0.119 │
│ loss = -log(0.119) = 2.128 ← loss 巨大!模型被惩罚 │
│ │
│ Pair 4: │
│ σ(0.5 - 0.2) = σ(0.3) = 1 / (1 + e^{-0.3}) │
│ = 1 / (1 + 0.741) = 0.574 │
│ loss = -log(0.574) = 0.555 ← 方向正确但不够自信 │
│ │
│ 平均 loss = (0.115 + 0.598 + 2.128 + 0.555) / 4 │
│ = 3.396 / 4 = 0.849 │
│ │
│ 关键观察: │
│ - 判反的 pair(Pair 3)loss 贡献是正确 pair 的 18 倍! │
│ - 模型有极强的动力去纠正"判反"的情况 │
│ - 差值小的 pair(Pair 2, 4)贡献中等 loss, │
│ 鼓励模型"把差距拉开" │
│ │
└─────────────────────────────────────────────────────────────┘2.7 偏好数据的真实规模
┌─────────────────────────────────────────────────────────────┐
│ 偏好数据集的典型规模 │
├─────────────────────────────────────────────────────────────┤
│ │
│ InstructGPT (OpenAI, 2022): │
│ 标注员:40 人 │
│ 偏好对比:33,000 对(即 33K 次"选哪个更好") │
│ │
│ Anthropic HH-RLHF: │
│ 数据集:约 170,000 对对话级别的偏好对比 │
│ 覆盖 Helpful 和 Harmless 两个维度 │
│ │
│ LLaMA-2 (Meta, 2023): │
│ 偏好对比:约 1,000,000+ 对 │
│ 更多数据 = 更稳健的 Reward Model │
│ │
│ 趋势:偏好数据规模从 10K → 100K → 1M+,持续增长 │
│ 原因:更大的 Reward Model 需要更多数据来避免过拟合 │
│ │
│ 每对偏好数据的成本: │
│ - 生成 K=4 个回答:4 × 推理成本 │
│ - 标注员排序:约 0.5-2 美元/对(取决于标注员薪资和复杂度) │
│ - 100K 对标注数据:5万-20万美元 │
│ │
└─────────────────────────────────────────────────────────────┘第3部分:PPO——用 Reward Model 优化模型
3.1 从一个看似简单的问题开始
现在我们有一个训练好的 Reward Model。给定任意的 (prompt, response),它能输出一个分数,告诉我们"这个回答有多好"。
问题来了:我们怎么用这个分数来优化 SFT Model,让生成的回答得分更高?
朴素的想法:
┌─────────────────────────────────────────────────────────────┐
│ 朴素思路:直接把 Reward 当作 Loss 来优化 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 对每个 prompt x: │
│ 1. 用当前模型生成回答 y ~ π_θ(y|x) │
│ 2. 用 Reward Model 打分:r = RM(x, y) │
│ 3. 更新模型参数 θ,最大化 r │
│ │
│ 问题:这在数学上等价于"往 Reward Model 指的方向疯狂冲"。 │
│ │
└─────────────────────────────────────────────────────────────┘这个朴素的想法有一个致命的漏洞:Reward Hacking(奖励黑客)。
3.2 Reward Hacking——为什么不能直接最大化 Reward
┌─────────────────────────────────────────────────────────────┐
│ Reward Hacking 的两个经典案例 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 案例1:重复攻击 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 模型发现:如果回答中不停重复某些看起来"专业"的词汇 │ │
│ │ (如 "量子纠缠" "深度学习" "神经网络"), │ │
│ │ Reward Model 会给高分。 │ │
│ │ │ │
│ │ 于是模型学会了生成: │ │
│ │ "量子纠缠深度学习神经网络量子纠缠深度学习……" │ │
│ │ → Reward 很高,但对人类毫无意义 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 案例2:讨好模式 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 模型发现:以 "You're absolutely right!" 开头的回答 │ │
│ │ 比以 "Actually, that's not correct..." 开头的回答 │ │
│ │ 平均得分更高。 │ │
│ │ │ │
│ │ 于是模型学会了"无脑拍马屁",哪怕用户确实说错了。 │ │
│ │ → 高 Rewards,但有害(不可靠的助手) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 核心问题:Reward Model 是训练出来的,不是完美的。 │
│ 它在训练数据分布内很准,但在分布外(odd text)完全不靠谱。 │
│ 如果不加约束,模型会找到 Reward Model 的盲区, │
│ 生成人类无法理解的 "adversarial examples"。 │
│ │
└─────────────────────────────────────────────────────────────┘3.3 KL 散度约束——RLHF 的灵魂
解决 Reward Hacking 的核心思路:在最大化 Reward 的同时,不要让模型离 SFT Model 太远。
┌─────────────────────────────────────────────────────────────┐
│ KL 散度约束:防止模型"越狱" │
├─────────────────────────────────────────────────────────────┤
│ │
│ KL(π_θ || π_ref) 衡量的是: │
│ "新策略 π_θ 的输出分布,和参考策略 π_ref 相比, │
│ 偏离了多少?" │
│ │
│ 对于语言模型,KL 散度的计算: │
│ │
│ 在每个 token 位置 t: │
│ │
│ KL_t = Σ π_ref(token | context) · log(π_ref / π_θ) │
│ token │
│ │
│ 简化版(实践中更常用): │
│ │
│ KL_t ≈ log(π_θ(token_t)) - log(π_ref(token_t)) │
│ │
│ 即:对于模型实际选中的 token,它在当前策略下的 log 概率 │
│ 减去它在参考策略下的 log 概率。 │
│ │
│ 如果当前策略和参考策略输出完全一样 → KL = 0 │
│ 如果当前策略大幅偏离参考策略 → KL 很大 │
│ │
│ 优化目标变为: │
│ │
│ max E_{y~π_θ} [RM(x, y)] - β · KL(π_θ || π_ref) │
│ θ │
│ │
│ ↑ 奖励最大化 ↑ 惩罚偏离 │
│ │
│ 其中 β 是超参数,控制"允许偏离多少": │
│ - β 小 → 允许更多探索,但可能 Reward Hack │
│ - β 大 → 更保守,更安全,但改进空间小 │
│ - InstructGPT 中 β ≈ 0.02(和 reward 的量级匹配) │
│ │
└─────────────────────────────────────────────────────────────┘3.4 为什么 PPO 而不是随便一个 RL 算法
现在问题正式变成了一个强化学习问题:
- 状态 (State):当前已生成的 token 序列
- 动作 (Action):选择下一个 token
- 策略 (Policy):π_θ(token | context) —— 就是 LLM 本身
- 奖励 (Reward):RM(prompt, full_response) —— 只在完整回答结束时给出
- 约束:KL(π_θ || π_ref) ≤ threshold
这是一个标准的 RL 问题,那为什么 InstructGPT 选择了 PPO(Proximal Policy Optimization)这个具体算法?
┌─────────────────────────────────────────────────────────────┐
│ 为什么是 PPO? │
├─────────────────────────────────────────────────────────────┤
│ │
│ PPO 有两个特性,对 RLHF 至关重要: │
│ │
│ 1. Clipped Objective(裁剪目标) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 标准 Policy Gradient: │ │
│ │ L = E[ratio · advantage] │ │
│ │ ratio = π_θ(a|s) / π_old(a|s) │ │
│ │ │ │
│ │ PPO 加上裁剪: │ │
│ │ L_clip = E[min(ratio · A, clip(ratio, 1-ε, 1+ε)·A)]│ │
│ │ │ │
│ │ 含义:如果某步更新会让策略变化超过 ε(通常 0.2), │ │
│ │ 就把这一步切掉——不允许单步更新太大。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 2. 为什么裁剪对 LLM 特别重要 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ LLM 的输出空间极大(词汇表大小 × 序列长度)。 │ │
│ │ 一次不受约束的策略更新可能导致模型"忘记"如何生成 │ │
│ │ 流畅的语言(Catastrophic Forgetting)。 │ │
│ │ │ │
│ │ PPO 的裁剪保证了"小步快跑"——每次都只改进一点点, │ │
│ │ 不会一脚踩空掉进 reward hacking 的深渊。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 其他算法的对比: │
│ - TRPO(Trust Region Policy Optimization): │
│ 也有"安全区域"的概念,但用了复杂的二阶优化(Hessian), │
│ 在大模型上计算代价太高。 │
│ - A2C/A3C: │
│ 没有约束机制,在 RLHF 中表现不稳定。 │
│ - REINFORCE: │
│ 最基础的 Policy Gradient,方差巨大,几乎无法收敛。 │
│ │
│ PPO = 最简单但有效的"带约束的 Policy Gradient"。 │
│ │
└─────────────────────────────────────────────────────────────┘3.5 Advantage 是什么——为什么不能直接用 Reward
在 RL 中,我们关心的不是"某个动作的绝对奖励是多少",而是"这个动作比平均好多少"。
┌─────────────────────────────────────────────────────────────┐
│ Advantage = "比预期好多少" │
├─────────────────────────────────────────────────────────────┤
│ │
│ 假设一个 Prompt: │
│ "证明地球是圆的" │
│ │
│ Policy 生成了一个回答,Reward Model 给了 0.7 分。 │
│ 这个分数是高是低? │
│ │
│ 你需要知道"平均能拿多少分": │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 场景A:平均分 = 0.3 │ │
│ │ → 你拿了 0.7,Advantage = +0.4,做得好! │ │
│ │ │ │
│ │ 场景B:平均分 = 0.9 │ │
│ │ → 你拿了 0.7,Advantage = -0.2,低于平均,不够好 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Value Model 的作用: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ V(s) = 从状态 s 出发,按照当前策略, │ │
│ │ 预期能获得的累计奖励 │ │
│ │ │ │
│ │ Advantage = Actual_Reward - V(s) │ │
│ │ = "实际拿到的" - "预期拿到的" │ │
│ │ │ │
│ │ Advantage > 0 → 这个动作值得鼓励 │ │
│ │ Advantage < 0 → 这个动作需要抑制 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ PPO 使用 GAE(Generalized Advantage Estimation): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ GAE 是 Advantage 的一个加权版本,综合考虑: │ │
│ │ - 当前步的即时 reward │ │
│ │ - 未来步的 discounted reward │ │
│ │ - Value Model 的估计 │ │
│ │ │ │
│ │ 对于 LLM(每个回答只有一个 terminal reward), │ │
│ │ 情况简化很多。但 GAE 仍然有用——它帮助平滑梯度。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘3.6 PPO in RLHF——完整的一步
现在我们把所有组件拼起来,走一遍 PPO 训练的一个完整 step。
┌─────────────────────────────────────────────────────────────┐
│ PPO Training Step 完整流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 输入:一个 batch 的 prompts │
│ │
│ Step 1: Generate(用当前策略生成回答) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 对每个 prompt x_i,用 Policy Model π_θ 自回归生成 │ │
│ │ 回答 y_i。记录每个 token 的概率 log π_θ(token_t) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ Step 2: Score(用 Reward Model 打分) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 对每个 (x_i, y_i),用 Reward Model 计算 r_i │ │
│ │ 注意:RM 只对整个回答打分,不在中间步骤打分 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ Step 3: Compute KL Penalty(计算偏离度) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 对每个 token t: │ │
│ │ KL_t = log π_θ(token_t) - log π_ref(token_t) │ │
│ │ │ │
│ │ 总 KL = Σ_t KL_t(或取平均) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ Step 4: Compute Adjusted Reward(计算修正后的奖励) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ R_adj = r_i - β · KL(π_θ || π_ref) │ │
│ │ │ │
│ │ Reward Model 的分数 减去 KL 惩罚 = 最终优化目标 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ Step 5: Compute Advantage(用 Value Model) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ A_i = R_adj_i - V(x_i) │ │
│ │ V(x_i) 是 Value Model 对 "这个 prompt 平均能拿多少 │ │
│ │ adjusted reward" 的估计 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ Step 6: PPO Update(更新策略) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ L = min(ratio · A, clip(ratio, 1-ε, 1+ε) · A) │ │
│ │ ratio = π_θ(token_t) / π_old(token_t) │ │
│ │ │ │
│ │ 多个 epoch 的梯度更新(通常 2-4 个 epoch per batch) │ │
│ │ 同时更新 Value Model(用 MSE loss 拟合实际的 R_adj) │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ Step 7: Repeat │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 回到 Step 1,用更新后的策略生成新一批回答 │ │
│ │ 注意:每次迭代都要重新生成回答!(On-Policy) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 关键认知: │
│ PPO 是 On-Policy 算法——每一步用来计算梯度的数据 │
│ 必须由当前的策略生成。不能用 SFT 那样离线准备数据。 │
│ 这就是为什么 RLHF 训练很贵:每次更新后都要重新推理! │
│ │
└─────────────────────────────────────────────────────────────┘3.7 一个具体的数值示例
┌─────────────────────────────────────────────────────────────┐
│ PPO Update 数值示例 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 设定: │
│ β = 0.02(KL 惩罚系数) │
│ ε = 0.2(PPO clip 范围) │
│ │
│ 某个 batch 中的一个 prompt: │
│ x = "解释为什么天空是蓝色的" │
│ │
│ Step 1-2: 生成 + 打分 │
│ Policy 生成 y = "天空呈现蓝色是因为瑞利散射……(200字)" │
│ RM score = 1.5(在 Reward Model 的尺度上) │
│ │
│ Step 3: KL 惩罚 │
│ 每个 token 的 KL 累计 ≈ 0.8 │
│ │
│ Step 4: Adjusted Reward │
│ R_adj = 1.5 - 0.02 × 0.8 = 1.484 │
│ │
│ Step 5: Advantage │
│ Value Model 估计 V(x) = 1.2 │
│ A = 1.484 - 1.2 = +0.284 │
│ → 这个回答比预期好,advantage 为正 │
│ │
│ Step 6: PPO Update │
│ 对于每个 token: │
│ 如果 ratio = π_new / π_old ∈ [0.8, 1.2]: │
│ 直接用 ratio × A 作为梯度 │
│ 如果 ratio 超出这个范围: │
│ 裁剪,阻止梯度继续扩大 │
│ │
│ 正 advantage → 鼓励这个 token(增加 π(token)) │
│ 负 advantage → 抑制这个 token(减少 π(token)) │
│ │
│ 整个回答被"整体评价"(因为 reward 是 terminal), │
│ 所有 token 共享同一个 advantage。 │
│ │
└─────────────────────────────────────────────────────────────┘第4部分:InstructGPT 的实际流程回顾
4.1 InstructGPT 论文的三阶段数据明细
OpenAI 的 InstructGPT 论文(2022)是 RLHF 的里程碑。以下是它的实际数据规模:
┌─────────────────────────────────────────────────────────────┐
│ InstructGPT 数据规模一览 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 标注团队:40 名标注员 │
│ 基础模型:GPT-3(175B, 13B, 6.7B, 1.3B) │
│ │
│ Stage 1 — SFT: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Prompts:来自 OpenAI API 用户的真实请求 + 标注员编写 │ │
│ │ Demonstrations:13,000 个 (prompt, ideal_response) │ │
│ │ 训练:16 epochs on 13K data │ │
│ │ 输出:SFT Model(学会了对话格式) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Stage 2 — Reward Model Training: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Prompts:同上 + SFT 阶段的数据 │ │
│ │ Responses:SFT Model 对每个 prompt 生成 K=4~9 个回答 │ │
│ │ Comparisons:33,000 个人类排序对 │ │
│ │ 训练:1 epoch on 33K data(需要早停防止过拟合) │ │
│ │ 输出:6B Reward Model(从 SFT Model 初始化) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Stage 3 — PPO: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Prompts:31,000 个(仅 prompt,不需要标注回答) │ │
│ │ 训练:PPO with β=0.02, ε=0.2 │ │
│ │ 每个 prompt 生成 1 个回答 → 打分 → 更新 │ │
│ │ 输出:InstructGPT(对齐后的模型) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 关键发现: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 1.3B InstructGPT 被人类标注员偏好超过 175B GPT-3! │ │
│ │ │ │
│ │ 即使参数量小 100 倍,对齐后的模型输出质量压倒性更好。 │ │
│ │ 这证明了 RLHF 的效果不在于模型更大, │ │
│ │ 而在于模型更"懂"人类想要什么。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘4.2 为什么这个结果如此震撼
┌─────────────────────────────────────────────────────────────┐
│ 1.3B Aligned > 175B Unaligned │
├─────────────────────────────────────────────────────────────┤
│ │
│ 这意味着什么? │
│ │
│ 175B GPT-3 有更多的"知识"和"推理能力", │
│ 但它不懂"人类想要什么样的回答"。 │
│ │
│ - 用户问"如何看待疫苗",GPT-3 可能"客观地" │
│ 列举正反两方观点,不加判断。 │
│ - InstructGPT 知道用户想要的是准确、可靠、有帮助的信息, │
│ 而不是不加筛选的"正反两面"。 │
│ │
│ 对齐的价值: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 知识量: GPT-3 175B > 1.3B InstructGPT │ │
│ │ 有用度: GPT-3 175B < 1.3B InstructGPT │ │
│ │ │ │
│ │ "知道多少" 和 "会不会用" 是两码事。 │ │
│ │ RLHF 解决的是"会不会用"的问题。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘第5部分:RLHF 的局限
5.1 局限一:Reward Model 是"学"出来的,不是真理
┌─────────────────────────────────────────────────────────────┐
│ 局限1:Reward Model ≠ 人类偏好 │
├─────────────────────────────────────────────────────────────┤
│ │
│ RM 的训练数据来自 40 个标注员 → 不代表全人类。 │
│ │
│ 可能出现的问题: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 1. RM 有过拟合:在训练数据上表现好, │ │
│ │ 但对没见过的回答类型打分不靠谱。 │ │
│ │ │ │
│ │ 2. RM 有系统性偏差:如果标注员普遍喜欢"长的回答" │ │
│ │ (即使质量相同),RM 学到"长度 = 质量"。 │ │
│ │ → 模型变得冗长啰嗦。 │ │
│ │ │ │
│ │ 3. RM 对"灰色地带"没有真正判断力: │ │
│ │ 对于完全没见过的概念或论点,RM 只能猜测。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 后果:PPO 优化的是 RM 认为好的东西, │
│ 而不是人类真正认为好的东西。 │
│ 这是一层不可避免的隔阂。 │
│ │
└─────────────────────────────────────────────────────────────┘5.2 局限二:人类偏好本身就是噪声
┌─────────────────────────────────────────────────────────────┐
│ 局限2:偏好不是客观真理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 同一道题的三个标注员: │
│ │
│ 标注员A(25岁,美国,自由派): │
│ 喜欢简洁、直接的回答,不喜欢"政治正确"的回避 │
│ │
│ 标注员B(45岁,英国,保守派): │
│ 喜欢礼貌、安全、规避争议的回答 │
│ │
│ 标注员C(30岁,印度,实用主义): │
│ 喜欢详细、包含具体步骤的回答 │
│ │
│ 他们对同一个回答的排序可能完全不同。 │
│ │
│ 训练数据中的偏好是这 40 个人的平均值, │
│ "平均偏好"可能不等于任何一个人的偏好。 │
│ │
│ → ChatGPT 有时"谁都不得罪"的调性, │
│ 正是"平均偏好"的副作用。 │
│ │
└─────────────────────────────────────────────────────────────┘5.3 局限三:成本——人和机器都很贵
┌─────────────────────────────────────────────────────────────┐
│ 局限3:RLHF 的成本 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Stage 2 — 标注成本: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ - 33K 偏好对比 × $1-2/对比 ≈ $33K-66K │ │
│ │ - 13K 演示数据 × $3-5/条 ≈ $39K-65K │ │
│ │ - 标注员管理、质量检查 ≈ $50K+ │ │
│ │ - 合计:$100K-200K(仅标注费用) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Stage 3 — 计算成本: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ - 4 个模型同时加载(Policy, Ref, RM, Value) │ │
│ │ - 每次 PPO step 都要推理(生成回答 + 打分) │ │
│ │ - On-Policy 意味着不能复用之前的数据 │ │
│ │ - 对于 7B 模型:需要约 8×A100 (80GB) GPU │ │
│ │ - 训练时间:数天到数周 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 持续成本: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 模型升级 → 需要新的偏好数据 → 重复全流程 │ │
│ │ 不是一次性的开销。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘5.4 局限四:训练的不稳定性
┌─────────────────────────────────────────────────────────────┐
│ 局限4:PPO + LLM = 脆弱的组合 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 四个模型在内存中同时存在,任何一环出问题都会导致训练崩溃。 │
│ │
│ 常见的失败模式: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 1. Reward 崩溃:PPO 更新太激进 → 策略突变 → │ │
│ │ 生成的回答变成垃圾 → RM 给的分数随机波动 │ │
│ │ → 模型在随机噪声中训练 → 彻底发散 │ │
│ │ │ │
│ │ 2. KL 惩罚失效:β 设得太小 → 模型快速偏离 SFT │ │
│ │ → 在 RM 的盲区找到高分回答 → Reward Hack │ │
│ │ │ │
│ │ 3. Value Model 不准:Value Model 和 Policy 同时更新 │ │
│ │ → Value 估计偏差越来越大 → Advantage 不准 │ │
│ │ → 梯度的方向是错的 → 训练跑偏 │ │
│ │ │ │
│ │ 4. 超参数敏感:β, ε, learning rate, batch size, │ │
│ │ PPO epochs per batch… │ │
│ │ 任何一个参数设不对,训练都可能失败。 │ │
│ │ 实际调参需要大量的试错和经验。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 这就是为什么 DPO(Direct Preference Optimization) │
│ 在 2023 年出现后迅速流行——它绕过了整个 RL 流程, │
│ 直接在偏好数据上做监督学习。但那是下一篇文章的话题。 │
│ │
└─────────────────────────────────────────────────────────────┘5.5 从 RLHF 到 DPO 的过渡
┌─────────────────────────────────────────────────────────────┐
│ RLHF → DPO:让对齐变得简单 │
├─────────────────────────────────────────────────────────────┤
│ │
│ RLHF 的复杂之处在于:你需要先训练一个 RM,再训练 PPO。 │
│ 这引入了 Reward Model 的误差和 PPO 的不稳定性。 │
│ │
│ DPO 的核心洞察(Rafailov et al., 2023): │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ "既然最终目标是最优化偏好,为什么不直接从偏好数据 │ │
│ │ 训练一个符合人类偏好的策略?" │ │
│ │ │ │
│ │ DPO 的 loss 直接从 Bradley-Terry 模型推导出来, │ │
│ │ 用了一个巧妙的 reparameterization,把 Reward │ │
│ │ Model 的训练和策略优化合并成一步。 │ │
│ │ │ │
│ │ Loss_DPO = -log σ( β · log(π_θ(y_c)/π_ref(y_c)) │ │
│ │ - β · log(π_θ(y_r)/π_ref(y_r))) │ │
│ │ │ │
│ │ 不需要 Reward Model,不需要 PPO,不需要 Value Model。 │ │
│ │ 只需要 π_θ(待训练的模型)和 π_ref(冻结的 SFT)。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ DPO 的优势: │
│ - 更简单:一个 loss,一个模型,不需要 RL 基础设施 │
│ - 更稳定:没有 reward hacking,没有训练发散 │
│ - 更便宜:不需要同时运行 4 个模型 │
│ │
│ DPO 的劣势: │
│ - 离线学习:偏好数据是固定的,不能在训练中探索新的回答 │
│ - 在某些 benchmark 上 RLHF 仍然略胜一筹 │
│ │
└─────────────────────────────────────────────────────────────┘核心总结
总结1:SFT vs RLHF 的本质区别
- SFT:最大化 P(ideal_response | prompt)。给定一个"标准答案",让模型模仿它。数据是 (prompt, response) 对。
- RLHF:最大化 Reward Score,同时约束不要偏离 SFT 太远。数据是人类偏好比较(排序,不是打分)。没有标准答案——只有"相对更好"。
总结2:Reward Model 的核心设计
- 为什么用比较不用打分? 因为人类在"谁更好"上高度一致,在"好多少"上没有共识。比较消除了评分偏差。
- Bradley-Terry 模型:P(winner > loser) = exp(r_w) / (exp(r_w) + exp(r_l))。把排序问题转化为概率预测问题。
- Loss 函数:L = -log σ(r_c - r_r)。简单但高效——判反的 pair 会被狠狠惩罚,判对但信心不足的 pair 会被温和地拉大差距。
总结3:PPO 的三个关键设计
- KL 散度约束:防止 Reward Hacking。如果不加约束,模型会找到 RM 的盲区,生成高分但无意义的文本。KL 约束保证模型在"安全的语言空间"内优化。
- Clipped Objective:防止灾难性遗忘。每次更新只允许策略变化 ε=0.2 左右。对于 LLM 这种输出空间极大的模型,小步快跑是唯一的出路。
- On-Policy:每次更新后必须重新生成回答。这是 RLHF 训练成本高的核心原因——每步都需要推理,不能像 SFT 那样离线准备数据。
总结4:InstructGPT 的震撼发现
1.3B 的 InstructGPT(对齐后)被人类标注员偏好超过 175B 的 GPT-3(未对齐)。参数量差 100 倍,但对齐后的模型输出质量压倒性更好。 这说明"懂得人类想要什么"比"知道更多"重要得多。
总结5:RLHF 不是终点
RLHF 有四大局限——RM 不完美、人类偏好有噪声、成本极高、训练不稳定。DPO(2023)通过巧妙的数学变换绕过了 RM 和 PPO,用单一的监督学习 loss 完成对齐。但了解 RLHF 仍然重要——它是"从参数到偏好"范式的开创者。
章节测试
测试1:为什么 RLHF 使用"排序"(comparison)而不是"打分"(rating)?
A. 排序更容易实现自动化 B. 排序消除了不同标注员之间的评分偏差——人类在"谁更好"上高度一致,在"好多少"上没有共识 C. 排序的计算量更小 D. 排序和打分的成本一样,只是历史习惯
测试2:Bradley-Terry 模型中,如果回答 A 的 Reward r_A=3.0,回答 B 的 Reward r_B=1.0,A 被选为更好的概率是多少?
A. 50% B. 75% C. 约 88% D. 约 95%
测试3:Reward Model 的输出层和普通 SFT Model 有什么不同?
A. RM 的输出层是 Linear(d_model → vocab_size) + Softmax B. RM 的输出层是 Linear(d_model → 1),输出一个标量分数 C. RM 没有输出层,直接用 hidden state 的 L2 范数作为分数 D. 两者完全相同
测试4:RLHF 训练中,KL 散度约束的作用是什么?
A. 加快训练速度 B. 防止模型生成与 SFT Model 差异过大的回答,从而避免 Reward Hacking C. 确保模型输出的概率分布是正态分布 D. 让 Reward Model 的分数更准确
测试5:为什么 PPO 是 On-Policy 算法,这对 RLHF 的训练成本意味着什么?
测试6:RLHF 的四个主要局限是什么?请至少列出三个。
测试7:1.3B 的 InstructGPT 为什么被人类偏好超过 175B 的 GPT-3?这说明什么?
参考答案
测试1答案
答案:B。排序(comparison)消除了不同标注员之间的评分偏差。标注员A 的"8分"可能等于标注员B 的"6分"——绝对分数在不同人之间不可比。但排序(A > B)在不同标注员之间高度一致。RLHF 利用了这个心理学事实来构建更干净的训练信号。
测试2答案
答案:C。P(A > B) = exp(3.0) / (exp(3.0) + exp(1.0)) = 20.09 / (20.09 + 2.718) = 20.09 / 22.81 ≈ 0.881。即 A 有约 88% 的概率被标注员认为比 B 好。
测试3答案
答案:B。Reward Model 将 SFT Model 最后一层的 Linear(d_model → vocab_size) + Softmax 替换为 Linear(d_model → 1)。输出的是一个实数标量(可以是任意实数),代表模型对该回答的评分。没有 Softmax——我们不需要概率分布,只需要一个分数。
测试4答案
答案:B。KL 散度约束核衡量当前策略 π_θ 和参考策略 π_ref(冻结的 SFT Model)之间的输出分布差异。优化目标变为:max Reward - β × KL。如果没有这个约束,模型会找到 Reward Model 的盲区(adversarial examples),生成对 RM 来说高分但对人类无意义的文本——即 Reward Hacking。
测试5答案
PPO 是 On-Policy 算法,意味着每一步用来计算梯度的数据(生成的回答)必须由当前的策略生成。不能像 SFT 那样离线准备好所有数据然后训练。
对成本的直接影响:
- 每次 PPO 更新后,策略变了,必须用新策略重新对所有 prompt 生成回答。
- 这意味着训练过程中推理(生成回答)占了很大比例的时间。
- 同时需要在内存中保持 4 个模型(Policy, Reference, Reward, Value)。
- 对于 7B 模型:约 8×A100 GPU,训练数天到数周。
相比之下,SFT 只需要 1 个模型,数据可以离线准备,同样的硬件上速度快得多。
测试6答案
RLHF 的四个主要局限:
Reward Model 不完美:RM 是从有限的人工标注数据中学出来的,不是真正的"人类偏好真理"。RM 有过拟合、系统性偏差(如偏好长回答)、对分布外数据判断不可靠。PPO 优化的是 RM 认为好的东西,不是人类真正认为好的东西。
人类偏好有噪声:40 个标注员的偏好 ≠ 全人类的偏好。偏好是主观的、文化依赖的、随时间变化的。"平均偏好"可能不等于任何真实用户的偏好。
成本极高:标注成本(偏好数据 + 演示数据 $100K-200K)加上计算成本(4 个模型同时加载、On-Policy 推理、多 GPU 训练)。模型每次升级都需要重复全流程。
训练不稳定:PPO + LLM 是一个脆弱的组合。Reward 崩溃、KL 惩罚失效、Value Model 不准、超参数敏感——任何一环出错都可能导致训练发散。实际调参需要大量经验和试错。
测试7答案
1.3B InstructGPT > 175B GPT-3 的原因:
GPT-3(175B)有更多的"知识"和"原始推理能力"——它读过更多数据,参数更多。但它没有经过对齐,不懂"人类想要什么样的回答"。它只是一个超级续写器。
InstructGPT(1.3B)虽然知识量不如 GPT-3,但它经过了 SFT + RM + PPO 的全流程对齐。它学会了:
- 理解用户意图(不只是续写)
- 生成有帮助的回答(而不是客观罗列所有观点)
- 回避有害内容
- 在不确定时说"我不知道"
这说明了什么:"懂得人类想要什么"(对齐)比"知道更多"(规模)对用户体验的影响更大。 当然,最理想的状态是"又大又对齐"——这就是 GPT-4、Claude 等模型的方向。
相关笔记
- [[14-post-training-overview]] — Post-Training 全景(SFT → RLHF → DPO 的对比)
- [[11-training-primer]] — 训练基础扫盲(Loss、Optimizer、GPU Memory)
- [[07-llm-evolution]] — 从 GPT-1 到 ChatGPT 的完整演化
- [[09-decoder-only-llm]] — GPT 架构为什么只需要 Decoder
- [[10-training-vs-inference]] — 训练和推理的差异(FLOPs / KV Cache)
下一步学习
- [ ] 在草稿纸上手算 Bradley-Terry loss——随机设几个 r_c 和 r_r,自己算一遍 loss
- [ ] 理解 DPO 的数学推导:DPO 论文的 loss 为什么可以从 Bradley-Terry 推导出来
- [ ] 了解 Constitutional AI(Anthropic):不用人类偏好数据,用"宪法规则"做对齐
- [ ] 了解 RLAIF(RL from AI Feedback):用另一个 LLM 代替人类做偏好判断
- [ ] 实践:如果条件允许,用 TRL(Transformer Reinforcement Learning)库跑一次 mini 版的 RLHF
学习状态:🟡 开始学习