DPO 训练
直接偏好优化使模型与人类偏好对齐,无需奖励建模。
什么是 DPO?
DPO(Direct Preference Optimization)是 RLHF 的更简单替代方案。DPO 不是训练单独的奖励模型,而是直接优化模型以偏好选择的响应而非被拒绝的响应。
快速开始
aitraining llm --train \
--model meta-llama/Llama-3.2-1B \
--data-path ./preferences.jsonl \
--project-name llama-dpo \
--trainer dpo \
--prompt-text-column prompt \
--text-column chosen \
--rejected-text-column rejected \
--dpo-beta 0.1 \
--peft
DPO 需要 --prompt-text-column 和 --rejected-text-column。--text-column 默认为 "text",因此只有当您的选择列名称不同时才需要指定。
Python API
from autotrain.trainers.clm.params import LLMTrainingParams
from autotrain.project import AutoTrainProject
params = LLMTrainingParams(
model="meta-llama/Llama-3.2-1B",
data_path="./preferences.jsonl",
project_name="llama-dpo",
trainer="dpo",
prompt_text_column="prompt",
text_column="chosen",
rejected_text_column="rejected",
dpo_beta=0.1,
max_prompt_length=128, # Default: 128
max_completion_length=None, # Default: None
epochs=1,
batch_size=2,
gradient_accumulation=4,
lr=5e-6,
peft=True,
lora_r=16,
lora_alpha=32,
)
project = AutoTrainProject(params=params, backend="local", process=True)
project.create()
数据格式
DPO 需要偏好对:一个提示词和选择/拒绝的响应。
{
"prompt": "What is the capital of France?",
"chosen": "The capital of France is Paris.",
"rejected": "France's capital is London."
}
多轮对话
{
"prompt": [
{"role": "user", "content": "What is AI?"},
{"role": "assistant", "content": "AI is artificial intelligence."},
{"role": "user", "content": "Give me an example."}
],
"chosen": "A common example is ChatGPT, which uses AI to understand and generate text.",
"rejected": "idk lol"
}
| 参数 | 描述 | 默认值 |
|---|
trainer | 设置为 "dpo" | 必需 |
dpo_beta | KL 惩罚系数 | 0.1 |
max_prompt_length | 提示词最大 token 数 | 128 |
max_completion_length | 响应最大 token 数 | None |
model_ref | 参考模型(可选) | None(使用基础模型) |
Beta
beta 参数控制模型可以从参考模型偏离多少:
0.01-0.05: 激进优化(可能过拟合)
0.1: 标准(推荐)
0.5-1.0: 保守(保持接近参考模型)
# 保守训练
params = LLMTrainingParams(
...
trainer="dpo",
dpo_beta=0.5, # 更高 = 更保守
)
参考模型
当 model_ref 为 None(默认值)时,DPO 使用初始模型作为参考。您可以指定不同的参考模型:
params = LLMTrainingParams(
model="meta-llama/Llama-3.2-1B", # 要训练的模型
model_ref="meta-llama/Llama-3.2-1B-base", # 参考模型
...
trainer="dpo",
)
训练技巧
使用 LoRA
DPO 与 LoRA 配合良好:
params = LLMTrainingParams(
...
trainer="dpo",
peft=True,
lora_r=16,
lora_alpha=32,
lora_dropout=0.05,
)
较低学习率
DPO 对学习率敏感:
params = LLMTrainingParams(
...
trainer="dpo",
lr=5e-7, # 远低于 SFT
)
更少轮次
DPO 通常需要更少的轮次:
params = LLMTrainingParams(
...
trainer="dpo",
epochs=1, # 通常 1-3 轮就足够
)
示例:有用助手
创建更有用的助手:
params = LLMTrainingParams(
model="meta-llama/Llama-3.2-1B",
data_path="./helpfulness_prefs.jsonl",
project_name="helpful-assistant",
trainer="dpo",
dpo_beta=0.1,
max_prompt_length=1024,
max_completion_length=512,
epochs=1,
batch_size=2,
gradient_accumulation=8,
lr=1e-6,
peft=True,
lora_r=32,
lora_alpha=64,
log="wandb",
)
DPO vs ORPO
| 方面 | DPO | ORPO |
|---|
| 参考模型 | 必需 | 不需要 |
| 内存使用 | 更高 | 更低 |
| 训练速度 | 更慢 | 更快 |
| 使用场景 | 细粒度对齐 | 组合 SFT + 对齐 |
收集偏好数据
人工标注
- 为每个提示词生成多个响应
- 让标注员对响应进行排序
- 创建选择/拒绝对
LLM 作为评判者
def create_preference_pairs(prompts, model_responses):
"""使用 GPT-4 判断哪个响应更好。"""
# ... 生成判断
return {"prompt": p, "chosen": better, "rejected": worse}
下一步