深度学习数据精度总结

前言

fp32 & fp16 & bf16 & tf32

fp32和fp16都是国际标准IEEE的单精度和半精度,相信计算机专业的都比较熟悉。

bf16是由google brain提出开发的,全称 brain floating point,主要为了加速机器学习的一种格式。

而tf32是由nvidia提出开发的,全称 Tensor float32,也是为了加速机器学习的一种格式。tf32目前只有在ampere架构以上才支持。是为了专门在 tensor core 上加速的一种数据结构。

他们的格式表示是完全一样的,都是指数小数形式,区别只有指数的位数和小数的位数。

在看格式表示之前,以float32为例,回顾一下浮点数的通用表示法。
ieee_fp32

float32,有1个符号位,8个指数位(exponent),23个小数位(fraction)。它的计算公式见下图:
float32_cacl

  • 符号位: 0代表正数,1代表负数
  • 指数位: 其数值范围为 [0, 255], 但是全0和全1有特殊作用,另外指数需要减去一个固定大小的偏置,因此指数的实际范围为 [-126, 127]
  • 小数位: 小数位是为了增大数据的精度范围,它有一个默认的偏置1

注意,指数为全0和全1有特殊含义:

  • 全0: 小数位的偏置1将被删去,此时表示的数值被称为 非规范化数
  • 全1: 此时分两种情况。如果小数位不全0,则为NaN,如果全0,则为 +inf 或者 -inf

可以看出:

float32的最大值是 0 11111110 111...111
float32的最小值是 1 11111110 111...111
float32的最小正值是 0 00000000 000...001
float32的最大负值是 1 00000000 000...001

而我们也可以看到的是,指数位的位数,决定了一个数据格式的范围大小。而小数位的位数,则决定了一个数据格式的精度范围。


下面看一下他们的格式区别,分别是 fp16, bf16,tf32

ieee_fp16
bfloat16
tf32

从上图很明显可以看出一些区别。

bf16

首先bf16和fp16的长度是一样,但是它的小数位数和指数位数完全不一样。然而bf16的小数其实是与fp32保持一致的。这就会带来第一个好处:fp32转到bf16几乎是没有开销的,只需要对指数进行截断即可。

而bf16比fp16的指数位更多,相应的小数位更少,这也意味着bf16比fp16的数据范围更大,但是精度会更低。

而在深度学习中,数据范围的重要性是远大于数据精度的(毕竟量化在训练和部署都非常的关键)。

tf32

tf32的数据长度是不太规则的(不是2的指数),因此它的兼容性上会有点问题。目前只能在nvidia gpu上的tensor core中使用。

tf32是直接拉取了bf16和fp16的优点,但是失去了兼容性。用了bf16的指数位和fp16的小数位。

fp8

FP8是FP16的衍生产物,它包含两种编码格式E4M3与E5M2。对于E4M3而言,其包含4比特指数、3比特小数、以及一比特符号位。E5M2同理包含5比特指数位、3比特小数、1比特符号。目前fp8处于试验阶段,很少会在工业界上使用。

论文链接

鲜有人使用的 fp24 & ef32

amd的fp24 和 遂原科技的ef32。ef32只比tf32多了1位小数位

fp24
ef32

参考文献