很多人都听过”预训练”和”微调”这两个词,但对它们到底在干什么、有什么区别,往往只有一个模糊的印象。其实,一个能流畅对话的大模型,几乎都经历了”先预训练、再微调”的过程。而监督微调(SFT),正是那个让模型从”会接话”变成”听得懂话”的关键转折点——理解了这一步,你就抓住了大模型训练流程里最重要的一环。

SFT 在整个训练流程里的位置
一个大语言模型的生命周期,通常可以分为几个阶段。理解 SFT 的位置,最好的方式是把整个流程串起来看。
第一阶段:预训练(Pre-training)。模型在海量的文本语料上做自监督学习,最常见的任务是”预测下一个 token”——给它前面的文字,让它猜下一个词是什么。这个过程让模型学会了语言本身:语法、常识、世界知识、推理的雏形。但此时模型只会”续写”,你问它问题,它可能给你续上一段不相干的话,因为它还没学会”回答问题”这件事。
第二阶段:监督微调(SFT)。这一步给模型喂的是”人工标注的指令-回答对”,比如(”把这句话翻译成英文:你好” → “Hello”)。模型学习的是:当用户给出某种指令时,我应该给出怎样的回答。这一步之后,模型才真正”听懂人话”、能按照要求办事。SFT 就是本文的主角。
第三阶段(可选):强化学习(RLHF / DPO 等)。在 SFT 之后,进一步用人类偏好或奖励信号来对齐模型的输出,让它不仅”答得对”,还”答得让人满意”——更符合人类的价值观、偏好和安全要求。
所以简单说:预训练学会”说话”,SFT 学会”听指令”,强化学习学会”说得好听”。
SFT 具体是怎么做的
SFT 的全称是 Supervised Fine-Tuning,监督微调。这里的”监督”,指的是有标注的数据——每一笔训练样本都是”输入指令 + 期望输出”的成对数据。
训练过程和预训练类似,本质还是在优化”预测下一个 token”的目标,只不过训练数据换成了高质量的人机对话。举个具体的例子,一条 SFT 训练样本可能是这样的:
用户:帮我总结下面这段话的要点…… 助手:这段话主要有三个要点:第一……
模型被训练成:看到”用户”这段话,就倾向于生成”助手”那段回答。通过成千上万条这样的高质量样本,模型逐渐学会了各种任务的通用模式——总结、翻译、问答、分类、写作、写代码等。
SFT 的关键在于数据质量。数据要覆盖足够多样的任务和表达方式,标注要准确、一致。业界常说”数据是模型的上限”,在 SFT 阶段体现得尤其明显:同样的基座模型,用高质量数据微调出来的效果,往往比用海量低质数据更好。
指令微调:SFT 的一个重要分支
指令微调(Instruction Tuning)可以看作是 SFT 的一种典型形式,它特别强调用”指令化”的格式来组织训练数据。2022 年 OpenAI 的 InstructGPT 是这一路线的标志性工作——它通过收集人工编写的指令和演示,让 GPT-3 学会更好地遵循人类意图。
指令微调的思路,是把各种 NLP 任务都统一成”指令 → 回答”的格式。比如把”情感分类”变成”请判断下面这句话的情感是正面还是负面”,把”翻译”变成”把下面的英文翻译成中文”。这种统一格式带来了一个重要的好处——模型学会的不是某一个具体任务,而是”遵循指令”这个更通用、可泛化的能力。这也是为什么经过指令微调的模型,能处理它从没专门训练过的任务:它学到的是”怎么听人话”,而不是”背答案”。
全量微调 vs 参数高效微调
说到微调,绕不开”怎么微调”的技术选择。大致可以分为两派。
全量微调(Full Fine-Tuning):更新模型的所有参数。效果上限最高,但对显存和算力的要求也最高——需要为整个模型保存梯度和优化器状态,一个 70B 的模型全量微调,需要非常可观的硬件。此外,每个任务都要存一份完整的模型副本,存储和部署成本也高。
参数高效微调(PEFT,Parameter-Efficient Fine-Tuning):只更新模型的一小部分参数,其余参数冻结。最著名的代表是 LoRA(Low-Rank Adaptation,低秩适配)——它不直接改原权重,而是在旁边加一个低秩的”旁路矩阵”,只训练这个旁路。LoRA 让微调的门槛大幅下降:显存需求骤减,一份基座模型可以配多个不同的 LoRA 适配器,切换任务只需要换一个很小的适配器文件。QLoRA 更进一步,把基座模型量化到 4-bit,把 LoRA 的显存需求再压缩,让单张消费级显卡也能微调大模型。
选哪种,通常取决于资源和对效果的要求:资源充足、追求极致效果、要深度改造模型 → 全量微调;资源有限、想快速试、要多任务复用 → LoRA/QLoRA。
为什么要做 SFT:它到底改变了什么
一个常见的疑问是:预训练模型已经很聪明了,为什么还要 SFT?
原因在于,预训练的目标和”帮助用户”的目标并不一致。预训练模型学的是”补全文本”,它不知道什么是”用户提问”、什么是”回答”。你问它”今天天气怎么样”,它可能接着你的话写一段小说。SFT 做的事,是目标对齐的第一步——把模型从”预测下一个词”重新引导到”遵循用户意图、给出有用回答”上。
具体来说,SFT 带来了几个可见的变化:模型会区分用户和助手两种角色了;它学会了任务格式,能稳定地总结、翻译、问答;它的回答风格更贴近人类期望,废话和跑题变少了。可以说,SFT 是把一个”语言能力强但不懂交流”的模型,变成一个”能正常对话的助手”的那一步。
SFT 之后:为什么还需要强化学习对齐
SFT 让模型”会答”,但”会答”不等于”答得让人满意”。SFT 只能学到”参考答案是什么样”,却很难刻画”哪个回答更好”这种排序偏好。比如两个回答都对,但一个更简洁、更礼貌、更安全,SFT 不容易学会这种细微的优劣——因为 SFT 的数据是”标准答案”,而不是”哪个更好”的对比信号。
于是有了 RLHF(基于人类反馈的强化学习):先让人类对多个回答排序,训练一个”奖励模型”,再用强化学习让模型去最大化这个奖励。RLHF 解决的是 SFT 解决不了的”偏好对齐”问题。后来的 DPO(直接偏好优化)则简化了 RLHF 的流程,直接用偏好数据做优化,不需要单独训练奖励模型。
所以完整的对齐链条通常是:预训练 → SFT(学会听指令)→ RLHF/DPO(学会对齐偏好)。三者各司其职,缺一环都会让最终体验打折扣。
自己动手做 SFT,要注意什么
如果你打算给自己的业务微调一个模型,有几件事值得提前想清楚:
- 数据是核心:先把精力花在收集、清洗、标注高质量的指令-回答对上,而不是急着调参。数据脏,怎么调都白搭。
- 选对基座模型:基座模型的底子决定了上限。选一个和你任务领域相近、本身能力够强的开源模型,能省很多事。
- 评估要跟上:微调前后用同一套测试集对比,确认真的变好了,而不是”感觉变好了”。
- 警惕灾难性遗忘:微调可能导致模型忘记原有的通用能力。用 PEFT(如 LoRA)通常能缓解这个问题,同时保留基座能力。
- 控制过拟合:数据量小、训练太久,模型容易只背下训练样本、泛化变差。要监控验证集表现,及时早停。
SFT 数据是怎么来的:数据构建是门手艺
SFT 的效果,很大程度上由数据质量决定。而高质量的数据,不是随便抓来的,需要精心构建。
数据来源:SFT 数据通常有几种来源。一是人工编写——让标注员手写高质量的指令和回答,质量最高但成本也最高;二是从已有的高质量问答、客服对话、社区优质回答中筛选;三是用更强的模型”合成”数据——让一个能力强的模型生成指令和回答,再人工筛选,这是目前性价比很高的一种方式。许多开源模型用合成数据配合人工过滤,做出了不错的效果。
多样性与覆盖度:数据要覆盖足够多样的任务类型——问答、总结、翻译、写作、代码、推理、多轮对话等。如果数据太单一,模型就会”偏科”,在没见过的任务类型上表现差。业界常说”SFT 数据要广”,就是这个意思。
质量与一致性:数据的标注要准确、格式要统一。一条答错的样本,比十条平庸的样本危害更大——模型会学走错误的模式。所以数据清洗、去重、一致性检查,是 SFT 数据构建里最耗时也最关键的环节。
一句话总结:SFT 是”数据驱动”的,数据的天花板就是模型的天花板。很多团队花在数据上的时间,远多于花在训练本身上的时间。
SFT 的训练细节:它到底在优化什么
SFT 在训练时,其实和预训练用的是同一种基础方法——梯度下降优化”预测下一个 token”的目标,只不过数据换成了指令-回答对。
具体来说,模型看到一条样本的”指令”部分,然后要预测”回答”部分的每个 token。损失函数计算的是”模型预测的回答”和”真实回答”之间的差距,通过反向传播更新参数。通常只对”回答”部分计算损失,指令部分不参与损失计算——因为我们要训练的是”怎么回答”,而不是”怎么提问”。
训练时还有几个关键超参数:学习率(lr)通常比预训练小几个数量级,因为基座模型已经很好了,只需”微调”而非”重学”;训练轮数(epoch)一般不多,1 到 3 轮居多,轮数太多容易过拟合——模型把训练数据背下来了,反而丧失泛化能力。所以 SFT 讲究”小火慢炖”,而不是”大火猛煮”。
LoRA 到底”低秩”在哪:原理拆解
LoRA 是参数高效微调里最流行的技术,它背后的数学思想其实很优雅。
LoRA 的核心假设是:微调时,模型权重的”变化量”是低秩的——也就是说,不需要更新完整的权重矩阵,只需要更新一个低秩的小矩阵,就能近似捕捉到微调所需的大部分变化。
具体做法是:对原权重矩阵 W(比如 4096×4096),冻结它不动,在旁边加一个”旁路”,由两个小矩阵 A 和 B 相乘组成(比如 4096×r 和 r×4096,其中 r 是一个很小的秩,常见取 8、16、32)。前向传播时,输出等于原权重 W 的输出,加上旁路 A×B 的输出。训练时只更新 A 和 B,不动 W。
因为 r 远小于原始维度,A 和 B 的参数总量极小——可能只占原模型的百分之零点几。这就是为什么 LoRA 能用极少的可训练参数,实现接近全量微调的效果,同时显存占用大幅下降。训练完成后,旁路可以合并回原权重(W + A×B),推理时零额外开销;也可以单独保存为一个小文件,随时挂载到同一个基座模型上,实现”一份基座 + 多个适配器”。
QLoRA:把 LoRA 再压缩一步
QLoRA 在 LoRA 的基础上又往前走了一步,核心是”量化”——把基座模型的权重用 4-bit 精度存储(NF4 格式),从而大幅降低显存占用。
这样做的好处是革命性的:原本需要多张 A100 才能微调的 65B 大模型,用 QLoRA 可以在单张消费级显卡(如 48GB 或更小)上完成。它把”微调大模型”的门槛,从”大厂专属”拉低到了”个人开发者也能玩”。
QLoRA 的关键技巧包括:用 NF4(NormalFloat4)这种专门设计的 4-bit 格式来存权重,损失比普通 INT4 更小;用双重量化进一步压缩;以及用分页优化器(paged optimizer)来处理训练中的显存峰值。这些技术叠加起来,让 QLoRA 在几乎不损失效果的前提下,把微调的显存需求压到了极致。
所以,从全量微调到 LoRA 再到 QLoRA,本质上是一条”用更少的资源,逼近同样效果”的演进线,也是”大模型微调平民化”的技术基础。
SFT 和「继续预训练」的区别
很多人把”微调”当成一个笼统的概念,但其实里面至少有两件不同的事,容易混为一谈。
SFT(指令微调):目标是把模型对齐到”听懂指令、完成任务”。它用的是指令-回答格式的数据,训练后模型学会了对话和任务格式。
继续预训练(CPT,Continue Pre-Training):也叫领域预训练,是在基座模型上,用某个特定领域的海量文本继续做”预测下一个 token”的自监督训练。它的目标是让模型”懂某个领域”——比如医疗、法律、金融的专有知识和术语,而不是教它对话。
两者的区别在于:SFT 改变的是”行为”(怎么回答问题),CPT 改变的是”知识”(懂不懂某个领域)。实际项目里,如果模型在你的领域知识不足,先做 CPT 补知识,再做 SFT 调行为,是一个常见的组合。只做 SFT 而知识不足,模型可能”格式对了,内容错了”。
SFT 常见误区
- 数据越多越好:错。低质量的脏数据会拉低模型,海量平庸数据不如少量高质量数据。数据质量优先于数据数量。
- 训练越久越好:错。SFT 训练过久容易过拟合,模型只会背训练集、泛化变差。要监控验证集,及时早停。
- 微调能解决一切:错。如果问题是”模型缺乏某领域的知识”,靠 SFT 补不回来,得先做继续预训练或引入检索(RAG)。
- 微调后就一劳永逸:错。基座模型会更新、数据会过时,微调是个需要迭代维护的过程。
怎么评估 SFT 做得好不好
微调不是”训练完就完事”,必须用一套客观的方法来验证效果,否则就是”感觉变好了”。
留出测试集:在构建数据时,就划出一部分作为测试集(hold-out set),不参与训练。训练完成后,用同一套测试集对比微调前后的表现,看是否真的有提升。
看具体任务指标:如果是分类、抽取这类有明确答案的任务,可以直接算准确率、F1 等指标;如果是生成类任务,可以用人工打分、或用更强的模型做自动评测(LLM-as-a-Judge)。
警惕”背诵式提升”:如果模型只在训练过的样本上表现好、在没见过的样本上变差,那就是过拟合了,要回退(减少轮数、降低学习率、加正则)。
看通用能力有没有退化:微调可能带来”灾难性遗忘”——模型在学会新任务的同时,忘了原来的通用能力。所以除了看目标任务,还要测一测通用问答、常识推理是否还正常。用 LoRA 这类参数高效方法,通常能显著缓解遗忘。
一句话:评估是微调的一部分,而不是微调之后的可选项。没有评估的微调,等于盲调。
ChatML:SFT 数据里的角色格式约定
做过微调的人,都会遇到一个看起来很琐碎、实则很关键的问题:一条对话数据,到底该怎么”写”给模型看?这里就涉及”对话模板”(Chat Template)的约定。
早期模型没有统一的对话格式,各家各写各的。后来 ChatML(Chat Markup Language)成为一种被广泛采用的角色标记格式:用特殊 token 明确标出每条消息是谁说的。典型的 ChatML 长这样:<|im_start|>system(系统设定)、<|im_start|>user(用户输入)、<|im_start|>assistant(模型回答),每条消息结束用 <|im_end|> 收尾。有的模型用 [INST]、<s>、<|user|> 等不同标记,但思想是相通的:把”谁在说话”这个信息,用模型能识别的 token 显式表达出来。
这件事为什么重要?因为 SFT 教给模型的核心能力之一,就是”区分角色”。如果训练数据里的角色格式和推理时用的格式不一致,模型就会”错乱”——分不清哪句是用户说的、哪句该它来答,轻则答非所问,重则把自己和用户的身份搞混。所以微调时,数据格式必须和基座模型自带的对话模板对齐;换了模板,往往需要重新微调或至少做格式适配。这也是为什么很多开源模型会明确公布自己的 Chat Template,提醒微调者”别乱改格式”。
顺带一提,system 消息(系统提示)在 SFT 里也很有讲究:它可以给模型设定人设、约束输出风格、注入规则。在数据构建时给每条样本配上合适的 system 提示,能让模型在推理时更稳定地遵循你设定的角色和规则。
小结
监督微调是大模型训练里承上启下的一环:它把预训练学到的语言能力,重新对齐到”理解指令、完成任务”上。理解了 SFT,你也就理解了大模型”为什么能听话”——它不是天生就会回答,而是被大量高质量的指令-回答对一步步”教”出来的。从数据构建、训练细节,到 LoRA/QLoRA 这些降低门槛的技术,再到评估与防过拟合的方法,这一整套流程共同决定了微调的成败。这也是为什么高质量数据、合适的微调方法(全量 / LoRA / QLoRA)和后续的对齐(RLHF / DPO)会如此重要——它们环环相扣,共同塑造了一个最终”既听得懂话、又答得让人满意”的模型。

