背景
如图:Qwen2.5-1.5B 模型在微调过程中的训练损失曲线。横轴为训练轮次(epoch),纵轴为训练损失值。可以看到在第 10 轮左右,训练损失不降反升,并呈指数式上涨趋势,最终在第 20 轮时达到约 37 的高值。这种异常的损失曲线表明训练过程出现了严重问题,模型并未正常收敛而是发生了发散。
在正常情况下,训练损失应随着训练进行逐渐降低并趋于收敛。如果出现过拟合,通常表现为训练集上的损失持续下降而验证集损失开始回升;欠拟合则表现为训练损失长期维持在较高水平且下降缓慢。而本次案例中,训练损失不仅没有下降,反而持续上升,明显不符合正常收敛范式。接下来,我们将详细分析这种训练失败现象的判断标准、可能原因以及相应的优化策略。
训练失败的表现与判断标准
训练失败通常指模型的损失在训练过程中非但不收敛,反而不断上升甚至发散。判断标准之一是训练集损失呈现持续上升趋势且没有收敛迹象。在本案例中,从第 10 轮开始训练损失骤增,即是训练发散的典型信号。与之相对,比方说过拟合会表现为训练损失下降而测试损失上升,欠拟合则是二者都居高不下 。但是当我们看到训练损失不断攀升(往往验证损失也同步上升或变得无意义),就可以判断出现了训练失败或数值发散的问题 。简单来说,损失不降反升且持续攀高是训练失败的明显标志。
失败原因分析
导致训练过程中损失发散的原因可能来自两个方面:一是优化过程中的参数设置或算法问题,二是数据方面的问题。下面从这两方面分别分析常见原因。
优化相关原因
- 学习率过高:过大的学习率是训练发散最常见的原因之一。当学习率设置过大时,每次参数更新幅度过猛,可能“跳出”了损失函数的最优解区域,导致损失不降反升 。简单来说,梯度更新步长太大,模型在最优点附近不是震荡就是直接发散 。极端情况下,过高的学习率会引发数值计算问题:例如某次更新使得某层神经元激活值过大,导致后续计算 exp(激活值) 溢出为无穷大 INF,反向传播使权重变成 NaN,之后损失就彻底飞散了 。因此,如果训练从某个迭代开始损失骤增,很可能是学习率过大引起的。
- 梯度爆炸:梯度爆炸是指在深层网络中反向传播时梯度值指数级增大,使得参数更新过大,模型无法正常学习。即使学习率适中,如果模型结构或初始化不当,也可能出现梯度爆炸现象,造成损失陡增 。例如网络过深且未采取合适的初始化或正则化时,梯度在层间累乘可能变得非常大,最终导致损失函数出现断崖式上涨 。如果训练中没有对梯度进行裁剪等控制,一次异常的梯度爆炸就能使模型发散。梯度爆炸往往和学习率过高有关联(高学习率放大了本就偏大的梯度 ),但也可能由模型本身的数值不稳定性引起。
- BatchNorm 不稳定:批量归一化(Batch Normalization)一般用于稳定和加速训练,但在某些情况下反而会引入不稳定性。如果BatchNorm层使用不当(例如批大小过小、数据分布剧烈变化等),可能导致网络输出分布波动过大,干扰训练过程。已有研究指出,在某些任务中加入BatchNorm会使训练变得不稳定甚至最终发散 。例如在生成对抗网络等对分布敏感的场景,BatchNorm可能破坏数据分布的特性,使得模型难以收敛 。因此,如果模型中大量使用了BatchNorm且训练出现发散,需要考虑BatchNorm层自身的影响(例如运行均值/方差估计不稳定 )。总的来说,BatchNorm 若未正确配置,有可能成为训练不稳定的诱因。
数据相关原因
- 数据格式错误:数据输入的格式若不符合模型预期,会导致模型学习到错误的东西,严重时使损失异常波动或发散。例如输入数据包含了非法值(NaN/Inf),或者特征的维度、归一化方式不正确,都会影响损失计算 。如果训练数据本身存在异常值,比如标签缺失或无效,模型预测会产生无效结果,进而导致loss计算出Inf或NaN 。举例来说,某些框架下如果提供的标签索引超出范围,可能出现 log(0) 这样的计算使损失变为无穷大或NaN 。因此,任何数据管道中的格式或数值错误(包括特征处理和标签处理)都可能导致训练损失的异常上升。
- 标签错位或错误:如果数据集的标签与输入没有正确对齐,模型实际上学不到正确的对应关系,损失自然无法正常降低。标签错位可能发生在数据预处理或加载阶段,例如在序列建模任务中,输入和目标序列出现偏移,或者在监督训练中样本和标签混淆。这类错误会造成模型的预测与真实标签毫不相关,损失可能维持高位甚至越训越高。更严重的是,错误标签相当于在向模型灌输噪声,会对训练造成极大的破坏性 。因此,若训练过程中损失表现异常,需要检查标签是否正确匹配到对应的输入。数据标签错误或错位往往会导致训练无法收敛,甚至比随机标签的情况更糟糕。
- 样本不均衡:训练数据中不同类别或不同类型的样本分布严重不均衡,也可能引发训练困难。模型在训练时会倾向于优化总体损失,占多数的样本类别主导了梯度方向,当某一轮碰巧遇到少数类样本时,损失可能会飙升,因为模型尚未充分学习该类样本的特征。这种样本不平衡会导致训练过程中损失震荡甚至上升。虽然样本不均衡更多地影响模型的泛化性能,但在极端情况下(比如某些罕见样本损失始终居高不下),也会拖累总体训练损失的下降。对于不均衡数据集,我们通常需要做额外处理,以使每个类别对训练的影响相近 。总之,如果数据分布不合理,模型可能难以同时顾及所有样本,从而表现为损失收敛不佳甚至反复升高。
工程应对策略
针对上述训练失败的可能原因,我们可以从优化参数和数据处理两方面采取相应的工程措施来改进:
- 调低学习率:首先考虑将学习率降低一个量级或更多。经验上,如果在训练初期(比如前100个迭代)就观察到loss出现NaN或暴涨,往往是学习率过高所致,应及时将学习率调小 。降低学习率可以减缓每次参数更新的幅度,避免“跳过”最优点。有时需要多次尝试不同数量级的学习率来找到模型稳定收敛的范围。如果原使用的是固定学习率,也可以考虑使用自适应优化算法(如 Adam、AdaGrad 等)来自动调节有效学习率,从而提高训练的稳定性。
- 使用梯度裁剪:梯度裁剪(Gradient Clipping)是一种限制梯度最大范数或最大值的方法,常用于防止梯度爆炸 。在每次参数更新前,对梯度进行裁剪(例如限制其 L2 范数不超过某一阈值),可以有效防止一次异常更新破坏整个模型 。特别是训练大规模模型或深层网络时,梯度裁剪能提供额外的安全边际。当检测到梯度出现异常增大趋势时,裁剪操作可以将其拉回合理区间,从而避免损失函数梯度爆炸导致的训练发散。
- 采用学习率 Warmup:Warmup(预热)策略指在训练开始阶段使用较小的学习率,然后再逐步提高到预设值。这样做可以让模型先以安全的步长开始学习,避免一开始由于学习率过大而发散 。具体而言,我们可以在前若干个epoch或一定数量的step内,将学习率从一个很小的值线性或指数地增加到目标学习率,再继续正常的训练过程。Warmup能够平滑地引导模型进入训练状态,尤其对非常深的网络或大模型有帮助——预热阶段限制了网络初始阶段参数剧烈发散的程度 。因此,对于像Qwen2.5-1.5B这样的大模型微调,引入适当的学习率warmup有助于稳定训练开局。
- 检查数据管道:彻底排查数据读取和预处理流程,确保输入数据和标签的格式与模型要求一致。需要验证数据集中是否存在异常值或错误标注,例如:图像数据是否正确归一化,文本数据的token是否正确对齐标签,分类标签是否在合法范围内等等。任何脏数据(NaN/Inf)或格式不符都会对训练造成干扰 。工程上,可以在训练前对数据集进行一次全面的清洗和验证,移除明显异常的样本。此外,建议在训练代码中加入断言或日志监控,一旦读入的数据出现不合理值,能够及时发现并纠正。
- 验证标签配对:针对标签错位或不正确的问题,建议取少量样本手动检查模型输入与标签是否一一对应。可以打印一些训练样本及其标签,人工确保它们匹配无误。如果是序列生成或序列标注任务,要确认对齐方式符合预期(例如offset、padding处理正确)。当发现标签有错误时,应立即修正标注或清除这些样本,因为错误标签对训练的破坏作用往往非常大 。在实践中,也可以编写单元测试让模型只训练一个batch的数据,并观察其loss能否下降——如果连单一batch都无法收敛,十有八九是数据和标签存在对应问题。
- 平衡样本分布:对于样本类别不均衡引起的训练不稳定,可采用一些策略来缓解其影响。例如,在采样时对少数类样本过采样、对多数类欠采样,或在损失函数中引入类别权重,使模型在计算loss时更加关注少数类。另一种方法是使用focal loss等改进的损失函数,让模型更关注难分类的样本,从而减小多数类主导梯度的情况。更直接的办法是在数据层面进行增强,增加少数类别的样本数量。如果条件允许,确保各类别的样本数目相对接近,以免模型过度偏向某一部分数据 。通过这些措施,减轻数据不均衡对模型优化轨迹的干扰,使训练损失曲线更加平稳。
- 监控异常值并及时停止:在训练过程中加入对loss和梯度的监控也是重要的工程手段。可以定期检查梯度范数和loss值,一旦发现loss出现异常巨大的增幅或者变为NaN/Inf,应当触发早停机制或中断训练进行排查 。例如,很多深度学习框架支持检测到NaN时自动停止训练,或者开发者可以在训练循环中手动监视。如果发生发散,保存出事时刻的模型快照和优化状态用于事后分析。检查模型的权重参数是否出现NaN或∞也是诊断手段之一 ——如果权重中已经有了NaN,说明梯度爆炸等问题已经发生,需要从最近的正常检查点恢复训练并采取上述措施(降学习率等)。总之,及时发现并停止能防止模型在错误的方向上越走越远,减少无效的计算开销。
- 调整模型及其他超参:如果经过以上排查仍无法稳定训练,可能需要审视模型本身的设计和其他超参数。比如检查网络层的设置(过深的网络是否加了残差结构来缓解梯度问题),选择合适的激活函数和初始化方法来保证数值稳定。对于BatchNorm层导致的不稳定,可以尝试增大批量大小以获取更稳定的均值/方差估计,或者缩小其动量,甚或在微调过程中冻结预训练的BN参数不更新。若问题仍然存在,也可以考虑替换为对小批量不敏感的归一化方法(例如LayerNorm或GroupNorm)。此外,适当降低梯度累积步数、检查优化器的动量因子、关闭过强的正则化等,都属于可能的调参方向。在LLM微调实战中,有时需要综合调整多个方面,逐步逼近稳定收敛的配置。
总结
通过对上述案例的损失曲线进行分析,我们确定该 Qwen2.5-1.5B 模型微调过程中出现了训练失败(损失发散)现象。判断依据是训练损失在若干轮后不仅没有下降,反而以指数趋势上升,这是训练过程严重异常的标志。造成这种问题的原因可能包括学习率设置不当、梯度爆炸未被抑制、BatchNorm 层引入的不稳定,以及数据格式和标签问题等。针对此,我们提出了多方面的解决思路:在优化层面降低学习率、使用 warmup 和梯度裁剪来稳健训练;在数据层面校验数据管道、确保标签正确、缓解样本不均衡;并通过监控机制及时捕获异常。实践经验表明,大部分训练发散的问题都可以通过仔细地定位原因并调整相应配置来解决。在未来的模型调优中,训练工程师应当密切关注损失曲线的走势,一旦发现类似本案例的异常模式,及时应用上述策略进行干预。通过不断地实验和调参,我们有望将像Qwen2.5这样的模型微调训练重新拉回正轨,实现损失稳步下降和模型性能的提升。
脱敏说明:本文所有出现的表名、字段名、接口地址、变量名、IP地址及示例数据等均非真实, 仅用于阐述技术思路与实现步骤,示例代码亦非公司真实代码。 示例方案亦非公司真实完整方案,仅为本人记忆总结,用于技术学习探讨。
• 文中所示任何标识符并不对应实际生产环境中的名称或编号。
• 示例 SQL、脚本、代码及数据等均为演示用途,不含真实业务数据,也不具备直接运行或复现的完整上下文。
• 读者若需在实际项目中参考本文方案,请结合自身业务场景及数据安全规范,使用符合内部命名和权限控制的配置。版权声明:本文版权归原作者所有,未经作者事先书面许可,任何单位或个人不得以任何方式复制、转载、摘编或用于商业用途。
• 若需非商业性引用或转载本文内容,请务必注明出处并保持内容完整。
• 对因商业使用、篡改或不当引用本文内容所产生的法律纠纷,作者保留追究法律责任的权利。
Copyright © 1989–Present Ge Yuxu. All Rights Reserved.