Logo Vincent
返回文章列表

SFT 是什么?搞懂监督微调:从数据集到训练自己的模型

大模型
SFT 是什么?搞懂监督微调:从数据集到训练自己的模型
目录

先给结论:SFT 是什么

SFT(Supervised Fine-Tuning,监督微调)就是:拿一批「输入 → 理想输出」的样本,去调整一个已经会说话的模型,让它按你要的方式回答。

如果说预训练是让模型”学会语言”,那 SFT 就是教它”听懂指令、扮演角色、输出你想要的样子”。它是训练自己模型的第一步,也是投入产出比最高的一步。

你对流程的理解基本正确,只差一个重点:

选基座 → 准备数据集 → SFT

真正的门槛不在训练本身(现在的工具几行配置就能跑),而在数据集。可以说,SFT 的成败,90% 在数据。

SFT 在整个训练流程里的位置

回到大模型训练的三阶段:

阶段做什么你的使用场景
预训练学语言与世界知识一般不自己做
SFT学指令、风格、行为你要做的第一步
对齐(DPO/RLHF)让输出更符合偏好SFT 之后的增强
  • 预训练决定了模型”知道什么”;
  • SFT决定了模型”怎么说话、怎么做事”;
  • 对齐决定了它”说得让人多满意”。

顺序不能乱:先 SFT,再对齐。 基座没调好就直接上 DPO,等于在歪地基上盖楼。

第一步:选一个基础模型

默认选 Instruct / Chat 版,而不是纯 Base 版。

  • 纯 Base 模型只会”续写”,不会对话;
  • Instruct 版已经过通用指令微调,能正常聊天,你是在它基础上做二次微调(领域/风格 SFT)。

常见选择:

基座特点
Qwen2.5-1.5B / 7B / 14B-Instruct中文强、生态好、可商用,最推荐
Llama 3.1/3.2 8B / 3B-Instruct英文强、社区大
GLM、Yi、DeepSeek 系列视语言和数据而定

选多大?从 7B 起步,先用 LoRA 跑通;效果不够再考虑 14B,或改用全量微调。

第二步:准备数据集(核心)

数据长什么样

SFT 数据就是一条条”示例对话”。主流有三种格式:

① Alpaca 格式(单轮)

{
  "instruction": "给出一段角色扮演的回复",
  "input": "今天工作好累",
  "output": "听起来你今天真的辛苦了,要不要跟我说说发生了什么?"
}

② 多轮对话格式(ShareGPT / messages)——微调助手类模型更常用

{
  "messages": [
    { "role": "system", "content": "你是小雅,温柔、会倾听的虚拟伴侣。" },
    { "role": "user", "content": "今天工作好累" },
    { "role": "assistant", "content": "听起来你今天真的辛苦了,要不要跟我说说?" },
    { "role": "user", "content": "老板又临时加需求" },
    { "role": "assistant", "content": "又是这样……你当时是不是特别想翻白眼?" }
  ]
}

③ ShareGPT 格式

{
  "conversations": [
    { "from": "human", "value": "今天工作好累" },
    { "from": "gpt", "value": "听起来你今天真的辛苦了……" }
  ]
}

三种只是外壳不同,本质都是「上下文 → 期望回复」。

一个必须搞懂的关键点:只对 assistant 算 loss

训练时,只有 assistant(模型要生成的部分)参与 loss 计算,user 和 system 部分要 mask 掉(label 设为 -100)。

为什么?因为你要教的是”模型该怎么回答”,而不是”用户会怎么说话”。如果不 mask,模型会连用户的口吻一起学,甚至学成自己问自己答。

好消息是:主流框架(TRL、LLaMA-Factory)用多轮格式时会自动完成 masking,你只要用对的数据格式就行。

数据从哪来

  • 人工标注:质量最高,成本最高,适合少量精品
  • 真实业务日志:量大、真实,但必须清洗(去重、脱敏、去低质、按会话重建)
  • 强模型合成(蒸馏):用效果好的大模型批量生成,再人工/规则筛选,性价比高
  • 开源数据集:直接可用,但通用,通常要混入自己的数据

数据量要多少

  • 从几百到几万条都能显著见效;
  • 有研究证明,约 1000 条高质量数据就能让模型学会一个明确的任务;
  • 质量远比数量重要:几万条噪声数据,效果常常不如几千条精挑细选的。

清洗要点:去重、去乱码/短废句、统一角色设定、平衡不同类型、剔除评测集(数据泄漏会让你误判)。

第三步:开跑——全量还是 LoRA?

方式说明适合
全量微调更新所有参数,效果上限高数据多、算力足
LoRA / QLoRA只训少量附加参数,显存省个人/小团队首选

工具上,基本轮不到你手写训练循环:

  • LLaMA-Factory:配置即用,最省心;
  • Unsloth:单卡提速省显存;
  • Hugging Face TRL:SFTTrainer,灵活;
  • Axolotl:配置化,社区活跃。

一个 LLaMA-Factory 的 LoRA SFT 配置大概长这样:

model_name_or_path: Qwen/Qwen2.5-7B-Instruct
stage: sft
finetuning_type: lora
lora_rank: 8
lora_alpha: 16
dataset: my_sft_dataset
template: qwen # 必须匹配基座的对话模板
cutoff_len: 2048
per_device_train_batch_size: 2
gradient_accumulation_steps: 8
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true

几个要盯的超参:

  • learning rate:LoRA 常用 1e-4 量级,全量微调要小得多(1e-5 量级);
  • epoch:2~3 轮通常够,太多容易过拟合;
  • chat template:必须和基座一致(Qwen 用 ChatML 格式),否则训练全白费;
  • cutoff_len / packing:长样本截断策略要合理。

训练时最常见的坑

  • 数据格式或模板不匹配 → loss 不降、模型学坏
  • 灾难性遗忘:全量微调 + 小数据 + 高学习率,会把原有能力冲掉;可混入少量通用指令数据缓解
  • 过拟合:学会”背答案”,换个问法就不会了;减少 epoch、加数据
  • 只学了格式,没学内容:数据同质化太严重
  • 训练/推理时的 system prompt 不一致:训练写”你是小雅”,推理换个设定,效果对不上
  • EOS / 截断问题:回复停不下来,或没加结束符

怎么判断 SFT 成功了

  • 建一套固定的评测集(别用训练数据);
  • 用 LLM-as-judge + 人工打分,对比 SFT 前后的输出:
    • 是否符合目标风格/人设?
    • 指令遵循是否变好?
    • 通用能力是否退化(灾难性遗忘)?
  • 只看 loss 曲线是不够的——loss 低不等于输出好。

SFT 的边界:它能做什么,不能做什么

  • ✅ SFT 擅长:改变行为、风格、输出格式、角色扮演
  • ❌ SFT 不擅长:注入新知识(用继续预训练或 RAG)
  • ❌ SFT 不负责:优化偏好、减少不喜欢的回答(用 DPO 等对齐方法)

一句话:SFT 教”怎么回答”,不教”知道什么”。

最小可跑通流程

  1. 选基座:Qwen2.5-7B-Instruct
  2. 准备数据:JSONL,多轮 messages 格式,只对 assistant 算 loss
  3. 选工具:LLaMA-Factory 或 TRL
  4. 先用 QLoRA 小规模跑通,看 loss 和输出
  5. 建评测集,对比 SFT 前后
  6. 合并 LoRA、部署(vLLM / Ollama)

流程就这么短——难的是每一步背后的数据质量和评测。把这两件事做好,SFT 本身反而最简单。

© 2026 vincentqiao.com . 保留所有权利。