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的尾數部即可轉換,這是實現上的一個優勢。

使用提示

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

常見問題

兩者合計都是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位表示得以廣泛普及,這可以說是有別於傳統電腦科學常識的、機器學習領域獨有的最佳化。