核心结论

监督微调 (Supervised Fine-Tuning, SFT) 的成败几乎完全由数据的覆盖结构决定,而不是由数据量决定。用小模型在窄任务上超过前沿模型是可行的,但前提是该任务的难点必须是私有规则而非通用能力,并且训练数据必须覆盖规则被触发时的表面形态分布。

一句话的操作判据:训练集里「表面形态」的分布必须和测试集一致;一旦不一致,模型就会去拟合表面形态,而不是真实规则。

[WARNING] 修正(2026-09-18,见 私有规则任务上小模型 SFT 的真实上限 (The Real Ceiling of Small-Model SFT on Private-Rule Tasks))
本笔记开头"用小模型在窄任务上超过前沿模型是可行的"这个判断被后续实验收窄了:在同一个任务上,即使把数据构造做到最好(六批数据、混淆家族定向、复述抽样、权重插值),小模型最终也只有 82.0%,与公平基线 83.0% 打平,没有超过。
真正的杠杆是规则文档的完整度而不是模型大小:把策略文档写全之后,同一个前沿模型从 83.0% 涨到 92.0%。所以本笔记的适用前提应改为"规则业务方写不出来",而不是"规则私有"。规则能写出来时,正确做法是先写文档,而不是投 SFT。

先判断任务值不值得做

任务特征小模型能否超过前沿模型
闭集输出 + 硬验证 + 规则私有可以,这是主要机会
通用知识、推理、代码、数学不可以,不要浪费时间
规则公开且前沿模型能靠提示词学会很难,对方把规则写进上下文就追平
需要长尾世界知识不可以

私有规则是关键:它不在任何预训练语料里,前沿模型只能靠提示词现场猜,而 SFT 把规则烧进权重。

但公平对比要求同时给基线模型同一份显式规则文档,否则赢了也不成立。实测中把规则文档写进 system prompt 后,基线从 76% 涨到 81%,再叠加 14 个带判据的示例涨到 83%——这就是需要打败的真实门槛,而不是"基线不知道规则"时的那个虚高差距。

三类训练数据,价值差异极大

1. 自然分布数据:便宜,但覆盖不到规则边界

从真实日志取或让教师模型自由生成,得到的是最常见形态。实测这类数据只有约 10% 属于「不放规则就会判错」的样本,其余 90% 靠字面语义就能猜对,对学习规则几乎没有贡献。

2. 对抗性数据:每条强制含误导信号

生成时把规则文档喂给教师模型,要求每条满足「只看字面会判成另一个标签」,并输出 naive_label 字段(不懂规则的人会判成什么)用于程序化校验。这样能得到 100% 都是规则边界样本的数据集。

3. 表面形态定向数据:最容易被忽略、收益最大

这是最关键、也最容易漏的一类。

实测案例:某 7 分类任务里,其中一个标签(投诉升级)在测试集中全部表现为平静的疑问句——用户问「这钱该我出吗」「这单据怎么贴的」「这机器售出前是不是被激活过」,正文里没有任何「投诉 / 欺诈 / 索赔」字面词,但问题实质是诚信违规。

而第一版训练数据里同一标签的样本,66% 含有显式投诉词(「投诉你们欺诈」「去消协告你们」)。结果模型学成「有投诉词 → 投诉升级」,该类别召回只有 12%,同期前沿模型是 53%。

补入 70 条「零显式投诉词、表面像咨询、实质是诚信违规」的定向样本后,该维度才被真正覆盖。

教训:对抗性不等于覆盖。对抗性数据保证「有误导信号」,但不保证「覆盖测试集里的表面形态」。必须回头检查测试集里每个类别的语用形态(疑问句还是感叹句?有无关键词?语气强弱?),再按形态补数据。

一个反直觉的坑:不要用「另一个模型是否同意」过滤数据

第一版校验设计是「换一个模型只看正文重判标签,一致才留用」。跑下来一致率只有 65%,看起来像数据噪声。

实际不是。验证模型同样没有规则文档,推不出私有规则,所以它必然在最有价值的那批样本上不一致。用「另一个模型是否同意」当过滤器,等于专门把训练信号扔掉。

正确做法是判断判据能否推出标签(内部自洽性):给验证模型同时提供正文、标签、判据,只问「判据能否推出该标签」。实测自洽率 92.6%,剩下 7.4% 里确实存在真错误——例如规则写明「未收货价差归退款退货」,样本却标成了售前咨询。

两个信号要分开用:

  • consistent:判据与标签自洽 → 用于过滤脏数据
  • blind_label 与 label 不同(记为 hard)→ 该样本依赖私有规则,是训练信号的核心

训练集的难度配比

对抗性样本与自然样本混合,并给对抗性样本加权。实测 66% 对抗样本的混合集在规则边界类别上明显更好;纯自然分布数据会把模型带向字面模式匹配。

但不要只喂对抗样本:必须保留一部分「字面就能判对」的样本,否则模型会学到「看到关键词就选反直觉答案」这种同样错误的偏置。

评测协议必须在动手前定死

  • 冻结测试集:不参与任何训练或数据生成。生成训练数据时要把测试集文本预先塞进去重集合,防止撞车
  • 判分口径对基线宽容:思维链 (Chain-of-Thought) 模型的推理过程会复述候选标签,只取首个匹配会冤枉它;只取末个又会冤枉直答模型。逐条取「任一命中」是最宽容判法,用这个数字去比才没有争议
  • 契约合规与语义正确分开统计:闭集任务里小模型的一部分失分来自输出了闭集外的标签,这部分不需要任何能力提升,SFT 一次就能吃掉。单独度量后才知道剩下的差距是不是真能力差距
  • 用配对检验,而不是比较两个比例:同一批题目上比两个模型应当用 McNemar 精确检验,只看两者判断不一致的题目,小样本上远比比较独立比例灵敏。注意判优方向极易写反——gain 是「基线错、本模型对」,loss 是反之

训练超参经验(单卡 CPU 实测,Qwen3-0.6B)

  • LoRA 秩 r=16、alpha=32、dropout 0.05,作用在全部注意力与 MLP 投影层,0.6B 规模足够
  • 学习率 1e-4 + cosine 调度,约 100~150 个优化步即可收敛
  • 序列长度按实际长度设,不要盲目放大。分类任务含提示词约 150 token,上限设 256 足够
  • CPU 线程数设成物理核数:实测 12 线程 4.5 s/步,16 线程反而 6.0 s/步,超线程是负收益
  • 训练损失从 5.3 降到 0.65、token 准确率从 0.31 升到 0.87,属正常收敛区间
  • 0.6B + LoRA 在 12 核移动 CPU 上约 5.1 s/样本,1000 样本 2 轮约 85 分钟,不需要租 GPU

相关


本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/LLM