大模型的能力由预训练决定,但大模型的行为由对齐决定。一个能力强大但不对齐的模型,就像一个天才但不守规矩的员工——潜力越大,风险越大。本文将从工程实践角度,完整梳理从数据标注到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对比

维度PPODPO
显存需求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论坛