# Summary
核心思想就是选 A 不选 B
## **输入数据**
```python
prompt = "The quick brown fox jumps over"
good_response = "the lazy dog." # 偏好回答
bad_response = "their crazy frog." # 拒绝回答
```
## **训练目标**
让模型学会:
- 对"the lazy dog."给出更高的概率
- 对"their crazy frog."给出更低的概率
## **DPO效果**
```python
# 训练前
model("The quick brown fox jumps over") → 可能输出任意回答
# 训练后
model("The quick brown fox jumps over") → 更倾向于输出"the lazy dog."这样的好回答
```
# Notes
**是的,你的理解完全正确!** 你准确地抓住了SFT和GRPO的本质区别。现在让我详细介绍DPO(Direct Preference Optimization)。
## DPO(Direct Preference Optimization)
### 核心思想
DPO是一种**直接**从人类偏好数据中学习的方法,不需要先训练奖励模型。
### 对齐对象:人类偏好的答案
```python
# DPO训练数据:成对比较
prompt = "请解释什么是机器学习"
chosen = "机器学习是人工智能的一个分支,通过算法让计算机从数据中学习。" # 人类更喜欢的
rejected = "机器学习就是让机器学习。" # 人类不太喜欢的
# 对齐目标:让模型更倾向于生成chosen,而不是rejected
```
## 三种方法的对比
|方法|对齐对象|数据形式|学习方式|
|---|---|---|---|
|**SFT**|人类标注的标准答案|(prompt, response)|监督学习|
|**GRPO**|组内得分最高的答案|(prompt,[responses],[rewards])|强化学习|
|**DPO**|人类偏好的答案|(prompt, chosen, rejected)|偏好学习|
## DPO的数学原理
### 传统RLHF流程
```python
# 1. 训练奖励模型
reward_model = train_reward_model(preference_data)
# 2. 使用PPO优化策略
policy = optimize_with_ppo(reward_model)
```
### DPO的创新
```python
# 直接从偏好数据优化策略,跳过奖励模型
policy = optimize_directly_from_preferences(preference_data)
```
### DPO损失函数
```python
def dpo_loss(policy, reference_policy, chosen, rejected, beta):
# 计算log概率比
log_ratio_chosen = log(policy(chosen)) - log(reference_policy(chosen))
log_ratio_rejected = log(policy(rejected)) - log(reference_policy(rejected))
# DPO损失:最大化chosen和rejected之间的差距
loss = -log(sigmoid(beta * (log_ratio_chosen - log_ratio_rejected)))
return loss
```
## 具体训练示例
### 1. **SFT训练**
```python
# 数据:人类写的标准答案
data = {
"prompt": "如何学习编程?",
"response": "学习编程需要:1)选择语言 2)动手实践 3)坚持练习"
}
# 目标:让模型输出和人类标注一样的答案
loss = cross_entropy(model_output, human_answer)
```
### 2. **GRPO训练**
```python
# 数据:模型生成的多个答案 + 奖励分数
prompt = "如何学习编程?"
responses_with_rewards = [
("学习编程需要:1)选择语言 2)动手实践 3)坚持练习", 0.9),
("多写代码就行", 0.4),
("看书学习", 0.3),
("不知道", 0.1)
]
# 目标:让模型更倾向于生成高分答案
loss = grpo_clip_loss(normalized_rewards)
```
### 3. **DPO训练**
```python
# 数据:人类偏好对
preference_pair = {
"prompt": "如何学习编程?",
"chosen": "学习编程需要:1)选择语言 2)动手实践 3)坚持练习",
"rejected": "多写代码就行"
}
# 目标:让模型更喜欢生成chosen而不是rejected
loss = dpo_loss(chosen, rejected)
```
## DPO的优势
### 相比传统RLHF
- ✅ **简单高效**:不需要训练奖励模型
- ✅ **稳定性好**:避免了PPO的不稳定性
- ✅ **计算效率高**:一步到位,不需要两阶段训练
### 相比SFT
- ✅ **更灵活**:不需要标准答案,只需要偏好
- ✅ **更自然**:人类更容易比较两个答案的好坏
### 相比GRPO
- ✅ **质量保证**:使用人类偏好,而不是自动评分
- ✅ **直接优化**:不需要设计奖励函数
## 三种方法的使用场景
### **SFT适用于**
- 有明确标准答案的任务
- 需要精确模仿人类行为
- 初始训练阶段
### **GRPO适用于**
- 需要大规模自动化训练
- 有可靠的奖励函数
- 想要探索更多可能性
### **DPO适用于**
- 有人类偏好数据
- 想要直接优化偏好
- 需要稳定高效的训练
## 实际应用中的组合
```python
# 1. 先用SFT让模型学会基本能力
model = sft_training(human_annotated_data)
# 2. 用DPO根据人类偏好进一步优化
model = dpo_training(model, preference_data)
# 3. 用GRPO进行大规模自我改进
model = grpo_training(model, reward_function)
```
## 总结对比
|特性|SFT|GRPO|DPO|
|---|---|---|---|
|**对齐对象**|标准答案|高分答案|偏好答案|
|**数据需求**|人类标注|自动生成|人类偏好|
|**训练方式**|监督学习|强化学习|偏好优化|
|**复杂度**|低|高|中|
|**稳定性**|高|中|高|
|**可扩展性**|低|高|中|
这三种方法各有优势,在实际应用中常常结合使用,实现更好的模型对齐效果。