以 8 位元儲存的浮點數

論文

2022 年發表了兩篇論文,介紹以位元組儲存的浮點數,而非以 4 個位元組儲存的 float 32。浮點數精度要低得多,但訓練準確度不會受到太大影響。

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 中引入了四種新類型,以支援一組有限的運算子,以實現使用浮點數 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\) 描述以 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。GraphCore 引入了另一種類型定義,以更好地使用這四個值。每個名稱中包含 UZ 的類型都只有一個零和一個 nan (= 負零)。另一個差異來自指數偏差。因此,由於此指數偏差差異,一個非 null、非 nan 的浮點數 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}\)

轉換

從 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

其他

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

其他

RNE

RNE

RNE

RNE