资讯动态

微调时loss曲线一直降,效果却变差?一文讲透loss骗人的原因与监控方案

发布时间:2026/10/24 4:45:19 来源:尧图企业网站定制
我一直有个习惯训练跑起来之后第一件事不是看准确率而是盯 loss 曲线。loss 降了心里踏实loss 不动就开始焦虑。如果你也有这种感觉那这篇文章大概率能帮你省下几周的无效调参时间——因为在微调场景里loss 这个指标不仅会骗人而且骗得有理有据、骗得让人毫无防备。它是最容易让从业者“自嗨”的指标没有之一。这不是说 loss 没用而是它的作用被我们严重高估了。这篇内容来自我自己踩过的一些坑适合正在做模型微调、指令微调或者任何深度迁移学习任务的开发者参考尤其是刚入门、习惯拿 loss 曲线当“健康指标”的朋友。1. 先搞清楚loss 到底在衡量什么1.1 你优化的是代理目标不是业务目标先复习一个老概念。深度学习里我们从来没直接优化过“业务成果”。做文本分类业务目标是准确率、召回率、F1做生成任务业务目标是回答有没有用、格式对不对、逻辑通不通做推荐业务目标是点击率、转化率。但我们训练的时候优化器手里的唯一信号是 loss——它是所有这些目标的“代理”。代理的意思是它只是近似地、间接地反映目标而不是目标本身。我常打的一个比方loss 是考卷里的“模拟题”业务指标才是“高考题”。模拟题做得好不一定高考就考得好尤其是当你发现模拟题出得和真题风格不一致的时候。微调阶段最大的问题就是我们很多人的训练流程里只有模拟题成绩loss从来不看真题成绩业务指标最后模型上线翻车了才回头找原因。1.2 loss 曲线的天然诱惑它给了你“正在变好”的控制感loss 曲线之所以诱人是因为它每一轮都在更新。你可以看着它从 2.1 慢慢降到 1.8、再到 1.5那种平滑下行带来的“掌控感”是任何指标都替代不了的。而业务指标往往不是每步都更新的——你不可能每 100 步就跑一遍完整评测集也没法实时让真人给生成结果打分。于是你只能盯着 loss用它的变化来推测模型好坏。问题是loss 的变化方向和业务指标的变化方向在微调阶段有相当高的概率是不一致的而且越接近收敛、越容易背离。我见过太多团队训练日志里 loss 一路走低看起来一切尽在掌握结果 lr_scheduler 还没走完验证集上的效果已经退化到和没训差不多。这种“loss 自嗨”几乎每个搞过微调的人都经历过只是很多人没刻意总结过为什么。1.3 loss 是训练集上的记忆信号不是泛化信号一个更本质的点训练时你看到的 loss几乎都是训练集或验证集上的经验风险。经验风险只能告诉你“模型对当前数据的拟合程度”它不能告诉你“模型在新数据上的表现”。而我们在微调场景下最关心的是后者也就是泛化能力。这就像学生每天做同一本练习册练习册上的题正确率越来越高但期末考试换成新题就不一定了。loss 下降充其量说明模型正在适应你喂给它的数据分布至于这个适应是“学会了规律”还是“背下了答案”仅凭 loss 曲线是区分不了的。要区分只能靠独立评测。2. loss 在微调场景下更容易骗人的五个原因2.1 训练集 loss 下降常常就是过拟合的开始微调阶段和预训练阶段有个本质区别预训练数据以亿计微调数据往往只有几千条到几十万条。数据量小模型容量大就极容易过拟合。过拟合的典型信号之一就是训练集 loss 持续下降、验证集 loss或验证集业务指标反向恶化。但很多人只看训练集 loss因为它每个 step 都在更新而验证集指标可能一两个 epoch 才评估一次。等验证集指标终于跑出来发现已经崩了的时候模型可能已经过拟合了好几个 epoch。我在实际项目里见过一种更讽刺的情况训练 loss 降到了 0.05验证集准确率却从 90% 掉到 60%。为什么会这样因为微调数据里往往有重复样本。模型只要记住那几千条重复数据的标准答案训练 loss 就能压得极低但这种“记忆”完全无法泛化到验证集的同分布新样本上——尤其当验证集和训练集同源采样时这种风险更隐蔽。2.2 数据噪声会让 loss 下降的方向和“正确”方向完全不同微调数据很少是干净的。指令微调数据里有错误答案、劣质翻译、标注不一致这些噪声在数据集中占比可能只有 5%但足以把 loss 的下降方向带偏。举个例子。做文本分类微调你有 1000 条样本其中 50 条标签打错了。模型开始会正常学学到后期它的 loss 在这 50 条错误样本上会显得很高。优化器为了压掉这些 loss就会调整决策边界去迎合错误标签。表现为训练 loss 继续降但验证集 F1 在某个点之后开始掉。如果你只盯着训练 loss你根本不会在正确的时间点做 early stopping而是会等它彻底过拟合。更麻烦的是很多人把训练集和验证集都放在同一个清洗流程里验证集里也有噪声。这个情况下 loss 会表现出一种“假收敛”训练 loss 和验证 loss 都降得不错但你去人工检查模型输出时会发现它在很多简单 case 上犯低级错误。因为验证集里的噪声样本把评估结果也一起“污染”了。2.3 生成任务里 loss 存在不敏感区间如果是文本生成类微调比如做指令微调loss 的欺骗性比分类任务更严重。原因在于 token 级别的交叉熵对答案质量的敏感度很低。假设一个回答有 100 个 token模型在关键的第 80 个 token 上预测错了导致整句话含义完全相反。但从 loss 的数值看这 100 个 token 里只有 1 个 token 错了loss 只上升了一点点。反过来如果模型在每个 token 上的置信度都稍微均匀一点loss 可能上升更多但生成结果反而更稳、更合理。还有一个我印象很深的点beam search 的生成质量和 loss 之间没有单调关系。我做过一个实验同一个模型loss 更低的那版 checkpoint用 beam search 生成的结果反而更差。原因在于 beam search 是逐 token 寻优的搜索过程它对模型给出的概率分布形状非常敏感而 loss 是平均化的指标它把每个 token 的误差揉在一起。一个在长尾 token 上概率稍微更准的模型loss 数值会更好看但 beam search 核心路径上的概率可能反而更差。2.4 推理策略和评测方式loss 全都管不着这点最容易被忽略loss 是在训练阶段的优化目标但模型上线后的表现取决于你和推理策略之间的配合。同一个 checkpoint温度设 0.1 和设 0.9生成结果差异巨大用 greedy decoding 还是 sampling输出风格也差很多。这些推理策略层面的变量不会在 loss 上体现分毫。更直接的场景是微调时你用的是“teacher forcing”式的交叉熵训练——也就是每个位置都喂真实的上一 token。但推理的时候模型用的是自回归生成——每一步都吃自己上一步生成的 token。训练和推理的不一致本身就是 gap 的来源。这种 gap 导致的生成质量下降loss 是一点都看不出来的。所以很多生成模型微调完loss 曲线漂亮得可以拿去当教材配图但一测实际生成就是答非所问原因就在这里。2.5 数据泄漏和“背题”现象loss 越低反而越要警惕还有一种更隐蔽的“自嗨”场景数据泄漏。比如微调数据里混入了测试集的相似样本或者用未经过去重处理的公开数据做评测。这种情况下模型并不是学会了通用的规律而是直接把评测集里的答案背下来了。背题的直接表现就是训练 loss 和验证 loss 都很低业务指标也非常高——但你换个稍微有点分布偏移的测试集效果立刻跳水。我见过有人拿着这种模型报喜号称准确率从 80% 提到了 95%结果重新整理评测集之后真实水平直接打回原形。这种数据泄漏带来的假象比过拟合可怕得多因为它会让团队误判模型的实际能力做出错误的上线决策。3. 一个真实案例loss 一直降效果却崩了3.1 背景与配置我来说一个自己经历过的案例细节做了脱敏处理但过程非常典型。当时接了一个任务要做某个领域的指令微调基座模型是一个 7B 规模的开源预训练模型训练数据大概 2 万条指令-回答对验证集 2000 条来自同一个数据源但做了去重。训练配置用的是 LoRA 微调rank 设为 16学习率 2e-4训练 3 个 epochbatch size 32混合精度。日志平台里每 100 步记录一次训练 loss每个 epoch 结束跑一次验证集 loss 和验证集上的 ROUGE-L。整套配置看得出来吗当时我心里觉得挺“标准”的问题恰恰出在这个“标准”上。3.2 过程复盘指标间完全脱节训练开始之后训练 loss 从 1.2 一路降到 0.4肉眼可见的丝滑。验证集 loss 也从 1.3 降到了 0.8看着问题不大。我甚至已经有“这次稳了”的错觉。真正发现问题是在第二个 epoch 结束后的手动抽检。我把验证集里的一部分生成结果打印出来看发现模型输出的格式已经开始出问题该分段的地方没有分段该结束的地方绕来绕去不结束甚至有些回答开始出现“呃”“嗯”这种无意义填充。但此时训练 loss 还在继续下降。到了第三个 epoch验证集 ROUGE-L 不升反降比第一个 epoch 结束时还低了 3 个点。也就是说模型在最该继续变好的阶段实际效果已经在退化而训练 loss 曲线还保持着一路向下的姿态。如果当时不看验证集生成样本只看 loss我大概率会在这个“最佳”checkpoint 上停下来然后带着一个过拟合模型上线。3.3 排查逻辑与结论回头排查最后定位到的核心原因是过拟合加上数据噪声叠加。那 2 万条数据里有一些重复度较高的模板LoRA 其实很容易把它们“背”下来导致训练 loss 越来越低。但验证集去重做得比较好模型在新样本上的泛化能力并没有同步提升一个 epoch 之后就达到最佳点了。这件事给我留下一个固定流程热身的第一个 epoch 过后每个 checkpoint 都必须做样本级抽检而不是只看指标。尤其是生成类模型人工看 20 到 30 条输出比任何单一数值指标都靠谱。你可以很快建立起“模型正在变好还是变坏”的直觉——这种直觉是 loss 曲线永远给不了你的。4. 那到底该盯哪些指标实操监控方案4.1 验证集指标优先且要与业务对齐先把原则立住验证集指标永远优先于训练集 loss业务相关指标优先于通用指标。具体做法是在训练前先明确一个“主指标”这个主指标必须和业务目标对齐。分类任务就用 F1 或准确率检索任务就用 RecallK生成任务就用 ROUGE/BLEU 作为粗筛加上人工抽检作为最终判断。主指标确定之后所有的 early stopping、checkpoint 选择、学习率调整都应该围绕它来做而不是围绕 loss。如果你的任务没有一个现成的量化指标比如“回答有没有帮助”那也要在训练前设计一个可重复的人工评价框架哪怕只是 5 级打分。没有评价框架就开始调参本质上就是闭着眼睛开车。4.2 样本级人工抽检应该固定成流程这是我个人最推荐的一种“指标”每隔固定步数比如每 500 步或每个 epoch从验证集随机抽 20 到 30 条样本把模型的输出打印出来肉眼过一遍。不要只看训练器的日志也不要只看 loss 曲线一定去“读”模型实际生成的东西。做法很简单把模型生成的文本和真实答案并排打出来快速标记是否有明显问题——格式错误、重复、跑题、幻觉。只要连续两个 epoch 的抽检结果开始变差即使 loss 还在降也该考虑回滚或 early stopping。这个操作看起来“不智能”但它能捕获到一切数值指标都可能遗漏的定性退化。4.3 辅助动态指标梯度范数、权重更新幅度、激活分布除了验证集指标还有一些训练动态指标可以作为辅助判断。第一梯度范数。训练正常时梯度范数会在一个合理区间内波动。如果梯度范数突然暴涨或归零通常意味着训练出了问题比如学习率过大、数据异常、或者已经进入了过拟合后期。第二权重更新幅度。LoRA 这类参数高效微调方法里如果权重更新的幅度大得离谱那模型原始能力可能已经被破坏生成结果往往崩坏。一个比较实用的检查方法对比微调前后的输出对同一组 prompt 做差异统计如果差异过大说明微调破坏性太强。第三激活分布或 logits 分布。如果模型输出的 logits 越来越尖锐说明模型对自己的预测越来越“自信”但这种自信不一定代表正确——尤其在过拟合时模型会变得过度自信。4.4 落地方案把指标组织到一张表里我自己的做法是训练过程中同时开三块监测面板。第一块是损失曲线包括训练 loss 和验证 loss但只作为“是否有异常波动”的粗筛。第二块是业务指标曲线比如每 K 步跑一次验证集上的主指标这个才是真正用于决策的信号。第三块是抽检面板每 K 步自动把若干条生成结果和 prompt 打印到日志里方便人工扫一眼。这三块信息合在一起才能组成一套相对完整的训练监控体系。只盯着其中任何一块都会产生盲区。顺便说一句如果你用在线日志平台记录这些指标记得在实验里同时记录数据版本、模型版本、超参数否则后面想复盘的时候会非常痛苦。4.5 early stopping 和 checkpoint 策略该怎么定基于上面的判断checkpoint 保存策略建议这样设计每个 epoch或者每隔固定步数保存一个带编号的 checkpoint绝不只在训练结束时保存一次。选择最终模型时不要在训练 loss 最低点挑也不要在最后一个 epoch 挑而是在验证集主指标最高点所在的 checkpoint 附近再精修几天。early stopping 的 patience 也建议以验证集业务指标为准而不是看 loss。比如设定“如果验证集主指标连续 2 个 epoch 没有提升就回滚到最佳点并停止训练”。这套策略看起来很保守但能杜绝“loss 自嗨”带来的大部分损失。4.6 关于学习率和收敛的一个额外提醒很多人习惯看到 loss 不降了就认为“模型已经收敛”然后提前结束训练。但微调场景里loss 不降很可能只是因为学习率过低或者数据里的噪声样本在拖后腿。这时候不是停止训练而是应该调整学习率、重新计算数据筛选策略或者干脆判定当前数据量已经不够支撑进一步优化。反过来loss 还在降也不代表应该继续训练。回到前面的案例训练 loss 一直降到底结果业务指标早就崩了。所以 loss 曲线的“趋势”只能用作训练是否稳定的参考不能用作是否应该停止的决策依据。5. 常见问题速查训练现场速查表5.1 训练 loss 一直降但验证 loss 开始上升这是教科书级别的过拟合信号没什么好犹豫的模型开始记忆训练数据但丧失泛化能力。此时优先回滚到验证 loss 最低点对应的 checkpoint然后考虑减少训练轮数、增加数据增强、提高 dropout或者引入早停机制。但如果验证 loss 上升的同时验证集业务指标也在上升那就出现了“指标背离”现象。这种情况偶尔会发生通常是因为业务指标和 loss 的度量方式不一致——比如分类任务里 F1 对阈值不敏感而 loss 对置信度很敏感。这种时候以业务指标为准不用过度关注 loss 的上升。5.2 loss 震荡很剧烈正常吗要看阶段。训练初期 loss 震荡大是正常的尤其是学习率比较高时。但到训练中后期如果训练 loss 还是大幅震荡就要排查了batch size 是否太小、学习率是否需要衰减、数据里是否存在标注噪声大的样本。这里有个经验值供参考如果训练 loss 的震荡幅度和它的绝对值在同一个量级问题比较大。应该先降到一个小数量级再做进一步判断。5.3 两个任务的 loss 能直接比大小吗不能。loss 的绝对数值和任务类型、数据规模、token 数量、标签分布都有关系跨任务比较 loss 没有意义。我见过有人搞对比实验时把 A 任务的 loss 0.5 和 B 任务的 loss 0.2 放在一起比较得出结论说 B 任务“训得更好”。这个结论站不住脚因为两个任务的 loss 量纲都不一定相同。正确的比较方式是只看同一个任务、同一种数据分布下的相对变化而不是跨任务比绝对值。5.4 loss 不降了但我觉得还能继续训那你的“觉得”不能只建立在感觉上。先确认三件事学习率是否还有下降空间、验证集业务指标是否还在上升、人工抽检是否还在改善。如果这三件事都还在往好的方向发展那继续训练没问题。如果业务指标已经不再提升即使 loss 还能降也不建议继续——你大概率只是在过拟合的边缘反复试探。5.5 怎么判断过拟合和欠拟合欠拟合的表现是训练 loss 和验证 loss 都很高业务指标低于预期。过拟合的表现则是训练 loss 很低、验证 loss 高并且两者之间存在明显 gap。有个更细的经验如果训练 loss 已经降到接近 0 但验证 loss 还很高说明模型容量大、数据不够或正则化不足优先增加数据或正则项。如果训练 loss 降不下去、验证 loss 也跟着高可以考虑增大模型容量、调低正则、或检查数据质量。6. 写在最后的个人经验6.1 我踩过几次坑之后形成的固定动作我现在做微调时的固定动作是训练开始前先手工看 30 条验证集真实样本每个 epoch 结束打印 20 条新样本的输出对比训练结束后回滚到验证集指标最佳的 checkpoint再做 100 条脱敏样本的人工评测。只有这套流程全部走完我才会把模型交给下一环节。我知道这个流程“很重”但微调阶段的隐性成本本来就很高。一次错误的 early stopping、一个被 loss 曲线误导的选择浪费的不仅是训练时长还有后续评测、人力抽检、部署回滚的整个链路。相比之下多花十几分钟看样本输出真的是最便宜的保险。6.2 最后的自检问题清单每次训练准备结束前我都会问自己几个问题如果我现在把模型上线它会不会在训练数据之外的世界里犯低级错误如果只给一个指标来判断模型好坏我会选 loss 吗如果验证集换一批数据我的结论还成立吗这三个问题里只要有一个回答得不踏实就说明训练监控体系还有漏洞。而这个漏洞的根源往往就是一开始太信任那个看起来永远在下降的 loss 曲线。希望这篇内容能让你在下次微调时少走一段“自嗨”的弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑