bitsandbytes
是一个轻量级的 Python 库,专注于为 PyTorch 提供低精度(k-bit)优化和量化功能,主要用于降低大型语言模型(LLM)在训练和推理过程中的内存消耗,同时保持性能。它通过 CUDA 自定义函数实现 8 位和 4 位量化、优化器和矩阵乘法操作,特别适合在 GPU 上运行深度学习任务。以下是对 bitsandbytes
库的详细介绍,包括其功能、主要模块、用法和注意事项。
1. 核心功能
bitsandbytes
提供以下三大主要功能,用于大幅减少内存占用并加速计算:
- 8 位优化器:通过块级量化(block-wise quantization),以 8 位精度存储优化器状态,内存占用仅为 32 位优化器的 25%,同时保持接近 32 位性能。
- 8 位量化(LLM.int8()):通过向量级量化(vector-wise quantization),将模型权重量化为 8 位,异常值(outliers)使用 16 位矩阵乘法处理,推理内存占用减半,无明显性能下降。
- 4 位量化(QLoRA):将模型权重量化为 4 位,并结合低秩适配(LoRA)插入少量可训练权重,支持高效的模型微调,显著降低训练内存需求。
此外,库还支持:
- 稳定的嵌入层(
StableEmbedding
),提高 NLP 模型的训练稳定性。 - 高效的矩阵乘法操作,如
LLM.int8()
。 - 正在扩展对更多硬件后端(如 Intel CPU/GPU、AMD GPU、Apple Silicon)的支持,目前主要支持 NVIDIA CUDA GPU。
2. 主要模块和功能
bitsandbytes
库的 Python 接口主要包括以下模块和类:
a. bitsandbytes.optim
模块
提供 8 位优化器,替代 PyTorch 的标准优化器,支持常见的优化算法:
- 优化器:
Adam
,AdamW
,RMSProp
,LARS
,LAMB
,AdEMAMix
(8 位和分页变体)。 - 特点:
- 使用 8 位状态存储,节省内存。
- 支持百分位裁剪(percentile clipping),动态调整梯度裁剪阈值。
- 默认情况下,小于 4096 元素的参数(如偏置、批归一化参数)保持 32 位精度,以确保稳定性。
- 示例:
import bitsandbytes as bnb model = MyModel().cuda() # 替换标准 Adam 为 8 位 Adam optimizer = bnb.optim.Adam8bit(model.parameters(), lr=0.001, betas=(0.9, 0.995)) # 调整小参数的 8 位阈值 optimizer = bnb.optim.Adam8bit(model.parameters(), min_8bit_size=16384)
b. bitsandbytes.nn
模块
提供量化的神经网络层,替代 PyTorch 的标准层:
Linear8bitLt
:8 位线性层,支持LLM.int8()
,用于推理。import bitsandbytes as bnb linear = bnb.nn.Linear8bitLt(dim1, dim2, bias=True, has_fp16_weights=False, threshold=6.0) out = linear(x.to(torch.float16)) # 输入需为 FP16
Linear4bit
:4 位线性层,用于 QLoRA 微调。StableEmbedding
:为 NLP 模型设计的稳定嵌入层,通过更好的初始化和归一化提高稳定性。Embedding4bit
:4 位嵌入层,用于量化嵌入表。import torch.nn as nn from bitsandbytes.nn import Embedding4bit fp16_module = nn.Embedding(128, 64) quantized_module = Embedding4bit(128, 64) quantized_module.load_state_dict(fp16_module.state_dict()) quantized_module = quantized_module.to(0) # 移动到 GPU
c. bitsandbytes.functional
模块(部分功能已废弃)
提供底层的量化和矩阵乘法函数,例如:
matmul(...)
:支持 8 位矩阵乘法,带混合精度分解。- 注意:部分功能在最新版本(如 0.45.x)中已标记为废弃,建议使用
nn
模块中的高层接口。
d. bitsandbytes.optim.GlobalOptimManager
用于混合精度优化,允许部分参数使用 32 位优化器,其他参数使用 8 位优化器:
import torch
import bitsandbytes as bnb
model = MyModel()
mng = bnb.optim.GlobalOptimManager.get_instance()
mng.register_parameters(model.parameters())
model = model.cuda()
optimizer = bnb.optim.Adam(model.parameters(), lr=0.001, optim_bits=8)
mng.override_config(model.fc1.weight, 'optim_bits', 32) # 指定 fc1.weight 使用 32 位
3. 安装和环境要求
-
依赖:
- Python >= 3.8
- PyTorch(推荐通过 Anaconda 安装)
- CUDA > 10.0(0.39.0 版本后仅支持 CUDA >= 11.0)
- NVIDIA GPU(Turing/Ampere 架构,如 RTX 20xx/30xx、A40-A100 等支持 8 位张量核心;8 位优化器需要 Kepler 或更新架构,如 GTX 78x)
-
安装命令:
pip install bitsandbytes
或安装特定 CUDA 版本的预编译包:
pip install bitsandbytes-cudaXXX # XXX 为 110、111、113 等
-
验证安装:
python -m bitsandbytes
或运行官方测试脚本:
wget https://gist.githubusercontent.com/TimDettmers/1f5188c6ee6ed69d211b7fe4e381e713/raw/check_bnb_install.py python check_bnb_install.py
-
Windows 支持:截至 0.45.5,Windows 支持不完整,推荐使用 Linux 或从源代码编译:
git clone https://github.com/bitsandbytes-foundation/bitsandbytes.git cd bitsandbytes CUDA_VERSION=117 make cuda11x python setup.py install
-
注意:
- 确保 CUDA 版本与 PyTorch 和
bitsandbytes
兼容。 - 对于 Apple Silicon(M1/M2),目前无官方 MPS 支持,需等待多后端 alpha 版本。
- 确保 CUDA 版本与 PyTorch 和
4. 典型用法
以下是一些常见的使用场景和代码示例:
a. 加载 4 位量化模型(QLoRA)
结合 Hugging Face 的 transformers
库加载 4 位模型:
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
model_name = "facebook/opt-350m"
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True, # 双重量化,节省额外 0.4 位/参数
bnb_4bit_compute_dtype=torch.float16 # 计算使用 FP16
)
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto"
)
- 说明:
load_in_4bit=True
启用 4 位量化。device_map="auto"
自动分配模型到可用设备。
b. 使用 8 位优化器训练
替换标准优化器为 8 位优化器:
import bitsandbytes as bnb
model = MyModel().cuda()
optimizer = bnb.optim.Adam8bit(model.parameters(), lr=0.001)
for data in dataloader:
optimizer.zero_grad()
outputs = model(data)
loss = outputs.loss
loss.backward()
optimizer.step()
c. LLM.int8() 推理
使用 8 位线性层进行高效推理:
import torch
import bitsandbytes as bnb
linear = bnb.nn.Linear8bitLt(64, 64, bias=True, has_fp16_weights=False, threshold=6.0)
x = torch.randn(32, 64).to(torch.float16).cuda()
out = linear(x)
d. 结合 PEFT 进行 QLoRA 微调
结合 Hugging Face 的 PEFT 库进行 4 位模型微调:
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model
model_name = "facebook/opt-350m"
bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_compute_dtype=torch.float16)
model = AutoModelForCausalLM.from_pretrained(model_name, quantization_config=bnb_config, device_map="auto")
lora_config = LoraConfig(r=8, lora_alpha=16, target_modules=["q_proj", "v_proj"])
model = get_peft_model(model, lora_config)
# 进行微调
5. 注意事项
- 硬件限制:
LLM.int8()
要求 Turing 或 Ampere GPU(RTX 20xx/30xx、A40-A100)。- 8 位优化器支持 Kepler 或更新 GPU(GTX 78x 起)。
- 当前仅支持 Linux,Windows 支持需编译或使用非官方轮子(如
bitsandbytes-windows
)。
- 性能权衡:
- 8 位和 4 位量化可能引入轻微精度损失,需通过
threshold
或双重量化调整。 - 计算仍需 16 位或 32 位数据类型(如
torch.float16
)。
- 8 位和 4 位量化可能引入轻微精度损失,需通过
- 兼容性:
- 确保
bitsandbytes
、PyTorch 和 CUDA 版本匹配。 - 与 Hugging Face 的
transformers
和accelerate
配合使用时,建议安装最新版本:pip install -U bitsandbytes transformers accelerate
- 确保
- 已知问题:
6. 许可和引用
- 许可证:
bitsandbytes
大部分代码采用 MIT 许可证,PyTorch 部分采用 BSD 许可证。 - 引用:如果使用
LLM.int8()
或 8 位优化器,建议引用以下论文: - 致谢:库中 CPU 量化使用了 Fabio Cannizzo 的 FastBinarySearch。
7. 最新动态
- 版本 0.45.5(2025 年 4 月发布):修复了 CPU 构建问题,增强了 CUDA 12.8 支持(包括 NVIDIA Blackwell GPU)。
- 多后端支持:正在开发对 AMD ROCm、Intel CPU/GPU 和 Apple Silicon 的支持,目前处于 alpha 阶段。
- 4 位推理加速:最新版本的 4 位推理比 16 位推理快达 4.2 倍。
- 社区贡献:库由 90+ 贡献者维护,每周下载量超 62 万,GitHub 星标 6,556 次。
8. 参考资源
- 官方 GitHub:https://github.com/bitsandbytes-foundation/bitsandbytes
- PyPI:https://pypi.org/project/bitsandbytes/
- Hugging Face 文档:https://huggingface.co/docs/bitsandbytes
- QLoRA 博客:https://huggingface.co/blog/4bit-quantization
- LLM.int8() 博客:https://huggingface.co/blog/hf-bitsandbytes-integration