8位浮点数

论文

2022年发表了两篇论文,介绍了以一个字节存储的浮点数,与以四个字节存储的float32相比。浮点精度低得多,但训练精度并未受到太大影响。

来自NVIDIA、Intel和ARM的FP8 Formats for Deep Learning介绍了两种遵循IEEE规范的格式。第一种是E4M3,1位符号,4位指数,3位尾数。第二种是E5M2,1位符号,5位指数,2位尾数。第一种主要用于权重,第二种用于梯度。

第二篇论文8-bit Numerical Formats For Deep Neural Networks介绍了类似的格式。IEEE标准为+0(或整数0)和-0(或整数128)赋予了相同的值。他们选择为这两个数字赋予不同的浮点值。该论文实验了指数和尾数之间不同的分割方式,并表明E4M3和E5M2是最佳选择。

因此,在onnx==1.15.0中引入了四种新类型,以支持一组有限的操作符,从而实现float 8的计算。

  • E4M3FN:1位符号,4位指数,3位尾数,只有NaN值,没有无穷大值(FN)。

  • E4M3FNUZ:1位符号,4位指数,3位尾数,只有NaN值,没有无穷大值(FN),没有负零(UZ)。

  • E5M2:1位符号,5位指数,2位尾数。

  • E5M2FNUZ:1位符号,5位指数,2位尾数,只有NaN值,没有无穷大值(FN),没有负零(UZ)。

实现通常依赖于硬件。NVIDIA、Intel和Arm实现了E4M3FNE5M2,这是其最新的图形处理器。GraphCore仅使用E4M3FNUZE5M2FNUZ

E4M3FN和E5M2

\(S\)代表符号。\(10_2\)表示二进制数。

Float8类型

E4M3FN

E5M2

指数偏差

7

15

无穷大

\(S.11111.00_2\)

NaN

\(S.1111.111_2\)

\(S.11111.\{01, 10, 11\}_2\)

\(S.0000.000_2\)

\(S.00000.00_2\)

Max

\(S.1111.110_2\)

\(1.75 \times 2^{15}= 57344\)

Min

\(S.0000.001_2 = 2^{-9}\)

\(S.00000.01_2 = 2^{-16}\)

我们将位表示表示为\(S.b_6 b_5 b_4 b_3 b_2 b_1 b_0\)。浮点值由以下表达式定义

Float8类型的值

E4M3FN

E5M2

指数 \(\neq\) 0

\((-1)^S 2^{\sum_{i=3}^6 b_i 2^{i-3} - 7} \left( 1 + \sum_{i=0}^2 b_i 2^{i-3} \right)\)

\((-1)^S 2^{\sum_{i=2}^6 b_i 2^{i-2} - 15} \left( 1 + \sum_{i=0}^1 b_i 2^{i-2} \right)\)

指数 \(=\) 0

\((-1)^S 2^{-6} \sum_{i=0}^2 b_i 2^{i-3}\)

\((-1)^S 2^{-14} \sum_{i=0}^1 b_i 2^{i-2}\)

E4M3FNUZ 和 E5M2FNUZ

之前的类型支持正零、负零、正NaN和负NaN。GraphCore引入了另一种类型定义,以更好地利用这四个值。所有名称中包含UZ的类型只有一个零和一个NaN(=负零)。另一个区别在于指数偏差。因此,一个非零、非NaN的float 8 FLOAT8E4M3FN,由于指数偏差的差异,无法直接转换为FLOAT8E4M3FNUZ。即使尾数相同,指数也不同。

Float8类型

E4M3FNUZ

E5M2FNUZ

指数偏差

8

16

无穷大

NaN

\(1.0000.000_2\)

\(1.00000.00_2\)

\(0.0000.000_2\)

\(0.00000.00_2\)

Max

\(S.1111.111_2\)

\(S.11111.11_2\)

Min

\(S.0000.001_2 = 2^{-10}\)

\(S.00000.01_2 = 2^{-17}\)

浮点值由以下表达式定义

Float8类型的值

E4M3FNUZ

E5M2FNUZ

指数 \(\neq\) 0

\((-1)^S 2^{\sum_{i=3}^6 b_i 2^{i-3} - 8} \left( 1 + \sum_{i=0}^2 b_i 2^{i-3} \right)\)

\((-1)^S 2^{\sum_{i=2}^6 b_i 2^{i-2} - 16} \left( 1 + \sum_{i=0}^1 b_i 2^{i-2} \right)\)

指数 \(=\) 0

\((-1)^S 2^{-7} \sum_{i=0}^2 b_i 2^{i-3}\)

\((-1)^S 2^{-15} \sum_{i=0}^1 b_i 2^{i-2}\)

Cast

从float 8转换为float 16(或E5M10)、bfloat16(或E8M7)、float32(或E8M23)更容易。转换是精确的。转换不一定保留某些值的符号,例如-0-NaN

转换为float 8包括找到最接近原始float 32值的float 8。这通常通过移位和截断来完成。

转换可能带有饱和,超出范围的所有值将变为可用的最高值。下表总结了所有情况。[x]表示舍入到目标尾数宽度的值。

x

E4M3FN

E4M3FNUZ

E5M2

E5M2FNUZ

0

0

0

0

0

-0

-0

0

-0

0

NaN

NaN

NaN

NaN

NaN

Inf

FLT_MAX

NaN

FLT_MAX

NaN

-Inf

-FLT_MAX

NaN

-FLT_MAX

NaN

[x] > FLT_MAX

FLT_MAX

FLT_MAX

FLT_MAX

FLT_MAX

[x] < -FLT_MAX

-FLT_MAX

-FLT_MAX

-FLT_MAX

-FLT_MAX

else

RNE

RNE

RNE

RNE

转换也可以定义为不带任何饱和。

x

E4M3FN

E4M3FNUZ

E5M2

E5M2FNUZ

0

0

0

0

0

-0

-0

0

-0

0

NaN

NaN

NaN

NaN

NaN

-NaN

-NaN

NaN

-NaN

NaN

Inf

NaN

NaN

Inf

NaN

-Inf

-NaN

NaN

-Inf

NaN

[x] > FLT_MAX

NaN

NaN

Inf

NaN

[x] < -FLT_MAX

NaN

NaN

-Inf

NaN

else

RNE

RNE

RNE

RNE

E8M0

E8M0数据类型作为所有OCP Microscaling (MX) Formats的通用比例类型。它有八位用于指数,没有符号位或尾数位。

E8M0

E8M0

指数偏差

127

无穷大

NaN

\(11111111_2\)

Max

\(11111110_2 = 2^{127}\)

Min

\(00000000_2 = 2^{-127}\)

在计算MX格式的比例因子时,可以做出不同的转换选择。因此,ONNX Cast运算符规范引入了一个额外的“round_mode”属性,该属性接受以下值:

  • “up”:四舍五入到离零最近的值

  • “down”:四舍五入到零最近的值

  • “nearest”:四舍五入到最近的值,平局时向上舍入

研究表明,与其它舍入模式相比,饱和舍入在LLM预训练中能实现更高的精度。