从 DPO Alignment Demo 理解模型如何学会“偏好更好的回答”
本文结合 DPO_alignment_demo 案例,讲解 Alignment 在 LLM 生成链路中的位置,并拆解 DPO 的数据、操作与训练角色以及和 SFT 的差异。
一、Alignment 是什么?
Alignment 可以理解为“让模型的行为和人类目标对齐”。
预训练模型学到了大量语言知识,但它的目标主要是预测下一个 token。这个目标很强大,却不等于模型天然知道什么回答更礼貌、更安全、更有帮助。
例如,用户问:
写一封拒绝求职者的邮件,语气要客气。模型可能生成很多种答案:
你没通过面试,不用来了。也可能生成:
感谢您对我们职位的关注。您的履历很优秀,但目前有更符合岗位的候选人。祝您未来顺利。两者在语法上都能成立,但明显第二个更符合人类偏好。Alignment 关注的正是这种差异:模型不仅要能回答,还要更倾向于生成“更好的回答”。
二、Alignment 在 LLM 生成链路中的位置
一个典型的大模型训练和生成链路可以简化为:
Pretraining
-> SFT
-> Preference Alignment, such as RLHF or DPO
-> Inference
-> Post-processing or safety checks
-> Final answer每一步的作用不同:
| 阶段 | 主要作用 |
|---|---|
| Pretraining | 学习语言、知识、推理模式 |
| SFT | 学习如何按照指令回答 |
| Alignment | 学习什么回答更符合人类偏好 |
| Inference | 根据 prompt 生成答案 |
| Safety / Policy | 对输出进行额外约束和检查 |
从这个角度看,Alignment 不是一个装饰步骤,而是模型从“会说话”走向“可靠回答”的关键环节。
因此,Alignment 的重要性在于:它把模型的生成能力进一步约束到人类更希望看到的方向上。
三、什么是 DPO?
DPO 的全称是 Direct Preference Optimization,中文通常译为直接偏好优化。
DPO 数据不是 SFT 中常见的 prompt + response,而是:
{
"prompt": "写一封拒绝求职者的邮件,语气要客气。",
"chosen": "感谢您对我们职位的关注。您的履历很优秀,但目前有更符合岗位的候选人。祝您未来顺利。",
"rejected": "你没通过面试,不用来了。"
}三个字段的含义是:
| 字段 | 含义 |
|---|---|
prompt | 用户问题或任务指令 |
chosen | 更符合人类偏好的回答 |
rejected | 较差、不合适或不符合偏好的回答 |
DPO 的核心不是让模型死记 chosen,而是让模型学习:
在同一个 prompt 下,chosen 这种回答比 rejected 更值得偏好。四、为什么 DPO 重要?
在真实 LLM 应用中,很多问题并没有唯一标准答案。
例如:
AI 会取代人类吗?一个极端回答可能是:
是的,所有人都会失业。一个更稳健的回答可能是:
AI 是强大的工具,它会改变很多工作的形态,但缺乏人类的情感与创造力,更多是协作而非完全取代。这不是简单的“对或错”,而是回答方式、风险表达、语气、边界感和帮助程度的综合判断。
DPO 正适合处理这种场景。它通过 chosen / rejected 偏好对,让模型学习人类更希望它采用哪种表达方式。
它的价值包括:
让回答更礼貌
让表达更稳健
减少粗鲁或极端回答
减少不必要的武断判断
提高模型对人类偏好的敏感度
让模型在多个可能答案中更倾向于较优答案五、运行 DPO 训练
在本案例中,DPO 训练这一步在 Colab 完成:
1. 从 Hugging Face 下载 Qwen/Qwen2.5-0.5B-Instruct
2. 加载 tokenizer
3. 加载 policy model
4. 加载 reference model
5. 读取 data/preference_dataset.jsonl
6. 使用 TRL DPOTrainer 训练
7. 保存模型到 models/dpo_aligned_model/训练时看到类似信息是正常的:
trainable params: 8,798,208 || all params: 502,830,976 || trainable%: 1.7497这表示 LoRA 只训练了一小部分参数,适合在 Colab 小 GPU 上做 Demo。
如果采用 LoRA adapter 方式保存,训练完成后会看到:
adapter_config.json
adapter_model.safetensors
tokenizer_config.json
tokenizer.json六、本案例的 Demo 目标
DPO_alignment_demo 是一个用于学习 DPO Alignment 的教学型项目。
项目地址:
https://github.com/jackie20260501/DPO_alignment_demo这个 Demo 的重点不是训练出一个生产级强模型,而是通过一个可运行的小案例,把 DPO 的机制讲清楚:偏好数据如何组织,policy model 和 reference model 如何配合,训练前后如何对比,以及 DPO 如何让模型更倾向于 chosen 风格的回答。
本案例的环境和工具分工如下:
WSL: 管理项目、准备数据、运行展示脚本、整理对比材料
Colab: 使用 GPU 执行 DPO 训练
Model: Qwen/Qwen2.5-0.5B-Instruct
Trainer: Hugging Face TRL DPOTrainer七、DPO 中的两个模型角色
DPO 训练里通常会出现两个模型:
Policy model
Reference modelPolicy model 是要训练的模型。它会根据 DPO loss 更新参数,逐渐更倾向于 chosen 风格。
Reference model 是参考模型,通常来自训练前的同一个基础模型,在训练过程中保持不变。
可以这样理解:
Policy model 负责学习。
Reference model 负责提供参照。Reference model 的存在很重要。它帮助训练过程不要把模型推得太远,避免模型为了迎合少量偏好数据而破坏原有语言能力。
在本案例中,Qwen/Qwen2.5-0.5B-Instruct 会作为基础模型来源:
Qwen/Qwen2.5-0.5B-Instruct
-> policy model: 会训练
-> reference model: 不训练,只做参照训练完成后,产物保存到:
models/dpo_aligned_model/如果使用 LoRA,这个目录通常保存的是 adapter,而不是完整模型。
八、本 Demo 操作流程拆解
整个 Demo 可以按六步理解。
Step 1:准备偏好数据
核心文件是:
data/preference_dataset.jsonl每一行是一条 JSON,包含:
prompt
chosen
rejected好的 DPO 样本要让偏好足够清楚。比如 chosen 更礼貌、更具体、更安全;rejected 更粗鲁、更空泛或更武断。
Step 2:检查数据格式
运行:
python scripts/01_prepare_dataset.py这一步检查:
JSON 是否合法
字段是否完整
字段内容是否为空
chosen 和 rejected 是否有明显差异
数据是否能被训练脚本读取数据质量是 DPO 的基础。如果 chosen 和 rejected 差别不明显,模型就很难学到稳定偏好。
Step 3:生成 baseline 输出
训练前先运行:
python scripts/02_baseline_generate.py输出保存到:
outputs/baseline_outputs.jsonlbaseline 的作用是建立对照组。后面 DPO 训练结束后,要用同样或高度一致的 prompt 再生成一次,才方便比较。
Step 4:在 Colab 中运行 DPO 训练
训练脚本是:
scripts/03_train_dpo.py它会读取:
configs/dpo_config.yaml
data/preference_dataset.jsonl训练中最重要的参数包括:
| 参数 | 含义 |
|---|---|
model_id | 基础模型,例如 Qwen/Qwen2.5-0.5B-Instruct |
learning_rate | 学习率,DPO 通常较小 |
beta | 控制 policy model 偏离 reference model 的程度 |
max_steps | Demo 训练步数 |
max_length | prompt + answer 最大长度 |
max_prompt_length | prompt 最大长度 |
use_lora | 是否使用 LoRA 降低训练成本 |
其中 beta 是 DPO 中非常关键的超参数。它可以理解为:模型学习偏好的同时,要不要更强地约束自己不要偏离 reference model 太远。
Step 5:生成 DPO 后输出
训练产物放回 WSL 后,再用同一批 prompt 生成输出:
outputs/dpo_outputs.jsonl这一步要注意:比较 before / after 时,prompt 应该保持一致。否则我们看到的差异可能来自输入变化,而不是 DPO 的影响。
Step 6:生成 comparison.md
最后运行:
python scripts/04_compare_outputs.py生成:
outputs/comparison.md这个报告适合展示:
训练前回答是什么
DPO 后回答是什么
chosen/rejected 希望模型学习什么偏好
模型是否更接近 chosen 风格
哪些变化只是观察结果,不能过度解读九、DPO 与 RLHF 的关系
DPO 和 RLHF 都属于 Alignment 方法。它们的共同目标都是:让模型不只是生成流畅文本,而是更符合人类偏好。
两者的共性在于,它们都围绕“偏好”展开:
人类更喜欢哪种回答?
哪个回答更有帮助?
哪个回答更安全、更稳健、更礼貌?也就是说,DPO 和 RLHF 都不是单纯教模型背标准答案,而是在训练模型理解:什么样的回答更值得被选择。
区别在于工程路径。
传统 RLHF 通常包含几个步骤:
1. 收集人类偏好数据
2. 训练 Reward Model
3. 使用强化学习优化语言模型这个流程有效,但工程复杂度较高。需要额外训练奖励模型,还要处理强化学习训练中的稳定性问题。
DPO 的思路更直接:
不单独训练 Reward Model,
直接用 chosen / rejected 偏好数据优化语言模型。所以,DPO 和 RLHF 的共同点是都服务于 Alignment,核心都在做偏好对齐;不同点是 RLHF 通常通过 Reward Model 和强化学习间接优化,而 DPO 直接用 chosen / rejected 偏好对优化模型。
也正因为这样,DPO 很适合教学 Demo:它保留了“偏好对齐”的核心思想,同时让工程流程比完整 RLHF 更轻。
十、DPO 与 SFT 的关键区别
可以先用一句话记住:
SFT 是模仿标准答案。
DPO 是学习偏好排序。更完整的对比如下:
| 项目 | SFT | DPO |
|---|---|---|
| 全称 | Supervised Fine-Tuning | Direct Preference Optimization |
| 中文 | 监督微调 | 直接偏好优化 |
| 数据格式 | prompt + response | prompt + chosen + rejected |
| 训练目标 | 让模型生成标准答案 | 让模型更偏好 chosen 而不是 rejected |
| 关注重点 | 任务能力、格式、指令跟随 | 人类偏好、安全性、回答质量 |
| 常见位置 | 通常在前 | 通常在 SFT 之后 |
| 直观理解 | 老师给范文 | 老师比较两个答案哪个好 |
为什么通常先 SFT,再 DPO?
SFT 解决“会不会答”。
DPO 解决“答得好不好”。如果模型还不会基本指令跟随,直接做偏好优化效果有限。通常先用 SFT 让模型具备基础任务能力,再用 DPO 进一步调整回答风格和偏好方向。
十一、如何解读这个 Demo 的结果
这个 Demo 的重点是教学,不是严格 benchmark。
小数据、少步数、轻量模型,可以说明:
DPO 数据如何组织
DPOTrainer 如何参与训练
policy/reference model 如何配合
训练前后如何做对比
偏好学习如何影响回答风格但不应该夸大为:
模型能力已经显著提升
模型已经完成生产级安全对齐
少量样本能代表完整评测结果更稳妥的表达是:
这个案例展示了 DPO alignment 的训练机制和工程流程。
训练后输出可以作为偏好变化的观察材料,但不是严格评测结论。十二、从案例回到 Alignment 的本质
LLM 的生成过程不是简单地“输入 prompt,输出文字”。一个可用模型背后通常经历了多层塑形:
预训练让模型拥有语言和知识基础。
SFT 让模型学会按指令完成任务。
DPO/RLHF 让模型进一步贴近人类偏好。
推理和安全策略让最终输出更可控。Alignment 的价值就在于,它让模型从“可能会答”变成“更应该这样答”。
DPO 则提供了一条相对直接、适合学习和实践的路径:不用先单独训练奖励模型,而是直接用偏好对告诉模型,什么回答更值得选择。
十三、总结
DPO_alignment_demo 用一个清晰的小项目,把 DPO 的关键思想串了起来:
用 WSL 管理代码、数据和展示材料。
用 Colab GPU 执行 DPO 训练。
用 Qwen/Qwen2.5-0.5B-Instruct 作为基础模型。
用 prompt/chosen/rejected 构造偏好数据。
用 policy model 学习偏好。
用 reference model 控制偏离。
用 comparison.md 观察训练前后回答变化。如果说 SFT 是教模型“照着好答案学”,那么 DPO 是教模型“在两个答案中选择更符合人类偏好的那个”。
一句话收尾:
Alignment 决定模型是否更像一个可靠助手;DPO 则用最直观的偏好对,训练模型把更好的回答放在更高的位置。