mcpField
Q
quantizing-models-bitsandbytes

quantizing-models-bitsandbytes

github.com/orchestra-research开发14.1k974 次安装19 周前更新
代码仓库

关于 quantizing-models-bitsandbytes

一份介绍 bitsandbytes 的技能指南,讲解如何量化语言模型以降低推理和训练的内存占用。内容涵盖 4-bit 与 8-bit 加载、QLoRA 微调,以及面向 HuggingFace Transformers 用户的 8-bit 优化器。

主要功能

  1. 01以 4-bit 或 8-bit 加载模型
  2. 02配置 NF4 与双重量化
  3. 03使用 QLoRA 和 LoRA 适配器微调
  4. 04使用 8-bit Adam 和 AdamW 优化器
  5. 05将模型数据卸载到 CPU 或磁盘

适用场景

  1. 01在 GPU 内存有限时加载大型模型
  2. 02使用 QLoRA 微调量化模型
  3. 03减少训练期间的优化器内存
  4. 04GPU 内存不足时卸载模型权重

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/orchestra-research/ai-research-skills --skill quantizing-models-bitsandbytes

安装后在 Claude Code 中输入/quantizing-models-bitsandbytes确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
memory-optimization.md
qlora-training.md
quantization-formats.md

详细介绍

bitsandbytes - 大模型量化

快速开始

bitsandbytes 可将大模型的内存占用降低 50%(8 位)或 75%(4 位),准确率损失低于 1%。

安装:

pip install bitsandbytes transformers accelerate

8 位量化(内存占用降低 50%):

from transformers import AutoModelForCausalLM, BitsAndBytesConfig

config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=config,
    device_map="auto"
)

# Memory: 14GB → 7GB

4 位量化(内存占用降低 75%):

config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16
)
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=config,
    device_map="auto"
)

# Memory: 14GB → 3.5GB

常见工作流

工作流 1:在有限的 GPU 内存中加载大型模型

复制此检查清单:

Quantization Loading:
- [ ] Step 1: Calculate memory requirements
- [ ] Step 2: Choose quantization level (4-bit or 8-bit)
- [ ] Step 3: Configure quantization
- [ ] Step 4: Load and verify model

步骤 1:计算内存需求

估算模型内存:

FP16 memory (GB) = Parameters × 2 bytes / 1e9
INT8 memory (GB) = Parameters × 1 byte / 1e9
INT4 memory (GB) = Parameters × 0.5 bytes / 1e9

Example (Llama 2 7B):
FP16: 7B × 2 / 1e9 = 14 GB
INT8: 7B × 1 / 1e9 = 7 GB
INT4: 7B × 0.5 / 1e9 = 3.5 GB

步骤 2:选择量化级别

GPU VRAM模型大小建议
8 GB3B4 位
12 GB7B4 位
16 GB7B8 位或 4 位
24 GB13B8 位或 70B 4 位
40+ GB70B8 位

步骤 3:配置量化

8 位(准确率更高):

from transformers import BitsAndBytesConfig
import torch

config = BitsAndBytesConfig(
    load_in_8bit=True,
    llm_int8_threshold=6.0,  # Outlier threshold
    llm_int8_has_fp16_weight=False
)

4 位(最大限度节省内存):

config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16,  # Compute in FP16
    bnb_4bit_quant_type="nf4",  # NormalFloat4 (recommended)
    bnb_4bit_use_double_quant=True  # Nested quantization
)

步骤 4:加载并验证模型

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-13b-hf",
    quantization_config=config,
    device_map="auto",  # Automatic device placement
    torch_dtype=torch.float16
)

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-13b-hf")

# Test inference
inputs = tokenizer("Hello, how are you?", return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_length=50)
print(tokenizer.decode(outputs[0]))

# Check memory
import torch
print(f"Memory allocated: {torch.cuda.memory_allocated()/1e9:.2f}GB")
工作流 2:使用 QLoRA 微调(4 位训练)

QLoRA 可在消费级 GPU 上微调大型模型。

复制此检查清单:

QLoRA Fine-tuning:
- [ ] Step 1: Install dependencies
- [ ] Step 2: Configure 4-bit base model
- [ ] Step 3: Add LoRA adapters
- [ ] Step 4: Train with standard Trainer

步骤 1:安装依赖项

pip install bitsandbytes transformers peft accelerate datasets

步骤 2:配置 4 位基础模型

from transformers import AutoModelForCausalLM, BitsAndBytesConfig
import torch

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True
)

model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=bnb_config,
    device_map="auto"
)

步骤 3:添加 LoRA 适配器

from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training

# Prepare model for training
model = prepare_model_for_kbit_training(model)

# Configure LoRA
lora_config = LoraConfig(
    r=16,  # LoRA rank
    lora_alpha=32,  # LoRA alpha
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM"
)

# Add LoRA adapters
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Output: trainable params: 4.2M || all params: 6.7B || trainable%: 0.06%

步骤 4:使用标准 Trainer 训练

from transformers import Trainer, TrainingArguments

training_args = TrainingArguments(
    output_dir="./qlora-output",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    num_train_epochs=3,
    learning_rate=2e-4,
    fp16=True,
    logging_steps=10,
    save_strategy="epoch"
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    tokenizer=tokenizer
)

trainer.train()

# Save LoRA adapters (only ~20MB)
model.save_pretrained("./qlora-adapters")
工作流 3:使用 8 位优化器实现高效内存训练

使用 8 位 Adam/AdamW 可将优化器内存占用降低 75%。

8-bit Optimizer Setup:
- [ ] Step 1: Replace standard optimizer
- [ ] Step 2: Configure training
- [ ] Step 3: Monitor memory savings

步骤 1:替换标准优化器

import bitsandbytes as bnb
from transformers import Trainer, TrainingArguments

# Instead of torch.optim.AdamW
model = AutoModelForCausalLM.from_pretrained("model-name")

training_args = TrainingArguments(
    output_dir="./output",
    per_device_train_batch_size=8,
    optim="paged_adamw_8bit",  # 8-bit optimizer
    learning_rate=5e-5
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset
)

trainer.train()

手动使用优化器:

import bitsandbytes as bnb

optimizer = bnb.optim.AdamW8bit(
    model.parameters(),
    lr=1e-4,
    betas=(0.9, 0.999),
    eps=1e-8
)

# Training loop
for batch in dataloader:
    loss = model(**batch).loss
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()

步骤 2:配置训练

内存对比:

Standard AdamW optimizer memory = model_params × 8 bytes (states)
8-bit AdamW memory = model_params × 2 bytes
Savings = 75% optimizer memory

Example (Llama 2 7B):
Standard: 7B × 8 = 56 GB
8-bit: 7B × 2 = 14 GB
Savings: 42 GB

步骤 3:监控内存节省情况

import torch

before = torch.cuda.memory_allocated()

# Training step
optimizer.step()

after = torch.cuda.memory_allocated()
print(f"Memory used: {(after-before)/1e9:.2f}GB")

何时使用及替代方案

以下情况适合使用 bitsandbytes:

  • GPU 内存有限(需要容纳更大的模型)
  • 使用 QLoRA 进行训练(在单个 GPU 上微调 70B 模型)
  • 仅用于推理(内存占用降低 50-75%)
  • 使用 HuggingFace Transformers
  • 可以接受 0-2% 的准确率下降

以下情况适合使用替代方案:

  • GPTQ/AWQ:生产环境服务(推理速度快于 bitsandbytes)
  • GGUF:CPU 推理(llama.cpp)
  • FP8:H100 GPU(硬件 FP8 速度更快)
  • 全精度:准确率至关重要且内存不受限

常见问题

问题:加载期间出现 CUDA 错误

安装匹配的 CUDA 版本:

# Check CUDA version
nvcc --version

# Install matching bitsandbytes
pip install bitsandbytes --no-cache-dir

问题:模型加载缓慢

对大型模型使用 CPU 卸载:

model = AutoModelForCausalLM.from_pretrained(
    "model-name",
    quantization_config=config,
    device_map="auto",
    max_memory={0: "20GB", "cpu": "30GB"}  # Offload to CPU
)

问题:准确率低于预期

尝试使用 8 位而非 4 位:

config = BitsAndBytesConfig(load_in_8bit=True)
# 8-bit has <0.5% accuracy loss vs 1-2% for 4-bit

或者使用带双重量化的 NF4:

config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",  # Better than fp4
    bnb_4bit_use_double_quant=True  # Extra accuracy
)

问题:即使使用 4 位仍出现 OOM

启用 CPU 卸载:

model = AutoModelForCausalLM.from_pretrained(
    "model-name",
    quantization_config=config,
    device_map="auto",
    offload_folder="offload",  # Disk offload
    offload_state_dict=True
)

进阶主题

QLoRA 训练指南:参见 references/qlora-training.md,了解完整的微调工作流、超参数调优和多 GPU 训练。

量化格式:参见 references/quantization-formats.md,了解 INT8、NF4、FP4 的比较、双重量化和自定义量化配置。

内存优化:参见 references/memory-optimization.md,了解 CPU 卸载策略、梯度检查点和内存分析。

硬件要求

  • GPU:计算能力为 7.0+ 的 NVIDIA GPU(Turing、Ampere、Hopper)
  • VRAM:取决于模型和量化方式
    • 4 位 Llama 2 7B:4GB
    • 4 位 Llama 2 13B:8GB
    • 4 位 Llama 2 70B:24GB
  • CUDA:11.1+(建议使用 12.0+)
  • PyTorch:2.0+

支持的平台:NVIDIA GPU(主要)、AMD ROCm、Intel GPU(实验性)

资源

评论

支持 Markdown