FP16與bfloat16位模式視覺化工具

視覺化半精度浮點數(FP16、IEEE 754 binary16)和bfloat16的位模式。支援十進位制與位模式互相轉換,符號位、指數部、尾數部分色顯示。適合學習機器學習中的量化與推理加速。

FP16與bfloat16的結構比較

兩者合計都是16位,但指數部與尾數部的位數分配不同,導致可表示的數值範圍和精度完全不同。

專案 FP16(IEEE 754 半精度) bfloat16
總位數 16 16
指數部位數 5 8
尾數部位數 10 7
可表示的數值範圍 約±6.1×10⁻⁵ 至 ±65504(範圍較窄但尾數位多、精度較高) 約±1.2×10⁻³⁸ 至 ±3.4×10³⁸(與float32相同的寬範圍,但精度較低)
主要用途 影像處理、圖形學、推理時的省記憶體化(半精度訓練) 深度學習訓練(TPU、最新GPU)。從float32轉換時無需擔心指數溢位

bfloat16的指數部位數(8位)和偏移量(127)與float32(單精度)完全相同,因此只需截斷float32的尾數部即可轉換,這是實現上的一個優勢。

看清 FP16 與 bfloat16 的位元是怎樣排布的

雖同佔十六位元,FP16(即 IEEE 754 binary16)與 bfloat16 分配這些位元的方式卻大不相同。本工具在十進位數與位元模式之間雙向轉換,並把符號、指數、尾數分別著色,讓這份差別看得見,而不只是讀得到。

關鍵正在於分配之別。FP16 給指數五位、給尾數十位,bfloat16 則給指數八位、給尾數七位。 八位指數恰與單精度相同,由此生出兩條性質:其一,bfloat16 所能表示的取值範圍與 FP32 相同;其二,由 FP32 轉換過來,不過是截取高十六位而已。 機器學習偏愛 bfloat16 正是為此——訓練途中數值飛出範圍而把整輪毀掉的風險小得多。代價則是尾數只有七位,精度比 FP16 來得粗。 要精度便取 FP16,要範圍便取 bfloat16。

使用方法

  1. 選擇轉換的方向 十進位到位元,或位元到十進位,兩者皆可。
  2. 輸入數值 十進位數或一串 0 與 1 皆可。
  3. 閱讀著色的位元 符號、指數、尾數各以自己的顏色標出。
  4. 把 FP16 與 bfloat16 並置 同一個數用兩種格式表示,便知它們在何處分道揚鑣。

用好本工具的小技巧

  • 即使是同一個值0.1,FP16和bfloat16的舍入誤差表現也完全不同。切換格式比較尾數部的位模式吧。
  • bfloat16的指數部位數和偏移量與float32相同,因此即使是超過65504的大數值也不易溢位。相反FP16一旦超過65504就會立即變為無窮大。
  • 將"70000"轉換為FP16會溢位變為無窮大,而bfloat16則能正常表示(精度有所下降)。
  • 在PyTorch、TensorFlow等機器學習框架中進行模型量化時,bfloat16容易從float32轉換,而FP16由於範圍較窄有時需要預先縮放。
  • 從位模式逆向轉換為十進位制時,需輸入帶0x字首的4位十六進位制值,或16位二進位制值(0b字首可省略)。

這些情境會用到

理解量化的代價

可以具體弄清:模型降到十六位元時,數值會被捨入到什麼地步。

在兩種格式間取捨

它為「您這件事要的是範圍還是精度」提供了判斷的材料。

找出溢位的起點

可以拿真實數值試一試:一旦超過 FP16 所能表示的最大數會怎樣。

學習浮點數的機理

可以一位一位地追下去,看指數與尾數如何合力表出一個數。

浮點數的術語

符號位元
最高的那一位,給出正負:0 為正,1 為負。
指數
表示數值量級的部分。FP16 撥給它五位,bfloat16 撥給它八位。
尾數
相當於有效數字的部分。FP16 有十位,bfloat16 有七位,這道差距正是精度之別。
bfloat16
一種把指數保持在 FP32 的八位的十六位元格式。 它把儲存減半,而不犧牲範圍。
次正規數
指數取到最小時所用的表示,可表出極其貼近零的數值。
量化
以更少的位元數表示模型權重的做法。儲存與計算隨之減少,精度也隨之下降。

常見問題

兩者合計都是16位,但FP16(IEEE 754半精度)是指數部5位、尾數部10位,而bfloat16是指數部8位、尾數部7位。FP16尾數位多精度更高但範圍較窄,bfloat16能表示與float32相同的寬範圍但精度較低。

深度學習訓練中,梯度和引數可能變得非常大或非常小,因此更傾向於使用能保持float32那樣寬的表示範圍(不易溢位/下溢)同時將記憶體和計算量減半的bfloat16。FP16範圍較窄容易溢位,訓練時有時需要額外的損失縮放(loss scaling)。

約65504。若將超過此值的數轉換為FP16,會因溢位而變為無窮大(Infinity)。而bfloat16與float32指數部位數相同,可表示約3.4×10³⁸的數值。

指數部全為0而尾數部不為0的位模式。常規(正規化)浮點數尾數有隱含的前導1,而非正規數省略了這一點,從而能表示比通常最小值更接近零的值(但犧牲了有效精度)。

bfloat16的指數部位數(8位)和偏移量(127)與float32完全一致,因此只需保留float32位模式尾數部的高7位(並四捨五入)即可轉換,無需重新計算指數或檢查範圍,實現十分簡單。
工具君

閒話 ― 為何機器學習需要"降低精度"的數值表示

2018年前後,Google為其TPU(Tensor Processing Unit)設計了一種新的16位浮點格式bfloat16。此前已存在的FP16(IEEE 754半精度)已在影像處理和圖形學領域實用化,但由於指數部僅5位,可表示的數值範圍較窄,難以應對深度學習訓練中梯度時而極小、時而極大的現象(梯度消失、梯度爆炸)。

bfloat16的設計思路很明確:犧牲尾數部的精度,換取與float32(單精度)完全相同的8位指數部寬度,從而能安全處理訓練過程中頻繁出現的極大極小值。"Brain Floating Point"這個名字來源於Google的機器學習研究部門"Google Brain"。

在傳統電腦科學中,降低浮點數精度一直被視為"漏洞的溫床"而被避免。但深度學習模型有一種特殊性質:即使存在一定的數值誤差,對最終預測精度的影響也微乎其微。利用這種"稍有不精確但整體仍能工作"的特性,將記憶體佔用和計算成本減半的16位表示得以廣泛普及,這可以說是有別於傳統電腦科學常識的、機器學習領域獨有的最佳化。