Transformers documentation

Bitsandbytes

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Bitsandbytes

Thư viện bitsandbytes cung cấp các công cụ lượng tử hóa cho LLM thông qua một lớp bọc Python nhẹ nhàng quanh các hàm của bộ tăng tốc phần cứng. Nó cho phép làm việc với các mô hình lớn bằng tài nguyên tính toán hạn chế thông qua việc giảm dung lượng bộ nhớ của chúng.

Về cốt lõi, bitsandbytes cung cấp:

  • Tầng Linear đã lượng tử hóa: các tầng Linear8bitLt và Linear4bit thay thế các tầng linear chuẩn của PyTorch bằng các phương án lượng tử hóa tiết kiệm bộ nhớ
  • Trình tối ưu được tối ưu hóa: các phiên bản 8-bit của các trình tối ưu phổ biến thông qua module optim, cho phép huấn luyện các mô hình lớn với yêu cầu bộ nhớ thấp hơn
  • Nhân ma trận: Các thao tác nhân ma trận được tối ưu hóa, tận dụng định dạng lượng tử hóa

bitsandbytes cung cấp hai tính năng lượng hóa chính:

  1. LLM.int8() - Phương pháp lượng tử hóa 8-bit giúp suy luận dễ tiếp cận hơn mà không gây suy giảm hiệu suất đáng kể. Khác với lượng tử hóa đơn giản, LLM.int8() động giữ lại độ chính xác cao hơn cho các phép tính quan trọng, ngăn ngừa mất thông tin ở những phần nhạy cảm của mô hình.

  2. QLoRA - Kỹ thuật lượng tử hóa 4-bit nén mô hình sâu hơn nữa trong khi vẫn duy trì khả năng huấn luyện bằng cách chèn một tập hợp nhỏ các trọng số thích ứng hạng thấp (LoRA) có thể huấn luyện được.

Lưu ý: Để có trải nghiệm lượng tử hóa thân thiện với người dùng, bạn có thể sử dụng không gian cộng đồng của bitsandbytes.

Chạy lệnh bên dưới để cài đặt bitsandbytes.

pip install --upgrade transformers accelerate bitsandbytes

Để biên dịch từ mã nguồn, hãy làm theo các hướng dẫn trong hướng dẫn cài đặt bitsandbytes.

Tương thích phần cứng

bitsandbytes được hỗ trợ trên GPU NVIDIA cho các phiên bản CUDA 11.8 - 13.0, Intel XPU, Intel Gaudi (HPU) và CPU. Hiện có nỗ lực đang diễn ra để hỗ trợ thêm các nền tảng khác. Nếu bạn quan tâm đến việc cung cấp phản hồi hoặc kiểm thử, hãy xem kho bitsandbytes để biết thêm thông tin.

GPU NVIDIA (CUDA)

Backend này được hỗ trợ trên các nền tảng Linux x86-64, Linux aarch64 và Windows.

Tính năngYêu cầu phần cứng tối thiểu
Trình tối ưu hóa 8-bitGPU NVIDIA Pascal (dòng GTX 10X0, P100) hoặc mới hơn *
LLM.int8()GPU NVIDIA Turing (dòng RTX 20X0, T4) hoặc mới hơn
Lượng tử hóa NF4/FP4GPU NVIDIA Pascal (dòng GTX 10X0, P100) hoặc mới hơn *

GPU Intel (XPU)

Backend này được hỗ trợ trên các nền tảng Linux x86-64 và Windows x86-64.

Intel Gaudi (HPU)

Backend này được hỗ trợ trên Linux x86-64 cho Gaudi2 và Gaudi3.

CPU

Backend này được hỗ trợ trên các nền tảng Linux x86-64, Linux aarch64 và Windows x86-64.

Ví dụ về Lượng tử hóa

Thực hiện lượng tử hóa một mô hình bằng cách truyền BitsAndBytesConfig vào from_pretrained(). Cách này hoạt động với bất kỳ mô hình nào thuộc bất kỳ chế độ nào, miễn là mô hình đó hỗ trợ Accelerate và chứa các lớp torch.nn.Linear.

8-bit
4-bit
Quantizing a model in 8-bit halves the memory-usage, and for large models, set `device_map="auto"` to efficiently distribute the weights across all available GPUs.
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
)

Mặc định, tất cả các module khác như torch.nn.LayerNorm được đặt thành dtype torch mặc định. Bạn có thể thay đổi kiểu dữ liệu của các module này bằng tham số dtype. Đặt dtype="auto" sẽ tải mô hình với kiểu dữ liệu được định nghĩa trong tệp config.json của mô hình.

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, 
    dtype="auto"
)
model_8bit.model.decoder.layers[-1].final_layer_norm.weight.dtype

Khi một model đã được lượng tử hóa xuống 8-bit, bạn không thể đẩy các trọng số đã lượng tử hóa lên Hub trừ khi bạn đang sử dụng phiên bản mới nhất của Transformers và bitsandbytes. Nếu bạn có các phiên bản mới nhất, bạn có thể đẩy model 8-bit lên Hub bằng push_to_hub(). File cấu hình lượng tử hóa config.json sẽ được đẩy trước, sau đó là các trọng số model đã lượng tử hóa.

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")

Huấn luyện 8-bit và 4-bit chỉ được hỗ trợ cho việc huấn luyện các tham số thêm.

Kiểm tra mức sử dụng bộ nhớ của bạn bằng get_memory_footprint.

print(model.get_memory_footprint())

Tải các mô hình đã lượng tử hóa bằng from_pretrained() mà không cần quantization_config.

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("{your_username}/bloom-560m-8bit", device_map="auto")

LLM.int8

Phần này khám phá một số tính năng cụ thể của lượng tử hóa 8-bit, chẳng hạn như offloading, ngưỡng ngoại lệ, bỏ qua chuyển đổi module và finetuning.

Offloading

Các mô hình 8-bit có thể chuyển đổi trọng số giữa CPU và GPU để đưa các mô hình rất lớn vào bộ nhớ. Các trọng số được chuyển đến CPU được lưu ở dạng float32 và không được chuyển đổi sang 8-bit. Ví dụ, hãy bật tính năng offload cho bigscience/bloom-1b7 thông qua BitsAndBytesConfig.

from transformers import AutoModelForCausalLM, BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(llm_int8_enable_fp32_cpu_offload=True)

Thiết kế một bản đồ thiết bị tùy chỉnh để đặt mọi thứ lên GPU của bạn, ngoại trừ lm_head, phần này sẽ được điều phối sang CPU.

device_map = {
    "transformer.word_embeddings": 0,
    "transformer.word_embeddings_layernorm": 0,
    "lm_head": "cpu",
    "transformer.h": 0,
    "transformer.ln_f": 0,
}

Bây giờ hãy tải mô hình của bạn với device_map tùy chỉnh và quantization_config.

model_8bit = AutoModelForCausalLM.from_pretrained(
    "bigscience/bloom-1b7",
    dtype="auto",
    device_map=device_map,
    quantization_config=quantization_config,
)

Ngưỡng ngoại lai

Một “outlier” là giá trị trạng thái ẩn lớn hơn một ngưỡng nhất định, và các giá trị này được tính toán ở fp16. Mặc dù các giá trị thường có phân phối chuẩn ([-3.5, 3.5]), nhưng phân phối này có thể rất khác nhau đối với các mô hình lớn ([-60, 6] hoặc [6, 60]). Lượng tử hóa 8-bit hoạt động tốt cho các giá trị ~5, nhưng vượt quá mức đó, sẽ có sự suy giảm hiệu suất đáng kể. Một giá trị ngưỡng mặc định tốt là 6, nhưng có thể cần một ngưỡng thấp hơn cho các mô hình kém ổn định hơn (mô hình nhỏ hoặc finetuning).

Để tìm ngưỡng tối ưu cho mô hình của bạn, hãy thử nghiệm với tham số llm_int8_threshold trong BitsAndBytesConfig. Ví dụ, đặt ngưỡng thành 0.0 sẽ tăng tốc độ suy luận đáng kể, với chi phí tiềm ẩn là một phần độ chính xác.

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,
    dtype="auto",
    device_map=device_map,
    quantization_config=quantization_config,
)

Bỏ qua chuyển đổi module

Đối với một số mô hình, chẳng hạn như Jukebox, bạn không cần phải lượng tử hóa mọi module xuống 8-bit vì điều này thực sự có thể gây ra sự bất ổn. Với Jukebox, có một số module lm_head nên được bỏ qua bằng cách sử dụng tham số llm_int8_skip_modules trong BitsAndBytesConfig.

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,
    dtype="auto",
    device_map="auto",
    quantization_config=quantization_config,
)

Tinh chỉnh

Thư viện PEFT hỗ trợ tinh chỉnh các mô hình lớn như flan-t5-large và facebook/opt-6.7b với lượng tử hóa 8-bit. Bạn không cần truyền tham số device_map cho quá trình huấn luyện vì nó tự động tải mô hình của bạn lên GPU. Tuy nhiên, bạn vẫn có thể tùy chỉnh bản đồ thiết bị bằng tham số device_map (device_map="auto" chỉ nên được sử dụng cho suy luận).

QLoRA

Phần này khám phá một số tính năng cụ thể của lượng tử hóa 4-bit, chẳng hạn như thay đổi kiểu dữ liệu tính toán, kiểu dữ liệu Normal Float 4 (NF4) và lượng tử hóa lồng nhau.

Loại dữ liệu tính toán

Thay đổi kiểu dữ liệu từ float32 (giá trị mặc định) sang bf16 trong BitsAndBytesConfig để tăng tốc độ tính toán.

import torch
from transformers import BitsAndBytesConfig

quantization_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16)

Float 4 thông thường (NF4)

NF4 là kiểu dữ liệu 4-bit từ bài báo QLoRA, được điều chỉnh cho các trọng số được khởi tạo từ phân phối chuẩn. Bạn nên sử dụng NF4 để huấn luyện các mô hình cơ bản 4-bit.

from transformers import BitsAndBytesConfig

nf4_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
)

model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, dtype="auto", quantization_config=nf4_config)

Đối với suy luận, bnb_4bit_quant_type không có tác động lớn đến hiệu suất. Tuy nhiên, để nhất quán với trọng số của mô hình, bạn nên sử dụng các giá trị bnb_4bit_compute_dtype và dtype.

Lượng tử hóa lồng nhau

Lượng tử hóa lồng nhau có thể tiết kiệm thêm bộ nhớ mà không làm tăng chi phí hiệu năng. Tính năng này thực hiện lượng tử hóa lần hai đối với các trọng số đã được lượng tử hóa để tiết kiệm thêm 0,4 bit/tham số. Ví dụ, với lượng tử hóa lồng nhau, bạn có thể tinh chỉnh một mô hình Llama-13b trên GPU NVIDIA T4 16GB với độ dài chuỗi là 1024, kích thước lô là 1, và bật tích lũy gradient với 4 bước.

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", dtype="auto", quantization_config=double_quant_config)

Khử lượng hóa các mô hình bitsandbytes

Sau khi lượng tử hóa, bạn có thể dequantize() một mô hình về độ chính xác ban đầu, nhưng điều này có thể dẫn đến một số suy giảm chất lượng. Hãy đảm bảo bạn có đủ bộ nhớ GPU để chứa mô hình đã khử lượng tử hóa.

from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m", BitsAndBytesConfig(load_in_4bit=True))
model.dequantize()

Tài nguyên

Tìm hiểu thêm về các chi tiết của lượng tử hóa 8-bit trong A Gentle Introduction to 8-bit Matrix Multiplication for transformers at scale using Hugging Face Transformers, Accelerate and bitsandbytes.

Thử nghiệm lượng tử hóa 4-bit trong notebook này và tìm hiểu thêm về các chi tiết của nó trong Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA.

Update on GitHub