尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LoRA / QLoRA:低秩更新、量化和显存预算

LoRA / QLoRA:低秩更新、量化和显存预算 LoRA / QLoRA低秩更新、量化和显存预算系列开源 AI 论文复现实验与代码解读日期2026-08-26适合读者研究生、科研新人、希望把参数高效微调做清楚的工程读者检索日期2026-08-26目录为什么先复现 LoRA 而不是直接跑 PEFTLoRA 的公式和张量形状官方代码阅读路线QLoRA 多省显存省在哪里最小实验与验收协议如何报告复现实验边界失败排查清单可以继续研究的问题总结与参考资料为什么先复现 LoRA 而不是直接跑 PEFT参数高效微调Parameter-Efficient Fine-Tuning, PEFT指的是不更新模型全部参数而只训练少量新增参数或少量原参数。它适合科研新人入门因为实验规模可以小很多也容易误导人因为库调用太简单隐藏了关键约束。若只写get_peft_model(model, config)很难看出 LoRA 增量究竟加在什么矩阵上也难以判断训练参数比例是否符合预期。LoRA 论文的核心假设是下游任务所需的权重更新Delta W可能具有低内在秩因此不必完整学习一个与原矩阵同形状的更新。对一个线性层原始权重W0冻结只训练两个小矩阵A和B前向时使用W0 Delta W其中Delta W B A。这样复现时的第一条验收标准就很明确基座权重必须requires_gradFalse只有 LoRA 参数和必要的任务头参与优化。这和“只冻结一部分层”不同。LoRA 仍然让输入经过原模型的同一计算路径只是在目标线性层旁边并联一个低秩增量。推理时若不需要动态切换 adapter可以把B A合并回原权重避免额外矩阵乘法。这也是 LoRA 相比传统 adapter 的一个重要工程卖点。LoRA 的公式和张量形状设某个线性层输入x形状为[B, T, d_in]原始权重W0形状为[d_out, d_in]。全量微调会直接更新W0中的d_out * d_in个参数LoRA 冻结W0学习Δ W B A , A ∈ R r × d i n , B ∈ R d o u t × r \Delta W B A,\quad A\in R^{r\times d_{in}},\ B\in R^{d_{out}\times r}ΔWBA,A∈Rr×din​,B∈Rdout​×r于是前向计算可以写成y x W 0 T α r x A T B T y x W_0^T \frac{\alpha}{r} x A^T B^TyxW0T​rα​xATBT这里r是 rankalpha/r是缩放因子。若d_ind_out4096且r8全量更新需要约 1677 万参数而 LoRA 增量只有8*(40964096)65536个参数。这个数量级差异解释了为什么训练优化器状态会明显变小但它不表示激活显存、KV cache 或数据加载开销自动消失。初始化也有复现意义。PEFT 文档说明默认初始化会让 LoRA 起步时近似 no-opA随机初始化B初始化为零。这样第 0 步模型输出与冻结基座一致训练不会在一开始破坏预训练行为。若为了调试把两者都随机化应明确标注这不再是常用初始化。官方代码阅读路线Microsoft 的loralib是阅读 LoRA 实现的最短路径。建议先看loralib/layers.py中的Linear它创建lora_A、lora_B设置self.scaling lora_alpha / r并把预训练weight.requires_grad设为False。前向函数先计算普通F.linear(x, weight)再加上x A^T B^T * scaling。训练/评估模式切换中还包含 merge/unmerge 逻辑用来把低秩更新加回原权重或撤销。Hugging Face PEFT 则展示了科研复现实验会遇到的配置层。LoraConfig里最容易影响结果的是r、lora_alpha、target_modules、lora_dropout和bias。如果目标模块名写错训练参数可能为零如果只给q_proj、v_proj加 LoRA和 QLoRA 风格的target_modulesall-linear就不是同一实验。正式报告应打印 trainable parameter ratio并保存 adapter 配置。QLoRA 官方仓库的阅读重点不是把整套训练脚本复制到本机而是看它如何加载量化模型、调用prepare_model_for_kbit_training再添加 LoRA 模块。这样能明确一件事QLoRA 不是“训练 4-bit 权重”而是把冻结基座以 4-bit 存储/计算并把梯度反传到 LoRA adapter。QLoRA 多省显存省在哪里QLoRA 的关键增量有三项NormalFloat 4-bitNF4、double quantization 和 paged optimizers。NF4 是面向近似正态分布权重的 4-bit 数据类型double quantization 继续量化量化常数减少平均存储开销paged optimizers 用来缓解长序列或大 batch 下的瞬时显存峰值。论文报告称 QLoRA 可在单张 48GB GPU 上微调 65B 模型但这个结论依赖具体模型、序列长度、batch、checkpointing、优化器和硬件不能从 toy 脚本直接推出。显存预算要拆开看。全量 fp16 微调通常要存基座权重、梯度、优化器状态和激活LoRA 冻结基座后梯度和 Adam 状态主要只为 adapter 保留QLoRA 进一步把冻结基座权重压到 4-bit。配套脚本位于code/minimal_lora_qlora_budget.py默认用一个 7B 参数模型和 2000 万 LoRA 参数做粗略账本python3 code/minimal_lora_qlora_budget.py --check-only本次实际运行的标准库检查输出了单层base_weight、lora_A、lora_B、delta_W形状并给出 full fp16、LoRA fp16 base、QLoRA 4-bit base 三种粗略 tracked memory。注意它没有统计激活、临时 kernel、allocator 碎片、CUDA 上下文、checkpoint 保存和 tokenizer batch因此只能作为复现实验前的预算草稿。最小实验与验收协议安装 PyTorch 后可以运行一个 CPU toy 训练python3-mpipinstall-rcode/requirements.txt python3 code/minimal_lora_qlora_budget.py--steps40--seed7toy 模型只有一个冻结线性层和一个 LoRA 增量用合成二分类任务检查 LoRA 参数是否能被优化。验收不应只看 loss 是否下降还要检查四个不变量冻结权重梯度为空LoRA 参数数等于r*(d_ind_out)第 0 步 no-op 初始化不会改变基座输出训练日志记录 seed、rank、alpha、学习率和 batch size。若扩展到真实模型建议把评测协议分成三层。第一层是配置可复查模型名、revision、tokenizer、数据集版本、target modules、rank、alpha、dropout、量化配置全部写入日志。第二层是资源可复查峰值显存、每步时间、有效 batch、序列长度、gradient checkpointing 是否开启。第三层才是任务指标验证集 loss、准确率、MT-Bench 或 Vicuna 这类对话评测。动态榜单和闭源评测器版本必须标注“待人工核验”。如何报告复现实验边界LoRA/QLoRA 的复现报告尤其需要把“配置成功”和“方法有效”分开。配置成功只说明 adapter 已经插入、参数量符合预期、训练循环能跑通方法有效还需要在固定数据切分、固定评测脚本和合理 baseline 下比较指标。很多失败记录之所以后来无法复查是因为只保存了最终 checkpoint却没有保存 adapter 配置、量化配置和训练日志。建议每次实验至少保存五类材料。第一是config.json或命令行参数里面应包含 rank、alpha、dropout、target modules、是否训练 bias、是否合并 adapter。第二是环境信息包括 PyTorch、Transformers、PEFT、bitsandbytes、CUDA、GPU 型号和驱动版本。第三是资源日志至少记录峰值显存、每步耗时、序列长度、batch size 和 gradient accumulation。第四是数据记录包括数据集版本、过滤规则、模板、最大长度和随机种子。第五是评测输出最好保留逐样本预测或打分明细而不只是一行平均分。对论文指标的引用也要谨慎。LoRA 论文报告了在 RoBERTa、DeBERTa、GPT-2、GPT-3 等模型上的参数效率和质量对照QLoRA 论文报告了 4-bit 微调大模型的显存可行性和对话模型结果。本文没有复现这些规模实验因此只能说“论文报告”或“官方仓库说明”不能写成本机结论。本文真正验证的是脚本中的 LoRA 参数形状、参数比例公式和粗略显存账本可以在无 PyTorch 环境下运行PyTorch toy 训练与真实 QLoRA 训练仍待安装依赖和硬件后验证。还有一个常被忽略的边界是随机性。LoRA 参数很少不代表实验方差一定小。小数据集、短训练步数、不同 prompt 模板、不同 tokenizer 截断策略都可能让最终指标明显波动。可靠报告应至少跑多个 seed或把单 seed 结果明确标成探索性结果。若预算不足以多 seed也应优先保留 loss 曲线、验证集逐项输出和失败样本而不是只保留最好一次的截图。失败排查清单第一训练参数为零。通常是target_modules没匹配到真实层名或 adapter 注入后没有打印 trainable 参数。不同架构的投影层命名不同不能把 LLaMA 的q_proj原样套到所有模型。第二显存没有明显下降。常见原因是仍在全量更新 embedding、LM head 或 bias序列太长导致激活成为主要开销或者没有启用 gradient checkpointing。LoRA 主要减少可训练权重、梯度和优化器状态不会免费消除前向激活。第三QLoRA 量化配置不一致。Hugging Face 文档中典型配置包括load_in_4bitTrue、bnb_4bit_quant_typenf4、bnb_4bit_use_double_quantTrue和合适的 compute dtype。若库版本、硬件后端或 dtype 不同显存和速度都可能变化。第四把 adapter merge 后继续训练。merge 适合推理或导出若训练阶段反复 merge/unmerge要确认没有把低秩更新重复加到权重上。官方实现中维护merged状态就是为了避免这类错误。第五报告方式混淆。论文报告的 65B 单卡结论、官方仓库的 Guanaco 结果、本机 toy script 的参数检查属于三种证据。科研博客必须分开写论文声称什么本次实际验证什么作者据此推断什么。第六忽略 merge 校验。adapter 合并前后应在同一输入上比较 logits 差异若误差异常优先检查 dtype、缩放因子、是否重复合并以及权重转置方向。这个检查很便宜却能提前发现导出阶段的严重问题。复现日志越细后续排错成本越低。可以继续研究的问题在相同训练预算下LoRA rank 从 4、8、16 到 64 时验证集收益和显存增量是否线性q_proj/v_proj、attention 全投影、MLP 全线性层和all-linear的差异是否来自容量还是目标模块位置NF4、FP4、INT8 在同一模型、同一数据上的困惑度退化和训练稳定性如何比较LoRA adapter merge 前后logit 最大误差在不同 dtype 下是否可接受小数据指令微调中LoRA 的过拟合表现是否比全量微调更轻还是只是训练参数少导致收敛慢这些问题都比“能不能省显存”更适合作为研究入口因为它们把方法、预算、指标和失败模式放在同一个可复现框架内。总结LoRA 的最小复现可以浓缩成一句话冻结W0训练A和B用B A近似下游任务所需的权重更新。QLoRA 则在这个基础上把冻结基座量化到 4-bit并继续只训练 LoRA adapter。理解这两点后显存预算就不再是玄学基座权重、可训练参数、优化器状态、激活峰值必须分别估算。本文完成了源码阅读、公式对齐、预算脚本和正式配图。本机尚未安装 PyTorch因此 toy 训练与真实模型 QLoRA 仍标注为待人工核验。下一步最值得做的是在固定模型 revision 和数据集切分后比较 full fine-tuning、LoRA 和 QLoRA 的显存、速度与验证指标而不是只报告一个漂亮的 adapter 参数比例。参考资料检索日期2026-08-26。以下链接优先采用论文页、官方仓库和官方文档PEFT、Transformers 与 bitsandbytes 文档会随版本变化正式复现实验应记录本地包版本、GPU 型号和模型 revision。Edward J. Hu et al., LoRA: Low-Rank Adaptation of Large Language Models, arXiv 2021 / ICLR 2022。Microsoft, LoRA official repositoryloralibPyTorch 实现。Microsoft,loralib/layers.pyLoRA Linear、merge/unmerge 与冻结权重逻辑。Tim Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, arXiv 2023 / NeurIPS 2023。Artidoro Pagnoni et al., QLoRA official repository训练脚本、配置和 Guanaco 说明。Hugging Face PEFT, LoRA documentationLoraConfig、初始化和 target modules。Hugging Face PEFT, Quantization guideLoRA 与 4-bit/8-bit 量化结合流程。Hugging Face Transformers, bitsandbytes quantization documentationBitsAndBytesConfig、NF4 与 nested quantization。Hugging Face bitsandbytes, Linear4bit / LinearNF4 reference4-bit 线性层和 NF4 API 说明。
返回列表