SFT 从零写 — 训练信号怎么只落在回答上
这一章讲三件事: SFT 的监督信号到底是什么;一份「问题+回答」怎么被加工成机器能吃的形状; 以及怎么确认模型真的变了。 这一章跟着原书把训练循环亲手写一遍——每个循环不到一百行,单卡能跑,代码逐行讲。 读完你能回答:「为什么说 SFT 只是换数据的预训练?」
1. 先看现象:损失在降,但模型学对了吗
跑训练时屏幕上最显眼的是一个不断变小的数——损失(衡量「模型的输出离目标差多远」的一个数,下一节讲它怎么算)。损失在降,只说明优化器(负责挪动权重、让损失变小的角色,下一节还会见到它)在干活,不说明模型学的是你想教的东西。
原书这一章的立意就是对付这件事:把训练循环拆到最简,让「训练信号怎么流进权重」看得见,再配两个探针直接看模型的输出1。这一章的主走查是一条只有一轮对话的数据:
问:「用一词总结:回答永远保持简洁。」 答:「Concise.」(简洁)
目标是 30 步训练后,模型对这句话的回答从「随机的续写」变成「Concise」。 下面每一节都在给这条走查铺一步。
2. 顶层全景
一轮对话:「问句 + 回答」
│ 对话模板:套上特殊 token,标出谁是用户、谁是回答
▼
一条 token 序列 + 一份标签(prompt 位置改成 -100)
│ 五步循环,重复 30 次
▼
模型前向算分 → 错位对齐 → 交叉熵(跳过 -100)→ 反向传播 → 优化器挪权重
│
▼
探针①:这条示范的损失从高变低
探针②:贪婪解码的文本从「别的什么」变成「Concise」
图说:机制与预训练完全相同,唯一的差别是数据——
预训练猜「互联网的下一个词」,SFT 猜「示范回答的下一个词」。
整张图只有一个核心量在动:损失。下一节讲它怎么算。
先打个预防针,那里会用到熵(衡量一份消息有多出乎意料)——名字唬人,用法朴素。
还会用到对数(把大数字的连乘压缩成连加的数学记法)。到时候我当场演示。