第7章补充材料:指令微调进阶与DPO偏好优化

1. 指令数据集的构建方式 [MLNLP]

主章使用了 Alpaca 模板格式化指令数据,但未涉及数据来源。高质量的指令数据是 SFT 成功的关键。

1.1 人工编写 vs 模型生成

来源优点缺点
人工编写质量高、多样性好成本高、速度慢
GPT-4 生成成本低、可大规模扩展可能含有模板化痕迹
开源数据集混合平衡成本与质量许可证问题

1.2 Alpaca 方法:用 GPT-4 生成指令数据

Stanford Alpaca 项目的方法至今仍被广泛使用:

  1. 收集 175 条”种子任务”
  2. 用 GPT-4 从种子任务自举生成 52K 条指令-回答对
  3. 过滤低质量样本(过短、重复等)

1.3 指令多样性的重要性

MLNLP 项目的 ch07/02_dataset-utilities 强调了指令类型的多样性。一个好的指令数据集应覆盖:

  • 开放式问答:“解释量子计算的基本原理”
  • 信息提取:“从以下文本中提取所有人名”
  • 文本变换:“把这段话翻译成法语 / 总结为三句话”
  • 创意写作:“写一首关于秋天的诗”
  • 代码生成:“写一个 Python 函数实现二分搜索”
  • 推理:“如果 A > B 且 B > C,A 和 C 的关系是什么?”

单一类型的指令会导致模型在其他类型上表现差。


2. DPO:直接偏好优化 [MLNLP]

主章末尾提到了 RLHF / DPO 等偏好对齐方法。MLNLP 的 ch07/04_preference-tuning-with-dpo 提供了 DPO 的完整从零实现。

2.1 从 RLHF 到 DPO

传统 RLHF 流程:

SFT 模型 → 人工标注偏好数据 → 训练奖励模型 → PPO 优化策略

问题:PPO 训练不稳定,需要四个模型(策略、参考、奖励、价值网络)同时运行,工程复杂度极高。

DPO 的核心洞察:直接用偏好数据优化策略模型,绕过奖励模型的训练

2.2 DPO 的损失函数

给定一条提示 $x$,模型生成的两个回答 $y_w$(chosen)和 $y_l$(rejected),DPO 的损失为:

$$\mathcal{L}{\text{DPO}} = -\mathbb{E}\left[\log \sigma\left(\beta \left(\log\frac{\pi\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)} - \log\frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)}\right)\right)\right]$$

其中:

  • $\pi_\theta$ 是正在训练的策略模型
  • $\pi_{\text{ref}}$ 是冻结的参考模型(通常是 SFT 后的模型)
  • $\beta$ 是控制偏好强度的超参数(通常 0.1~0.5)
  • $\sigma$ 是 sigmoid 函数

直觉:最小化这个损失会让 $\pi_\theta$ 相对于 $\pi_{\text{ref}}$ 更偏好 $y_w$ 而非 $y_l$。

2.3 DPO 的实现要点

def dpo_loss(policy_chosen_logps, policy_rejected_logps,
             ref_chosen_logps, ref_rejected_logps, beta=0.1):
    """计算 DPO 损失"""
    chosen_rewards = beta * (policy_chosen_logps - ref_chosen_logps)
    rejected_rewards = beta * (policy_rejected_logps - ref_rejected_logps)
    
    loss = -F.logsigmoid(chosen_rewards - rejected_rewards).mean()
    
    # 可选:添加 chosen reward 的准确率指标
    with torch.no_grad():
        accuracy = (chosen_rewards > rejected_rewards).float().mean()
    
    return loss, accuracy

关键实现细节:

  • 对数概率计算:需要用 prompt mask 确保只在 response 部分计算 log probability
  • 参考模型:完全冻结,不做梯度更新,但每次 forward 都需要跑一遍
  • 批量构成:每个 batch 包含成对的 (chosen, rejected) 回答
  • $\beta$ 的选择:太大会导致模型过于保守(趋近参考模型),太小则偏好信号弱

2.4 偏好数据的生成 [MLNLP]

MLNLP 的 ch07/04_preference-tuning-with-dpo/create-preference-data-ollama.ipynb 展示了如何用 LLaMA 3.1 + Ollama 生成偏好数据:

  1. 用 SFT 模型对同一指令生成多个回答(不同温度)
  2. 用 GPT-4 或人工标注哪个回答更好
  3. 也可以用”自我评分”策略:让模型给自己的回答打分

3. 合成数据集生成 [MLNLP]

MLNLP 的 ch07/05_dataset-generation 提供了两种合成数据集生成方法。

3.1 使用 LLaMA 3 + Ollama 生成

llama3-ollama.ipynb 的流程:

  1. 准备一组多样化的种子指令
  2. 用 LLaMA 3 通过 Ollama 本地推理生成回答
  3. 过滤和清洗(去除过短、格式错误、重复的样本)
  4. 可选:用 LLM 自评筛选高质量子集

3.2 反思微调(Reflection-Tuning)

reflection-gpt4.ipynb 介绍了更高级的数据优化方法:

  1. 生成初始指令-回答对
  2. 让 GPT-4 “反思”每个回答,指出不足
  3. 根据反思重写更好的回答
  4. 用”原始 vs 改进”的对比作为偏好数据

这种方法同时产出了更高质量的 SFT 数据和偏好数据。


4. 模型评估方法 [MLNLP]

主章介绍了困惑度、LLM-as-a-judge 和人工评估三种方法。MLNLP 的 ch07/03_model-evaluation 提供了更多细节。

4.1 使用 Llama 3 本地评估

可以用本地运行的 Llama 3 模型作为评估器:

EVAL_PROMPT = """请评估以下回答的质量。

指令:{instruction}
回答:{response}

请从以下维度打分(1-5分):
1. 指令遵循程度
2. 正确性
3. 有用性
4. 表达清晰度

输出格式:{"scores": [s1, s2, s3, s4], "overall": s_avg}
"""

4.2 使用 GPT-4 API 评估

对于更准确的评估,可以用 GPT-4 做成对比较:

JUDGE_PROMPT = """你是一个公正的评委。请比较以下两个回答。

指令:{instruction}

回答A:{response_a}
回答B:{response_b}

哪个回答更好?请只输出 A 或 B,然后简要说明理由。"""

注意事项:

  • 位置偏置:A/B 的顺序会影响判断。解决方案是每次交换位置,取多数票。
  • 冗长偏置:更长的回答倾向于得到更高评分。可以在提示中明确”简洁性也是考量因素”。
  • 一致性:同一条指令评估两次,结果应该一致。如果不一致率 >20%,说明评估提示需要改进。

4.3 AlpacaEval 风格的胜率评估

工业界常用的评估方式:

  1. 准备一组基准指令(如 AlpacaEval 的 805 条)
  2. 让被评估模型和参考模型各生成一个回答
  3. 用 GPT-4 做成对比较
  4. 报告胜率(win rate)

胜率 >50% 表示被评估模型优于参考模型。


5. SFT 与 DPO 的联合训练流程 [Datawhale]

完整的对齐流程通常是:

预训练模型 → SFT(监督微调)→ DPO(偏好优化)

超参数推荐

阶段学习率epochbatch_size特殊设置
SFT2e-52~364~128prompt mask
DPO1e-6 ~ 5e-61~232~64$\beta=0.1$

DPO 之后的效果

典型的 DPO 训练可以带来:

  • 指令遵循度:显著提升(尤其是复杂指令)
  • 安全性:减少有害输出
  • 风格一致性:更符合人类偏好(如简洁 vs 详细)
  • 代价:可能略微降低在纯知识性任务上的表现(对齐税)

6. 扩展阅读 [MLNLP]

  • DPO 实现ch07/04_preference-tuning-with-dpo/dpo-from-scratch.ipynb 提供了完整的 DPO 从零实现
  • 偏好数据生成ch07/04_preference-tuning-with-dpo/create-preference-data-ollama.ipynb 展示了用 Ollama 生成偏好数据
  • 合成数据集ch07/05_dataset-generation/ 包含 LLaMA 3 生成和反思微调两种方法
  • 模型评估ch07/03_model-evaluation/ 提供了 Llama 3 和 GPT-4 两种评估工具
  • 交互界面ch07/06_user_interface 提供了与微调后模型对话的 Gradio 界面