Transformers 文件

Bitsandbytes

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

Bitsandbytes

bitsandbytes 庫透過 CUDA 函式的輕量級 Python 包裝器,為 LLM 提供了量化工具。它透過減少記憶體佔用,使得使用有限計算資源處理大型模型成為可能。

bitsandbytes 的核心功能包括:

  • 量化線性層:`Linear8bitLt` 和 `Linear4bit` 層取代了標準的 PyTorch 線性層,提供了記憶體效率更高的量化替代方案。
  • 最佳化器最佳化:透過其 `optim` 模組提供常見最佳化器的 8 位版本,從而能夠以更低的記憶體需求訓練大型模型。
  • 矩陣乘法:利用量化格式最佳化的矩陣乘法操作。

bitsandbytes 提供兩個主要量化功能:

  1. LLM.int8() - 一種 8 位量化方法,使推理更易於訪問,而不會顯著降低效能。與樸素量化不同,LLM.int8() 動態地為關鍵計算保留更高的精度,防止模型敏感部分的 R 息丟失。

  2. 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 層,此方法適用於任何模態的任何模型。

8位
4位
將模型量化為 8 位可將記憶體使用量減半,對於大型模型,設定 `device_map="auto"` 可有效將權重分佈到所有可用的 GPU 上。
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 位。例如,透過 BitsAndBytesConfigbigscience/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-largefacebook/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 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.