深入分析 bf16 在模型微调时对权重更新的限制,揭示稀疏更新机制及解决方案
在大规模语言模型的微调过程中,bf16 这种低精度格式因其显存和计算优势受到广泛关注,然而不少研究者和工程师发现,使用 bf16 训练时模型的权重更新似乎被冻结,导致训练效果不佳甚至出现性能倒退。 bf16 的数值表示方式与常规 fp32 相似,它保留 8 位指数并使用只有 7 位有效数字的尾数,这使得每个数值所能覆盖的精度间隔远大于 fp32,即在同一指数区间内,bf16 的相邻可表示值之间的差距会随着数值大小呈指数级扩大。 当 Adam 类优化器在每一步计算出的更新量小于该间隔的一半时,更新会在四舍五入后回到原来的数值,导致实际上没有任何变化。由于学习率通常在 1e-6 左右,绝大多数中等尺度的权重(大约 0.001 到 0.01)的更新会被直接抹去,只有极小的权重才能够突破这个「精度门槛」并产生有效的步长。 AdamW 在 bf16 环境下有三个关键问题,首先是重量衰减在极小的相对变化下会被四舍五入消失,其次是第二动量的衰减同样被限制,使得 v 变量难以缩小,最后是更新本身如果小于间隔就会被直接丢弃,这三者共同形成了对 bf16 参数的稀疏更新效果。 Quiet‑STaR 等已公开的实验表明,在 1e-6 的学习率下,大约只有 5% 到 6% 的权重在整个训练过程中曾经被更新,而每一步实际改动的权重比例往往在 1% 到 3% 之间,这说明模型实际上只在极小的子集上进行学习,其余部分保持原始初始化状态。
这种稀疏更新的现象并非偶然,它可以看作是一种固定的权重掩码,只要权重的绝对值大于学习率乘以 512(约为 5e-4),更新就会被视为无效,从而形成一种与学习率强相关的剪切效应,使得模型在不同学习率下的行为呈现出明显的分层。 为规避这一限制,研究者提出了几种可行的方案,其一是保持 fp32 主副本并在 AdamW 中使用混合精度,这样更新会在高精度空间中完成后再转换回 bf16;其二是使用 torchao 提供的随机舍入(stochastic rounding),让极小的步长有机会在多次迭代中累计成完整的间隔跨度;其三是根据实验经验将学习率下调 3 到 10 倍,让更新量足够大以跨越精度间隔。 如果仅仅想在不增加显存的前提下继续使用 bf16,则可以在每个训练步骤后检查实际被修改的权重比例,若发现单步变化比例低于 10% 则考虑采用随机舍入或切换到 fp32 主副本,以确保梯度在不同尺度上都能得到适当的传播。 从更宏观的角度看,bf16 引发的更新稀疏现象与已有的参数高效微调方法如 PaFi、NanoAdam 以及 Child‑Tuning 等所倡导的「只更新小权重」思想相吻合,这表明低精度本身并不是问题的根源,而是这些方法在低精度环境下的自然延伸。 实验数据进一步显示,使用完整 fp32 主副本的模型在相同学习率下往往出现训练损失的剧烈波动,甚至在早期步骤出现数值爆炸,而 bf16 训练则因大部分权重被锁定而保持相对平稳的损失曲线,这也解释了为何在公开的 Quiet‑STaR 检查点上,模型的最终评价指标虽有提升,却是基于极度稀疏的更新实现的。 因此,在使用 bf16 进行模型微调时,务必评估模型中权重的分布,确认学习率是否足以让足够多的权重跨越精度门槛,若有必要可尝试随机舍入或引入 fp32 主副本,同时关注每一步实际更新的权重比例,以确保训练过程既高效又稳定。
在实际部署时,若使用 DeepSpeed、FSDP 等分布式训练框架的混合精度功能,也会在内部完成 fp32 与 bf16 之间的转换,此时仍需注意是否在梯度传播阶段保留了足够的精度,否则同样会出现更新被截断的现象。 另外,一些社区博客已经观察到,使用较小的学习率(如 3e-7)时,即使在 fp32 环境下也能复制 bf16 的训练效果,这进一步说明学习率与精度门槛之间的相互作用,提醒我们在选择学习率时要结合模型的权重尺度进行细致的调试。 未来的优化器可能会在感知到 bf16 参数时自动进行梯度裁剪或自适应学习率调节,以避免因精度间隔过大而导致的更新丢失,而开源框架如 PyTorch 正在考虑在 AdamW 中加入对低精度参数的警告机制,这将帮助开发者更早发现潜在的更新稀疏问题。 因此,在使用 bf16 进行模型微调时,务必评估权重分布、调节学习率或采用随机舍入等技术,以确保更新不被精度间隔截断,从而获得稳定且高效的训练过程。 。