Transformers 文件
Bitsandbytes
並獲得增強的文件體驗
開始使用
Bitsandbytes
bitsandbytes 庫透過 CUDA 函式的輕量級 Python 包裝器,為 LLM 提供了量化工具。它透過減少記憶體佔用,使得使用有限計算資源處理大型模型成為可能。
bitsandbytes 的核心功能包括:
- 量化線性層:`Linear8bitLt` 和 `Linear4bit` 層取代了標準的 PyTorch 線性層,提供了記憶體效率更高的量化替代方案。
- 最佳化器最佳化:透過其 `optim` 模組提供常見最佳化器的 8 位版本,從而能夠以更低的記憶體需求訓練大型模型。
- 矩陣乘法:利用量化格式最佳化的矩陣乘法操作。
bitsandbytes 提供兩個主要量化功能:
LLM.int8() - 一種 8 位量化方法,使推理更易於訪問,而不會顯著降低效能。與樸素量化不同,LLM.int8() 動態地為關鍵計算保留更高的精度,防止模型敏感部分的 R 息丟失。
QLoRA - 一種 4 位量化技術,透過插入少量可訓練的低秩適應 (LoRA) 權重,進一步壓縮模型,同時保持可訓練性。
注意: 如需使用者友好的量化體驗,您可以使用 `bitsandbytes` 社群空間。
執行以下命令安裝 bitsandbytes。
pip install --upgrade transformers accelerate bitsandbytes
要從原始碼編譯,請遵循 bitsandbytes 安裝指南 中的說明。
硬體相容性
bitsandbytes 目前僅支援 CUDA 版本 11.0 - 12.8 的 CUDA GPU。但是,一項多後端工作正在開發中,目前處於 Alpha 階段。如果您有興趣提供反饋或進行測試,請檢視 bitsandbytes 倉庫 獲取更多資訊。
CUDA
特性 | 最低硬體要求 |
---|---|
8 位最佳化器 | NVIDIA Maxwell (GTX 900 系列, TITAN X, M40) 或更新的 GPU * |
LLM.int8() | NVIDIA Turing (RTX 20 系列, T4) 或更新的 GPU |
NF4/FP4 量化 | NVIDIA Maxwell (GTX 900 系列, TITAN X, M40) 或更新的 GPU * |
多後端
後端 | 支援版本 | Python 版本 | 架構支援 | 狀態 |
---|---|---|---|---|
AMD ROCm | 6.1+ | 3.10+ | 最低 CDNA - gfx90a, RDNA - gfx1100 | Alpha |
Apple Silicon (MPS) | 進行中 | 3.10+ | M1/M2 晶片 | 計劃中 |
Intel CPU | v2.4.0+ (ipex) | 3.10+ | Intel CPU | Alpha |
英特爾 GPU | v2.4.0+ (ipex) | 3.10+ | 英特爾 GPU | 實驗性 |
Ascend NPU | 2.1.0+ (torch_npu) | 3.10+ | Ascend NPU | 實驗性 |
注意: Bitsandbytes 正在從多後端方法轉向使用 Pytorch Custom Operators,作為支援新硬體和分派到正確後端的主要機制。
量化示例
透過將 BitsAndBytesConfig 傳遞給 from_pretrained() 來量化模型。只要模型支援 Accelerate 並且包含 torch.nn.Linear 層,此方法適用於任何模態的任何模型。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model_8bit = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-1b7",
device_map="auto",
quantization_config=quantization_config
)
預設情況下,所有其他模組(如 torch.nn.LayerNorm)都設定為預設的 torch dtype。您可以使用 `torch_dtype` 引數更改這些模組的資料型別。設定 `torch_dtype="auto"` 會以模型 `config.json` 檔案中定義的資料型別載入模型。
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model_8bit = AutoModelForCausalLM.from_pretrained(
"facebook/opt-350m",
device_map="auto",
quantization_config=quantization_config,
torch_dtype="auto"
)
model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtype
一旦模型被量化為 8 位,除非您使用的是最新版本的 Transformers 和 bitsandbytes,否則無法將量化後的權重推送到 Hub。如果您有最新版本,則可以使用 push_to_hub() 將 8 位模型推送到 Hub。量化 config.json 檔案首先被推送,然後是量化後的模型權重。
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-560m",
device_map="auto",
quantization_config=quantization_config
)
model.push_to_hub("bloom-560m-8bit")
8 位和 4 位訓練僅支援訓練*額外*引數。
使用 `get_memory_footprint` 檢查您的記憶體佔用。
print(model.get_memory_footprint())
使用 from_pretrained() 載入量化模型,無需 `quantization_config`。
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("{your_username}/bloom-560m-8bit", device_map="auto")
LLM.int8
本節探討 8 位量化的一些特定功能,例如解除安裝、離群值閾值、跳過模組轉換和微調。
解除安裝
8 位模型可以在 CPU 和 GPU 之間解除安裝權重,以將非常大的模型適應記憶體。排程到 CPU 的權重以 float32 儲存,不會轉換為 8 位。例如,透過 BitsAndBytesConfig 為 bigscience/bloom-1b7 啟用解除安裝。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True)
設計一個自定義裝置對映,將所有內容都放在 GPU 上,除了 `lm_head`,它被排程到 CPU。
device_map = {
"transformer.word_embeddings": 0,
"transformer.word_embeddings_layernorm": 0,
"lm_head": "cpu",
"transformer.h": 0,
"transformer.ln_f": 0,
}
現在,使用自定義 `device_map` 和 `quantization_config` 載入您的模型。
model_8bit = AutoModelForCausalLM.from_pretrained(
"bigscience/bloom-1b7",
torch_dtype="auto",
device_map=device_map,
quantization_config=quantization_config,
)
離群值閾值
“異常值”是指超過某個閾值的隱藏狀態值,這些值以 fp16 形式計算。雖然這些值通常呈正態分佈([-3.5, 3.5]),但對於大型模型,此分佈可能非常不同([-60, 6] 或 [6, 60])。8 位量化對於 ~5 的值效果很好,但超出此範圍,效能會顯著下降。一個好的預設閾值是 6,但對於更不穩定的模型(小型模型或微調),可能需要更低的閾值。
要為您的模型找到最佳閾值,請在 BitsAndBytesConfig 中嘗試使用 `llm_int8_threshold` 引數。例如,將閾值設定為 `0.0` 可以顯著加快推理速度,但可能會損失一些準確性。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
model_id = "bigscience/bloom-1b7"
quantization_config = BitsAndBytesConfig(
llm_int8_threshold=0.0,
llm_int8_enable_fp32_cpu_offload=True
)
model_8bit = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map=device_map,
quantization_config=quantization_config,
)
跳過模組轉換
對於某些模型,例如 Jukebox,您不需要將每個模組都量化為 8 位,因為這實際上可能導致不穩定。對於 Jukebox,有幾個 `lm_head` 模組應該使用 BitsAndBytesConfig 中的 `llm_int8_skip_modules` 引數跳過。
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "bigscience/bloom-1b7"
quantization_config = BitsAndBytesConfig(
llm_int8_skip_modules=["lm_head"],
)
model_8bit = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map="auto",
quantization_config=quantization_config,
)
微調
PEFT 庫支援使用 8 位量化微調大型模型,如 flan-t5-large 和 facebook/opt-6.7b。您無需傳遞 `device_map` 引數進行訓練,因為它會自動將模型載入到 GPU 上。但是,您仍然可以使用 `device_map` 引數自定義裝置對映(`device_map="auto"` 僅應用於推理)。
QLoRA
本節探討 4 位量化的一些特定功能,例如更改計算資料型別、普通浮點 4 (NF4) 資料型別和巢狀量化。
計算資料型別
更改 BitsAndBytesConfig 中的資料型別,從 float32(預設值)更改為 bf16 以加速計算。
import torch
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)
普通浮點 4 (NF4)
NF4 是 QLoRA 論文中的 4 位資料型別,適用於從正態分佈初始化的權重。您應該使用 NF4 來訓練 4 位基礎模型。
from transformers import BitsAndBytesConfig
nf4_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
)
model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype="auto", quantization_config=nf4_config)
對於推理,`bnb_4bit_quant_type` 對效能影響不大。但是,為了與模型權重保持一致,您應該使用 `bnb_4bit_compute_dtype` 和 `torch_dtype` 值。
巢狀量化
巢狀量化可以在不增加額外效能成本的情況下節省額外的記憶體。此功能對已經量化的權重執行第二次量化,以額外節省 0.4 位元/引數。例如,使用巢狀量化,您可以在具有 1024 序列長度、1 批次大小和啟用 4 步梯度累積的 16GB NVIDIA T4 GPU 上微調 Llama-13b 模型。
from transformers import BitsAndBytesConfig
double_quant_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
)
model_double_quant = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-13b-chat-hf", torch_dtype="auto", quantization_config=double_quant_config)
Bitsandbytes 模型去量化
一旦量化,您可以 dequantize() 模型至原始精度,但這可能導致一些質量損失。請確保您有足夠的 GPU 記憶體來適應去量化後的模型。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", BitsAndBytesConfig(load_in_4bit=True))
model.dequantize()
資源
在 使用 Hugging Face Transformers、Accelerate 和 bitsandbytes 對大型 Transformer 進行 8 位矩陣乘法的溫和介紹 中瞭解更多關於 8 位量化的細節。
在 此 notebook 中嘗試 4 位量化,並在 透過 bitsandbytes、4 位量化和 QLoRA 使 LLM 更易於訪問 中瞭解更多細節。
< > 在 GitHub 上更新