AI训练中的BF16与FP16:精度与稳定性
AI训练中的BF16与FP16:BF16在保持精度和防止训练崩溃中的关键作用
在AI训练中,选择FP16(16位浮点数)还是BF16(脑浮点数)是一个关键决策,需要在数值稳定性、精度和硬件效率之间取得平衡。
根本区别:范围与精度
FP16和BF16都是16位格式,这意味着它们占用的内存是标准32位浮点数(FP32)格式的一半。然而,它们分配位的方式不同:FP16(IEEE 754)使用5位表示指数,10位表示尾数(小数部分)。这为小数字提供了更高的精度,但动态范围非常窄。BF16(脑浮点数)使用8位表示指数,7位表示尾数。这种设计使其具有与FP32完全相同的动态范围,尽管牺牲了尾数中的一些精度。
为什么BF16能防止训练崩溃
BF16成为大规模AI训练事实标准的主要原因是其对数值不稳定性的抵抗力,这种不稳定性常常导致“训练崩溃”。由于FP16的指数范围有限,它极易发生溢出(值变得过大)或下溢(值变得过小,实际上变为零)。这常常导致梯度“爆炸”或消失,从而使训练过程完全失败。BF16的8位指数与FP32的指数相匹配,使其能够处理深度神经网络中通常遇到的广泛值范围,而不会出现这些问题。
为了使用FP16,工程师通常必须采用“损失缩放”——一种将损失乘以一个因子以将梯度保持在FP16可表示范围内,然后再取消缩放的技术。这是一个复杂的试错过程。BF16实际上是FP32的“即插即用”替代品;由于它共享相同的动态范围,因此不需要损失缩放,这使得训练工作流程更加稳定且易于管理。BF16和FP32之间的转换在计算上非常简单,因为它们共享相同的指数结构——只需截断FP32数的尾数位即可获得BF16值。FP16需要更复杂的转换逻辑,这会增加开销。
何时使用哪种格式?
BF16适用于稳定性至关重要的大规模LLM和深度神经网络的预训练。其更宽的范围确保了梯度和激活在长时间训练运行中保持有效。FP16适用于需要高数值精度的特定场景,例如某些类型的强化学习(RL)微调。最近的研究表明,在某些RL环境中,FP16的更高精度(由于其10位尾数)有助于防止舍入误差的累积,这些误差可能导致模型的训练和推理行为出现分歧。
浮点格式比较
| 属性 | FP16 | BF16 | FP32 |
|---|---|---|---|
| 指数位 | 5 | 8 | 8 |
| 尾数位 | 10 | 7 | 23 |
| 动态范围 | ~2^-14 到 2^15 | ~2^-126 到 2^127 | ~2^-126 到 2^127 |
| 精度 | 高(10位) | 中(7位) | 高(23位) |
| 是否需要损失缩放 | 是 | 否 | 否 |
| 转换成本(与FP32之间) | 高 | 低 | – |
结论
BF16在现代AI中广受青睐,因为它提供了“两全其美”的优势:16位计算的内存和速度优势与FP32的数值鲁棒性相结合。通过匹配FP32的动态范围,它消除了损失缩放等复杂变通方法的需要,从而防止了FP16系统经常出现的训练崩溃。然而,对于细粒度数值精度比动态范围更重要的任务,FP16仍然是一个有价值的工具。
