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 上更新