模型 SFT(Supervised Fine-Tuning,有监督微调)
SFT 是在预训练基座模型上,用”指令 + 理想回答”的成对数据继续训练,让它从”会续写”变成”会听指令、会对话、会按格式输出”的关键一步。它是把基座模型装修成可用 Instruct 模型的”精装”阶段。
一句话类比:基座模型是”毛坯房”(读完整个互联网,只会接着上文往下写);SFT 是”装修”——用成千上万条”用户会怎么问、理想回答长啥样”的样本,把它训成能按人类期望作答的”精装可入住”房。这也正是 foundation_model.md 里说 “Hermes 是 SFT 的产物” 的含义。
关联:SFT 只解决”格式 / 风格 / 指令遵循”,不负责灌大量新知识——新知识靠 RAG(见
embedding_model.md)。hermes.md就是 SFT 在 Llama/Qwen 上做的产物;SFT 训练目标仍是交叉熵,见../machine-learning/cross-entropy-loss.md。
1. 为什么需要它:从”毛坯”到”能对话”
基座模型(Base)在海量文本上做自监督预训练,学到的是”下一个 token 的概率分布”,本质是个超强续写器,并不懂”按指令作答”。SFT 用人工/合成的高质量配对数据做有监督训练,把模型的对齐方式从”续写”扳到”遵循指令 + 给出理想回答”。
关键认知:训练目标没变(还是预测下一个 token / 最小化交叉熵),变的是”喂什么数据、在哪些 token 上算 loss”。SFT 是预训练的延续,不是另一种范式。
2. 核心概念
| 概念 | 含义 |
|---|---|
| 训练数据 | 成对样本:instruction(+input) → output;或多轮 system/user/assistant 对话 |
| Chat Template | 把对话转成模型训练时见过的特殊标记格式(如 `< |
| Loss Masking | 只在 assistant 的回答 token 上算 loss,prompt 部分 mask 掉不反传 |
| 全量 SFT (Full FT) | 更新模型全部参数;效果好但吃显存、易遗忘 |
| LoRA / QLoRA | 参数高效微调(PEFT):只训低秩适配器,省显存、防灾难性遗忘 |
| 数据类型 | 通用指令(OpenHermes、ShareGPT、FLAN)、领域数据、函数调用数据(如 Hermes-Function-Calling) |
3. 工作原理(训练流程)
配对数据 (instruction → output)
│
▼ 套上该模型的 Chat Template(拼成训练文本)
[模型] 前向:对整段预测下一个 token
│
▼ Loss Masking:只保留 output 部分的 token 算交叉熵
[反向传播] 更新参数(全量 or LoRA 适配器)
│
▼ 多 epoch 后 → Instruct 模型(会听指令、会按格式答)
为什么 mask prompt:如果让模型也去”预测用户问题”,它学到的是”模仿提问”而非”给出好回答”。只在回答上优化,才能把能力聚焦到”如何作答”。
4. 变体辨析:全量 vs LoRA vs QLoRA
| 维度 | 全量 SFT | LoRA | QLoRA |
|---|---|---|---|
| 更新参数 | 100% | 仅低秩矩阵(<1%) | 仅低秩矩阵 |
| 显存 | 最高(要存全量梯度/优化器状态) | 低 | 最低(基座量化到 4bit 再训) |
| 灾难性遗忘 | 风险高 | 低(原权重冻结) | 低 |
| 适用 | 数据极大、要深度改造 | 绝大多数场景 | 单卡/消费级显卡 |
实践里 LoRA/QLoRA 是默认选择:省资源、可插拔(一个基座挂多个 LoRA 适配器)、且因冻结底座而更不易忘本。
5. 基本用法(以 TRL + LoRA 为例)
from datasets import load_dataset
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import SFTConfig, SFTTrainer
from peft import LoraConfig
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B")
dataset = load_dataset("teknium/OpenHermes-2.5", split="train") # 指令配对数据
# LoRA:只训低秩适配器,省显存、防遗忘
lora = LoraConfig(r=16, lora_alpha=32, lora_dropout=0.05,
target_modules="all-linear")
trainer = SFTTrainer(
model=model,
args=SFTConfig(max_length=2048, per_device_train_batch_size=4),
train_dataset=dataset,
peft_config=lora,
# formatting_func:把样本套成模型的 chat template(system/user/assistant)
)
trainer.train() # 得到的 LoRA 权重可单独保存、即插即用# 数据长这样(Alpaca 风格)
{"instruction": "用一句话解释梯度下降",
"input": "",
"output": "梯度下降是沿损失负梯度方向逐步调整参数、最小化误差的优化算法。"}
# 多轮对话则是 system/user/assistant 交替的列表6. 典型工作流
- 想让某个基座”会听话 / 会某种格式 / 会调某类工具” → 选 SFT(而非改架构)。
- 收集或合成配对数据:通用指令 + 你的领域/函数调用样本(如
hermes.md的 FC 数据)。 - 用 LoRA/QLoRA 训练,控制学习率、保留少量通用数据防遗忘。
- 评测指令遵循/格式正确率;若要进一步对齐价值观,再上 RLHF/DPO。
7. 常见误区
- ❌ “SFT 能灌大量新知识” → 微调擅长格式/风格/指令遵循,灌新知识效率远低于 RAG,且易遗忘、易幻觉。新知识走 RAG(见
embedding_model.md)。 - ❌ “数据越多越好” → 质量 > 数量;脏数据、重复、格式不一致的害处远大于数量收益。需要多样性覆盖目标场景。
- ❌ “SFT 一定会破坏底座能力” → 过度 SFT 才会灾难性遗忘;用 LoRA、控学习率、混入通用数据可显著缓解。
- ❌ “不用对应模型的 Chat Template 也行” → 必须用该模型训练时见过的 template,否则分布偏移、效果骤降。
- ❌ “只有全量微调才有效” → LoRA/QLoRA 通常足够且更稳,除非要做极深度的领域改造。
8. 延伸阅读 / 关联概念
- 基座模型 — SFT 的输入”毛坯”;见
foundation_model.md - Hermes — SFT 的典型产物(Llama/Qwen + OpenHermes);见
hermes.md - Tool Calling — FC 能力靠在 SFT 数据里加入函数调用样本获得;见
tool_calling.md - Embedding / RAG — “灌知识靠 RAG 而非微调”的对照;见
embedding_model.md - 交叉熵损失 — SFT 的训练目标;见
../machine-learning/cross-entropy-loss.md