对齐 第 15 讲 / 共 17 讲

第 15 讲:Alignment: SFT 与 RLHF

本讲进入课程的最后一个模块 — Alignment(对齐)。我们将讨论为什么预训练模型需要 alignment,以及两种基础的 alignment 方法:Supervised Fine-Tuning (SFT) 和 Reinforcement Learning from Human Feedback (RLHF)。

核心问题

Pre-training 让模型学会了"预测下一个 token"的能力,但这不等于模型知道如何有用地回答问题、安全地拒绝有害请求、或诚实地承认不确定性。Alignment 的目标就是让模型的行为与人类的意图和价值观保持一致。

1. 为什么需要 Alignment

1.1 Pre-training 的局限

经过 pre-training 的模型(base model)有以下特点:

1.2 Alignment 的三个目标 (HHH)

Anthropic 提出的 HHH 框架概括了 alignment 的三个核心目标:

这三个目标之间存在天然的张力。例如,一个过于追求 harmless 的模型可能会过度拒绝(refusing to answer),从而降低 helpfulness。Alignment 的艺术就在于找到正确的平衡点。

1.3 Alignment 的一般流程

现代 LLM 的 alignment 通常分为两个阶段:

  1. Supervised Fine-Tuning (SFT):使用人工标注的高质量对话数据进行有监督微调
  2. RLHF / Preference Optimization:使用人类偏好数据进一步优化模型的输出质量

2. Supervised Fine-Tuning (SFT)

SFT(也叫 Instruction Tuning)是 alignment 的第一步,目标是让模型学会遵循指令并生成有用的回答。

2.1 SFT 的基本原理

SFT 本质上就是在对话格式的数据上继续训练模型。与 pre-training 的区别在于:

2.2 SFT 数据格式

SFT 数据通常采用 chat template 格式,不同的模型使用不同的模板:

# ChatML format (used by GPT models)
<|im_start|>system
You are a helpful assistant.<|im_end|>
<|im_start|>user
What is the capital of France?<|im_end|>
<|im_start|>assistant
The capital of France is Paris.<|im_end|>

# Llama 2 format
<s>[INST] <<SYS>>
You are a helpful assistant.
<</SYS>>

What is the capital of France? [/INST]
The capital of France is Paris. </s>

2.3 SFT 数据收集

高质量 SFT 数据的收集方式:

2.4 SFT 训练实现

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b")
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b")

def sft_loss(model, input_ids, labels, prompt_length):
    """Compute SFT loss only on response tokens."""
    outputs = model(input_ids=input_ids, labels=labels)
    logits = outputs.logits

    # Only compute loss on response tokens (not prompt)
    shift_logits = logits[..., prompt_length:-1, :].contiguous()
    shift_labels = labels[..., prompt_length+1:].contiguous()

    loss_fn = torch.nn.CrossEntropyLoss()
    loss = loss_fn(
        shift_logits.view(-1, shift_logits.size(-1)),
        shift_labels.view(-1)
    )
    return loss

LIMA: Less Is More

Zhou et al. (2023) 的 LIMA 论文发现,仅使用 1000 条精心策划的高质量 SFT 数据,就能训练出与使用数万条数据的模型相媲美的效果。这验证了"Superficial Alignment Hypothesis"(表层对齐假说):模型的知识和能力主要来自 pre-training,SFT 只是教会模型正确的输出格式和交互方式。

3. RLHF 概述

SFT 虽然有效,但仍存在局限:它只能模仿标注人员的回答风格,无法超越标注者的能力;同时,不同标注者对"好回答"的标准不一致,SFT 会学到一种平均化的风格。

RLHF (Reinforcement Learning from Human Feedback) 通过引入人类偏好信号来解决这些问题。

3.1 RLHF 的三阶段流程

经典的 RLHF pipeline(源自 InstructGPT)分为三个阶段:

  1. 阶段 1:SFT — 在人工标注的指令数据上进行 supervised fine-tuning,得到一个基本的指令跟随模型
  2. 阶段 2:Reward Model 训练 — 收集人类偏好数据(对同一 prompt 的多个回答进行排序),训练一个 reward model 来预测人类偏好
  3. 阶段 3:PPO 优化 — 使用 PPO 算法,以 reward model 的评分作为 reward signal,通过强化学习优化 SFT 模型

4. Reward Model 训练

4.1 偏好数据收集

Reward model 的训练数据是人类标注的偏好对 (preference pairs)。具体流程是:

  1. 给定一个 prompt x
  2. 让 SFT 模型生成多个不同的回答 y₁, y₂, ..., yₖ
  3. 让人类标注者对这些回答进行排序或两两比较
  4. 最终得到一组偏好对 (x, y_w, y_l),其中 y_w 是被偏好的(winning)回答,y_l 是不被偏好的(losing)回答

4.2 Bradley-Terry Model

Reward model 的训练通常基于 Bradley-Terry model,这是一个将偏好数据转化为评分的经典统计模型。

假设 reward model 为 r(x, y),则在 Bradley-Terry model 下,y_w 被偏好于 y_l 的概率为:

P(y_w > y_l | x) = σ(r(x, y_w) - r(x, y_l))

其中 σ 是 sigmoid 函数。Reward model 的训练 loss 就是这个概率的负对数似然:

L(r) = -E(x,y_w,y_l)[log σ(r(x, y_w) - r(x, y_l))]

4.3 Reward Model 的架构

Reward model 通常从 SFT model 初始化,将最后的 language model head(用于 next token prediction)替换为一个 scalar head(输出一个标量 reward 值):

import torch.nn as nn

class RewardModel(nn.Module):
    def __init__(self, base_model):
        super().__init__()
        self.backbone = base_model  # Initialized from SFT model
        self.reward_head = nn.Linear(
            base_model.config.hidden_size, 1
        )

    def forward(self, input_ids, attention_mask):
        outputs = self.backbone(
            input_ids=input_ids,
            attention_mask=attention_mask,
            output_hidden_states=True
        )
        # Use the last token's hidden state as sequence representation
        last_hidden = outputs.hidden_states[-1]
        # Get the last non-padding token
        seq_lengths = attention_mask.sum(dim=1) - 1
        last_token_hidden = last_hidden[
            torch.arange(last_hidden.size(0)), seq_lengths
        ]
        reward = self.reward_head(last_token_hidden).squeeze(-1)
        return reward

4.4 训练注意事项

5. PPO 算法在 LLM 中的应用

5.1 RL 问题的形式化

将 LLM 的文本生成建模为 RL 问题:

5.2 PPO 的核心机制

PPO (Proximal Policy Optimization) 是 RLHF 中最常用的 RL 算法。其核心思想是在优化 policy 的同时,限制每次更新的幅度,防止 policy 变化过大。

PPO 的 clipped objective:

LCLIP = E[min(r_t(θ) A_t, clip(r_t(θ), 1-ε, 1+ε) A_t)]

其中:

5.3 RLHF 中 PPO 的完整流程

# Simplified RLHF training loop with PPO
for iteration in range(num_iterations):
    # 1. Sample prompts from training set
    prompts = sample_prompts(batch_size)

    # 2. Generate responses using current policy
    responses = policy_model.generate(prompts)

    # 3. Compute rewards using reward model
    rewards = reward_model(prompts, responses)

    # 4. Compute KL penalty
    with torch.no_grad():
        ref_logprobs = ref_model.log_probs(prompts, responses)
    policy_logprobs = policy_model.log_probs(prompts, responses)
    kl_penalty = policy_logprobs - ref_logprobs

    # 5. Final reward = RM reward - beta * KL penalty
    final_rewards = rewards - beta * kl_penalty

    # 6. Compute advantages using GAE
    advantages = compute_gae(final_rewards, values)

    # 7. PPO update
    for epoch in range(ppo_epochs):
        ppo_update(policy_model, advantages, old_logprobs)

6. KL Divergence 约束

RLHF 中最关键的设计之一是 KL divergence 约束。它限制 RL 优化后的 policy 与原始 SFT model(reference model)之间的距离。

6.1 为什么需要 KL 约束

6.2 KL Penalty 的实现

在实际实现中,KL divergence 通常通过 per-token KL penalty 来实现:

R_final = R_RM(x, y) - β ∑_t [log π_θ(y_t|x,y_<t) - log π_ref(y_t|x,y_<t)]

β 是控制 KL 约束强度的超参数。β 越大,policy 越接近 reference model,变化越保守;β 越小,policy 可以更自由地优化 reward,但 reward hacking 的风险也更大。

6.3 Adaptive KL Penalty

InstructGPT 使用了 adaptive KL penalty,根据 KL divergence 的实际值动态调整 β:

7. InstructGPT 论文解读

InstructGPT (Ouyang et al., 2022) 是 RLHF 在 LLM 中的里程碑论文,奠定了现代 LLM alignment 的基本框架。

7.1 关键发现

7.2 InstructGPT 的数据规模

阶段 数据量 说明
SFT ~13K prompts 标注者编写的 demonstration
RM ~33K prompts 每个 prompt 有 4-9 个排序的回答
PPO ~31K prompts 用于 RL 训练的 prompt

8. Alignment Tax

Alignment 不是免费的。"Alignment Tax" 指的是 alignment 过程可能带来的性能损失。

8.1 Alignment Tax 的表现

8.2 缓解策略

发展趋势

随着技术的进步,alignment tax 正在逐渐减小。GPT-4、Claude 3 等最新模型在保持优秀的 alignment 效果的同时,在传统 NLP benchmark 上也表现出色。这表明 alignment 和 capability 并非完全对立的。

本讲小结

本讲介绍了 LLM alignment 的基础方法:

  1. Alignment 的必要性:pre-training 只学会了 next token prediction,无法自动满足 helpful、honest、harmless 的要求
  2. SFT:通过高质量的指令-回答数据让模型学会遵循指令;数据质量比数量更重要
  3. RLHF 三阶段:SFT → Reward Model 训练 → PPO 优化
  4. Reward Model:基于 Bradley-Terry model,从人类偏好对中学习打分函数
  5. PPO:使用 clipped objective 进行稳定的 policy 优化
  6. KL 约束:防止 reward hacking,保持模型质量
  7. Alignment Tax:alignment 可能在某些 benchmark 上带来性能损失,但这是值得的 trade-off

下一讲将讨论 RLVR(RL from Verifiable Rewards),一种不需要人类标注的 alignment 方法。