浮点数
FP32(Single Precision)
FP32是最常见的浮点数格式,遵循IEEE 754标准,使用32位来表示一个数字,包括1位符号位、8位指数位和23位小数位。FP32提供了高精度的表示,适用于对精度要求极高的模型训练过程,但是FP32的数据和计算需要更多的内存和计算资源。
-
Sign(符号位):1位,0表示整数;1表示负数
-
Exponent(指数位):8位,用来表示整数部分,范围为00000001(1)到11111110(254)。为了让指数位能表示负数,引入偏置值127后,指数位可以表示-126到+127的范围即 $2^{-126}$ 到 $2^{127}$ .
-
Fraction(尾数位):23位,用来表示小数部分,存储的尾数位数为23位,但是隐去了首位的1。可以根据下面一个公式进行数值计算。
$$(-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的组成为
-
Sign(符号位):1位,0表示整数;1表示负数
-
Exponent(指数位):5位,用来表示整数部分,范围为00001(1)到11110(30)。为了让指数位能表示负数,引入偏置值15后,指数位可以表示-14到+15的范围即 $2^{-14}$ 到 $2^{15}$ .
-
Fraction(尾数位):10位,用来表示小数部分,存储的尾数位数为10位,但是隐去了首位的1,假设尾数部分为1001000000,默认会在这个尾数部分前面加一个1,变成1.1001000000(二进制表示),可以根据下面的两个公式计算得出为1.5625。
$$(-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在减少内存和计算成本的同时,还能较好地保持模型的训练稳定性和准确性。
-
Sign(符号位):1位,0表示整数;1表示负数
-
Exponent(指数位):8位,用来表示整数部分,同FP32一样,范围为00000001(1)到11111110(254)。为了让指数位能表示负数,引入偏置值127后,指数位可以表示-126到+127的范围即 $2^{-126}$ 到 $2^{127}$ .
-
Fraction(尾数位):7位,用来表示小数部分,存储的尾数位数为7位,也隐去了首位的1。可以根据下面一个公式进行数值计算。
$$(-1)^{sign} * 2^{exponent -127} * 1.fraction(2进制)$$
注意:对BF16来说,十进制中相隔0.01(-1~1之间精度是0.001),在bfloat16中才会有变化。可以看到bfloat16比float16精度降低了,但是表示的范围更大了,可以有效的防止在训练过程中的溢出。
FP8
FP8是FP16的衍生物,包含两种编码格式:
-
E4M3:包含1位符号位、4位指数和3位底数
-
E5M2:包含1位符号位、5位指数和2位底数
相对而言,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的数据格式转换过程可以刻画为:
-
Unscaled FP32 = FP32 / scale
-
FP8 = Convert(Unscaled FP32)
-
当Unscaled FP32 数据已经超出FP8的表示范围,即Unscaled FP32的幅值大于448(FP8 E4M3可表示的最大值),那么直接进行截断,此时为浮点上溢出
-
当Unscaled FP32数据范围在FP8的表示范围内,且幅值大于FP8能够表达的最小值,此时需要移去多余的底数位,并对底数进行四舍五入
-
当Unscaled FP32数据小于规范化FP8能够表达的最小值,此时浮点下溢出,需要除以非规格化的FP8最小值并取整。
-
补充:
-
FP8量化经研究具有一个优势,FP8的量化对scale的选择不敏感,在FP8的场景下,几乎可以不做校准(calibration)就完成网络的量化
-
总的来说,FP8的量化并不精确,但是FP8量化具有良好的宽容度,因此在量化感知训练中可能会有更好的稳定性
FP8 与 INT8 综合对比
-
INT8在数值空间是均匀分布的,将浮点数空间的数值按照等分区间映射到一个整数上,这样很多浮点数数值都会映射到相同的整数数值,从而损失边界特征值。而FP8仍然是浮点数,有更大的动态范围表示和更高的精度表示。
-
在混合精度训练时,FP8到FP16/FP32/BF16的转换时,更简单直接,而INT8到FP的转换需要乘法和加法运算增加额外开销。
-
在CPU上,FP8的速度会比INT8慢很多。
-
INT的量化步长(scale)是均匀的,总是以一定的步长完成量化,而浮点的量化则是非均匀的,随着数值增大,其步长也在逐渐变大。而且E5M2的步长变化相较E4M3而言更加明显。从另一个角度出发,量化的误差是与步长正相关的,因此FP8浮点量化相比于INT8而言,对于小数会更加精确,但是对于大数则更不精确。
整型数
INT8
INT8是一种8位整数类型,其表示范围为-128到127,可将其类比为一个8位计数器,通过每一位不同的0/1组合来表示不同的整数值。
INT4
INT4是一种4位整数类型,其表示范围较INT8更小,为-8到7,INT4以牺牲数值表示范围为代价,换取更小的存储空间占用和更快的计算速度。
FP32到INT8的数据格式转换
-
简单的将FP32的数值映射到等间距的INT8整数上的计算过程可以分为三步:
-
计算缩放因子:根据该组浮点数的最大绝对值计算缩放因子(利用最大绝对值计算缩放因子的方法相对简单,但可能对异常值敏感,选择合适的缩放因子计算方法,需要在精度和计算开销之间进行权衡)
-
量化操作:将FP32的浮点值乘以缩放因子并四舍五入到最接近的整数,得到INT8量化值
-
反量化操作:量化后的INT8值通过除以缩放因子来还原为FP32值,但会存在一定的精度损失
-
-
为了进一步缩小量化误差,还可以引入零点(zero-point)量化。零点量化在量化公式中加入零点偏移,是的浮点数0精确映射到整数0,从而提高量化精度,尤其是在激活值中存在大量0值时。
参考文献&网页
博客: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/