Last Updated on 2024-09-20 by Clay
深度神經網路訓練、微調的過程中,最重要也最稀缺的資源讓我來說肯定是 GPU 的 VRAM,所以讓每一位元真正發揮它的能力是非常重要的事情。
通常資料精度的表示分成以下三個部份:
- 符號位元(Sign)
- 指數範圍位元(Exponent Range)
- 小數精度位元(Fraction Precision)
一般來說,符號位元只佔 1-bit,而指數範圍位元影響浮點數的範圍、小數精度位元影響浮點數的精細程度。
而在深度學習的任務中,選擇適合的數值精度對計算時的性能、VRAM 使用量、模型的準確度會有重大的影響,因此我們需要評估任務的需求,審慎地選擇。
全精度的 Float32 自然是最精準的,但是對於計算的時間、模型的儲存空間都有較高的要求。所以,從我還在唸研究所時開始,就有許多人在研究混合精度訓練,來進一步降低訓練時的 GPU 開銷;不過當時比較多的資料精度是轉換成半精度(Float16)。
而 BFloat16 則是由 Google 所提出來的,目的其實也是為了提昇深度學習的效能而設計。我們可以從上方的圖示中看出,與常規的 Float16 不同,BFloat16 與 Float32 擁有一樣的指數範圍,其結構更加接近,只是精度比較低。這樣做的好處是比起 Float16 更好地因應深度學習中的極端數值情況,如梯度爆炸或梯度消失。
而且減少的精度,由於影響的範圍太小,基本上不會影響模型的收斂與準確性。
最後來談談 Float8(FP8),這是一種新興的精度表示,特別適合極端資源條件下的深度學習推理。跟 BFloat16 的概念相似,它至少擁有與 Float16 相似的表現力 —— 不過在推理場景中數值穩定性需要額外注意。