大模型后训练跑歪了,先回滚到哪个检查点再动手改数据

48分钟前发布

后训练跑歪,多数能救,代价在 1 到 7 天之间。先看 3 个信号分方向:格式突然不守、拒答变多、通用题掉分。方向定错了,改数据改 1 周也不见好。下面按定位、回滚、改数据、重训、验收 5 步写。

先判断歪在哪一侧

三种典型症状对应两类原因,判断只需要跑 1 组回归题。把训练前的基线答案拿出来,对同一批 50 条问题各答一遍,逐条比。

  1. 格式不守:要求输出 JSON 却给散文,或开头结尾加固定套话。这一类多在数据侧,训练样本里的回答格式不统一。
  2. 拒答变多:正常问题也说「无法回答」。这一类在对齐侧,安全样本比例过高或标注口径过严。
  3. 通用题掉分:业务题涨了、常识题掉了 5 分以上。这一类是学习率过大或轮次过多,把底座能力盖掉了。
症状先查什么常见原因改法
格式不守训练样本的答案字段模板混用、样本里带多余说明统一模板,剔除带解释的样本
拒答变多安全样本占比占比超过 20%,标注偏严压到 10% 以内,重写拒答口径
通用题掉分学习率与轮次学习率大 1 个数量级,跑了 5 轮降 1 个数量级,回到 2 到 3 轮
复读与死循环重复样本同一问答出现 3 次以上按问题去重,保留 1 条
答案变超长奖励模型偏好标注时偏爱长答案标注规范加同等信息量不比长度
机房内一台机柜的侧面特写,指示灯排列,冷色调,无标识

要备什么

救之前先把 4 样东西凑齐,缺一样就会反复试错。这 4 样在开训时就该留,事后补不回来。

  • 检查点:每 1 个 epoch 存 1 份,SFT 跑 3 轮就有 3 个点可回。只留最后 1 份的,等于没有退路。
  • 训练日志:loss 曲线、学习率、梯度范数,按步记录,用来判断是哪一步开始偏。
  • 回归题集:50 到 200 条,覆盖业务与通用两类,训练前后各跑一遍。
  • 标注规范:写明什么算合格回答,尤其是长度、格式、拒答边界 3 项。

我经手的一次微调,团队只留了最终权重,跑歪后只能从头再训,多花 2 天卡时。后面改成每轮存 1 份,同样的问题回滚 1 个点、重训 4 小时就解决了。

5 步救回来

第 1 到 2 步:定位与回滚

先跑回归题集,把掉分的题按类型分组,看集中在哪一类。接着回滚到偏之前的那 1 个检查点,用同一批题再测一遍,确认回滚后回到了基线附近。这一步通常 2 到 4 小时,占整件事的两成时间。

第 3 到 4 步:改数据与重训

改数据只改 1 个变量。样本重复就只去重,格式混用就只统一模板,别同时动 3 处,否则下次还是不知道哪一处起了作用。重训从回滚点接着跑 1 到 2 轮,学习率比原来低 1 个数量级。

  1. 去重:按问题文本做指纹,同一问题留信息量最全的那 1 条。
  2. 统一模板:答案字段只保留正文,说明性文字整段删掉。
  3. 调配比:安全样本压到 10% 以内,通用指令样本补到 20% 到 30%。
  4. 重训:从回滚点起跑 1 到 2 轮,每轮结束存 1 份检查点,跑完先测不急着发。
白板上的曲线示意图与箭头,抽象笔迹,无文字,马克笔在旁

第 5 步:验收与灰度

验收跑 3 组题:业务题、通用题、该拒答的题。三组都不低于基线才算救回来。灰度放 5% 流量跑 3 到 7 天,看用户追问率与人工兜底率,追问率高于基线 10 个百分点就说明还没好。

卡在哪:6 个卡点

  1. 只有最终权重,没有中间检查点。现象是没法回滚,解法是从头重训,同时改训练脚本加上按轮存档。
  2. 回归题集和训练集重叠。现象是测出来分数很高、上线却掉,解法是把题集里的题从训练数据里剔掉,重叠率压到 0。
  3. 改完数据没重跑基线。现象是不知道该跟谁比,解法是每次改动前先存 1 份基线快照,改完对同一批题比。
  4. 一次改 3 个地方。现象是效果好了也不知道为什么好,解法是单变量迭代,1 次只动 1 处。
  5. 学习率按预训练的量级给。现象是 1 轮就把通用能力冲掉,解法是后训练的学习率比预训练低 1 到 2 个数量级。
  6. 只在训练集上看 loss。现象是 loss 一直降、效果一直差,解法是每 100 步在保留集上测 1 次,两条曲线分开看。

救之前先做一次基线对齐

把题集固定下来

同一个问题换了问法,分数就不一样。救之前把 50 到 200 条题的问法固定,标点都别改,后面每次复测用同一份,前后才可比。

记下 3 个数字

基线版本要记 3 个数:业务题通过率、通用题通过率、平均回答长度。二次训练后这 3 个数一起看,只盯业务题的,容易把通用能力练没了还在庆祝。

留 1 份可回滚的镜像

训练环境做成镜像,依赖版本、分词器、数据版本一起打包。换机器重跑能复现,出问题时才有得比。我吃过依赖版本不一致的亏,同一份数据跑出两个结果,查了 1 天才发现是框架小版本不同。

这三件事花半天做完,后面每次救火都省 1 到 2 天。赶时间跳过这一步的,最后基本都要回来补。

重训时怎么避免再歪

  1. 每 100 步在保留集上测 1 次,曲线一有抬头就停下看数据,别等跑完 3 轮。
  2. 学习率用余弦衰减,最后 10% 的步数降到初始值的 1/10,收尾更稳。
  3. 每轮结束存 1 份检查点,命名带上数据版本号,回滚时知道回到哪一天。
  4. 改动记录写成 1 行字:改了哪一项、为什么改、预期什么变化,下次不用重新推理。

这 4 条加进训练脚本,1 次配置能用很久。我现在的习惯是每次开训先跑 200 步看曲线,形状不对就停,比跑 2 天再发现有问题是省时间。

救火时还有人爱换框架版本,想靠升级解决。版本一换,变量多出 3 个,问题反而更难定位,先把版本锁定再谈改数据。

什么情况下别救

两种情况直接重训更省。训练数据本身只有几百条、且质量参差,改不如重做;底座换过版本,旧检查点和新的分词器对不上,回滚也跑不起来。这两种情况重训 1 到 2 天能出结果,硬救反而拖 1 周。

救与不救的分界线在数据量。样本 5000 条以上、只是配比或格式出问题,值得救;样本 500 条以下、问题出在标注本身,重做标注比重训划算。

桌面上摊开的手写记录纸与笔,纸面空白,暖光

整套流程走完,1 次跑歪的处理成本能压到 1 天以内。真正省时间的是开训前那 4 样准备,检查点和回归题集留好了,后面每一步都有参照。

跑歪本身不可怕,怕的是没有可比的对象。题集固定、检查点留好、数字记下,这三件事做了,1 次故障处理 1 天能收尾。

团队里养成 1 个习惯:每次开训前把 3 个基线数字写在共享文档第一行,谁接手都能看明白上一版是什么水平。

处理完把这次的过程写 1 页纸:什么症状、改了什么、结果如何。下次遇到同类问题,翻这页纸比重新推理快,团队里也能直接复用。

本文信息核对时间:2026-11。学习率与轮次按常见 7B 到 32B 规模的后训练经验给出,具体取值按所用框架与数据规模调整。