對應原題(Common ‧ Inference, Serving and GPU Performance)

  • Compare FP16, BF16, FP8, INT8, INT4 and FP4 for serving. What breaks at each step down?
    — Asked at: Mistral AI, Apple, NVIDIA, Together AI, Character.AI

📌 分層:格式怎麼選、GGUF 代號怎麼讀 → 工具-模型量化格式選擇(決策層)。
這一頁講數值格式本身的機制與各級的失效模式。

🎯 什麼情境該想到我

當你「要判斷量化到底會壞掉什麼、或搞不懂為什麼 BF16 精度更差卻是訓練首選」的時候。

⚙️ 怎麼用(機制)

浮點 vs 整數:兩種完全不同的取捨

浮點 = 符號 + 指數 + 尾數。指數給動態範圍,尾數給相對精度。格點是不均勻的——靠近 0 密集,遠離 0 稀疏。
整數 = 均勻格點 + 一個 scale(和 zero-point)。範圍固定,格點均勻。

LLM 的權重與激活分布接近鐘形但有長尾,所以「靠近 0 精細」這件事對浮點有利;但整數有更便宜的硬體。

格式對照表

格式位元配置 (S-E-M)動態範圍相對精度硬體
FP321-8-23~最高全部
FP161-5-10±65,504,最小正規值 ~較高Volta+
BF161-8-7與 FP32 相同低(只有 7 bit 尾數)Ampere+
FP8 E4M31-4-3±448尚可Hopper+
FP8 E5M21-5-2±57,344很低Hopper+
INT8—由 scale 決定均勻 256 格很久以前就有
INT4—由 scale 決定均勻 16 格靠 kernel 解包
FP4 (E2M1)1-2-1由 block scale 決定只有 16 個值Blackwell (NVFP4/MXFP4)

★ 為什麼訓練用 BF16 不用 FP16(高頻考點)

FP16 的指數只有 5 bit:

  • 最大 65,504 → 梯度或激活稍微一大就 Inf
  • 最小正規值 ~ → 小梯度直接 underflow 成 0,那一步就沒學到

所以 FP16 訓練必須配 loss scaling(把 loss 乘大再把梯度除回來),而且要動態調整、遇到 Inf 要跳過該步——一堆脆弱的工程。

BF16 的指數和 FP32 一模一樣(8 bit),範圍問題直接消失。代價是尾數只剩 7 bit(相對精度約 )。

核心洞察:深度學習對動態範圍敏感,對相對精度不敏感。
梯度是隨機的,本來就有噪聲;多 0.4% 的量化噪聲影響很小。但一個 Inf 就毀掉整步。

→ BF16 犧牲精度換範圍,這個交易在訓練上是壓倒性的。 今天幾乎所有大模型訓練都是 BF16。

推論就不一樣了:推論不算梯度,數值範圍溫和,FP16 的高精度反而有利。所以訓練 BF16、推論 FP16 是常見組合。

★ 兩種量化對象(決定它有沒有加速效果)

類型記法做什麼加速在哪
Weight-onlyW4A16、W8A16只量化權重;計算前反量化回 FP16decode ✅ / prefill ❌
Weight + ActivationW8A8、FP8兩者都量化,直接用低精度 Tensor Core 算decode ✅ / prefill ✅
KV cache 量化KV-int8 / KV-fp8量化 KV cache省顯存 + decode 讀取量

★ 為什麼 weight-only 對 decode 有效但對 prefill 沒效(必考):

回到 Prefill 與 Decode 的算術強度。

  • decode 是 memory-bound,時間 ≈ 權重讀取量 ÷ 頻寬。W4 把讀取量砍成 1/4 → 直接快近 4×。反量化的那點算力反正是閒置的。
  • prefill 是 compute-bound,時間由算力決定。反量化多加了計算,所以 W4A16 在 prefill 可能更慢。

這修正了一個常見說法「量化只省記憶體不會變快」——在 decode 階段,省記憶體讀取就是變快,因為那裡的瓶頸就是頻寬。

★ 為什麼激活比權重難量化:離群值

Dettmers et al. (2022, LLM.int8()) 的關鍵發現:

模型超過約 6.7B 參數後,會出現系統性的離群特徵——少數幾個隱藏維度的激活值比其他維度大 ~20 倍,而且固定出現在同樣的通道。

均勻量化的 scale 由最大值決定。有一個 20× 的離群值,其餘 99.9% 的數值就被擠進格點的最底部,精度全毀。

解法做法
混合精度分解(LLM.int8())把離群通道挑出來用 FP16 算,其餘走 INT8
SmoothQuant(Xiao et al., 2023)把激活的難度數學上遷移到權重:。權重比較好量化
per-channel / per-group scale不用單一 scale,每個通道或每 128 個權重一個
FP8指數位讓它天然容忍大動態範圍——這正是 FP8 相對 INT8 的主要優勢

權重就溫和多了:分布集中、而且是靜態的可以離線慢慢校準。所以 weight-only 量化到 4-bit 相對安全。

校準方法(weight-only 4-bit 的主流)

方法核心想法
GPTQ(Frantar et al., 2022)逐層量化,用近似 Hessian(二階)資訊決定順序,並把已產生的誤差補償到還沒量化的權重上
AWQ(Lin et al., 2023)依激活幅度找出約 1% 的重要權重通道,用 per-channel scaling 保護它們。不做反向傳播,快
SmoothQuant見上,主要給 W8A8
QAT訓練時就模擬量化。品質最好、成本最高

★ 逐級會壞掉什麼(這題的核心)

降到省多少會壞什麼
FP32 → BF16/FP1650%推論幾乎無損。訓練用 FP16 要 loss scaling;累加(reduction)務必用 FP32,否則長序列的加總誤差會累積
→ FP8再 50%要決定 per-tensor / per-channel scaling 策略。E4M3 給前向、E5M2 給梯度。長生成會開始出現緩慢漂移;需要 Hopper+
→ INT8 weight-only再 50%通常近乎無損,是最安全的一級
→ INT8 W8A8同上但加速更多離群值問題浮現。沒做 SmoothQuant 或混合精度就會明顯掉
→ INT4 weight-only再 50%必須 group-wise scale(常見 group=128)+ 校準。⚠️ perplexity 看起來只掉一點,但長上下文、多語言(含中文)、多步推理、工具呼叫格式的退化遠大於 benchmark 顯示的
→ FP4 / INT4 以下再 50%只有 16 個可表示值。必須用細粒度 block scale(NVFP4:每 16 個值配一個 FP8 scale;MXFP4:每 32 個配一個 E8M0 scale)。實務上要配 QAT 或蒸餾才穩
→ INT2—一般認為不堪用,除非有專門的訓練流程

★ 評估的陷阱

perplexity 對量化極不敏感。 常見情況是 PPL 只升 0.1%,但:

  • agent 的工具呼叫格式開始出錯
  • 長回答到後半段品質崩壞
  • 中文、程式碼比英文散文退化更多
  • 多步推理的錯誤率明顯上升

→ 一定要用自己的任務評估集,而且要涵蓋長輸出與結構化輸出。 見 工具-AI系統評估。

⚠️ 注意 / 什麼時候不適用

  • 省的顯存只有權重那一塊。KV cache 要另外量化,activation 與框架開銷不受影響。W4 的 70B 不是 35 GB 就夠——還要 KV(見 GPU 記憶體估算)。
  • 硬體支援要確認。FP8 要 Hopper+,FP4 要 Blackwell。沒有原生支援時框架會模擬——更慢,而且你不會收到警告。
  • 量化格式與推論框架綁定。GPTQ/AWQ/GGUF/FP8 各有支援矩陣,換框架可能要重新量化。
  • MoE 對量化更敏感。專家被激活得少、校準資料覆蓋不足,容易有某些專家品質特別差。
  • 別在量化模型上微調後又期待原精度的品質。要嘛 QLoRA(見 LoRA 與 QLoRA),要嘛先微調再量化。
  • 累加精度是隱形殺手。權重 INT4 但累加用 FP16,長序列會累積誤差。好的 kernel 都用 FP32 累加。

🧪 我實際套用的紀錄

  • 2026-09-20:從面試題庫展開,尚未實際套用。

🔗 相關