机器学习中常用的数据类型
常用的数据类型有FP64、FP32、FP16、BFLOAT16等,以及LLM量化用到的INT4、NF4、INT8、FP8
指数位长度提供范围,尾数位长度决定精度
TF32剩余的13位填充或未使用
FP64
FP64表示64位浮点数,通常为IEEE 754定义的双精度二进制浮点格式,由1位符号位、11位指数位、52位尾数位组成
表示范围:
- 正数范围:约 4.9 x 10e-324 ~ 1.8 x 10e308
- 负数范围:约 -1.8 x 10e308 ~ -4.9 x 10e-324
通常用于精度要求较高的科学计算,一般不用于深度学习
FP32
FP32表示32位浮点数,通常为IEEE 754定义的单精度二进制浮点格式,由1位符号位、8位指数位、23尾数位组成
表示范围:
- 正数范围:约 1.4 x 10e-45 ~ 3.4 x 10e38
- 负数范围:约 -3.4 x 10e38 ~ -1.4 x 10e45
深度学习的主力数据格式,神经网络中的权重等默认以FP32表示
FP16
FP16表示16位浮点数,通常为IEEE 754定义的半精度二进制浮点格式,由1位符号位、5位指数位和10位尾数位组成
表示范围:
- 正数范围:约 6.10 x 10e-8 ~ 65504
- 负数范围:约 -65504 ~ -6.10 x 10e-8
可用于深度学习的混合精度训练,模型权重的加载使用FP32,前向和反向传播、梯度更新等使用FP16提高训练速度
BF16
一种特殊的数据存储格式,为解决FP16应用在深度学习上时动态范围太窄的问题,由Google开发的16位格式 Brain Floating Point Format
由1位符号位、8位指数位、7位尾数位组成
表示范围:
- 正数范围:约 1.18 x 10e-38 ~ 3.39 x 10e38
- 负数范围:约 -3.39 x 10e38 ~ -1.18 x 10e-38
BF16保持与BF32相同的指数范围,但牺牲了一部分精度,其可在深度学习训练中减少内存和存储需求
FP8
FP8是由Nvidia在Hopper和Ada Lovelace架构GPU上推出的数据类型,有如下两种形式:
- E4M3:由1位符号位、4位指数位和3位尾数位组成
- E5M2:由1位符号位、5位指数位和2位尾数位组成
E4M3支持的动态范围更小,精度更高,E5M2支持的动态范围更广,精度更低,而LLM推理过程对精度要求较高,对数值范围要求较低,故二者中FP8-E4M3更适合推理。
由于浮点数的特性,FP8表示的数值是非均匀的,越靠近0,分布越稠密,越远离0,分布越稀疏,因此FP8对较大值的精度较差,但对较小的值的精度较好。
NF4
4-bit NormalFloat,一种用于量化的特殊格式,由华盛顿大学于23年5月在QLoRA的量化论文中提出。
NF4是建立在分位数量化技术基础上的一种信息理论上最优的数据类型,把4位的数字归一化到均值0、标准差位 [-1, 1] 的正态分布的固定期望值上。
浮点数转为十进制数计算
以如下的FP32为例
计算公式为
S - 符号位 M - 尾数位 E - 指数位
式中尾数M时一个小数,前面有一个隐含的1,转换十进制时需要加上,即尾数表示的二进制数为 1.01,十进制为 1.25
FP32的指数位共8位,故偏移值为 2 ^ 8 - 1 = 127,计算时需减去偏移值,01111100 -> 124 - 127 -> -3
故最终的值计算为
详细可见wiki :https://en.wikipedia.org/wiki/Single-precision_floating-point_format