指令微调 SFT:从“会说话“到“会干活“

发布时间:2026/10/26 1:55:55

指令微调 SFT:从“会说话“到“会干活“ 指令微调 SFT从会说话到会干活你给 Base 模型一段话“请把下面这句话翻译成英文今天天气不错。”它可能会接着写“请把下面这句话翻译成英文今天天气不错。请把下面这句话翻译成英文今天天气不错……”你当场沉默。它不是不会翻译它是没搞懂你现在是在提问不是在给它一段要续写的文本。本文的关系图Base 模型会续写不会听指令 ↓ 准备数据指令 回答带角色模板 一条条 (prompt, response) 样本 ↓ 前向 → 只对回答算 loss → 反向 学会看到「问题」就输出「回答」而不是继续编问题 ↓ Instruct / Chat 模型会听话但知识还是原来那些一、Base 模型缺的不是知识是上班经验先把一个常见的误会掰正Base 模型不是笨它只是没上过班。它读过海量文本知道语法、事实、代码、翻译甚至知道很多冷门知识。但它学到的唯一技能是接着往下写。你给它一个问句它最自然的反应不是回答而是把问句后面通常会跟什么继续写出来。所以在它眼里请介绍一下杭州不是一个问题而是一段文章的开头。它可能接着写请介绍一下杭州并说明它有哪些著名景点、适合几月份去、人均消费多少……它以为自己在帮你完善提纲其实你只是想让它说两句话。SFTSupervised Fine-Tuning监督微调干的事就是给这个读完了整座图书馆的人做岗前培训。不是重新上学是教他客户问什么你先回答问题别接着替客户提问先给结论再给理由不知道就说不知道别硬编回答完就停别没完没了。知识还是那些知识变的是什么时候开口、怎么开口。顺便说一句严格意义上的指令微调instruction tuning是 SFT 最常见的一种用法日常语境里两者基本混着叫本文也不抠这个字眼。二、SFT 到底在训什么SFT 的数据长这样指令请把下面这句话翻译成英文今天天气不错。 回答The weather is nice today.一条一条都是输入 标准答案。训练目标和预训练一模一样——还是猜下一个 Token。区别在于只对回答那部分算 loss指令部分不参与。这里有个容易望文生义的地方prompt 当然要喂给模型不然它根本不知道在回答什么。mask 掉的只是对 prompt 的预测误差不是 prompt 本身。它看得见问题只是不用为复述问题负责。这就是 SFT 最核心、也最容易被写错的一个细节。为什么要这样因为你要教的是P(回答 | 指令) 要高 P(继续编问题 | 指令) 要低如果你把指令也拿来算 loss模型就会花很多力气去学怎么把问题复述一遍——那不是你要的。你要的是一个客服不是一个复读机。所以 SFT 的本质不是往脑子里灌知识而是把条件概率的形状掰过来同样一个开头以前它倾向于继续提问现在它倾向于给出答案。用一张表对比一下维度预训练SFT数据无标注文本指令 回答对数据量几万亿 Token几万到几百万条目标猜下一个 Token同样但只算回答部分主要学到语言、知识、推理种子格式、任务、语气、边界成本极高一次低几个数量级产出Base 模型Instruct / Chat 模型一句话预训练给它能力SFT 教它把能力用出来。三、一条训练样本长什么样真实训练时一条样本不是一个字符串而是一串带角色的 Token|system| 你是助手。 |user| 中国的首都是哪里 |assistant| 北京。 |end|四个特殊标记各干各的活|system|设定人设和约束比如你是简洁的助手“只回答与客服相关的问题”|user|用户的指令|assistant|轮到模型说话了这个头本身不参与学习它只是一个发令枪|end|回答结束。没有它模型不知道什么时候该停可能一直说到天荒地老。下面这段代码把一条样本拼出来并标出哪些 Token 参与 lossimportmathfromcollectionsimportdefaultdict SYSTEM你是助手。SAMPLES[(中国的首都是哪里,北京。),(日本的首都是哪里,东京。),(法国的首都是哪里,巴黎。),(德国的首都是哪里,柏林。),(1 加 1 等于几,2。),(天空为什么是蓝色的,因为瑞利散射。),]defbuild(system,user,answer):tokens[|system|]list(system)tokens[|user|]list(user)tokens.append(|assistant|)startlen(tokens)# 从这里开始才是要学的部分tokenslist(answer)[|end|]returntokens,start ALL[build(SYSTEM,u,a)foru,ainSAMPLES]seq,resp_startALL[0]print(① 一条训练样本)print( 不学习 .join(seq[:resp_start]))print( 要学习 .join(seq[resp_start:]))print(f prompt{resp_start}个 Token回答{len(seq)-resp_start}个 Token)N,K,BOS2,0.01,|bos|Vlen({tfors,_inALLfortins}|{BOS})defpairs(tokens,n):p[BOS]*(n-1)tokensreturn[(tuple(p[i-n1:i]),p[i])foriinrange(n-1,len(p))]deftrain(sequences,n):mdefaultdict(lambda:defaultdict(int))fors,_insequences:forctx,nxtinpairs(s,n):m[ctx][nxt]1returnmdefnll(m,ctx,tok):cm.get(ctx,{})return-math.log((c.get(tok,0)K)/(sum(c.values())K*V))mtrain(ALL,N)losses[nll(m,ctx,tok)forctx,tokinpairs(seq,N)]p_losssum(losses[:resp_start])r_losssum(losses[resp_start:])p_n,r_nresp_start,len(seq)-resp_start totalp_lossr_lossprint(② loss 被谁贡献)print(f prompt{p_n}个 Tokenloss{p_loss:.2f}占{p_loss/total:.0%})print(f 回答{r_n}个 Tokenloss{r_loss:.2f}占{r_loss/total:.0%})print(f prompt 平均 loss{p_loss/p_n:.2f})print(f 回答平均 loss{r_loss/r_n:.2f})print(f 不 mask 平均 loss{total/(p_nr_n):.2f})print(f mask 后平均 loss{r_loss/r_n:.2f})真实运行结果本机实测完整脚本见code/09-sft-demo.py① 一条训练样本 不学习|system| 你 是 助 手 。 |user| 中 国 的 首 都 是 哪 里 |assistant| 要学习北 京 。 |end| prompt 17 个 Token回答 4 个 Token ② loss 被谁贡献 prompt17 个 Tokenloss 6.02占 65% 回答 4 个 Tokenloss 3.18占 35% prompt 平均 loss0.35 回答平均 loss0.80 不 mask 平均 loss0.44 mask 后平均 loss0.80这里的 n-gram 只是把 mask 的账算清楚的小玩具真实 SFT 用的是 Transformer但 loss 的定义和 mask 的逻辑一模一样。四、为什么必须 mask65% 的 loss 在教它复述问题看 ② 那段输出这是整篇最值得盯住的数字。在这条样本里prompt 有 17 个 Token回答只有 4 个。但如果不 maskprompt 贡献了 65% 的 loss。真实对话里system prompt 和多轮历史更长这个比例只会更夸张。注意这不是因为 prompt 难——prompt 的平均 loss 只有 0.35回答是 0.80。prompt 的单个 Token 更容易但它人多。17 个人一起交作业总分自然被它拉走。后果是什么模型会把大部分梯度花在怎么复述问题上而不是怎么回答问题。你训了半天它学会的是看到中国的首都是哪里就把它再写一遍看到请翻译这句话就把它再抄一遍。它成了一个非常擅长重复你说话的模型。mask 掉之后梯度只从回答那 4 个 Token 来。loss 数字看起来变高了0.44 → 0.80这不是变差是分母换成了真正要学的部分。就像考试只算大题分平均分当然会变但那才是你关心的。实现上常见做法是把 prompt 部分的 label 设成-100PyTorch 的ignore_index或者维护一个 0/1 的 loss mask。另外两个坑padding 不能被算进 loss否则模型会努力学习怎么生成空白packing 时要注意 attention mask别让后一条样本偷看前一条样本的内容。很多 SFT 翻车不是模型笨是 mask 写错了。五、数据从哪来SFT 的胜负手在数据不在模型SFT 的模型结构通常不变超参也不复杂。真正决定效果的是数据。来源优点风险人工编写质量高、意图清楚、覆盖可控贵、慢、规模有限强模型合成便宜、量大、风格统一同质化、错误被放大、许可证问题真实用户日志分布最真实、覆盖长尾隐私 / PII、噪声大、质量参差公开指令数据集起步快、可对比风格杂、领域不匹配、可能被污染人工数据是天花板但请人写一万条高质量指令-回答成本不低。合成数据是现在的主流用强模型批量生成再用规则或另一个模型筛。它能把量做起来但有两个副作用风格越来越像同一个模子以及错误会被继承和放大——老师错了学生跟着错。真实日志最宝贵因为它就是用户真正会问的东西。但里面有手机号、地址、内部项目名清洗不干净就是事故。还有一个反直觉的结论SFT 数据不是越多越好。Meta 的 LIMA 实验用一千条左右精心筛选的指令数据就训出了相当不错的指令跟随能力。这说明质量和多样性比堆量更重要。当然生产环境要覆盖的任务多几千条通常不够但十万条低质数据往往打不过一万条高质量、覆盖广的数据。数据配比也要讲究任务要杂问答、改写、总结、抽取、分类、写代码、拒答、多轮对话长度要杂一句话的问题和长文档摘要都得有要教它说不知道不然它遇到不会的也会硬编混一点预训练数据防止它在窄领域里训过头把通用能力忘了工具调用要单独教JSON 格式、参数名、什么时候该调工具这些不会凭空出现。一句话SFT 数据不是越多越好是越像你希望它面对的真实请求越好。你拿十万条写诗数据训它它写诗确实厉害你问它报销流程它可能给你写一首诗。六、训练细节低学习率、少轮次、别训忘了SFT 是微调不是重训所以有几个和预训练相反的习惯学习率要低。预训练可能用 1e-4 量级SFT 常用 1e-5 到 2e-5LoRA 可以到 1e-4。你是在给一个已经会走路的人纠正姿势不是在教婴儿站立。步子太大它会把原来会的东西也踩坏。轮次要少。通常 1 到 3 个 epoch。同一批指令反复训太多遍模型会开始背答案甚至在无关问题上也套同一个模板。小心灾难性遗忘。如果你只用客服话术训它它可能连写代码、做数学的能力都退化。常见做法是混入一部分预训练数据或者用 LoRA 这类参数高效方法只动一小部分权重。LoRA / QLoRA值得单独说一句它们不更新全部参数只训练一小块低秩适配器。好处是显存小、成本低、不容易把底座训坏而且一个底座可以挂多个 LoRA 切换不同任务。代价是上限通常略低于全量微调——但对大多数团队这个性价比是压倒性的。模板必须一致。训练时用|user|、|assistant|推理时也得用同一套。训练时一套模板、推理时另一套等于教它普通话、考它粤语。特殊 Token 还要在分词器里正确注册别让它们被拆成普通字符。评测别只看 loss。SFT 之后要看的至少有三类指令跟随该答的答了没有格式对不对事实性有没有为了像答案而编造回归原来会的任务现在还会不会。人工评测最可靠但慢LLM-as-judge 便宜但有偏见任务专用测试集最客观但覆盖有限。三样搭配着用别拿一个 loss 数字当结论。七、SFT 能给什么不能给什么能力SFT 能给吗说明听指令✅这是 SFT 的主业输出格式✅JSON、Markdown、固定字段都能教语气 / 人设✅客服、老师、编程助手都能演工具调用格式✅前提是数据里教过拒答 / 边界⚠️能教例子但不保证稳新知识⚠️能灌一点但不可靠容易变成自信的胡说实时信息❌训练数据没有就是没有复杂推理⚠️能教解题格式教不了解题能力安全对齐⚠️SFT 是起点不是全部最值得记住的是新知识这一行。你当然可以用 SFT 教它一条新事实“我们公司的报销上限是 5000 元。” 它会记住至少在训练集上。但这种方式不可靠数据一多、问题一绕、上下文一变它可能就答错而且错得很自信。事实性知识更适合放在模型外面用检索的方式在推理时喂给它。SFT 更适合教怎么回答而不是答案是什么。这就是那句话SFT 是把能力翻译成行为不是把知识灌进脑子。它能让模型会按格式回答但不能让它知道答案。一个是演技一个是台词。八、五个常见误区误区一SFT 就是给模型灌知识。不是。SFT 主要改的是行为什么时候答、怎么答、答多长、遇到不会的怎么办。知识的上限在预训练就定得差不多了。SFT 能让它像个专家但不能让它真的是专家。误区二数据越多越好。十万条低质数据可能打不过一万条高质量、覆盖广的数据。重复、同质、错误的指令数据会让模型学会一套固定的废话。先想清楚要它面对什么请求再决定收什么数据。误区三loss 越低模型越好。SFT 的 loss 只算回答部分低 loss 可能只是背下了训练集。要看留出集、看人工评测、看原来会的任务有没有退化。loss 是体温计不是体检报告。误区四随便套个模板就行。模板里的角色标记、特殊 Token、结束符都是模型学习轮到谁说话的信号。训练和推理不一致效果会莫名其妙地崩。模板不是格式问题是语义问题。误区五SFT 能替代 RLHF。SFT 教的是模仿标准答案RLHF / DPO 优化的是在两个回答里更喜欢哪个。前者教像不像后者教好不好。SFT 让模型会答题RLHF 让它答得更符合人类偏好——两件事不能互相替代。九、把这件事放回地图上把大模型的概念按依赖关系从下往上摞成几层——最底下是算力和数据往上依次是文字的表示、模型结构、训练、调用最顶上才是增强和智能体L6 智能体层 Agent / Function Calling / ReAct / 记忆 / MCP L5 增强层 RAG / 向量检索 / Rerank / GraphRAG / 微调 L4 调用层 Prompt / Few-shot / CoT / 温度 / Top-p L3 训练层 预训练 / ★ SFT ★ / RLHF / DPO / LoRA / Scaling Law L2 结构层 Transformer / 注意力 / 参数量 / 上下文窗口 / 开源闭源 L1 表示层 Token / 分词 / 词表 / Embedding L0 底座 算力 / 数据 / 成本SFT 在 L3 的中间预训练之后偏好对齐之前。顺便澄清一个容易混的点L5 里的微调指的是面向业务的领域微调和 L3 的 SFT 不在一个层面——SFT 是训练流程的一步业务微调是拿模型去适配场景的用法。往下看预训练给了它知识和语言能力SFT 只是把这些能力接到指令格式上。底座不行SFT 数据再好也救不回来底座行了SFT 才能四两拨千斤。往上看RLHF / DPO 在 SFT 的基础上继续调偏好RAG 在推理时补事实Agent 用的工具调用格式很多时候就是 SFT 教出来的。SFT 是从模型到产品的第一道加工也是性价比最高的一道。它的边界也很清楚SFT 能让模型会干活但改不了它能干多大的活。想让模型知道新事实靠检索想让模型更符合偏好靠对齐想让模型更强只能回到预训练。三条可以带走的结论SFT 教的是接口和行为不是知识。它把 Base 模型的续写能力翻译成听指令的能力。关键是 mask只对回答算 loss。不 mask大部分梯度会花在教模型复述问题上。数据质量和多样性 数量。模板一致性、防遗忘、评测比调参更能决定 SFT 的成败。《大模型概念地图》专栏 · 第 9 篇
延伸阅读

更多相关文章

2026/10/26 1:50:54

pandas 环境数据分析实战:4 个真实场景从读表到出结论

pandas 环境数据分析实战:4 个真实场景从读表到出结论 【免费下载链接】pandas Flexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much m…

2026/10/26 1:50:54

Files 内存占用优化指南:3个典型场景,实测能省多少

Files 内存占用优化指南:3个典型场景,实测能省多少 【免费下载链接】Files A modern file manager that helps users organize their files and folders. 项目地址: https://gitcode.com/gh_mirrors/fi/Files Files 是一款基于 WinUI 3 的现代文件…

2026/10/26 7:26:18

LSTM与GEE在东非植被监测中的应用与实践

1. 项目概述:当LSTM遇上GEE的东非植被监测去年在肯尼亚实地考察时,当地牧民向我展示了一本记录了30年牧场变化的笔记本。泛黄的纸页上手绘的植被分布图与气候记录,让我意识到时间序列数据对生态研究的重要性。这正是我们使用Google Earth Eng…

2026/10/26 7:26:18

UE5字典动画技术解析与优化实践

1. UE5字典动画技术解析与应用实践在虚幻引擎5(UE5)的动画系统开发中,字典(Dictionary)数据结构扮演着关键角色。不同于传统编程中的简单键值存储,UE5的字典系统深度整合了蓝图可视化编程和动画资源管理&am…

2026/10/26 7:26:18

端到端测试体系搭建:从设计到稳定的完整实践指南

我做了这么多年测试和工程效能,几乎在每个团队都见过同一个场景:周五下午,CI流水线里e2e测试又红了一片,开发群里开始互相,点开报告一看,不是hover没生效就是元素加载慢半拍。有人顺手点了"重跑"…

2026/10/26 7:26:18

MV-UMI:跨载体机器人学习的技术突破与应用

1. 论文核心思想解析:MV-UMI如何实现跨载体学习这篇论文提出的MV-UMI(Multi-View Universal Machine Interface)系统,本质上是在解决机器人学习领域的一个关键瓶颈:如何让不同形态的机器人共享学习经验。想象一下&…

2026/10/26 7:26:18

Selenium WebDriver协议与浏览器自动化核心技术解析

## 1. Selenium核心架构解析:从浏览器操作到代码执行的完整链路当你在IDE中写下driver.find_element(By.ID, "username").send_keys("test")这行代码时,Selenium在后台完成了从HTTP请求到浏览器DOM操作的全链路协同。这套诞生于2004…

2026/10/26 7:21:18

物理层与数据链路层排障:从错包计数到VLAN抓包

一台机器白天跑得好好的,晚上业务高峰就开始丢包,ping时通时断,延迟从 0.3ms 跳到 200ms 再掉回来。第一反应是查 IP 冲突、查路由、查防火墙策略,查了一整圈没问题,最后拔下网线换了一根,好了。这类事我碰…

2026/10/26 0:20:20

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/26 1:53:47

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/26 0:20:17

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/26 0:00:48

Nested Learning:解决AI灾难性遗忘的分层记忆架构

1. 为什么AI需要"记忆"能力?在传统深度学习模型中,我们常遇到一个根本性问题:模型在处理新任务时,往往会完全遗忘之前学到的知识。这种现象被业界称为"灾难性遗忘"(Catastrophic Forgetting)。想象一下&#…

2026/10/26 0:00:48

企业级大模型应用:OCR预处理、Dify编排与DeepSeek落地实战

1. 这不是“用大模型”,而是重构工作流的起点“大模型的应用和工具”——这八个字现在被贴在无数技术分享、招聘JD、内部立项书的标题栏里,但绝大多数人点进去后看到的,是零散的API调用示例、几个开源UI截图、或者一句“接入LLM就能降本增效”…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑