SFT 解决什么问题
预训练模型只学会了一件事:根据前文预测下一个 token。它可能续写文本、补全代码,但不一定听得懂“请把这段话翻译成英文”这样的指令。有监督微调(Supervised Fine-Tuning, SFT),也称指令微调(Instruction Tuning),用“指令—回答”数据把预训练模型的行为调整到人类期望的格式上。
SFT 不负责注入新知识,而是激活和整理预训练阶段已经学到的能力:让模型知道什么时候该回答、按什么格式回答、遇到不确定的问题如何表达。
与提示学习、上下文学习的关系
在 SFT 之前,让预训练模型完成任务主要有两种不更新参数的方式。
提示学习
提示学习(Prompt Learning)把任务改写成更接近预训练形式的一段文本。流程包括三步:
- 提示添加:设计模板,把输入 填入槽位,得到提示 ;
- 答案搜索:让模型在答案槽位 上给出概率最高的词;
- 答案映射:把生成的词映射回任务标签。
例如情感分析可以用模板:
我不小心错过了公共汽车。我感到[Z]。模型在 [Z] 处生成“开心”或“难过”,再映射为正面或负面。模板的措辞会显著影响结果,因此提示设计本身是一项技术。
软提示(Soft Prompt)放松了“提示必须是自然语言词”的限制,直接在嵌入空间学习一组可训练向量,作为虚拟上下文拼在输入前面。Prefix Tuning 就是其中的代表,见 参数高效微调。
上下文学习
上下文学习(In-Context Learning, ICL)在输入中给几个“示例输入—示例输出”,让模型通过类比完成新样本,不更新任何参数。它可以看作提示学习的一种:提示里不仅包含任务描述,还包含示例。
ICL 的效果依赖示例的质量、数量和顺序,对任务设置比较敏感,且受上下文长度限制。SFT 则把任务模式写进参数,推理时不需要示例,行为更稳定。
| 方式 | 是否更新参数 | 数据形式 | 特点 |
|---|---|---|---|
| 提示工程 | 否 | 手工模板 | 灵活,依赖设计 |
| 上下文学习 | 否 | 少量示例 | 无需训练,占上下文 |
| SFT | 是 | 指令—回答对 | 行为稳定,需要标注数据 |
SFT 的目标函数
给定指令数据集 ,其中:
- :指令,可包含输入;
- :目标回答。
SFT 最大化回答的对数似然:
实际训练时通常对指令部分做损失屏蔽:只对回答 token 计算损失,指令 token 的标签设为忽略值。这样模型学的是“看到指令后如何回答”,而不是复述指令。
多轮对话可以把整段对话拼成一个序列,只对助手回复的 token 计算损失;不同样本可以通过 packing 拼接到固定长度,提高训练效率。
指令数据的构建
SFT 的效果很大程度上由数据决定。好的指令数据需要满足:
- 质量:回答正确、完整、风格一致;
- 多样性:覆盖不同任务类型、领域、输入长度和难度;
- 覆盖面:包含模型实际会遇到的任务,而不是只针对评测集。
人工构建
从问答社区、文档、教材中收集高质量问答,再由标注人员筛选、改写或直接编写指令和回答。人工数据的质量最高,但成本高、规模有限。LIMA 的实验表明,少量高质量、多样化的指令数据就能显著提升模型遵循指令的能力,即“以少胜多”。
Self-Instruct 自动生成
Self-Instruct 用大模型自己生成指令数据,流程大致是:
- 准备一小批人工编写的种子指令(论文中为 175 条);
- 让模型根据种子指令生成新的任务指令,并判断它是否属于分类任务;
- 对非分类任务生成输入和输出,对分类任务生成候选标签和实例;
- 过滤与已有指令过于相似、格式错误或质量低的数据;
- 把新数据加入指令池,重复生成。
自动生成能快速扩大数据规模,但会引入噪声和模式重复,通常需要规则过滤、去重和人工抽检。常见开源指令数据集包括 Alpaca(约 5.2 万条英文)、BELLE(约 150 万条中文)等。
微调策略
全量微调
更新模型全部参数,效果通常最好,但显存和存储开销大,每个任务都要保存一份完整模型,且在小数据集上容易过拟合。资源充足、任务重要或需要大幅改变模型行为时使用。
参数高效微调
冻结大部分预训练参数,只训练少量新增参数或低秩矩阵。常见方法包括 Prefix Tuning、Adapter 和 LoRA,详见 LoRA 与 QLoRA。PEFT 显著降低显存需求,适合资源有限或多任务场景;LoRA 的效果通常接近全量微调。
特定能力微调
除了通用的指令遵循,SFT 也用于强化某方面能力:
- 长上下文:让模型适应更长的输入;
- 推理:训练模型写出中间步骤;
- 格式输出:让模型稳定生成 JSON、表格或特定模板;
- 领域适配:医疗、法律、金融等专业问答。
这类微调的数据更集中,容易导致通用能力下降,需要控制数据配比和训练轮数。
灾难性遗忘
SFT 的数据分布通常远窄于预训练语料,全量微调可能让模型遗忘预训练学到的通用知识,表现为通用任务性能下降、语言能力退化。常见缓解方法:
- 降低学习率、减少训练轮数;
- 在 SFT 数据中混入一部分预训练数据;
- 使用 LoRA 等参数高效方法,限制参数改动范围;
- 加入正则项或约束参数偏移;
- 用通用能力评测集监控退化。
训练与评估
SFT 通常使用 AdamW、较小的学习率( 量级)、1–3 个 epoch,并配合预热和余弦衰减。批次大小受显存限制时可用梯度累加。评估既看目标任务指标,也看通用能力是否退化;对于开放生成任务,常用 LLM-as-a-Judge 或人工评价,指标见 NLP 评价指标。
SFT 之后,模型已经能遵循指令,但回答未必符合人类偏好(更有用、更诚实、更无害)。这一步由 RLHF 与 PPO 或 DPO 完成。
相关阅读
- 预训练与模型架构:大模型预训练
- 参数高效微调:LoRA 与 QLoRA
- 提示工程与上下文学习:提示工程
- 人类偏好对齐:RLHF 与 PPO、DPO
- 生成任务评价:NLP 评价指标