问题与目标
LoRA 仍需在显存中加载基座模型。QLoRA 把冻结的基座权重量化为 4-bit,再通过量化权重反向传播到 LoRA 参数,使消费级 GPU 能进行更大模型的参数高效微调。本篇分清存储精度、计算精度与可训练参数。
核心概念
QLoRA 不是直接训练 4-bit 整数权重:
- 基座权重以 4-bit 形式存储并保持冻结;
- 计算时反量化到
bf16或fp16; - LoRA Adapter 通常以浮点精度训练;
- 梯度和优化器状态只对应可训练 Adapter。
NF4 针对近似正态分布的权重设计;双重量化继续压缩量化常数。是否可用还取决于 GPU、CUDA、PyTorch、Transformers 与 bitsandbytes 的组合。
可运行实现
bash
python -m pip install "transformers>=4.56,<6" "bitsandbytes>=0.46,<1" "peft>=0.17,<1" "trl>=0.26,<1"
python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, prepare_model_for_kbit_training
model_id = "Qwen/Qwen3-0.6B"
compute_dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16
quantization = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
bnb_4bit_compute_dtype=compute_dtype,
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=quantization,
device_map="auto",
)
model = prepare_model_for_kbit_training(model)
tokenizer = AutoTokenizer.from_pretrained(model_id)
peft_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules="all-linear",
lora_dropout=0.05,
task_type="CAUSAL_LM",
)
print(model.get_memory_footprint())
这段代码只验证量化加载和训练准备。完整训练继续使用 09.3 的 SFTTrainer,传入 peft_config。实验报告应记录加载后的显存、第一步峰值、每步耗时与模型输出,而不只写“4-bit 节省约 75%”。
常见问题与排查
CPU 环境直接运行 bitsandbytes 示例
先检查官方硬件支持矩阵。没有兼容设备时使用小模型的普通 LoRA,保留配置文件但不要伪造显存结果。
把 dtype 和 4-bit 存储混为一谈
bnb_4bit_compute_dtype 控制运算精度,不会把存储的量化权重变回全精度。日志中分别记录量化类型、计算 dtype 和 Adapter dtype。
量化模型直接 merge_and_unload
合并前确认 PEFT 与量化后端是否支持目标流程。更稳妥的方法是在 CPU 或足够显存上重新加载非量化基座,再合并 Adapter 并验收。
QLoRA 一定不损失效果
量化误差、数据规模和超参数都会影响结果。用同一测试集比较 LoRA 与 QLoRA,不用训练 Loss 单独下结论。
小结
QLoRA 压缩的是冻结基座的存储,并保留浮点 Adapter 学习能力。理解三种精度、硬件兼容和合并边界,比记住一份 BitsAndBytesConfig 更重要。
许可协议:CC BY-NC 4.0
更新于 1 小时前
觉得文章有帮助?点个赞吧!
0 条评论


