QLoRA

QLoRA 用低比特形式加载冻结的基础模型权重,同时在高精度计算路径上训练 LoRA adapter,以降低微调显存。

核心组成

  • 量化的 frozen base weights
  • LoRA trainable adapters
  • 适合量化权重分布的 4-bit 数据格式,例如 NF4
  • 可能结合 double quantization 与 paged optimizer 等工程策略

NF4 不是普通的 4-bit 无符号整数。

三条必须分开的路径

1
2
3
4-bit frozen base weights ──(dequant on the fly)──→ compute

trainable LoRA adapter

QLoRA 省下的主要是基础权重和其优化状态;前向计算仍需要合适的 compute dtype,adapter 仍以可训练精度更新。NF4 负责权重存储分布,double quantization 进一步压缩量化常数,paged optimizer 处理优化器峰值,它们是不同层次的手段,不能混为一个“QLoRA 开关”。

失败模式与定位

  • 显存仍爆:检查激活、序列长度、梯度累积和临时 dequant buffer,不要只看权重大小。
  • loss 不动:打印 adapter 的 requires_grad、梯度范数和命中模块,确认量化基座没有被误解冻。
  • 质量异常:对比 NF4/compute dtype、chat template、数据 mask,以及 merge 后与 adapter 推理的输出。

验证清单

  • 是否真的传入了量化配置?仅调用 prepare_model_for_kbit_trainingquantization_config=None 不是 QLoRA。
  • compute dtype 与硬件是否匹配?
  • target modules 是否与模型结构一致?
  • 训练框架和 SFTTrainer API 是否锁定版本?

相关节点:LoRAPEFTTraining Memory Accounting。参考:QLoRA 论文

三种“精度”不要混成一个数字

QLoRA 至少同时涉及存储精度、计算精度和 adapter 更新精度。基础权重可以以 4-bit 存储,矩阵乘时按实现 dequant 到 BF16/FP16;LoRA 参数和梯度通常保持更高精度。把 compute dtype 也改成 4-bit,不是自动得到更省显存的 QLoRA,反而可能让累积误差和 kernel 支持成为主要问题。记录这三种 dtype 以及量化 scale 的位置,才能复现结果。

为什么“权重放得下”仍然会 OOM

长序列的 activation 在每层反向都要保留或重算;gradient accumulation 让 micro-batch 的峰值不变,却让 optimizer step 之间的生命周期更长;paged optimizer 只能缓解优化器状态的峰值,不能消除 attention activation。排查时分别在 forward、backward、optimizer.step 和保存 checkpoint 处采样显存,通常很快能看出真正主导项。若 activation 主导,应优先缩短序列、启用 checkpoint 或减小 micro-batch,而不是继续压低 base weight bitwidth。

数据与评测仍决定 QLoRA 是否有用

低比特基座并没有修复数据模板、loss mask 或 target module 错误。先用几十条样本做过拟合测试:若不能接近零训练 loss,先查管线;能过拟合后再跑分桶验证,比较量化基座的通用回归、adapter 任务集和 merge 后一致性。特别记录对数字、代码和长上下文的影响,因为这些输入可能比普通短对话更容易放大量化误差。