🤗 Transformers 中原生支援的量化方案概述
我們的目標是清晰地概述 transformers 中支援的每種量化方案的優缺點,以幫助您決定選擇哪一種。
目前,模型量化主要用於兩個目的:
- 在較小的裝置上執行大型模型的推理
- 在量化模型之上微調適配器
到目前為止,Transformers 中已經 **原生** 支援兩種整合方案:*bitsandbytes* 和 *auto-gptq*。請注意,🤗 optimum 庫 中也支援一些額外的量化方案,但這不在本部落格文章的討論範圍之內。
要了解有關每種受支援方案的更多資訊,請參閱下面共享的資源之一。另請參閱文件中的相應部分。
另請注意,下面共享的詳細資訊僅適用於 PyTorch
模型,目前不適用於 Tensorflow 和 Flax/JAX 模型。
目錄
資源
- GPTQ 部落格文章——概述了 GPTQ 量化方法及其使用方法。
- bitsandbytes 4 位量化部落格文章——此部落格文章介紹了 4 位量化和 QLoRa,一種高效的微調方法。
- bitsandbytes 8 位量化部落格文章——此部落格文章解釋了 8 位量化如何與 bitsandbytes 配合使用。
- GPTQ 的基本用法 Google Colab 筆記本——此筆記本展示瞭如何使用 GPTQ 方法量化 Transformers 模型、如何進行推理以及如何使用量化模型進行微調。
- bitsandbytes 的基本用法 Google Colab 筆記本——此筆記本展示瞭如何使用所有變體的 4 位模型進行推理,以及如何在免費的 Google Colab 例項上執行 GPT-neo-X(一個 20B 引數模型)。
- Merve 關於量化的部落格文章——此部落格文章提供了量化和 Transformers 中原生支援的量化方法的簡要介紹。
比較 bitsandbytes 和 auto-gptq
在本節中,我們將介紹 bitsandbytes 和 gptq 量化的優缺點。請注意,這些是基於社群反饋得出的,並且隨著這些功能在各自庫的路線圖中不斷發展,它們可能會隨時間而變化。
bitsandbytes 有何優點?
簡易性:bitsandbytes 仍然是量化任何模型最簡單的方法,因為它不需要使用輸入資料校準量化模型(也稱為零樣本量化)。只要模型包含 torch.nn.Linear
模組,就可以開箱即用地量化任何模型。每當新的架構新增到 Transformers 中時,只要它們可以使用 accelerate 的 device_map="auto"
載入,使用者就可以直接使用 bitsandbytes 量化,並且效能損失極小。量化在模型載入時執行,無需執行任何後處理或準備步驟。
跨模態互操作性:由於量化模型的唯一條件是包含 torch.nn.Linear
層,因此量化開箱即用於任何模態,從而可以開箱即用地以 8 位或 4 位載入 Whisper、ViT、Blip2 等模型。
合併介面卡時效能零下降:(如果您不熟悉介面卡和 PEFT,請參閱這篇部落格文章)。如果您在量化基模型之上訓練介面卡,則可以將介面卡合併到基模型之上以進行部署,而推理效能不會下降。您還可以將介面卡合併到去量化模型之上!GPTQ 不支援此功能。
autoGPTQ 有何優點?
文字生成速度快:與 bitsandbytes 量化模型相比,GPTQ 量化模型在文字生成方面速度更快。我們將在適當的部分討論速度比較。
n 位支援:GPTQ 演算法可以將模型量化到 2 位!但是,這可能會導致嚴重的質量下降。推薦的位數為 4 位,這似乎是目前 GPTQ 的一個很好的權衡。
易於序列化:GPTQ 模型支援任意位數的序列化。只要安裝了所需的軟體包,就可以開箱即用地從 TheBloke 名稱空間載入模型:https://huggingface.co/TheBloke(查詢以 -GPTQ
字尾結尾的模型)。bitsandbytes 支援 8 位序列化,但目前不支援 4 位序列化。
AMD 支援:該整合應該開箱即用於 AMD GPU!
bitsandbytes 有哪些潛在改進空間?
文字生成速度慢於 GPTQ:使用 generate
時,bitsandbytes 4 位模型的速度慢於 GPTQ。
4 位權重不可序列化:目前,4 位模型無法序列化。這是社群的常見請求,我們相信 bitsandbytes 維護者很快就會解決這個問題,因為它在他們的路線圖中!
autoGPTQ 有哪些潛在改進空間?
校準資料集:對校準資料集的需求可能會勸退一些使用者使用 GPTQ。此外,量化模型可能需要幾個小時(例如,根據論文第 2 節,175B 規模的模型需要 4 個 GPU 小時)。
目前僅適用於語言模型:截至今天,用於使用 auto-GPTQ 量化模型的 API 已設計為僅支援語言模型。應該可以使用 GPTQ 演算法量化非文字(或多模態)模型,但原始論文或 auto-gptq 儲存庫中尚未闡述該過程。如果社群對此主題感興趣,將來可能會考慮。
深入研究速度基準
我們決定為 bitsandbytes 和 auto-gptq 在不同硬體上進行推理和微調適配器進行廣泛的基準測試。推理基準測試應該讓使用者瞭解我們提出的不同推理方法之間的速度差異,而介面卡微調基準測試應該讓使用者在決定微調 bitsandbytes 和 GPTQ 基模型時使用哪種方法時有一個清晰的概念。
我們將使用以下設定:
- bitsandbytes:4 位量化,
bnb_4bit_compute_dtype=torch.float16
。請確保使用bitsandbytes>=0.41.1
以獲得更快的 4 位核。 - auto-gptq:4 位量化,使用 exllama 核。您需要
auto-gptq>=0.4.0
才能使用 ex-llama 核。
推理速度(僅前向傳播)
此基準僅測量預填充步驟,這對應於訓練期間的前向傳播。它在單個 NVIDIA A100-SXM4-80GB GPU 上執行,提示長度為 512。我們使用的模型是 meta-llama/Llama-2-13b-hf
。
批處理大小 = 1
量化 | act_order | 位 | group_size | 核心 | 載入時間(秒) | 每令牌延遲(毫秒) | 吞吐量(令牌/秒) | 峰值記憶體(MB) |
---|---|---|---|---|---|---|---|---|
fp16 | 無 | 無 | 無 | 無 | 26.0 | 36.958 | 27.058 | 29152.98 |
gptq | 否 (False) | 4 | 128 | exllama | 36.2 | 33.711 | 29.663 | 10484.34 |
bitsandbytes | 無 | 4 | 無 | 無 | 37.64 | 52.00 | 19.23 | 11018.36 |
批處理大小 = 16
量化 | act_order | 位 | group_size | 核心 | 載入時間(秒) | 每令牌延遲(毫秒) | 吞吐量(令牌/秒) | 峰值記憶體(MB) |
---|---|---|---|---|---|---|---|---|
fp16 | 無 | 無 | 無 | 無 | 26.0 | 69.94 | 228.76 | 53986.51 |
gptq | 否 (False) | 4 | 128 | exllama | 36.2 | 95.41 | 167.68 | 34777.04 |
bitsandbytes | 無 | 4 | 無 | 無 | 37.64 | 113.98 | 140.38 | 35532.37 |
從基準測試中可以看出,bitsandbytes 和 GPTQ 是等效的,對於大批次,GPTQ 略快。有關這些基準測試的更多詳細資訊,請檢視此連結。
生成速度
以下基準衡量模型在推理期間的生成速度。可在此處找到基準指令碼,以確保重現性:這裡。
use_cache
讓我們測試 use_cache
以更好地瞭解在生成過程中快取隱藏狀態的影響。
該基準在 A100 上執行,提示長度為 30,我們生成了精確的 30 個標記。我們使用的模型是 meta-llama/Llama-2-7b-hf
。
使用 use_cache=True
使用 use_cache=False
從這兩個基準中,我們得出結論,正如預期的那樣,當使用注意力快取時,生成速度更快。此外,GPTQ 通常比 bitsandbytes 快。例如,在 batch_size=4
和 use_cache=True
的情況下,它的速度是兩倍!因此,讓我們在接下來的基準測試中使用 use_cache
。請注意,use_cache
將消耗更多記憶體。
硬體
在以下基準測試中,我們將嘗試不同的硬體,以瞭解其對量化模型的影響。我們使用的提示長度為 30,並且精確生成了 30 個令牌。我們使用的模型是 meta-llama/Llama-2-7b-hf
。
使用 NVIDIA A100
使用 NVIDIA T4
使用 Titan RTX
從上面的基準測試中,我們可以得出結論,對於這三種 GPU,GPTQ 都比 bitsandbytes 快。
生成長度
在下面的基準測試中,我們將嘗試不同的生成長度,以檢視它們對量化模型的影響。它在 A100 上執行,我們使用了 30 個令牌的提示長度,並改變了生成的令牌數量。我們使用的模型是 meta-llama/Llama-2-7b-hf
。
生成 30 個令牌
生成 512 個令牌
從上面的基準測試中,我們可以得出結論,無論生成長度如何,GPTQ 都比 bitsandbytes 快。
介面卡微調(前向 + 後向)
無法在量化模型上進行純訓練。但是,您可以透過利用引數高效微調方法 (PEFT) 並在其上訓練介面卡來微調量化模型。微調方法將依賴於一種名為“低秩介面卡”(LoRA) 的最新方法:您無需微調整個模型,只需微調這些介面卡並將其正確載入到模型中即可。讓我們比較一下微調速度!
該基準在 NVIDIA A100 GPU 上執行,我們使用了來自 Hub 的 meta-llama/Llama-2-7b-hf
模型。請注意,對於 GPTQ 模型,我們不得不停用 exllama 核,因為 exllama 不支援微調。
從結果來看,我們得出結論,bitsandbytes 在微調方面比 GPTQ 快。
效能下降
量化對於減少記憶體消耗非常有用。但是,它確實會帶來效能下降。讓我們使用 Open-LLM 排行榜 來比較效能!
使用 7b 模型
模型 ID | 平均分 | ARC | Hellaswag | MMLU | TruthfulQA |
---|---|---|---|---|---|
meta-llama/llama-2-7b-hf | 54.32 | 53.07 | 78.59 | 46.87 | 38.76 |
meta-llama/llama-2-7b-hf-bnb-4bit | 53.4 | 53.07 | 77.74 | 43.8 | 38.98 |
TheBloke/Llama-2-7B-GPTQ | 53.23 | 52.05 | 77.59 | 43.99 | 39.32 |
使用 13b 模型
模型 ID | 平均分 | ARC | Hellaswag | MMLU | TruthfulQA |
---|---|---|---|---|---|
meta-llama/llama-2-13b-hf | 58.66 | 59.39 | 82.13 | 55.74 | 37.38 |
TheBloke/Llama-2-13B-GPTQ (修訂版 = 'gptq-4bit-128g-actorder_True') | 58.03 | 59.13 | 81.48 | 54.45 | 37.07 |
TheBloke/Llama-2-13B-GPTQ | 57.56 | 57.25 | 81.66 | 54.81 | 36.56 |
meta-llama/llama-2-13b-hf-bnb-4bit | 56.9 | 58.11 | 80.97 | 54.34 | 34.17 |
從以上結果可以看出,模型越大,效能下降越小。更有趣的是,效能下降是微乎其微的!
結論和總結
在這篇部落格文章中,我們比較了 bitsandbytes 和 GPTQ 量化在多種設定下的表現。我們看到 bitsandbytes 更適合微調,而 GPTQ 更適合生成。從這個觀察中,獲得更好的合併模型的一種方法是:
- (1) 使用 bitsandbytes 量化基礎模型(零樣本量化)
- (2) 新增並微調適配器
- (3) 將訓練好的介面卡合併到基礎模型或去量化模型之上!
- (4) 使用 GPTQ 量化合並後的模型並用於部署
我們希望這份概述能讓大家更輕鬆地在其應用程式和用例中使用大型語言模型,我們期待看到大家將用它構建什麼!
致謝
我們要感謝 Ilyas、Clémentine 和 Felix 在基準測試方面提供的幫助。
最後,我們要感謝 Pedro Cuenca 在撰寫此部落格文章方面提供的幫助。