笔者做过目标检测模型、超分模型以及扩散生成模型。其中最常使用的是单精度FP32、半精度FP16、BF16 。
双精度"FP64"就不说了,不太会用到。
#1. 单精度、半精度和混合精度
单精度(FP32)、半精度(FP16)和混合精度(FP32+FP16) 是常见的浮点数计算格式,在深度学习模型的训练与推理中都有涉及。
它们在计算效率、显存占用和数值稳定性上有显著差异。以下是它们的核心区别对比:
精度类型 | 位数 | 显存占用&生成效果 | 生成速度 | 用途 |
---|---|---|---|---|
FP32 | 32-bit | 🌟🌟🌟🌟最高 | 🌟最慢 | 预训练 |
FP16 | 16-bit | 🌟🌟 | 🌟🌟🌟 | 微调训练、推理 |
BF16 | 16-bit | 🌟🌟 | 🌟🌟🌟 | 微调训练、推理 |
混合精度 | FP16+FP32 | 🌟🌟🌟 | 🌟🌟 | 微调训练、推理 |
FP8 (E4M3) | 8-bit | 🌟最低 | 🌟🌟🌟🌟最快 | 边缘设备推理 |
FP8 (E5M2) | 8-bit | 🌟最低 | 🌟🌟🌟🌟最快 | 边缘设备推理 |
注:推理即图像生成。
#2. BF16(Brain Float16)是什么?
简单的说,「BF16」的显存占用与「FP16」相近,但稳定性与训练效果更好。所以在训练时建议用「BF16」替代「FP16」。
「BF16」由 Google Brain 提出,保留与 FP32 相同的指数位数 (8 位指数),仅降低小数位数(从FP32的23 位缩减到7位)。虽然BF16点小数部分精度低于 FP16的10位,但这部分对深度学习影响较小,可以暂时忽略。
#3. 混合精度(FP16 + FP32)是什么?
混合精度会同时使用 FP16 和 FP32,关键部分(如梯度更新)保留 FP32。
笔者一般会直接使用自动混合精度(AMP),即让程序自己选择精度,一般来讲模型权重会保存为FP32,前向与反向传播用FP16。
#4. FP8的简单了解
实际中很少使用FP8,因为它们的生成效果几乎是最差的(不管INT8),基本只会用于边缘设备(如RV1126等)。所以只需简单了解:
- E5M2(5 位指数,2 位小数):动态范围大,适合梯度计算(训练)。
- E4M3(4 位指数,3 位小数):精度稍高,适合前向传播(生成)。