上一篇结尾我们留了个尾巴:预训练完的模型只是个「超级续写打字机」------你问它问题,它不一定会回答,反而顺着话头续写。今天要讲的 SFT(Supervised Fine-Tuning,指令微调),就是把「续写打字机」调教成「懂礼貌、听指挥、有逻辑的 AI 助手」的关键一步。
顺便说一句,常和 SFT 一起出现的 Alignment(对齐,如 RLHF / DPO) 是更进一步的工作,这篇先聚焦 SFT,把它讲透;对齐留到下一篇。
下面从数据准备、训练机制、全流程细节三个角度,看微调和预训练到底差在哪。
01 数据差异:预训练求「量」,指令微调 求「质」
1.1 规模:从 Trillions Token 到几万条对话
- 预训练 :训练数据规模在数万亿(Trillions)Token 级别------练的是模型的知识宽度,更看重数量;
- 指令微调 :训练数据是数万到数十万条高质量对话 ------练的是模型的指令遵循能力 和输出格式规范,更看重质量。
1.2 格式:从连续纯文本到「角色分明的对话」
预训练数据是 JSONL 格式的连续纯文本;但指令微调要让模型学会区分「系统指令」「用户提问」「模型回答」,所以训练数据是带明确角色标签的结构化对话 。目前业界以 OpenAI / Hugging Face 规范为核心,数据是 messages 数组------一个包含对象列表的数组,每个对象含两个核心字段:role(角色)和 content(内容)。
常见的角色定义:
- system(可选):设定全局人设、安全准则或输出格式(如「你是一个严格的代码审查专家」);
- user:人类用户输入的指令、提问或上下文数据;
- assistant:期望模型输出的标准答案(目标回答);
- tool / function(可选,Agent 场景):外部 API 或工具返回的结果。
一个典型的示例:
json
{
"messages": [
{"role": "system", "content": "你是一个严谨的翻译专家"},
{"role": "user", "content": "把这句话翻译成英文:大模型预训练需要海量算力。"},
{"role": "assistant", "content": "Pre-training large language models requires massive computing power."}
]
}
1.3 Chat Template:把 JSON「渲染」成模型认识的 Token
前面讲架构时说过:Transformer 的输入本质上是一串 token_id 序列,它根本不懂什么是 JSON,也不知道 "role": "user" 意味着什么。所以在喂给模型前,必须用 Chat Template(对话模板引擎) ,按照模型特定的特殊标记(Special Tokens),把 messages 数组「拼接/渲染」成一个带边界标识符的物理字符串。
对话模板里最重要的就是「开始」和「结束」两个特殊标记,不同模型各不相同。比如 Qwen 用的 ChatML 格式,定义了 <|im_start|> 和 <|im_end|> 两个特殊 Token,上面那段数据渲染后长这样:
text
<|im_start|>system
你是一个严谨的翻译专家<|im_end|>
<|im_start|>user
把这句话翻译成英文:大模型预训练需要海量算力。<|im_end|>
<|im_start|>assistant
Pre-training large language models requires massive computing power.<|im_end|>
这里有个 SFT 特有的细节------labels 的掩码处理:
text
inputs 序列:正常按逐个 Token 查表转换
labels 序列:system 和 user 区域全部填充成 -100(训练时不计算这部分梯度)
assistant 区域保留真实 Token ID(后续计算 Loss 和梯度)
原因很朴素:用户提问是给定的,模型不需要学会「预测用户会问什么」,
只需要学会「如何给出完美的回答」。
通过 messages 结构化定义 → Chat Template 规范渲染 → 特殊 Token 定位 Masking 这条完整链路,大模型就能在保持原有语言能力的同时,精准学会对话逻辑与格式遵循。
02 数据从哪来:AI 生成已经是主流
2.1 预训练数据:也在用 AI 提纯
预训练数据主要是从互联网爬取网页、图书和代码,再走规则清洗。但如今的主流做法里,借助 AI 对原始数据做浓缩、重写和合成,已经是业界通用且高效的手段,分三招:
- AI 浓缩(提信息密度):用高级模型把样本提炼成信息密度极高的结构化摘要,让模型消耗更少 Token 学到相同甚至更多的知识;
- AI 重写(提数据质量):把样本段改写成逻辑清晰、语法严谨的百科全书式文本,能显著提升基座模型的「智商」和语言建模能力;
- AI 合成(抹平数据鸿沟):对数学、科学论文、小语种等优质数据极度匮乏的领域,直接用高级模型批量生成高质量样本。
一条原始文本的处理流水线大致是:
text
[ 互联网原始文本 (Raw Web) ]
▼
【第一级:规则清洗】──> 去重、过滤标签
▼
【第二级:AI 质量打分】──> 按信息密度打分,过滤低质量
▼
【第三级:AI 浓缩与重写】──> 提取高价值文本
▼
【第四级:AI 合成生成】──> 补充优质样本匮乏的领域数据
▼
[ 最终放入预训练数据库 (.bin) ]
2.2 SFT 数据:对 AI 的依赖更夸张
如果说预训练数据是「AI 提纯」,那 SFT 数据基本就是「AI 生产」------行业实践中,AI 生成/提纯的 SFT 数据(Synthetic SFT Data)占比通常在 70% ~ 90% 以上 。原因很现实:纯靠人工一条条手写(Human-annotated),又贵又慢;而且 AI 在「格式遵循」和「逻辑链」上比普通标注员更稳定。这套用高级模型批量生成数据的技术,学术和工业界称之为模型蒸馏(Distillation)。
一套成熟的生产范式长这样:
text
[ 人工精筛 Seed Task 种子库 ]
▼
【第一步:Prompt 演化与裂变】──> 对种子任务增加约束 / 提高难度 / 扩展领域
▼
【第二步:AI 数据生成】──> 生成 CoT 推理链 / 格式化答案
▼
【第三步:自动化校验】──> 代码用编译器执行、数学题求解演算、格式规则校验
▼
【第四步:模型质量过滤】──> 让模型给生成的样本打分过滤
▼
【第五步:人工专家抽检/审核】──> 抽样交给人工专家把关
▼
[ 导出为标准 JSONL messages 数据集 ]
一个真实的 Seed Task(种子任务)通常包含三部分:指令(Instruction) 、可选输入(Input)和标准响应(Output):
text
Instruction: 从给定的招聘文本中,提取出职位名称、薪资范围和所需编程语言
Input: "高级后端工程师招募:负责云原生架构,月薪 30k-40k,需熟练掌握 Go 语言和 Python。"
Output: {"职位": "高级后端工程师", "薪资": "30k-40k", "语言": ["Go", "Python"]}
03 实际训练:底层一样,三个关键差异
SFT 的底层训练过程(前向传播、梯度计算、反向传播、权重更新)和预训练完全一致,真正的区别在 Loss 计算策略、数据组织方式和训练超参数上------一句话概括:
预训练是让模型学会「预测下一个词」(学语言和知识);SFT 是让模型学会「只在正确的位置回答」(学指令和格式)。
围绕这个目标,有三个关键差异:
差异 1:Loss 只算 assistant 区域。 预训练时序列里每个 Token 都参与 Loss 计算;SFT 则把 system 和 user 部分的 Label 设为 -100(Mask 掉,不计算 Loss),只计算 assistant 部分的损失。
差异 2:训练轮次不同。 预训练见过的样本太多,通常只跑 1 个 Epoch(甚至不到);SFT 数据量小,通常会跑多个 Epoch,把每一条高质量对话都吃透。
差异 3:学习率低一个量级。 学习率本质是「模型参数每次调整幅度/步长」的比例系数。SFT 的学习率通常比预训练低一个量级------从名字就能理解:预训练是从 0 到 1 学知识,步子可以迈大些;指令微调只是在已有能力上「加强练习」,步子大了反而会破坏已经学好的语言能力。
到这里,SFT 的核心就讲完了:数据上求质不求量、结构上分角色对话、训练上只对回答负责。经过 SFT 的模型,已经从「会续写」进化到「会回答」,但离真正「听话」还有最后一步------它可能还是会说出不符合人类价值观的内容。
下一篇,我们来讲最后的临门一脚:Alignment(RLHF / DPO 对齐),看模型是怎么被「对齐」成安全、有用、无害的助手。
觉得有用的话,点个赞 和在看 ,让更多做安全、做 AI 的朋友看到;也欢迎评论区聊聊你做微调时踩过的数据坑。