RLHF 深度解析:从人类反馈到 PPO/GRPO/DPO 的对齐革命
1. 引言:为什么需要”对齐”?
1.1 从 SFT 到 RLHF 的进化
如果说预训练给学生灌输了整个互联网的知识,SFT 教会学生”听人话做事”,那么RLHF 就是让学生学会**“做正确的事”**——不仅按指令,还要符合人类的价值观、偏好与安全约束。
训练范式的演进:
预训练 (Pre-training) ↓ 学习"语言 + 世界知识" ↓ 能力:续写、模仿
SFT (Supervised Fine-Tuning) ↓ 学习"指令 → 回答" ↓ 能力:助手、对话
RLHF (Reinforcement Learning from Human Feedback) ↓ 学习"偏好 + 价值观" ↓ 能力:有用 (Helpful) + 无害 (Harmless) + 诚实 (Honest)1.2 SFT 解决不了的问题
即使做完 SFT,模型仍会表现出:
| 问题 | 表现 | 例子 |
|---|---|---|
| 胡编乱造 | 一本正经说错信息 | 编造不存在的论文 |
| 有害输出 | 教用户做危险的事 | 制造武器、绕过安全 |
| 过度冗长 | 不必要的客套话 | ”作为 AI 助手…” |
| 风格不适配 | 不符合期望语气 | 客服场景过于正式 |
| 幻觉 + 自信 | 错误但充满信心 | 错误医学建议 |
这些问题是主观偏好与价值观判断,无法用”标准答案”完全标注——SFT 的最大似然损失没有偏好信号。
SFT 优化的是 ,但 RLHF 优化的是 。后者编码了”哪一个更好”这一隐性知识。
1.3 RLHF 的核心思想
两阶段训练:
- 奖励建模(Reward Modeling):学习一个人类偏好的”打分器”
- 策略优化(Policy Optimization):用 RL 让 LLM 生成高分回答
┌──────────────────────────────────────────────────────────────┐│ RLHF 流程总览 │├──────────────────────────────────────────────────────────────┤│ ││ ① 收集偏好数据 ││ prompt + response_A + response_B + 人类标注 A>B ││ ↓ ││ ② 训练奖励模型 RM(y|x) ││ loss = -log σ( RM(y_w|x) - RM(y_l|x) ) ││ ↓ ││ ③ 用 PPO 优化 SFT 模型 ││ reward = RM(y|x) - β·KL(π_θ || π_ref) ││ │└──────────────────────────────────────────────────────────────┘2. 偏好数据:从反馈到标注
2.1 数据形式
每个偏好样本是一个三元组或四元组:
其中:
- :提示(prompt)
- :被人类标注为”更好”的回答(winner)
- :被人类标注为”更差”的回答(loser)
2.2 数据来源
preference_data_sources = { # 1. 人类标注 "human_annotation": "标注员对同一 prompt 的多个回答进行排序",
# 2. AI 反馈(RLAIF / Constitutional AI) "ai_feedback": "用强模型按宪法原则评判弱模型回答",
# 3. 用户隐式反馈 "implicit_feedback": "点赞、采纳、停留时间、复制按钮",
# 4. 合成数据 "synthetic": "用 prompt 模板生成 y_w, 再故意制造 y_l 错误",}2.3 数据质量的关键
| 维度 | 影响 | 工程经验 |
|---|---|---|
| 标注一致性 | RM 学到正确偏好 | 多标注员 + Krippendorff α |
| 多样性 | RM 不偏科 | 跨领域、跨任务、跨长度 |
| 边界 case | RM 鲁棒性 | 故意加入对抗样本 |
| 失败模式覆盖 | 知道”哪里不好” | 红队测试数据 |
标注员有风格偏好(偏好长回答),导致 RM 学会”越长越好”。解决:在 prompt 中明确告知”长度不是评判标准”。
3. 奖励模型(Reward Model)
3.1 Bradley-Terry 模型
假设人类偏好遵循 Bradley-Terry 模型:
其中 是真实的”人类偏好分数”。我们用一个神经网络 来近似它。
3.2 损失函数
对数似然:
直觉:拉大 winner 和 loser 的分数差。
3.3 实现
import torchimport torch.nn as nnfrom transformers import AutoModelForCausalLM
class RewardModel(nn.Module): """ 基于 LLM 的奖励模型。 通常是一个 LLM + 一个标量回归头,预测回答的"人类偏好分数"。 """ def __init__(self, base_model_path: str, cache_dir: str = None): super().__init__() # 加载与 SFT 相同架构的 LLM self.backbone = AutoModelForCausalLM.from_pretrained( base_model_path, cache_dir=cache_dir, torch_dtype=torch.bfloat16 ) hidden_size = self.backbone.config.hidden_size # 标量奖励头 self.score_head = nn.Linear(hidden_size, 1, bias=False) # 初始化为接近 0(让初始分数居中) nn.init.zeros_(self.score_head.weight)
def forward(self, input_ids: torch.Tensor, attention_mask: torch.Tensor): """ 输入: 拼接 [prompt; response] 输出: 最后一个 token 的标量分数 """ outputs = self.backbone( input_ids=input_ids, attention_mask=attention_mask, output_hidden_states=True, ) # 取每个序列最后一个有效 token 的隐藏状态 last_hidden = outputs.hidden_states[-1] # (B, L, H) sequence_lengths = attention_mask.sum(dim=1) - 1 batch_idx = torch.arange(last_hidden.size(0), device=last_hidden.device) last_token_hidden = last_hidden[batch_idx, sequence_lengths] score = self.score_head(last_token_hidden).squeeze(-1) return score
class RewardModelLoss(nn.Module): """Bradley-Terry 偏好损失""" def forward(self, score_w: torch.Tensor, score_l: torch.Tensor) -> torch.Tensor: return -torch.nn.functional.logsigmoid(score_w - score_l).mean()3.4 训练实践
def train_reward_model(model, dataset, optimizer, epochs=2, batch_size=4): for epoch in range(epochs): for batch in dataset: # batch 包含 (x, y_w, y_l) 三组 tokenized 输入 score_w = model(batch["input_ids_w"], batch["attention_mask_w"]) score_l = model(batch["input_ids_l"], batch["attention_mask_l"]) loss = -torch.nn.functional.logsigmoid(score_w - score_l).mean()
optimizer.zero_grad() loss.backward() optimizer.step()3.5 评估 RM 的方法
def evaluate_rm(model, eval_pairs): """ 评估 RM 的"判别准确率": 在测试集上,正确判定 y_w > y_l 的比例。 """ correct = 0 for pair in eval_pairs: score_w = model(pair["x_w"]) score_l = model(pair["x_l"]) if score_w > score_l: correct += 1 return correct / len(eval_pairs)4. PPO:经典的策略优化算法
4.1 为什么不用 SFT 直接拟合 RM?
直觉:用 RM 给回答打分,然后 SFT 用 加权拟合。问题:
- 分布偏移:RM 只在 SFT 数据上学过,对”模型自己生成的分布”外推差
- Reward hacking:模型学会 RM 的盲点(比如生成”看起来很好但其实乱码”的回答)
- 无约束:可能偏离原始 SFT 模型,丧失能力
4.2 RL 基础
把 LLM 视为一个自回归策略 :
目标是最大化期望奖励:
4.3 KL 约束:锚定参考策略
为防止 偏离太远,加入 KL 惩罚:
其中 是 SFT 模型(参数冻结), 控制约束强度。
KL 项相当于”不许忘本”。模型可以优化 RM,但不能变成另一个完全不同的模型。
4.4 PPO 目标函数
PPO 是信赖域优化的实用版本:
其中:
- 重要性比率:
- 优势函数:(用 GAE 或 critic 估计)
- 通常为 0.2
clip 机制:限制新旧策略的比率不超出 ,避免一次更新步子过大。
4.5 RM + KL 的奖励设计
PPO 中每个 token 的”奖励”:
只有最后一个 token获得真实 RM 分数,前面所有 token 的”奖励”只是负的 KL 惩罚——鼓励每个位置的策略不偏离参考。
4.6 PPO for LLM 的完整实现
import torchimport torch.nn.functional as F
def compute_gae(rewards, values, dones, gamma=0.99, lam=0.95): """广义优势估计 GAE""" advantages = torch.zeros_like(rewards) last_adv = 0 T = rewards.size(1) for t in reversed(range(T)): if t == T - 1: next_value = 0 else: next_value = values[:, t + 1] nonterminal = 1.0 - dones[:, t] delta = rewards[:, t] + gamma * next_value * nonterminal - values[:, t] last_adv = delta + gamma * lam * nonterminal * last_adv advantages[:, t] = last_adv returns = advantages + values return advantages, returns
def ppo_loss( log_probs_new, # 新策略对每个 token 的 log prob: (B, T) log_probs_old, # 旧策略(rollout 时)的 log prob advantages, # GAE 优势 clip_ratio=0.2,): """PPO clipped surrogate loss""" ratio = torch.exp(log_probs_new - log_probs_old) surr1 = ratio * advantages surr2 = torch.clamp(ratio, 1 - clip_ratio, 1 + clip_ratio) * advantages policy_loss = -torch.min(surr1, surr2).mean() return policy_loss
def rlhf_train_step( policy_model, # π_θ,待优化 ref_model, # π_ref,冻结 reward_model, # R(x,y) critic, # 价值网络 V(s) batch, # prompt 列表 beta=0.1, # KL 系数 clip_ratio=0.2,): """ RLHF 单步训练流程(简化的 PPO): 1. 用当前 policy 生成回答(rollout) 2. 用 RM 评分 3. 计算 KL 惩罚 4. 用 GAE 计算优势 5. PPO 更新 policy 与 critic """ prompts = batch["prompts"]
# === 1. Rollout:用当前策略生成回答 === with torch.no_grad(): responses, response_mask = policy_model.generate( prompts, max_new_tokens=256, do_sample=True, temperature=1.0 )
# === 2. 计算旧策略的 log prob(用于重要性采样) === with torch.no_grad(): log_probs_old = compute_log_probs(policy_model, responses)
# === 3. 用奖励模型打分 === with torch.no_grad(): rewards = reward_model(prompts + responses)
# === 4. 计算 KL 惩罚(per token) === with torch.no_grad(): log_probs_ref = compute_log_probs(ref_model, responses) kl_per_token = log_probs_old - log_probs_ref # = log(π_θ / π_ref)
# 最后一个 token 获得 RM 分数;其余 token 仅 KL 惩罚 T = responses.size(1) token_rewards = -beta * kl_per_token token_rewards[:, -1] += rewards
# === 5. GAE 计算优势 === with torch.no_grad(): values = critic(responses) dones = torch.zeros_like(token_rewards) dones[:, -1] = 1.0 # 序列结束 advantages, returns = compute_gae(token_rewards, values, dones) advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8)
# === 6. PPO 更新(通常做 K_mini_epochs 次) === for _ in range(4): log_probs_new = compute_log_probs(policy_model, responses) policy_loss = ppo_loss(log_probs_new, log_probs_old, advantages, clip_ratio)
value_pred = critic(responses) value_loss = F.mse_loss(value_pred, returns)
loss = policy_loss + 0.5 * value_loss loss.backward() # ... optimizer.step()4.7 PPO 的工程痛点
| 痛点 | 原因 | 缓解 |
|---|---|---|
| 显存爆炸 | 同时持有 policy、ref、RM、critic | LoRA + 共享参数 |
| 训练不稳定 | 大 reward 方差 | Reward 归一化、KL warmup |
| Reward hacking | 模型找到 RM 漏洞 | 多 RM ensemble |
| 慢 | 每步 4 模型前向 | vLLM rollout |
| 崩溃 | 极端 KL 时崩 | 早停 + checkpoint rollback |
InstructGPT 论文报告:RLHF 训练中,约 10-30% 的训练会因奖励坍缩或 KL 爆炸而中断。需要持续监控。
5. GRPO:DeepSeek 提出的高效替代
5.1 动机
PPO 的最大开销:
- 一个额外的 critic 网络(与 policy 同尺寸)
- 每个 prompt 一次采样 → GAE 优势估计
- 4 个模型同时在显存
5.2 GRPO 核心思想
**GRPO(Group Relative Policy Optimization)**由 DeepSeek 提出:
不需要 critic,对同一 prompt 采样一组回答,用组内相对排名作为优势。
5.3 算法流程
对每个 prompt x: 1. 用 π_θ 采样 G 个回答 {y_1, y_2, ..., y_G} 2. 用 RM 给每个回答打分 {r_1, r_2, ..., r_G} 3. 组内归一化得到优势: A_i = (r_i - mean(r)) / std(r) 4. 用优势做 PPO 风格更新5.4 优势计算
直觉:比平均好的回答获得正优势,比平均差的获得负优势。无需 critic,无需 GAE。
5.5 完整损失
其中重要性比率:
5.6 GRPO 实现
import torchimport torch.nn.functional as F
def grpo_loss( log_probs_new, # (B, G, T) — B 个 prompt,每个 G 个回答 log_probs_old, # 同上 rewards_group, # (B, G) — 组内每个回答的 RM 分数 ref_log_probs, # (B, G, T) beta=0.04, clip_ratio=0.2,): """ GRPO 损失(DeepSeek-R1 风格)。 log_probs_new, log_probs_old, ref_log_probs 形状: (B, G, T) rewards_group 形状: (B, G) """ # === 组内归一化得到优势 === mean_r = rewards_group.mean(dim=-1, keepdim=True) std_r = rewards_group.std(dim=-1, keepdim=True) + 1e-8 advantages = (rewards_group - mean_r) / std_r # (B, G)
# === 重要性比率 === # 这里我们用平均 log prob(per sequence)作为比率 ratio = torch.exp( (log_probs_new - log_probs_old).sum(dim=-1) ) # (B, G)
# === PPO-style clipped surrogate === surr1 = ratio * advantages surr2 = torch.clamp(ratio, 1 - clip_ratio, 1 + clip_ratio) * advantages policy_loss = -torch.min(surr1, surr2).mean()
# === KL 惩罚 === kl = (log_probs_new - ref_log_probs).sum(dim=-1).mean() kl_loss = beta * kl
total_loss = policy_loss + kl_loss return total_loss, {"policy_loss": policy_loss.item(), "kl": kl.item()}5.7 PPO vs GRPO 对比
| 维度 | PPO | GRPO |
|---|---|---|
| Critic | 需要 | 不需要 |
| 优势估计 | GAE + Value Net | 组内排名 |
| 显存 | 4 模型 | 2 模型 (policy + ref) |
| 采样数 | 1/G | G(按 prompt) |
| 训练稳定 | 较稳定 | 需要足够大的 G |
| 代表工作 | InstructGPT, ChatGPT | DeepSeek-R1 |
6. DPO:免强化学习的对齐
6.1 核心洞见
DPO(Direct Preference Optimization)由 Stanford 在 2023 年提出,关键问题是:
能不能绕过 RM 和 RL,直接用偏好数据训练 LLM?
答案是:可以。RLHF 的目标函数有一个闭式解。
6.2 推导:从 RLHF 到 DPO
RLHF 目标:
其最优解为:
其中 是归一化常数。
反解出 RM:
代入 Bradley-Terry 偏好模型( 抵消):
这就是 DPO 损失!
6.3 DPO 损失
其中:
6.4 关键优势
RLHF 流程: 偏好数据 → 训练 RM → PPO 优化 policy (3 个阶段,复杂)
DPO 流程: 偏好数据 → 直接训练 policy (1 个阶段,简单)| 维度 | RLHF/PPO | DPO |
|---|---|---|
| 训练阶段 | 3(RM、critic、policy) | 1(policy) |
| 显存 | 4 模型 | 2 模型 |
| 超参 | + clip + GAE + KL | 只需 |
| 在线采样 | 需要 | 不需要(offline) |
| 稳定性 | 易崩 | 稳定 |
| 性能 | 略好(一般) | 与 PPO 相当 |
| 代表模型 | GPT-4, Claude 2 | Llama 3 Instruct, Mistral |
6.5 DPO 实现
import torchimport torch.nn.functional as F
def compute_log_probs(model, input_ids, attention_mask, response_mask): """计算回答部分的 log π(y|x) 之和""" outputs = model(input_ids=input_ids, attention_mask=attention_mask) logits = outputs.logits[:, :-1, :] # 预测下一个 token labels = input_ids[:, 1:] log_probs = F.log_softmax(logits, dim=-1) # 取出真实 token 的 log prob token_log_probs = log_probs.gather(2, labels.unsqueeze(-1)).squeeze(-1) # 只对 response 部分求和(mask 掉 prompt) response_token_log_probs = token_log_probs * response_mask[:, 1:] return response_token_log_probs.sum(dim=-1)
def dpo_loss( policy_chosen_logps, # π_θ(y_w|x) 对数和 policy_rejected_logps, ref_chosen_logps, # π_ref(y_w|x) 对数和 ref_rejected_logps, beta=0.1,): """ DPO 损失。 policy_chosen_logps: (B,) policy_rejected_logps: (B,) ref_chosen_logps: (B,) ref_rejected_logps: (B,) """ # log π_θ(y|x) - log π_ref(y|x) policy_logratios = policy_chosen_logps - policy_rejected_logps ref_logratios = ref_chosen_logps - ref_rejected_logps
# DPO 目标:β * (Δ_θ - Δ_ref) logits = beta * (policy_logratios - ref_logratios)
# 偏好损失 loss = -F.logsigmoid(logits).mean()
# 额外监控:chosen reward margin chosen_rewards = beta * (policy_chosen_logps - ref_chosen_logps).detach() rejected_rewards = beta * (policy_rejected_logps - ref_rejected_logps).detach()
return loss, { "chosen_rewards": chosen_rewards.mean().item(), "rejected_rewards": rejected_rewards.mean().item(), "accuracy": (chosen_rewards > rejected_rewards).float().mean().item(), }6.6 DPO 训练循环
from torch.optim import AdamW
def train_dpo(policy_model, ref_model, dataloader, beta=0.1, lr=1e-6, epochs=1): optimizer = AdamW(policy_model.parameters(), lr=lr) ref_model.eval() # 冻结 for epoch in range(epochs): for batch in dataloader: # batch: {chosen: input_ids, mask, response_mask, rejected: ...}
# Policy 对 chosen 和 rejected 的 log prob policy_chosen_logps = compute_log_probs( policy_model, batch["chosen_input_ids"], batch["chosen_attention_mask"], batch["chosen_response_mask"] ) policy_rejected_logps = compute_log_probs( policy_model, batch["rejected_input_ids"], batch["rejected_attention_mask"], batch["rejected_response_mask"] )
# Ref(不计算梯度) with torch.no_grad(): ref_chosen_logps = compute_log_probs( ref_model, batch["chosen_input_ids"], batch["chosen_attention_mask"], batch["chosen_response_mask"] ) ref_rejected_logps = compute_log_probs( ref_model, batch["rejected_input_ids"], batch["rejected_attention_mask"], batch["rejected_response_mask"] )
loss, metrics = dpo_loss( policy_chosen_logps, policy_rejected_logps, ref_chosen_logps, ref_rejected_logps, beta=beta, )
optimizer.zero_grad() loss.backward() torch.nn.utils.clip_grad_norm_(policy_model.parameters(), 1.0) optimizer.step()
print(f"loss={loss.item():.4f} " f"acc={metrics['accuracy']:.2f} " f"chosen_r={metrics['chosen_rewards']:.2f} " f"rejected_r={metrics['rejected_rewards']:.2f}")6.7 DPO 的局限与变体
DPO 容易过拟合到偏好数据,并出现”verbosity bias”——偏好变长但不一定变好。
主要变体:
| 算法 | 改进点 | 公式 |
|---|---|---|
| IPO | 防止过拟合 | |
| KTO | 不需要成对偏好(单回答 + 标签) | Kahneman-Tversky 前景理论 |
| SimPO | 移除 reference model | |
| ORPO | SFT + DPO 联合 | 联合 SFT 与 odds ratio 损失 |
| CPO | SFT + DPO 简化 | 加 SFT 正则项 |
7. 进阶:从 RLHF 到 RLAIF / Constitutional AI
7.1 RLAIF (RL from AI Feedback)
动机:人类标注慢、贵、不一致。用强模型替代人类打标。
传统 RLHF: 人类对 (y_A, y_B) 排序 → RM → PPO
RLAIF: GPT-4 对 (y_A, y_B) 按"宪法原则"排序 → RM → PPO7.2 Constitutional AI (CAI)
Anthropic 提出,两阶段:
阶段 1:监督式(SL-CAI)
1. 模型生成回答 y2. 模型基于"宪法原则"(如"不要有害")批评 y3. 模型根据批评改写 y'4. 用 (prompt, y') 做监督微调阶段 2:RL-CAI
1. 模型生成回答 y_A, y_B2. 模型按宪法原则判断哪个更好3. 用这些 AI 偏好训练 RM4. PPO 训练宪法原则示例:
## 宪法(Constitution)
1. 请选择更**有帮助**的回答。2. 请选择更**诚实**的回答。3. 请选择更**无害**的回答,不应协助暴力、欺骗。4. 请避免**歧视性**内容。5. 请避免**违反隐私**的回答。7.3 自我奖励语言模型(Meta,2024)
迭代过程:1. 用 CAI 生成偏好数据2. 训练 RM3. 用 DPO 训练 LLM4. 重复:用更强的 LLM 重新打标→ 模型自己当老师8. 实战:完整 RLHF 训练流水线
8.1 三阶段流水线
┌──────────────────────────────────────────────────────────────┐│ 完整 RLHF 训练流水线 │├──────────────────────────────────────────────────────────────┤│ ││ Stage 0: Base Model (预训练 LLM) ││ ↓ ││ Stage 1: SFT (监督微调) ││ ↓ 用高质量指令数据训练 π_SFT ││ Stage 2: Reward Model Training ││ ↓ 用偏好数据训练 R_θ ││ Stage 3: RL Fine-tuning (PPO / GRPO / DPO) ││ ↓ ││ Final: Aligned Model ││ │└──────────────────────────────────────────────────────────────┘8.2 推荐训练顺序(基于 Llama 2/3 论文经验)
1. 预训练(基模型) ............................. 1-3 月,~1万 GPU·小时2. SFT(指令微调) ............................... 数小时3. RLHF 阶段 A:采样 + RM 训练 .................. 数小时4. RLHF 阶段 B:PPO/DPO ......................... 数十小时5. 安全对齐(可选的第二轮 RLHF) ............... 数小时8.3 关键超参表
| 超参 | 推荐值 | 备注 |
|---|---|---|
| 学习率(policy) | 1e-6 ~ 5e-6 | 比 SFT 小一个数量级 |
| 学习率(RM) | 1e-5 ~ 5e-5 | RM 可以稍大 |
| (KL 系数) | 0.04 ~ 0.2 | DPO 论文用 0.1 |
| PPO clip | 0.2 | 标准值 |
| Rollout 采样数 | 4 ~ 16 | GRPO 用更大 |
| Mini-batch 大小 | 1 ~ 4 | 受显存限制 |
| GAE | 0.95 | |
| 折扣 | 1.0 | 序列级任务 |
8.4 监控指标
metrics_to_log = { # === RM 训练 === "rm/loss": "RM Bradley-Terry 损失", "rm/accuracy": "RM 在测试集上判别准确率", "rm/score_margin": "winner - loser 平均分数差",
# === PPO/DPO 训练 === "policy/kl": "π_θ 与 π_ref 的 KL", "policy/reward": "RM 给当前生成回答的平均分", "policy/reward_std": "RM 分数方差", "policy/clip_fraction": "被 clip 的 token 比例", "policy/advantages": "优势均值",
# === 任务指标 === "eval/helpfulness": "GPT-4 评分(1-10)", "eval/harmlessness": "安全率", "eval/win_rate": "相对基模型的胜率",}8.5 常见 Failure Mode
┌────────────────────────┬──────────────────────────────────┐│ 现象 │ 原因 / 解决 │├────────────────────────┼──────────────────────────────────┤│ KL 爆炸 │ β 太小 / LR 太大 → 增大 β、降低 LR ││ Reward 坍缩到 0 │ RM 过拟合 → 加正则、做 ensemble ││ 模型输出变成乱码 │ Reward hacking → 多 RM、加规则 ││ 模型变得太保守(拒绝一切)│ RM 偏负样本 → 重新平衡数据 ││ 偏好过拟合(DPO) │ 学习率太大 / epoch 多 → 减小 ││ Verbosity bias(越长越好)│ RM 没控制长度 → 加长度归一化 │└────────────────────────┴──────────────────────────────────┘9. 算法全景对比
9.1 主流对齐方法
┌─────────────────────────────────────────────────────────────┐│ 对齐方法谱系 │├─────────────────────────────────────────────────────────────┤│ ││ RL-based: ││ ├── PPO (2017) ── 经典,4 模型,复杂 ││ ├── GRPO (2024) ── DeepSeek-R1,无 critic ││ ├── REINFORCE ── 最简,公式简洁 ││ └── A2C / A3C ── 通用 RL,LLM 中较少用 ││ ││ RL-free (Direct Preference): ││ ├── DPO (2023) ── 开山之作,1 阶段 ││ ├── IPO (2023) ── 防过拟合 ││ ├── KTO (2024) ── 不需成对偏好 ││ ├── SimPO (2024) ── 无参考模型 ││ ├── ORPO (2024) ── SFT + DPO 联合 ││ └── CPO (2024) ── SFT + DPO 正则 ││ ││ Self-Play / Iterative: ││ ├── Constitutional AI ── AI 当标注员 ││ ├── Self-Rewarding LM ── 自我奖励迭代 ││ └── SPIN / Iterative DPO── 多轮迭代偏好对齐 ││ │└─────────────────────────────────────────────────────────────┘9.2 决策树
需要对齐 LLM │ ├── 你有多少 GPU?多少数据? │ │ │ ├── 资源受限(< 8 卡 A100) │ │ └── ✅ DPO / SimPO(最便宜、最稳) │ │ │ ├── 中等资源(8-32 卡) │ │ ├── 数据多 + 想追最强性能 → ✅ GRPO │ │ └── 数据少 + 想稳定 → ✅ DPO │ │ │ └── 大量资源(> 64 卡) │ └── ✅ PPO + 大 RM ensemble │ ├── 你能采集偏好数据吗? │ │ │ ├── 可以(人工标注) │ │ └── ✅ PPO / DPO │ │ │ ├── 不能人工,但有强模型 │ │ └── ✅ RLAIF + PPO / DPO │ │ │ └── 都没有 │ └── ✅ KTO(只需要"好/坏"标签) │ └── 是否需要在线探索? │ ├── 是 → ✅ PPO / GRPO └── 否 → ✅ DPO(offline)9.3 性能 vs 复杂度矩阵
| 算法 | 实现复杂度 | 显存 | 性能 | 稳定性 | 推荐场景 |
|---|---|---|---|---|---|
| PPO | 高 | 高 | ★★★★★ | ★★ | 大厂、追 SOTA |
| GRPO | 中 | 中 | ★★★★★ | ★★★ | DeepSeek 复现 |
| DPO | 低 | 低 | ★★★★ | ★★★★★ | 快速迭代、初创 |
| IPO | 低 | 低 | ★★★★ | ★★★★ | DPO 过拟合时 |
| KTO | 低 | 低 | ★★★ | ★★★★ | 只有二值标签 |
| SimPO | 低 | 最低 | ★★★★ | ★★★★ | 显存紧张 |
10. 核心数学公式汇总
10.1 Bradley-Terry 偏好模型
10.2 RM 损失
10.3 RLHF 目标
10.4 PPO Clipped Surrogate
10.5 GRPO 组内归一化
10.6 DPO 损失
10.7 IPO 损失
11. 总结
11.1 对齐范式的演进
阶段 1: SFT only → 学会"按指令回答" → 无法处理偏好、价值观
阶段 2: RLHF (InstructGPT, ChatGPT) → 引入 RM + PPO → 性能强但训练复杂
阶段 3: Direct Preference (DPO) → 闭式解,无需 RL → 工程简单,性能相当
阶段 4: Self-Improvement (RLAIF, Self-Rewarding) → AI 替代人类标注 → 持续自我改进11.2 选择建议
项目初期 / 资源受限: → DPO 是最好的起点。简单、稳定、性能强。
追求 SOTA: → PPO + 大 RM(如果算力足够) → 或 GRPO(DeepSeek 路径)
数据形式特殊: → 只有"好/坏"标签 → KTO → 没有 reference model → SimPO
长期迭代: → Constitutional AI + 自我奖励 → SPIN / Iterative DPO11.3 未解决的问题
- 超人类反馈:模型比人类专家更强时,谁来评判?
- 多目标对齐:Helpful + Harmless + Honest 之间的权衡
- 奖励模型的鲁棒性:对抗样本、分布外泛化
- 对齐税(Alignment Tax):对齐带来的能力损失如何最小化
- 可解释对齐:能否理解模型为什么”对齐”了
推荐按以下顺序阅读论文:
- InstructGPT(2022)—— RLHF 经典
- DPO(2023)—— 直接偏好优化
- Constitutional AI(2022)—— RLAIF 思想
- DeepSeek-R1(2024)—— GRPO 与推理 RL
- SimPO(2024)—— 简洁的现代变体
参考资料
- Ouyang, L., et al. (2022). “Training language models to follow instructions with human feedback.” NeurIPS.
- Christiano, P., et al. (2017). “Deep reinforcement learning from human preferences.” NeurIPS.
- Schulman, J., et al. (2017). “Proximal Policy Optimization Algorithms.” arXiv.
- Rafailov, R., et al. (2023). “Direct Preference Optimization: Your Language Model is Secretly a Reward Model.” NeurIPS.
- Azar, M., et al. (2023). “A General Theoretical Paradigm to Understand Learning from Human Feedback.” AISTATS (IPO).
- Ethayarajh, K., et al. (2024). “KTO: Model Alignment as Prospect Theoretic Optimization.” ICML.
- Meng, Y., et al. (2024). “SimPO: Simple Preference Optimization with a Reference-Free Reward.” arXiv.
- Shao, Z., et al. (2024). “DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models.” arXiv (GRPO).
- Bai, Y., et al. (2022). “Constitutional AI: Harmlessness from AI Feedback.” arXiv.
- Touvron, H., et al. (2023). “LLaMA 2: Open Foundation and Fine-Tuned Chat Models.” arXiv.
- Guo, D., et al. (2025). “DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning.” arXiv.
- Lambert, N., et al. (2024). “RewardBench: Evaluating Reward Models for Language Modeling.” arXiv.
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!

