4.4 RLHF 人类反馈强化学习
承前:从"会说话"到"说对话"
在 4.3 节中,我们学习了 PEFT(参数高效微调)技术——通过 LoRA 等方法,只需训练极少量参数就能让模型学会特定领域的知识。经过 PEFT 微调的模型已经能够遵循指令、完成特定任务,看起来似乎"够用了"。
但问题在于:微调后的模型还不够好。
想象一个场景:你让模型解释"黑洞是什么"。模型可能给出一个技术上正确但晦涩难懂的回答,也可能给出一个通俗有趣但不够准确的回答。对于普通用户来说,哪个更好?这取决于人类的主观偏好——有人喜欢简洁直白,有人喜欢深入详尽。单纯靠监督微调(SFT),模型学到的是"模仿训练数据",而训练数据本身并不能完全代表"什么是好的回答"。
这就是 RLHF 要解决的核心问题:如何让模型的输出真正对齐人类的偏好和价值观? 答案是——让人类来"批改作业",告诉模型哪个回答更好,然后让模型朝着人类偏好的方向优化。
4.4.1 一个直觉类比:老师批改作业
在深入技术细节之前,我们先用一个生活中的类比来理解 RLHF 的全貌。
想象一个写作文的学生(语言模型)和一位严格的语文老师(人类标注者):
第一阶段——学习写作文(SFT):学生先通过大量阅读优秀范文,学会基本的写作方法和格式。这一阶段相当于监督微调,学生掌握了"怎么写作文"的基本能力。
第二阶段——老师建立评分标准(Reward Model):老师把学生的作文收上来,每次给两篇作文打分排序——"这篇比那篇写得好"。通过大量的两两比较,老师的大脑里形成了一套"什么作文是好作文"的判断标准。我们把这套标准"提取"出来,变成一个可以自动打分的"虚拟老师"(奖励模型)。
第三阶段——根据评分反复练习(PPO):学生开始不断写作文,每写一篇,"虚拟老师"就给它打分。学生根据分数调整自己的写作策略——高分的多写,低分的少写。但老师会提醒学生:"不要为了讨好我的评分而胡编乱造,你的文章还是要像正常作文。"这就是 KL 惩罚的作用——防止学生"钻空子"。
这个类比揭示了 RLHF 的三个核心阶段:SFT → Reward Model → PPO。接下来我们逐一深入。
4.4.2 RLHF 三阶段全景
RLHF(Reinforcement Learning from Human Feedback,人类反馈强化学习)是 ChatGPT 取得巨大成功的核心技术。它通过三个阶段的训练,将预训练模型逐步塑造为一个真正对齐人类偏好的智能助手。
RLHF 三阶段全景图:
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ 阶段一:SFT(监督微调) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Base Model ──-> [指令-回答对训练] ──-> SFT Model │ │
│ │ 输入:高质量人类标注的 prompt-response 对 │ │
│ │ 目标:教会模型基本的指令遵循和对话能力 │ │
│ │ 输出:π_SFT(策略模型) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ 阶段二:Reward Model 训练(奖励模型) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ SFT Model 生成多个回答 -> 人类标注偏好排序 -> 训练 Reward Model │ │
│ │ 输入:(prompt, response_1, response_2, 人类偏好) │ │
│ │ 目标:学会预测人类更偏好哪个回答 │ │
│ │ 输出:R_φ(奖励模型) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ 阶段三:PPO 强化学习 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ SFT Model + Reward Model -> PPO 优化 -> Aligned Model │ │
│ │ 输入:多样化 prompt -> 模型生成回答 -> Reward Model 打分 │ │
│ │ 目标:最大化奖励,同时不过度偏离 SFT 模型 │ │
│ │ 输出:π_RL(最终对齐模型) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘这三个阶段是串行依赖的关系:第二阶段需要第一阶段的模型来生成候选回答,第三阶段需要第一阶段的模型作为优化的起点和参考基准,同时需要第二阶段的模型来提供奖励信号。任何一个阶段的失败都会影响最终效果。
4.4.3 阶段一:SFT——对齐的起点
SFT(Supervised Fine-Tuning,监督微调)在 4.2 节已经详细讲解,这里我们从 RLHF 的视角重新审视它的角色:
SFT 是 RLHF 的"初始化":PPO 优化的起点是 SFT 模型,而非原始的 Base Model。直接从 Base Model 做 RLHF 几乎不可行,因为模型连基本的指令遵循能力都没有,无法产生有意义的回答供 Reward Model 评分。
SFT 质量决定 RLHF 上限:如果 SFT 模型本身质量很差(比如生成的回答语句不通、逻辑混乱),那么后续的 Reward Model 学到的偏好标准也会是有偏差的,PPO 阶段的优化效果也会大打折扣。正所谓"garbage in, garbage out"。
SFT 定义了"合理行为"的基线:PPO 中的 KL 散度惩罚就是相对于 SFT 模型而言的。可以理解为——SFT 模型定义了"正常说话的样子",PPO 优化后的模型不能偏离这个"正常"太远,否则即使分数高,也可能是"胡言乱语"。
💡 实践建议:在工业实践中,SFT 阶段通常使用数千到数万条高质量的人工标注数据。数据质量远比数量重要——少量精心标注的数据,效果往往优于大量粗制滥造的数据。
4.4.4 阶段二:Reward Model——人类偏好的"数字化身"
Reward Model(RM,奖励模型)是 RLHF 中最关键的组件。它的任务是替代人类评估者,为模型生成的回答自动打分。有了它,我们才能在 PPO 阶段进行大规模的自动化训练,而不需要每一步都请人类来评判。
偏好数据如何构建
Reward Model 的训练数据不是普通的"输入-输出"对,而是偏好对比数据。构建过程如下:
偏好数据构建流程:
┌────────────────────────────────────────────────────────────────┐
│ │
│ 1. 采样阶段 │
│ 给定 prompt: "请解释黑洞是什么" │
│ SFT 模型生成 4 个不同回答 (A, B, C, D) │
│ (通过不同温度、不同前缀等方式获得多样性) │
│ │
│ 2. 人类标注阶段 │
│ 标注者比较回答并对偏好排序: │
│ A > C > B > D │
│ (A 最好,D 最差) │
│ │
│ 3. 构建训练对 │
│ 从排序中提取所有两两对比: │
│ (prompt, A, C) -> label: A 更好 │
│ (prompt, A, B) -> label: A 更好 │
│ (prompt, A, D) -> label: A 更好 │
│ (prompt, C, B) -> label: C 更好 │
│ (prompt, C, D) -> label: C 更好 │
│ (prompt, B, D) -> label: B 更好 │
│ → 4 个回答可以产生 C(4,2)=6 个训练对 │
│ │
└────────────────────────────────────────────────────────────────┘用"老师批改作业"的类比来理解:老师不需要给每篇作文打绝对分数(比如 85 分、72 分),只需要做相对比较——"这篇比那篇好"。这种相对比较对于人类标注者来说更容易、更一致,也更自然。
Reward Model 的训练原理
Reward Model 的本质是一个回归模型:给定 prompt 和 response,输出一个标量分数。它的架构非常简单——在 SFT 模型的基础上,把语言模型头(LM Head)替换为一个线性层(reward head),输出一个数字。
Reward Model 训练架构:
┌─────────────────┐
prompt + response │ SFT 模型 │ -> 最后一个 token 的 hidden state
│ (去掉 LM head) │
└─────────────────┘
│
▼
┌─────────────────┐
│ 线性层 │ -> 标量奖励值 r
│ (reward head) │
└─────────────────┘训练损失函数(Bradley-Terry 模型):
L(φ) = -E[log σ(r_φ(x, y_w) - r_φ(x, y_l))]
其中:
r_φ(x, y) = Reward Model 对 (prompt x, response y) 的评分
y_w = 被偏好的回答(winner)
y_l = 被拒绝的回答(loser)
σ = sigmoid 函数直观理解:让 RM 给好的回答打高分,给差的回答打低分,且两者差距越大越好。
用老师批改作业的类比来解释这个损失函数:老师每次比较两篇作文,给它们各自打分。如果好作文的分数明显高于差作文(差距大),说明老师的评分标准很清晰,损失就小;如果两篇分数差不多甚至反了(差作文分更高),说明老师还没学会区分好坏,损失就大。训练的过程就是让老师不断调整自己的评分标准,直到能稳定地给好作文更高分。
📌 为什么用两两比较而不是绝对评分? 因为人类对"绝对分数"的判断很不一致——同一个人在不同时间给同一篇作文打分可能差 10 分。但对"A 比 B 好"的相对判断则稳定得多。Bradley-Terry 模型正是利用了这一特性,从相对偏好中推导出隐含的绝对分数。
4.4.5 阶段三:PPO 强化学习
PPO(Proximal Policy Optimization,近端策略优化)是 RLHF 中使用的强化学习算法。它的目标是在 Reward Model 的指导下优化语言模型,让模型学会生成"高分回答"。
在老师批改作业的类比中,这一阶段就是学生不断写作文,老师不断打分,学生根据分数调整写作策略的过程。但关键在于——学生不能为了得高分而"投机取巧"(比如发现老师喜欢长文章就拼命凑字数),他还是要写出像样的作文。
PPO 的核心目标函数
PPO 优化目标:
maximize E[r_φ(x, y)] - β·KL[π_θ(y|x) || π_ref(y|x)]
↑ ↑
最大化奖励 惩罚:不要偏离 SFT 模型太远
其中:
π_θ = 当前正在优化的策略(语言模型)
π_ref = 参考策略(SFT 模型,冻结)
β = KL 惩罚系数(控制"保守程度")
KL[·||·] = KL 散度,衡量两个分布的距离这个目标函数由两部分组成:
奖励最大化:
E[r_φ(x, y)]——鼓励模型生成高分回答。这是模型"努力讨好老师"的动力。KL 惩罚:
β·KL[π_θ || π_ref]——惩罚模型偏离 SFT 模型太远。这是"不要投机取巧"的约束。
为什么需要 KL 惩罚
如果没有 KL 惩罚,模型可能会通过"奖励黑客"(Reward Hacking)来最大化奖励——比如生成无意义但被 RM 判定为高分的内容。
打个比方:如果"虚拟老师"碰巧对包含很多专业术语的回答给高分,学生可能会发现这个规律,然后开始堆砌术语——"量子力学相对论熵增热力学黑洞奇点"——看起来很"高级",但实际上毫无意义。KL 惩罚就是防止这种情况的保险:它要求学生的作文在"讨好老师"的同时,仍然要像一个正常人在写作文。
💡 Reward Hacking 的真实案例:在某些 RLHF 实验中,模型学会了在回答末尾添加大量"作为AI助手,我希望这个回答对您有帮助"之类的客套话来提高分数,因为 RM 对这种"礼貌"的回答倾向给高分。这就是典型的 reward hacking。
PPO 关键超参数
PPO 训练涉及大量超参数,以下是几个最关键的:
| 超参数 | 含义 | 典型值 | 影响 |
|---|---|---|---|
kl_penalty (β) | KL 散度惩罚系数 | 0.01~0.1 | 越大越保守,越小越激进 |
clip_range | PPO 裁剪范围 | 0.1~0.3 | 限制策略更新幅度 |
value_clip_range | 价值函数裁剪范围 | 0.1~0.2 | 限制价值估计更新幅度 |
gamma | 折扣因子 | 0.95~0.99 | 未来奖励的衰减率 |
lam (λ) | GAE 参数 | 0.95 | 优势估计的平滑参数 |
learning_rate | 学习率 | 1e-6~5e-6 | 比 SFT 小很多 |
⚠️ 学习率特别注意:PPO 阶段的学习率(1e-6 级别)远小于 SFT 阶段(通常 1e-5~1e-4)。因为 PPO 是在已经训练好的模型上做"精细调整",学习率太大会导致训练崩溃——模型输出突然变成乱码。
四个模型的协同工作
PPO 训练中最让人头疼的一点是:需要同时加载四个模型。这也是 RLHF 被认为"工程难度高"的主要原因。
PPO 训练中四个模型的角色:
┌────────────────────────────────────────────────────────────────┐
│ │
│ ① Actor Model (π_θ) ← 正在训练的策略模型 │
│ 从 prompt 生成 response,被 PPO 更新 │
│ 这是唯一需要梯度更新的模型 │
│ │
│ ② Reference Model (π_ref) ← 冻结的 SFT 模型 │
│ 用于计算 KL 散度,防止 Actor 偏离太远 │
│ 完全冻结,不参与训练 │
│ │
│ ③ Reward Model (r_φ) ← 冻结的奖励模型 │
│ 给 Actor 生成的 response 打分 │
│ 完全冻结,不参与训练 │
│ │
│ ④ Critic Model (V) ← 价值函数模型 │
│ 预测每个 token 的期望未来奖励,用于计算优势函数 │
│ 需要梯度更新(和 Actor 一起训练) │
│ │
│ 显存需求:同时加载 4 个模型,对显存要求极高 │
│ 例如 7B 模型 x 4 = 约 28B 参数量的显存占用 │
│ │
└────────────────────────────────────────────────────────────────┘其中 Actor 和 Reference 模型通常是同一个 SFT 模型的副本(Actor 会被更新,Reference 保持冻结)。Critic 模型通常也是一个 SFT 模型,但头被替换为价值输出头。Reward Model 是阶段二训练好的独立模型。
📊 显存估算:以 7B 参数模型为例,每个模型用 FP16 精度大约需要 14GB 显存。四个模型就是 56GB,再加上优化器状态和中间激活值,实际需要 80GB+ 显存。这也是为什么 RLHF 训练通常需要多卡甚至多机环境。
4.4.6 RLHF 的挑战与局限
RLHF 虽然效果显著,但也面临着多方面的挑战:
RLHF 的主要挑战:
┌────────────────────────────────────────────────────────────────┐
│ │
│ ❌ 训练复杂:需要同时维护 4 个模型,流程繁琐 │
│ ❌ 显存需求大:4 个模型同时驻留显存,成本高昂 │
│ ❌ 训练不稳定:PPO 对超参数敏感,容易崩溃 │
│ ❌ 奖励黑客:模型可能学会"欺骗" Reward Model │
│ ❌ 人类标注成本高:高质量的偏好数据需要大量专业标注 │
│ ❌ 标注者偏差:不同标注者的偏好不一致 │
│ ❌ 难以评估:没有客观指标衡量"对齐"效果 │
│ │
└────────────────────────────────────────────────────────────────┘这些挑战直接推动了后续替代方案的出现,其中最引人注目的就是 DPO(Direct Preference Optimization),我们将在 4.5 节详细讲解。
4.4.7 实战:Reward Model 训练演示
理论讲完了,让我们用代码来理解 Reward Model 的训练过程。以下是一个简化版的实现,帮助你理解核心逻辑:
import torch
import torch.nn as nn
from transformers import AutoModel, AutoTokenizer
# ========== 简化版 Reward Model ==========
class SimpleRewardModel(nn.Module):
"""基于预训练模型的简化 Reward Model"""
def __init__(self, base_model_name="Qwen/Qwen2-0.5B"):
super().__init__()
# 加载预训练模型作为骨干网络(backbone)
# trust_remote_code=True 允许执行模型仓库中的自定义代码
self.backbone = AutoModel.from_pretrained(
base_model_name, trust_remote_code=True
)
# 获取骨干网络的隐藏层维度(例如 768 或 4096)
hidden_size = self.backbone.config.hidden_size
# 创建一个线性层,将隐藏状态映射为标量奖励值
# 这就是所谓的 "reward head",输出维度为 1
self.reward_head = nn.Linear(hidden_size, 1)
def forward(self, input_ids, attention_mask):
# 第一步:将输入通过骨干网络,获取每一层的隐藏状态
outputs = self.backbone(
input_ids=input_ids,
attention_mask=attention_mask
)
# 取最后一个 token 的隐藏状态作为整个序列的表示
# shape: (batch_size, hidden_size)
last_hidden = outputs.last_hidden_state[:, -1, :]
# 通过 reward head 将隐藏状态映射为标量奖励值
# shape: (batch_size, 1) -> squeeze 后 (batch_size,)
reward = self.reward_head(last_hidden)
return reward.squeeze(-1)
# ========== Bradley-Terry 损失函数 ==========
def bradley_terry_loss(reward_model, prompt_ids, prompt_mask,
winner_ids, winner_mask, loser_ids, loser_mask):
"""
计算 Bradley-Terry 模型的损失
训练目标:让 reward_model 给 winner 的打分高于 loser
核心公式:L = -log(σ(r_winner - r_loser))
- 当 r_winner >> r_loser 时,σ ≈ 1,损失 ≈ 0(模型判断正确)
- 当 r_winner << r_loser 时,σ ≈ 0,损失 → ∞(模型判断错误)
"""
# 获取 winner(被偏好的回答)的奖励分数
r_winner = reward_model(winner_ids, winner_mask)
# 获取 loser(被拒绝的回答)的奖励分数
r_loser = reward_model(loser_ids, loser_mask)
# 计算两者的分数差,这就是 Bradley-Terry 模型中的 "logits"
logits = r_winner - r_loser
# 损失 = -log(σ(logits)),使用 logsigmoid 更数值稳定
loss = -torch.nn.functional.logsigmoid(logits).mean()
# 计算准确率:winner 分数是否确实高于 loser
accuracy = (logits > 0).float().mean()
return loss, accuracy
# ========== 演示训练流程 ==========
print("=" * 60)
print("Reward Model 训练演示")
print("=" * 60)
# 创建 Reward Model 实例
model = SimpleRewardModel()
# 加载对应的分词器
tokenizer = AutoTokenizer.from_pretrained(
"Qwen/Qwen2-0.5B", trust_remote_code=True
)
# 确保有 pad_token,用于对齐不同长度的序列
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
# 模拟偏好数据(实际应用中应使用真实标注的偏好数据)
# 每个 prompt 对应一对 (winner, loser) 回答
prompts = ["解释什么是机器学习", "写一首关于春天的诗"]
winners = [
"机器学习是让计算机从数据中学习模式,从而做出预测和决策的技术...",
"春风拂面暖融融,万物复苏绿意浓,桃花笑映青山外..."
]
losers = [
"机器学习就是机器学东西",
"春天很好,花开了"
]
# 对所有文本进行分词,padding 到同一长度
# truncation=True 确保不超过 max_length
prompt_enc = tokenizer(
prompts, padding=True, truncation=True,
return_tensors="pt", max_length=128
)
winner_enc = tokenizer(
winners, padding=True, truncation=True,
return_tensors="pt", max_length=128
)
loser_enc = tokenizer(
losers, padding=True, truncation=True,
return_tensors="pt", max_length=128
)
# 前向传播 + 计算损失
loss, acc = bradley_terry_loss(
model,
prompt_enc["input_ids"], prompt_enc["attention_mask"],
winner_enc["input_ids"], winner_enc["attention_mask"],
loser_enc["input_ids"], loser_enc["attention_mask"],
)
print(f"损失值: {loss.item():.4f}")
print(f"准确率: {acc.item():.2%}")
print(f"\n理想情况下,Reward Model 给好的回答高分,给差的回答低分")
print(f"初始状态下准确率约 50%(随机猜测),训练后会逐步提升")📝 代码说明:上述代码演示了 Reward Model 的前向传播和损失计算。在实际训练中,还需要加入优化器(如 AdamW)、学习率调度器、梯度裁剪等组件,并在验证集上监控准确率,防止过拟合。
4.4.8 实战:PPO 训练配置
完整的 PPO 训练需要同时加载四个模型,对显存要求极高。这里我们使用 TRL(Transformer Reinforcement Learning)库来展示 PPO 训练的配置代码,帮助你理解关键参数的含义:
# 注意:完整的 PPO 训练需要 4 个模型同时加载,对显存要求高
# 这里展示 TRL 库的 PPO 训练配置代码
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead
from transformers import AutoTokenizer
from datasets import load_dataset
# ========== PPO 配置 ==========
ppo_config = PPOConfig(
model_name="Qwen/Qwen2-0.5B",
# 学习率:PPO 阶段远小于 SFT,防止破坏已有能力
learning_rate=1.5e-6,
# 每次采样的 prompt 数量
batch_size=8,
# PPO 更新时的 mini-batch 大小
mini_batch_size=4,
# 梯度累积步数,用于模拟更大的 batch size
gradient_accumulation_steps=1,
# 每批数据重复 PPO 更新的次数
ppo_epochs=4,
# KL 惩罚类型:"kl" 使用标准 KL 散度
kl_penalty="kl",
# 初始 KL 系数:控制模型偏离 SFT 的程度
# 太小 → 模型可能"跑偏";太大 → 模型几乎不更新
init_kl_coef=0.05,
# 目标 KL 散度:训练时动态调整 KL 系数使 KL 接近此值
target=6.0,
# PPO 裁剪范围:限制策略更新的幅度,防止"一步迈太大"
cliprange=0.2,
# 价值函数裁剪范围:限制 Critic 模型的更新幅度
cliprange_value=0.2,
# 价值函数损失在总损失中的权重
vf_coef=0.1,
)上述配置中,init_kl_coef 和 cliprange 是最需要仔细调参的两个超参数。它们共同决定了模型在"追求高分"和"保持稳健"之间的平衡。
4.4.9 常见误区
在学习 RLHF 的过程中,初学者常会有以下误解,我们逐一澄清:
误区一:"RLHF 可以替代 SFT"
这是最常见的误解。实际上,RLHF 的第三阶段(PPO)必须从 SFT 模型开始优化。如果没有 SFT 先教会模型基本的对话能力,模型连一个完整的句子都说不出来,Reward Model 给它打分毫无意义。RLHF 是"锦上添花",不是"无中生有"。
误区二:"Reward Model 越大越好"
并不一定。Reward Model 的质量取决于偏好数据的数量和质量,而非单纯的模型大小。一个在高质量偏好数据上训练的小模型,可能比在劣质数据上训练的大模型效果好得多。实践中,Reward Model 通常和 SFT 模型大小相当。
误区三:"KL 系数越大越安全"
KL 系数确实防止模型"跑偏",但太大也有问题——模型几乎不更新,RLHF 的训练效果就消失了,等于白训练。反之太小,模型可能"奖励黑客"。关键在于找到一个平衡点,通常在 0.01~0.1 之间。
误区四:"RLHF 训练越久效果越好"
恰恰相反。PPO 训练存在"过拟合"风险——训练太久,模型可能过度迎合 Reward Model 的偏好,导致语言能力下降、多样性丧失。实践中通常需要在训练过程中持续评估,在合适的时机停止。
误区五:"有了 RLHF 就不需要人类标注了"
RLHF 减少的是推理阶段的人工评估,但训练阶段的偏好数据仍然需要大量人类标注。而且偏好数据的质量直接决定了 RLHF 的效果上限。
4.4.10 本节小结
本节我们学习了 RLHF(人类反馈强化学习)的完整流程。回顾一下核心要点:
| 要点 | 说明 |
|---|---|
| 三阶段流程 | SFT(初始化)→ Reward Model(学会打分)→ PPO(优化策略) |
| 老师批改作业类比 | SFT=学生学写作文,RM=老师建立评分标准,PPO=根据分数反复练习 |
| Reward Model | 用 Bradley-Terry 模型从人类偏好对比中学习打分,输出标量奖励值 |
| KL 惩罚 | 防止模型为追求高分而"胡言乱语",保持语言能力不退化 |
| 四个模型 | Actor + Reference + Reward + Critic 同时加载,显存需求大 |
| PPO 调参 | 学习率要小(1e-6),KL 系数要适中(0.01~0.1),裁剪范围 0.1~0.3 |
| 奖励黑客 | 模型可能"欺骗"Reward Model 获得高分但输出无意义内容 |
| 主要挑战 | 训练复杂、显存大、不稳定、标注成本高、标注者偏差 |
RLHF 是 ChatGPT 成功的关键技术,它第一次让大语言模型真正"对齐"了人类偏好。但它的工程复杂度和资源消耗也确实很高——四个模型同时驻留显存、PPO 超参数敏感、偏好数据获取困难。这些痛点催生了一系列更简洁的替代方案。
启后:从 RLHF 到 DPO
RLHF 的核心痛点在于——PPO 训练太复杂了。需要四个模型、复杂的强化学习算法、大量的超参数调优。这让人不禁思考:有没有可能跳过 Reward Model 和 PPO,直接从偏好数据中优化模型?
答案是肯定的。下一节(4.5)我们将学习 DPO(Direct Preference Optimization,直接偏好优化)。DPO 的核心洞见是:偏好数据本身已经隐含了奖励信号,我们可以用一个简洁的数学公式直接从偏好数据优化策略模型,完全不需要训练独立的 Reward Model,也不需要复杂的 PPO 训练。DPO 将 RLHF 的三阶段流程简化为一个阶段的简单训练,大大降低了工程门槛。
当然,DPO 也有自己的权衡——它是否能完全替代 RLHF?在什么场景下 RLHF 仍然更优?这些问题我们将在 4.5 节中深入探讨。
参考资料
- Training language models to follow instructions with human feedback (InstructGPT) - OpenAI 的 RLHF 奠基论文
- TRL 库 PPO Trainer 文档 - HuggingFace 官方 PPO 训练器
- Improving Reinforcement Learning from Human Feedback Using Contrastive Rewards - 2024 年 RLHF 改进论文
- Illustrating Reinforcement Learning from Human Feedback (RLHF) - HuggingFace 官方 RLHF 图解教程
- DeepSpeed-Chat: Easy, Fast and Affordable RLHF Training - 微软 DeepSpeed RLHF 训练方案