模型量化
神經網路通常將每個權重與中間數值都以 32 位元浮點數(FP32)儲存與運算,這種格式能以高精度涵蓋極大的數值範圍。量化的想法就是改用少很多的位元——典型是 8 位元整數(int8),有時甚至 4 位元——來表示這些數字。日常的比喻是:與其把每個價格都精確記到分,你改成四捨五入到整數元。你失去一點精度,但資料量小很多、運算也便宜很多——這正是把視覺模型部署到手機、攝影機或負載中的 GPU 伺服器時所追求的。
具體而言,均勻仿射量化(uniform affine quantization)以 q = round(r / s) + z 將實數值 r 映射成整數 q。其中 s(縮放係數,scale)是一個正的浮點數,等於一個量化步階的大小;z(零點,zero-point)是一個整數,選擇它使得實數 0 恰好映射到某個整數(這很重要,能讓補零保持精確)。要再使用該值時則做反量化:r ≈ s·(q − z)。位元寬度 b 提供 2^b 個離散階層,所以 int8 有 256 個。當強制 z=0 時稱為「對稱」(symmetric),否則為「非對稱」(asymmetric)。縮放係數可由整個張量共用(per-tensor),也可為權重的每個輸出通道分別選定(per-channel),後者對卷積與線性層精確得多。
好處既大且具體。從 FP32 轉到 int8 約可把模型大小縮為四分之一,而更重要的是降低串流權重與激活值所需的記憶體頻寬——這才是多數推論真正的瓶頸。整數矩陣乘法單元(CPU 的 SIMD、NVIDIA GPU 的 int8 張量核心、手機上的 NPU)比 FP32 快上數倍。代價則是量化誤差:四捨五入加上對落在選定範圍之外數值的截斷(clipping)。視覺 CNN(ResNet、MobileNet、EfficientNet)通常對 int8 非常穩健,top-1 準確率往往損失遠低於 1%;transformer 與 ViT 較困難,因為它們會產生很大的激活離群值(outlier),把縮放係數撐大,反而壓垮了一般數值的精度。
要區分幾種形態:僅量化權重(壓縮儲存、運算時即時反量化)對上量化權重與激活值(真正以整數執行矩陣乘法);靜態(激活值縮放係數透過校準固定)對上動態(在執行時依每個輸入計算);以及訓練後量化(PTQ,不需重訓)對上量化感知訓練(QAT,在訓練中模擬量化)。截至 2020 年代中期,int8 是已部署視覺模型的主力,FP8(E4M3/E5M2)在 Hopper/Ada 等級 GPU 上已是訓練與推論的標準,而僅量化權重的 int4(GPTQ、AWQ)在以記憶體為主要瓶頸的大型語言與多模態模型中很常見。
ResNet-50 在 FP32 下約 98 MB;採用 per-channel int8 量化可縮到約 25 MB,配合良好校準僅損失約 0.3% 的 ImageNet top-1,同時在 int8 張量核心上快上 2 至 4 倍。
並非每一層都該量化:第一層、最後一層、softmax 與正規化層常保留較高精度,真正的收益來自量化那些運算量大的卷積/矩陣乘法層。混合精度才是常態,而非例外。