浮點數 (Floating-Point Number) 是一種在計算機中表示帶有小數部分的數字的方式。它通過科學記數法類似的方式(尾數 × 基數 ^ 指數)來近似表示實數。浮點數的精度決定了它可以表示的數值范圍以及數值之間的精細程度。
常見的浮點數精度包括:
-
FP32 (Single-Precision Floating-Point)
- 也稱為單精度浮點數。
- 使用 32 位(4 字節)來存儲數字。
- 這 32 位通常分配給:1 位符號位,8 位指數位,23 位尾數/有效數字位。
- 特點:具有相對較好的數值范圍和精度。在傳統的科學計算、圖形渲染以及較早期的深度學習模型中廣泛使用。
- 缺點:相對于低精度格式占用更多內存,計算速度也可能較慢(因為硬件通常針對更小的數據類型進行優化)。
-
FP16 (Half-Precision Floating-Point)
- 也稱為半精度浮點數。
- 使用 16 位(2 字節)來存儲數字。
- 這 16 位通常分配給:1 位符號位,5 位指數位,10 位尾數/有效數字位。
- 特點:
- 優勢: 相比 FP32 占用內存減半,可以存儲更大的模型或處理更大的批量數據。在支持 FP16 計算的硬件上(如 NVIDIA 的 Tensor Cores),計算速度可以顯著加快(理論上可達 FP32 的兩倍甚至更高)。這對于深度學習的訓練和推理非常重要。
- 劣勢: 由于指數位和尾數位都減少了,FP16 的數值范圍更小,精度也較低。這可能導致在訓練過程中出現數值下溢(Underflow,數字太小無法表示)或上溢(Overflow,數字太大無法表示),以及梯度消失等問題,使得模型訓練不穩定或難以收斂。
-
BF16 (Bfloat16 - Brain Floating Point)
- 由 Google Brain 提出的一種 16 位浮點格式。
- 使用 16 位(2 字節)來存儲數字。
- 這 16 位通常分配給:1 位符號位,8 位指數位,7 位尾數/有效數字位。
- 特點:
- 優勢: 與 FP32 具有相同的指數位數量(8 位),因此擁有與 FP32 幾乎相同的數值范圍。這大大減少了訓練過程中出現上溢或下溢的風險,使得從 FP32 切換到 BF16 訓練時通常比切換到 FP16 更穩定、更容易收斂。同樣擁有 16 位格式帶來的內存和計算效率優勢。
- 劣勢: 尾數位只有 7 位,比 FP16 的 10 位少,這意味著 BF16 的表示精度比 FP16 要低。
FP16 和 BF16 的對比總結:
- 位數相同: 都是 16 位。
- 內存/速度: 都比 FP32 節省內存并可能在支持硬件上加速計算。
- 主要區別:
- FP16: 范圍小,但精度相對 BF16 高。
- BF16: 范圍大(與 FP32 相似),但精度相對 FP16 低。
- 應用: FP16 廣泛應用于各種支持的硬件,尤其在對精度要求不極致或通過混合精度訓練可以緩解精度問題的場景。BF16 在 TPU 和較新的 GPU 上得到很好的支持,因其大范圍帶來的訓練穩定性而在很多大型模型訓練中受到青睞。
在現代深度學習中,FP16 和 BF16 通常被稱為“標準精度”,相對于傳統的 FP32(全精度)以及更低的 INT8、INT4 等量化(整數)精度而言。許多現代模型和訓練技術都默認或推薦使用 FP16 或 BF16 來提高訓練和推理效率。
當 llama.cpp
轉換腳本要求輸入標準精度模型時,它就是指期望模型的權重是 FP16 或 BF16 格式,而不是經過 4 位或 8 位等其他庫的量化處理后的格式(這些格式通常會添加一些 llama.cpp
不認識的元數據張量)。
除了我們之前討論的 FP32 (單精度)、FP16 (半精度) 和 BF16 (Bfloat16) 這些浮點數精度之外,在 AI 特別是深度學習領域,還有一些非常主流的精度格式,主要用于追求更高的效率和更低的內存占用:
-
INT8 (8-bit Integer)
- 描述: 使用 8 位整數來表示數值。由于整數沒有小數部分,為了表示浮點數,通常需要結合一個縮放因子(scalar)和零點(zero point)來實現(這叫做量化)。
- 特點: 相比 FP32/FP16/BF16 占用內存顯著減少(權重大小變為原來的 1/4 到 1/2),計算量也大大降低。現代 AI 硬件(GPU, TPU, 專用推理芯片)通常都有專門的 INT8 計算單元,可以提供極高的吞吐量。
- 主要用途: 推理 (Inference)。INT8 是目前最普遍的模型量化格式,廣泛應用于各種邊緣設備和數據中心推理場景,以加速計算和降低部署成本。
- 挑戰: 將模型從浮點數轉換為 INT8 需要進行量化過程,可能需要校準數據集(Calibration)或進行量化感知訓練(Quantization-Aware Training, QAT)來最小化精度損失。
-
INT4 (4-bit Integer)
- 描述: 使用 4 位整數來表示數值。這是比 INT8 更低的精度。
- 特點: 相比 INT8 進一步減少模型大小(再次減半)和計算量。對于在資源極度受限的設備上部署超大型模型,或者在有限的顯存中運行更大模型非常有用(比如 L4 + 22GB 顯存,INT4 是進一步壓縮模型的手段)。
- 主要用途: 極限推理場景,尤其是在內存或帶寬是主要瓶頸時。
- 挑戰: 精度極低,量化到 INT4 對模型的精度影響更大,更容易導致性能下降。需要更先進的量化技術和算法來保持可用精度。4 位加載 (
load_in_4bit=True
) 就屬于這一范疇。
-
FP8 (8-bit Floating-Point)
- 描述: 一種新興的 8 位浮點格式。與 INT8 不同,它保留了浮點數的指數和尾數結構,因此具有一定的數值范圍。目前主要有兩個主流變體:E5M2 (5 位指數,2 位尾數) 和 E4M3 (4 位指數,3 位尾數)。
- 特點: 旨在結合 INT8 的效率和 FP16/BF16 的數值魯棒性。E5M2 強調范圍(與 FP16 范圍相似),E4M3 強調精度。在支持的硬件上提供 8 位計算的高吞吐量。
- 主要用途: 正在成為大型模型訓練的一種重要精度格式(尤其在最新的硬件如 NVIDIA Hopper/Blackwell 和 Google Trillium 上),以及高性能推理。它可以減少訓練時的內存和計算需求,同時提供比 INT8 更好的訓練穩定性。
此外,還有一個重要的概念是:
- 混合精度 (Mixed Precision)
- 描述: 這不是一種單一的精度格式,而是一種訓練技術。它在訓練過程中同時使用多種精度,通常是將模型權重和激活值存儲在低精度(如 FP16 或 BF16)以節省內存和加速計算,但在執行對數值精度要求較高的操作(如梯度累加、更新模型權重)時使用高精度(如 FP32)來保持數值穩定性。
- 特點: 是目前訓練大型深度學習模型的主流方法,可以在不犧牲太多精度的情況下大幅提高訓練速度和顯存利用率。需要硬件支持低精度浮點計算以及在不同精度之間高效轉換的能力。
除了 FP32, FP16, BF16 之外,目前深度學習領域主流的精度還包括用于量化推理的 INT8 和 INT4,以及用于高性能訓練和推理的新興 FP8。同時,混合精度是結合不同精度進行訓練的普遍技術。選擇哪種精度取決于具體的任務(訓練還是推理)、硬件平臺的能力、對性能和內存的嚴格要求,以及對模型精度損失的容忍度。