QLoRA概述
QLoRA(Quantized LoRA)是LoRA的量化版本,通过将基础模型量化为4-bit精度,将微调的内存需求降低到原来的1/4甚至更低。结合QLoRA,一张24GB显存的RTX 4090就能微调65B参数的大模型。
核心技术
QLoRA使用了三项关键技术创新:
- NF4量化:NormalFloat4是一种针对正态分布权重优化的4-bit量化格式,比传统的INT4量化效果更好
- 双重量化:对量化常数本身再进行量化,进一步减少内存占用
- 分页优化器:使用CPU内存来处理梯度检查点,避免显存OOM
QLoRA微调实战
import torch
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
BitsAndBytesConfig,
TrainingArguments
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from datasets import load_dataset
from trl import SFTTrainer
# 4-bit量化配置
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True
)
# 加载量化模型
model_name = "deepseek-ai/deepseek-llm-7b-chat"
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True
)
# 准备k-bit训练
model = prepare_model_for_kbit_training(model)
# LoRA配置
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
# 训练
# 注意:QLoRA训练时可能需要更小的batch size
# 和更高的gradient accumulation steps
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
args=TrainingArguments(
output_dir="./qlora-output",
per_device_train_batch_size=1,
gradient_accumulation_steps=16,
learning_rate=1e-4,
num_train_epochs=3,
fp16=True,
logging_steps=10
),
tokenizer=tokenizer
)
trainer.train()内存占用对比
| 方法 | 7B模型 | 13B模型 | 70B模型 |
|---|---|---|---|
| 全参数微调 | ~56GB | ~104GB | ~560GB |
| LoRA (FP16) | ~16GB | ~28GB | ~140GB |
| QLoRA (4-bit) | ~6GB | ~10GB | ~40GB |
QLoRA调优建议
- 学习率:QLoRA通常需要更低的学习率,1e-4到2e-4是常见范围
- batch size:由于量化模型的数值精度降低,建议使用更小的batch size配合更大的gradient accumulation
- r值选择:QLoRA下r值可以适当增大(16-64),因为量化损失了部分信息
- target_modules:建议覆盖所有线性层,包括gate_proj、up_proj、down_proj
注意事项
QLoRA虽然内存效率极高,但训练速度比LoRA慢约30%,且最终模型质量可能略低于LoRA。在显存充足的情况下,优先使用LoRA(FP16);当显存不足时,QLoRA是最佳选择。