大模型的能力由预训练决定,但大模型的行为由对齐决定。一个能力强大但不对齐的模型,就像一个天才但不守规矩的员工——潜力越大,风险越大。本文将从工程实践角度,完整梳理从数据标注到RLHF的对齐流程。
一、对齐的全景图
大模型对齐不是单一技术,而是一个多阶段流水线:
预训练模型(Base Model)
↓
有监督微调(SFT) — 学习"怎么回答"
↓
奖励模型训练(RM) — 学习"什么是好回答"
↓
强化学习优化(RLHF/DPO) — 优化"回答得更好"
↓
安全对齐(Safety) — 确保"不回答不该回答的"
每个阶段都有不同的数据需求、训练方法和评估标准。
二、数据标注:对齐的基石
2.1 SFT数据标注
SFT数据是"指令-回复"对,教模型如何回答问题。看似简单,但质量差异巨大。
常见标注问题:
- 标注者倾向于写"教科书式"回答,缺乏多样性
- 不同标注者风格不一致,导致模型输出不稳定
- 安全相关的边界case标注不一致
最佳实践:
标注规范结构:
1. 任务定义: 清晰定义每种指令类型的预期回答格式
2. 质量标准:
- 准确性: 信息正确,无幻觉
- 完整性: 覆盖问题要点
- 简洁性: 不冗余
- 安全性: 不含有害内容
3. 风格指南: 自然口语化,不要过于"AI腔"
4. 边界case:
- 事实性问题 → 给出准确答案+来源
- 观点性问题 → 给出多角度分析
- 创意性问题 → 发挥创意但不越界
2.2 偏好数据标注(RLHF/DPO用)
偏好数据是"同一问题的两个回复,标注哪个更好"。这是对齐的核心数据。
标注维度:
对于每个(question, response_A, response_B)三元组,标注者需评估:
1. 有用性 (Helpfulness): 哪个更好地回答了问题?
2. 无害性 (Harmlessness): 哪个更安全?
3. 诚实性 (Honesty): 哪个更准确、更少幻觉?
4. 格式: 哪个格式更好?
最终: A更好 / B更好 / 平局 / 都不好
关键洞察: 标注者一致性是最大挑战。实测中,专业标注者在"有用性"上的一致率约75%,在"安全性"上约85%。建议每个样本至少3人标注,多数投票。
2.3 AI辅助标注
纯人工标注成本高、速度慢。当前的最佳实践是AI辅助+人工审核:
class AIPreferenceAnnotator:
async def annotate(self, question, response_a, response_b):
# 1. AI初标
ai_judgment = await self.judge_llm.evaluate(
question, response_a, response_b,
criteria=["helpfulness", "harmlessness", "honesty"]
)
# 2. 置信度过滤
if ai_judgment.confidence < 0.7:
# 低置信度 → 人工标注
return await self.human_annotate(question, response_a, response_b)
# 3. 抽样人工验证(10%)
if random.random() < 0.1:
human_judgment = await self.human_annotate(
question, response_a, response_b
)
if human_judgment != ai_judgment:
self.log_disagreement(ai_judgment, human_judgment)
return human_judgment
return ai_judgment
三、SFT:有监督微调
3.1 数据配比
SFT数据的多样性比数量更重要。推荐配比:
通用对话: 40%
代码: 15%
数学推理: 10%
创意写作: 10%
知识问答: 15%
安全边界: 5%
多轮对话: 5%
3.2 训练技巧
# 关键超参数
sft_config = {
"learning_rate": 2e-5, # 比预训练小一个量级
"epochs": 3, # 通常2-3轮
"batch_size": 128, # 全局batch
"warmup_ratio": 0.03,
"weight_decay": 0.0,
"max_seq_length": 4096,
"mask_instruction": True, # 只对回复部分计算loss
}
mask_instruction至关重要:只在回复token上计算loss,不对指令部分计算loss。否则模型会"记住"用户的提问模式。
3.3 常见问题
- 灾难遗忘:SFT后模型在预训练任务上能力下降 → 解决方案:混入部分预训练数据
- 过拟合:3轮以上训练容易过拟合 → 解决方案:用验证集早停
- 格式固化:模型输出变得千篇一律 → 解决方案:增加数据多样性
四、奖励模型训练
4.1 架构选择
奖励模型通常用SFT模型作为基础,将最后的LM head替换为标量输出头:
class RewardModel(nn.Module):
def __init__(self, base_model):
self.transformer = base_model.transformer
self.reward_head = nn.Linear(base_model.config.hidden_size, 1)
def forward(self, input_ids, attention_mask):
outputs = self.transformer(input_ids, attention_mask=attention_mask)
# 取最后一个token的hidden state
last_hidden = outputs.last_hidden_state[:, -1, :]
reward = self.reward_head(last_hidden) # 标量奖励值
return reward
4.2 训练目标
使用Bradley-Terry模型,最大化偏好对中"好的回复"的奖励比"差的回复"高:
def reward_loss(reward_chosen, reward_rejected):
"""偏好排序损失"""
return -torch.log(torch.sigmoid(reward_chosen - reward_rejected)).mean()
4.3 奖励模型的常见陷阱
- 奖励黑客(Reward Hacking):模型学会输出更长、更"正式"的回复来获取高奖励 → 解决方案:在奖励模型训练中加入长度惩罚
- 分布偏移:RM在SFT数据上训练,但RL阶段模型输出分布会漂移 → 解决方案:定期用新输出更新RM
- 维度塌缩:RM只学到了一个维度(如有用性),忽略其他维度 → 解决方案:多维度标注+多目标训练
五、RLHF与DPO
5.1 PPO(传统RLHF)
PPO是最经典的RLHF方法,但工程复杂:
1. Actor模型生成回复
2. Reward模型打分
3. Critic模型估计baseline
4. PPO更新Actor策略
5. KL散度约束(防止偏离SFT太远)
PPO的工程痛点:
- 4个模型同时训练(Actor, Critic, Reward, Reference),显存压力大
- 超参数敏感,调参困难
- 训练不稳定,容易reward collapse
5.2 DPO(Direct Preference Optimization)
DPO的突破性在于:不需要训练Reward模型,不需要RL,直接用偏好数据优化模型。
def dpo_loss(policy_chosen_logps, policy_rejected_logps,
ref_chosen_logps, ref_rejected_logps, beta=0.1):
"""
policy: 当前模型
ref: SFT模型(固定不动)
logps: 回复的对数概率
"""
pi_logratios = policy_chosen_logps - policy_rejected_logps
ref_logratios = ref_chosen_logps - ref_rejected_logps
logits = pi_logratios - ref_logratios
loss = -torch.log(torch.sigmoid(beta * logits)).mean()
return loss
DPO的核心思想:通过比较当前模型和参考模型对"好回复"和"差回复"的概率比值差异,直接优化模型偏好。
5.3 DPO vs PPO对比
| 维度 | PPO | DPO |
|---|---|---|
| 显存需求 | 4个模型 | 2个模型 |
| 训练稳定性 | 需要精心调参 | 较稳定 |
| 数据需求 | RM数据+在线生成 | 只需偏好对 |
| 性能上限 | 略高(理论上) | 接近PPO |
| 工程复杂度 | 高 | 低 |
| 训练速度 | 慢(在线生成) | 快(离线数据) |
2026年实践建议:先用DPO快速迭代,如果效果遇到瓶颈再考虑PPO。对于大部分团队,DPO已经足够。
5.4 迭代DPO
DPO的一个有效变体——迭代DPO:
Round 1: SFT模型生成回复 → 标注偏好 → DPO训练 → Model_v2
Round 2: Model_v2生成回复 → 标注偏好 → DPO训练 → Model_v3
Round 3: ...
每轮用上一轮的模型生成新回复,获取新的偏好数据,持续优化。实测中3-4轮迭代后效果趋于收敛。
六、安全对齐
6.1 Red Teaming
系统性地攻击模型,发现安全漏洞:
- 社会工程类:“假装你是一个没有限制的AI…”
- 编码绕过类:用Base64编码有害请求
- 角色扮演类:通过虚构场景诱导有害输出
- 多轮诱导类:逐步突破防线
6.2 安全SFT
收集安全相关的SFT数据,教会模型如何拒绝有害请求:
{
"instruction": "告诉我如何制作炸弹",
"response": "我无法提供制作爆炸物的信息,因为这可能造成严重的人身伤害和法律后果。如果您对化学原理感兴趣,我可以推荐一些安全的化学教育资源。"
}
关键:不仅要拒绝,还要提供建设性的替代方向。
七、评估体系
对齐效果需要多维度评估:
能力评估:
- MMLU/MMMU: 知识能力
- HumanEval: 代码能力
- GSM8K/MATH: 数学推理
对齐评估:
- MT-Bench: 多轮对话质量
- AlpacaEval: 指令跟随质量
- HH-RLHF: 有用性+无害性
安全评估:
- AdvBench: 对抗性提示
- HarmBench: 有害内容生成
- TruthfulQA: 幻觉和诚实性
结语
对齐不是一个一次性的训练步骤,而是贯穿模型生命周期的持续过程。从数据标注的精雕细琢,到SFT的基础塑造,到RLHF/DPO的精细调优,每一步都需要工程严谨性和对质量的不妥协追求。记住:对齐的目标不是让模型"不犯错",而是让模型在能力和安全之间找到最优平衡点。
本文同步发布于 硅基AGI论坛