Transformers 文件
量化概念
並獲得增強的文件體驗
開始使用
量化概念
量化透過使用低精度資料型別(如 8 位整數或 int8)而非標準 32 位浮點數 (float32) 來表示模型權重和/或啟用,從而減少大型機器學習模型(例如 Transformers 庫中的模型)的記憶體佔用和計算成本。
降低模型精度帶來多項顯著優勢
- 更小的模型尺寸:低精度資料型別需要更少的儲存空間。例如,一個 int8 模型大約比其 float32 版本小 4 倍。
- 更快的推理:在相容硬體上(CPU 和 GPU 通常具有 int8 操作的專用指令),對低精度資料型別(特別是整數)進行操作可以顯著加快速度。這會降低延遲。
- 更低的能耗:更快的計算和更小的記憶體傳輸通常意味著更低的功耗。
量化的主要權衡是*效率*與*準確性*。降低精度可以節省資源,但不可避免地會引入小錯誤(量化噪聲)。目標是使用適當的方案(仿射/對稱)、粒度(每張量/通道)和技術(PTQ/QAT)來最大限度地減少此錯誤,以便模型在其目標任務上的效能儘可能少地下降。
以下部分將介紹量化方案、粒度和技術。
量化方案
核心思想是將原始 float32 權重和啟用中的值範圍對映到 int8 所表示的更小範圍(通常為).
本節介紹一些量化技術的工作原理。

仿射量化
最常見的方法是仿射量化。對於給定的 float32 張量(如層的權重),它找到最小值和最大值值。此範圍對映到 int8 範圍,通常為.
有兩種主要方法進行此對映:*對稱*和*非對稱*。對稱和非對稱量化之間的選擇決定了 float32 範圍如何對映到 int8 範圍。
- 對稱:此方法假設原始 float32 範圍圍繞零對稱()。此範圍對稱對映到 int8 範圍,例如,。一個關鍵特徵是 float32 值直接對映到 int8 值。這隻需要一個引數,即**比例()**,來定義對映。它可以簡化計算,但如果原始資料分佈並非自然地以零為中心,則準確性可能會降低。
- 非對稱(仿射):此方法不假設資料以零為中心。它將 float32 的精確範圍對映到完整的 int8 範圍,例如。這需要兩個引數:一個**比例()**和一個**零點()**。
比例():一個正的 float32 數,表示 float32 範圍和 int8 範圍之間的比率。
零點():一個 int8 值,對應於 float32 值.
在對稱量化中,Z 通常固定為 0。
有了這些引數,float32 值,。可以使用以下公式量化為 int8()。
int8 值,,可以透過以下公式反量化回近似 float32。

在推理過程中,像矩陣乘法這樣的計算是使用 int8 值()執行的,結果在傳遞給下一層之前,會反量化回 float32(通常在內部使用 int32 等更高精度累加型別)。
int4 和權重打包

int4 量化進一步減小了模型大小和記憶體使用(與 int8 相比減少了一半)。同樣的仿射或對稱量化原則適用,將 float32 範圍對映到 int4 可表示的 16 個可能值(對於有符號 int4)。
int4 量化的一個關鍵方面是**權重打包**。由於大多數硬體無法在記憶體中原生處理 4 位資料型別,因此通常將兩個 int4 值打包成一個 int8 位元組用於儲存和傳輸。例如,第一個值可能佔用低 4 位,第二個值佔用位元組的高 4 位(`packed_byte = (val1 & 0x0F) | (val2 << 4)`)。
即使沒有原生 int4 計算,int4 仍然有益,因為主要好處來自記憶體頻寬的減少。將打包的 int4 權重(儲存為 int8)從記憶體(RAM 或 VRAM)載入到計算單元的速度是載入 int8 權重的兩倍。對於大型模型,記憶體訪問通常是一個顯著的瓶頸。更快的傳輸速度帶來的加速可以抵消即時解包和反量化的計算開銷,從而實現整體更快的推理,尤其是在記憶體受限的場景中。
然而,int4 量化通常會導致比 int8 更大的精度損失。對於 int4 來說,通常需要像 GPTQ 或 AWQ 這樣的高階量化技術才能獲得良好的效能。
FP8 量化 (A8W8)

FP8 有兩種常見變體。
- E4M3:1 個符號位,4 個指數位,3 個尾數位。提供更高的精度(更多尾數位)但動態範圍更小(更少指數位)。
- E5M2:1 個符號位,5 個指數位,2 個尾數位。提供更寬的動態範圍但精度較低。
FP8 用於 *A8W8* 量化方案,該方案將啟用 (A) 和權重 (W) 都量化為 8 位精度。
雖然 int8 得到廣泛支援,但高效的 FP8 計算需要較新 GPU(如 NVIDIA H100/H200/B100 和 AMD Instinct MI300 系列)中特有的硬體功能。如果沒有原生的硬體加速,FP8 的優勢可能無法完全實現。
Transformers 透過特定的後端支援 FP8,例如 FBGEMM、FineGrainedFP8 和 compressed-tensors。當使用適當的硬體和配置時,這些後端處理底層的 FP8 轉換和計算。
粒度
量化引數(和)可以透過兩種方式計算。
- 每張量:整個張量使用一組和。更簡單,但如果張量內資料值差異很大,則精度較低。
- 每通道(或每組/塊):每個通道或組使用單獨的和。精度更高,效能更好,但成本是略微增加複雜性和記憶體。

量化技術
量化技術主要有兩種型別。
- 訓練後量化 (PTQ):在模型完全訓練*後*應用量化。
- 量化感知訓練 (QAT):在訓練*期間*透過插入“偽量化”操作來模擬量化效果,這些操作模擬量化的舍入誤差。這使得模型能夠適應量化,通常會帶來更好的準確性,尤其是在較低位寬下。
Transformers 中的量化
Transformers 集成了多個量化後端,例如 bitsandbytes、torchao、compressed-tensors 等(有關更多後端,請參閱量化概述)。
所有後端都統一在 `HfQuantizer` API 和相關的 `QuantizationConfig` 類下。您可以透過實現自定義 `HfQuantizer` 和 `QuantizationConfig` 來整合您自己的自定義量化後端,如貢獻指南中所示。
Transformers 中量化的典型工作流程是:
- 選擇適合您的硬體和用例的量化方法(請參閱概述或選擇量化方法指南以幫助您)。
- 從 Hugging Face Hub 載入預量化模型,或者載入 float32/float16/bfloat16 模型並使用 `QuantizationConfig` 應用特定量化方法。
下面的示例演示了載入一個 8B 引數模型並使用 bitsandbytes 將其量化為 4 位。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "meta-llama/Llama-3.1-8B-Instruct"
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quantization_config,
torch_dtype=torch.bfloat16,
device_map="auto"
)
資源
要更深入地探討量化和相關效能最佳化概念,請檢視以下資源。
- 使用 Hugging Face 進行量化基礎
- 深入瞭解量化
- 🤗 量化技術簡介 💗🧑🍳
- EfficientML.ai 講座 5 - 量化第一部分
- 從第一性原理實現深度學習的Brrrr
- 使用 PyTorch 加速生成式 AI 第二部分:LLM 最佳化