# Summary
把模型能生成人类人为的标准答案的概率,争取拉高到 1
Supervised Fine-Tuning,监督微调
## **对齐对象**:人类标注的标准答案
```python
# SFT训练数据
prompt = "请解释什么是机器学习"
human_answer = "机器学习是人工智能的一个分支,通过算法让计算机从数据中学习。" # 人类专家标注
# 训练目标:让模型学会输出人类标注的标准答案
model("请解释什么是机器学习") → "机器学习是人工智能的一个分支,通过算法让计算机从数据中学习。"
```
## **训练过程**
```python
# SFT损失计算
loss = -log_prob(model_output, human_answer)
# 目标:最大化模型对标准答案的预测概率
```
# Notes
## 简单理解:就像教小孩说话
### 1. **输入是什么?**
```python
policy_log_probs # 模型对每个人类预期的词的"信心程度"
response_mask # 哪些词是我们要训练的(1=要训练,0=不训练)
```
**举个例子**:
输入句子:"请解释什么是机器学习"
模型输出:"机器学习是人工智能的一个分支"(人工标注的输出结果)
```Java
policy_log_probs: 模型对每个词的预测概率
policy_log_probs = [
[-2.1, -1.8, -0.5, -1.2, -2.3, -1.9, -0.8, -1.5, -2.0, -1.7, -1.1]
# 机 器 学 习 是 人 工 智 能 的 一
]
response_mask: [0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1]
↑提示词部分↑ ↑响应部分↑
```
### 2. **函数在做什么?**
#### 步骤1:计算损失
```python
masked_losses = -policy_log_probs * response_mask
```
- 只对**响应部分**(mask=1的地方)计算损失
- 提示词部分(mask=0的地方)不计算损失
#### 步骤2:汇总损失
损失最好是 0,这样模型输出就和人类预期的完全一致了
```python
loss_per_example = masked_losses.sum(dim=-1) # 每个样本的总损失
loss = torch.mean(loss_per_example) # 所有样本的平均损失
```
#### 步骤3:梯度累积
```python
loss = loss / gradient_accumulation_steps
```
- 如果梯度累积步数是4,损失就除以4
- 这样多个小批次累积起来等于一个大批次
#### 步骤4:反向传播
```python
loss.backward() # 计算梯度,准备更新模型参数
```
## 为什么要这样做?
### 1. **只训练响应部分**
- 提示词是固定的,不需要训练
- 只训练模型生成好的回答
### 2. **梯度累积**
- 内存不够时,可以用小批次
- 累积多个小批次的梯度,效果等同于大批次
## 生活中的类比
想象你在教小孩回答问题:
1. **你问**:"1+1等于几?"(提示词 - 不训练)
2. **小孩答**:"等于2"(响应 - 要训练)
3. **你评价**:只评价小孩的回答,不评价你的问题
这个函数就是在做第3步:**只对小孩的回答进行评分和训练**。
## 经典问题变体
这实际上是**条件生成**的经典问题:
- **机器翻译**:源语言→目标语言
- **文本摘要**:长文本→短摘要
- **对话生成**:用户输入→系统回复
- **SFT训练**:提示词→模型响应
**核心思想**:在给定条件下,优化输出质量。