浮点数

FP32(Single Precision)

FP32是最常见的浮点数格式,遵循IEEE 754标准,使用32位来表示一个数字,包括1位符号位、8位指数位和23位小数位。FP32提供了高精度的表示,适用于对精度要求极高的模型训练过程,但是FP32的数据和计算需要更多的内存和计算资源。

$$(-1)^{sign} * 2^{exponent -127} * 1.fraction(2进制)$$

补充:IEEE 754标准的特殊情况

IEEE 754的特殊情况 符号位 指数位 尾数位
正零 0 全0 全0
负零 1 全0 全0
+inf 0 全1 全0
-inf 1 全1 全0
NaN 0/1 全1 非0
非规格数 0/1 全0 非0

注意:对FP32来说,十进制中相隔0.000001(-1~1之间精度是0.0000001),在float32中才会有变化

FP16(Half Precision)

FP16同样遵循IEEE 754标准,但是仅使用16位来表示一个数,包括1位符号位、5位指数位和10位小数位。相比较FP32,FP16减半了存储需求和计算带宽,非常适合于深度学习的训练和推理,特别是在对内存和计算速度有严格要求的场景。虽然精度相对较低,但是在很多深度学习任务中,这种精度损失是可以接受的,同时也可以通过混合精度训练等技术进行缓解。具体而言,FP16的组成为

$$(-1)^{sign} * 2^{exponent -15} * 1.fraction(2进制)$$

$$(-1)^{sign} * 2^{exponent -15} * (1 + \frac{fraction(10进制)}{1024})$$

注意:对FP16来说,十进制中相隔0.001(-1~1之间精度是0.0001),在float16中才会有变化

BF16(Brain Floating Point 16 or Bfloat16)

BF16是Google Brain为加速机器学习而设计的费标准浮点数格式,也使用16位来表示一个数字,但是不同于FP16,它拥有1位符号位、8位指数位和7位小数位,与FP32相同的指数范围。这样的设计使得BF16在保持与FP32相似的数值范围的同时,牺牲了一些精度以换取更高的计算效率。BF16在减少内存和计算成本的同时,还能较好地保持模型的训练稳定性和准确性。

$$(-1)^{sign} * 2^{exponent -127} * 1.fraction(2进制)$$

注意:对BF16来说,十进制中相隔0.01(-1~1之间精度是0.001),在bfloat16中才会有变化。可以看到bfloat16比float16精度降低了,但是表示的范围更大了,可以有效的防止在训练过程中的溢出。

FP8

FP8是FP16的衍生物,包含两种编码格式:

相对而言,E4M3的表示范围更小,但是精度略高于E5M2。另外,E5M2遵循IEEE 754标准,但是E4M3不遵循IEEE 754标准。E4M3在指数全为1时仍然可以表示有效数字,当且仅当指数与尾数部分都为1时,表示无穷大。

补充1: 当一个浮点数的指数部分全为0,且底数部分不为0时,表示的是非规格化浮点数,此时其底数部分不再额外加1.例如0 0000 001表示 $2^{0-7}*2^{-2}$

补充2: FP8 E4M3的特殊情况

符号位 指数位 尾数位
正零 0 全0 全0
负零 1 全0 全0
inf 不存在该值的表示
NaN 0/1 全1 全1
非规格数 0/1 全0 非0

FP32到FP8的数据格式转换

FP32到FP8的转换过程可以表示为先除以尺度因子得到中间结果Unscaled FP32,再由中间结果完成FP32到FP8的格式转换。对于FP8 E4M3的数据格式转换过程可以刻画为:

  1. Unscaled FP32 = FP32 / scale

  2. FP8 = Convert(Unscaled FP32)

    1. 当Unscaled FP32 数据已经超出FP8的表示范围,即Unscaled FP32的幅值大于448(FP8 E4M3可表示的最大值),那么直接进行截断,此时为浮点上溢出

    2. 当Unscaled FP32数据范围在FP8的表示范围内,且幅值大于FP8能够表达的最小值,此时需要移去多余的底数位,并对底数进行四舍五入

    3. 当Unscaled FP32数据小于规范化FP8能够表达的最小值,此时浮点下溢出,需要除以非规格化的FP8最小值并取整。

补充:

FP8 与 INT8 综合对比

整型数

INT8

INT8是一种8位整数类型,其表示范围为-128到127,可将其类比为一个8位计数器,通过每一位不同的0/1组合来表示不同的整数值。

INT4

INT4是一种4位整数类型,其表示范围较INT8更小,为-8到7,INT4以牺牲数值表示范围为代价,换取更小的存储空间占用和更快的计算速度。

FP32到INT8的数据格式转换

参考文献&网页

博客:BF16、FP16、FP32 的区别和精度排行 https://my.oschina.net/shoumenchougou/blog/11208941

博客:大模型精度(FP16,FP32,BF16)详解与实践 https://www.53ai.com/news/qianyanjishu/2024052494875.html

知乎:FP8 量化-原理、实现与误差分析 https://zhuanlan.zhihu.com/p/574825662

博客:使用FP8进行大模型量化原理及实践 https://www.53ai.com/news/finetuning/2024090250423.html

博客:模型量化是什么:FP32, FP16, INT8, INT4 数据类型详解 https://www.aisharenet.com/moxinglianghuashishencheng/