参考:
- 大模型训练三阶段总览(Pre-Training、SFT、RLHF 关系)
- LLaMA-Factory 官方文档
定义
SFT(Supervised Fine-Tuning,监督微调):在预训练模型基础上,用人工标注的高质量 (prompt, response) 数据做有监督训练,让模型从「通用」转向「特定任务可用」。
| 阶段 | 数据 | 目标 |
|---|---|---|
| Pre-Training | 海量无标签连续文本 | 学习语言规律、世界知识、生成能力 |
| SFT | 任务相关的 (问题, 答案) 对 | 学会按指令回答问题、格式化输出 |
| RLHF | 人类偏好数据 | 对齐价值观、提升体验 |
为何需要 SFT
- 指令遵循:预训练模型不一定按「指令 → 回答」模式输出,SFT 教会这一模式
- 格式规范:输出结构(如 JSON、步骤列表)需通过样例学习
- 领域适配:垂直场景(法律、医疗、代码)需注入领域知识与表述方式
- 为 RLHF 打基础:对齐类训练通常在 SFT 模型上进行
原理与公式
数学目标
语言模型用自回归生成:给定前文 $x_1,\ldots,x_{t-1}$,预测下一个 token $x_t$ 的分布。SFT 的数据形式为 $(c, r)$,其中 $c$ 为上下文(指令+输入),$r = r_1 r_2 \cdots r_m$ 为期望的回答。
目标:最大化模型生成 $r$ 的似然,等价于最小化负对数似然:
$$\mathcal{L}_{SFT}(\theta) = -\sum_{t=1}^{|r|} \log P_\theta(r_t \mid c, r_{1:t-1})$$
其中 $r_{1:t-1}$ 表示 $r_1$ 到 $r_{t-1}$。
与预训练的区别:预训练在整段文本上对所有 token 算 loss;SFT 通常只对 response 部分算 loss,prompt 部分不参与(见下节)。
Loss Mask:只对 response 算 loss
完整输入序列为:[BOS] prompt [sep] response [EOS]。若对整个序列算 loss:
- 模型会学习「如何生成 prompt」,但推理时 prompt 由用户提供,无需模型生成
- 容易学到「复述问题」等无效模式,浪费算力且影响质量
正确做法:只对 response 部分计算 loss,prompt 对应位置的 loss 置为 0(不参与梯度)。
实现:CrossEntropyLoss 支持 ignore_index。将 prompt 位置的 label 设为 -100(PyTorch 默认忽略),response 位置的 label 为真实 token id。
1 | input_ids: [BOS] p1 p2 p3 ... [sep] r1 r2 r3 ... [EOS] |
只有 $r_1, r_2, \ldots$ 参与 loss 计算与反向传播。
从公式到实现
设完整序列为 $s = [s_1,\ldots,s_n]$,其中 $s_1,\ldots,s_k$ 为 prompt,$s_{k+1},\ldots,s_n$ 为 response。
- 前向:模型输出 logits $\hat{y}_t = f_\theta(s_{
- Loss:仅对 $t \in [k+1, n]$ 计算交叉熵:
$$\mathcal{L} = -\sum_{t=k+1}^{n} \log P_\theta(s_t \mid s_{ 实现要点: 若 斯坦福 Alpaca 的标准字段: 数据文件:JSON Lines( 多轮对话常用字段: 为何需要两类: 选型建议:指令模型底座通常先用 Alpaca 类数据打指令能力,再混入 ShareGPT 提升多轮体验;纯单轮任务用 Alpaca 即可。 LLaMA-Factory 通过 Alpaca 风格配置示例: ShareGPT 风格:使用 硬件:7B 模型 LoRA 微调,建议 24GB 显存(如 RTX 3090/4090);QLoRA 可降至 12GB 左右。 Step 1:创建 Step 2:编辑 复制官方示例并修改,例如 关键参数: 或使用 训练结束后,LoRA 权重保存在 在 WebUI 中选择训练好的 adapter 路径,加载后即可对话测试。 合并 LoRA 到基座(可选): LoRA(Low-Rank Adaptation):在原有线性层旁路增加低秩矩阵 $B \cdot A$,训练时只更新 $A, B$,原权重冻结。 $$W' = W + B \cdot A, \quad A \in \mathbb{R}^{r \times d}, B \in \mathbb{R}^{d \times r}$$ 优点:显存占用小、训练快、易于切换不同 adapter;缺点:表达能力略弱于全参微调。 QLoRA:基座模型用 4-bit 量化加载,LoRA 用 fp16/bf16 训练。显存可再降一半左右,适合单卡 12GB 场景。 配置中设置
labels:prompt 段填 -100,response 段填真实 token idmodel(input_ids, labels=labels) 或 CrossEntropyLoss(ignore_index=-100) 计算 loss▸常见坑
labels 与 input_ids 错位(例如 labels 比 input_ids 少一位),会导致预测与标签不对齐。通常做法是 labels[i] 对应预测 input_ids[i+1],即 labels 整体左移一位,最后一个 token 不参与 loss。
数据准备
Alpaca 格式
字段
必填
说明
instruction
是
指令/问题
input
否
附加输入(可为空)
output
是
期望回答
1
2
3
4
5{
"instruction": "解释什么是机器学习",
"input": "",
"output": "机器学习是人工智能的一个分支,使计算机能够从数据中学习并改进,而无需显式编程..."
}1
2
3
4
5{
"instruction": "将以下英文翻译成中文",
"input": "Machine learning is a method of data analysis.",
"output": "机器学习是一种数据分析方法。"
}.jsonl),每行一个 JSON 对象;或 JSON 数组 [{...},{...}]。
ShareGPT 格式
字段
说明
conversations
列表,每项含
from(human/gpt)和 value(内容)
system
可选,系统提示
1
2
3
4
5
6
7
8{
"conversations": [
{"from": "human", "value": "什么是 SFT?"},
{"from": "gpt", "value": "SFT 是监督微调,用标注数据对预训练模型进行二次训练..."},
{"from": "human", "value": "和预训练有什么区别?"},
{"from": "gpt", "value": "预训练用无标签文本学习通用知识;SFT 用 (问题, 答案) 学习特定任务..."}
]
}
格式对比
维度
Alpaca
ShareGPT
结构
单轮:instruction + input → output
多轮:conversations 列表,human/gpt 交替
典型场景
指令跟随、单问单答、格式转换
多轮对话、追问、上下文依赖
优势
结构简单,易于构造与清洗;单轮 loss 清晰
保留对话流,模型学会多轮交互、指代消解
劣势
无多轮能力,复杂任务需拆成多单轮
数据来源多为爬取对话,质量参差;格式复杂
数据来源
人工构造或 GPT 生成(如 self-instruct)
用户与 ChatGPT 等产品的真实对话导出
dataset_info 配置
data/dataset_info.json 注册数据集。新建数据集时需:
data/ 下放置数据文件(如 my_sft.jsonl)dataset_info.json 中增加配置,指定列名映射与模板1
2
3
4
5
6
7
8
9
10
11{
"my_sft": {
"file_name": "my_sft.jsonl",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output",
"system": "system"
}
}
}
prompt:对应 instructionquery:对应 input(可为空)response:对应 outputsystem:可选系统提示sharegpt 格式,columns 中指定 messages 等字段,详见官方文档。
数据质量
LLaMA-Factory 实践
环境准备
1
2
3
4
5
6
7
8
9
10# 1. 克隆
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
# 2. 创建环境
conda create -n llama_factory python=3.10 -y
conda activate llama_factory
# 3. 安装依赖(含 metrics,可选)
pip install -e ".[metrics]"
准备数据
▸数据准备示例
data/my_sft.jsonl:1
2{"instruction": "什么是 SFT?", "input": "", "output": "SFT(监督微调)是在预训练模型基础上,用标注数据做有监督训练,使模型适配特定任务。"}
{"instruction": "解释机器学习中的过拟合", "input": "", "output": "过拟合指模型在训练集上表现很好,但在测试集上泛化较差,通常因模型过于复杂或训练数据不足导致。"}data/dataset_info.json,添加:1
2
3
4
5
6
7
8
9
10{
"my_sft": {
"file_name": "my_sft.jsonl",
"columns": {
"prompt": "instruction",
"query": "input",
"response": "output"
}
}
}
训练配置
examples/train_lora/llama3_lora_sft.yaml,新建 my_sft.yaml:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37### 模型
model_name_or_path: meta-llama/Meta-Llama-3-8B-Instruct # 或本地路径
### 训练阶段与微调方式
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
### 数据集
dataset: my_sft
template: llama3
cutoff_len: 1024
max_samples: 1000
overwrite_cache: true
### 输出
output_dir: saves/llama3-8b-lora-sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
### 训练超参
per_device_train_batch_size: 1
gradient_accumulation_steps: 8
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
### 验证
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500
参数
说明
典型值
finetuning_typelora / qlora / fulllora 省显存
lora_targetLoRA 作用的模块
all 或 q_proj,v_proj
cutoff_len最大序列长度
512–2048
learning_rate学习率
1e-4 ~ 5e-5
num_train_epochs训练轮数
2–5
启动训练
1
llamafactory-cli train my_sft.yaml
examples 下已有配置:1
llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml
output_dir 下。
推理验证
1
2
3
4
5# Web UI 对话
llamafactory-cli webui
# 或 API 服务
llamafactory-cli api1
2
3
4llamafactory-cli export --model_name_or_path meta-llama/Meta-Llama-3-8B-Instruct \
--adapter_name_or_path saves/llama3-8b-lora-sft \
--template llama3 \
--export_dir ./merged_model
LoRA / QLoRA
LoRA 原理
QLoRA
finetuning_type: qlora 即可。
选型
显存
模型规模
建议
12GB
7B
QLoRA
24GB
7B–8B
LoRA 或 QLoRA
40GB+
7B–13B
LoRA,batch 可更大
80GB+
13B–70B
LoRA;全参需多卡
常见问题
Loss 为 0 或 NaN
dataset_info 中列名与 JSON 字段对应正确过拟合
num_train_epochslora_dropout、加 weight_decay只会复述问题
### 回答:\n 后才是 response)显存不足
per_device_train_batch_size,增大 gradient_accumulation_stepscutoff_lenfinetuning_type: qlora
小结
环节
要点
原理
最大化 response 的似然;只对 response 算 loss,prompt 用 -100 mask
数据
Alpaca(instruction/input/output)或 ShareGPT 多轮;注意列名映射
实践
LLaMA-Factory:dataset_info → 配置 yaml →
llamafactory-cli train
选型
显存紧张用 QLoRA;一般场景 LoRA 即可


