直接偏好优化(DPO, Direct Preference Optimization)是一种新兴的LLM微调技术,旨在以更简单、更高效的方式实现人类偏好对齐。相比传统的RLHF(基于人类反馈的强化学习),DPO提供了更直接的优化路径,减少了复杂性和计算资源需求。本文将详细介绍DPO的工作原理、实现方法和实际应用。
DPO的核心思想是直接从人类偏好数据中学习,而不需要显式地构建奖励模型或执行复杂的强化学习过程。它通过比较人类偏好的”好”响应和”差”响应,直接优化模型参数,使其更倾向于生成符合人类偏好的输出。
工作原理:
| 方面 | DPO | RLHF |
|---|---|---|
| 复杂性 | 低:直接优化,无中间步骤 | 高:需要奖励模型和PPO |
| 训练稳定性 | 更高:避免了RL的不稳定性 | 较低:RL训练可能不稳定 |
| 计算资源 | 更少:单次训练过程 | 更多:多次训练过程 |
| 实现难度 | 更低:代码更简洁 | 更高:需要更多组件 |
| 对齐效果 | 相当:研究表明效果接近 | 成熟:经过广泛验证 |
DPO的目标是优化模型,使其在给定输入的情况下,产生偏好输出的概率高于非偏好输出。其核心公式为:
ℒ_DPO(θ; θ_ref) = -E[(x, y_pref, y_rej) ~ D] [log σ(β log π_θ(y_pref|x) - β log π_θ(y_rej|x))]
其中:
DPO需要偏好比较数据,通常格式为三元组(x, y_pref, y_rej):
数据收集方法:
数据质量要求:
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOTrainer, DPOConfig
import torch
# 加载模型和分词器model_name = "mistralai/Mistral-7B-v0.1"base_model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(model_name)
# 配置DPOdpo_config = DPOConfig(
learning_rate=5e-7,
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
beta=0.1, # 温度参数 logging_steps=10,
output_dir="./dpo_results",
fp16=True,
)
# 创建DPO Trainerdpo_trainer = DPOTrainer(
model=base_model,
ref_model=None, # 如果不提供,将从base_model克隆 args=dpo_config,
train_dataset=preference_dataset,
tokenizer=tokenizer,
max_length=1024,
max_prompt_length=512,
)
# 开始训练dpo_trainer.train()
# 保存模型dpo_trainer.save_model("./dpo_finetuned_model")