只训练 0.19% 的参数,LoRA 低秩适配是怎么做到的

大模型时代,全量微调(Full Fine-tuning)一个数百亿参数的模型需要惊人的算力和显存。LoRA(Low-Rank Adaptation,低秩适应)是目前最主流的解决方案:它让「人人都能微调大模型」成为现实。本文合并 LoRA 原始论文(arXiv:2106.09685)微软官方 LoRA 仓库QLoRA 论文(arXiv:2305.14314)Hugging Face PEFT 官方文档,完整梳理这一技术。

LoRA 低秩适应原理示意图(AI 生成插图)
LoRA 低秩适应原理示意图(AI 生成插图)

一、LoRA 是什么:来自论文的定义

LoRA 由微软研究院 Edward J. Hu 等人于 2021 年 6 月提出(ICLR 2022)。论文摘要原文的核心表述:

「我们提出低秩适应(LoRA):冻结预训练模型权重,并在 Transformer 架构的每一层注入可训练的秩分解矩阵,大幅减少下游任务的可训练参数数量。以 GPT-3 175B 为例——部署多个独立微调模型实例(每个 175B 参数)的成本令人望而却步。与使用 Adam 优化的 GPT-3 175B 全量微调相比,LoRA 可将可训练参数减少 10000 倍,GPU 显存需求降低 3 倍。尽管可训练参数更少、训练吞吐量更高,LoRA 在 RoBERTa、DeBERTa、GPT-2 和 GPT-3 上的模型质量与全量微调持平或更好,且与 adapter 不同,没有额外的推理延迟。」

一句话总结:冻结预训练权重,只训练一对低秩矩阵(B×A)的乘积作为权重更新的近似。微调结束后把 BA 合并回原权重,推理时与原模型完全一样——这正是「零额外推理延迟」的来源。

二、效果证据:官方基准数据

微软官方仓库公布的 GLUE 基准结果,LoRA 用极小的可训练参数即可达到甚至超过全量微调:

模型方法可训练参数量MNLI (m/mm Acc)SST2 (Acc)RTE (Acc)平均分
RoBERTa base全量微调125M87.694.878.786.40
RoBERTa baseLoRA0.8M87.5/86.995.186.687.24
DeBERTa XXL全量微调1.5B91.7/91.997.293.991.06
DeBERTa XXLLoRA4.7M91.9/91.996.994.991.32

在 GPT-2 上的生成任务对比中,LoRA 同样优于 adapter 与 prefix-tuning(E2E NLG Challenge,BLEU 分数):

模型方法可训练参数量E2E (BLEU)DART (BLEU)
GPT-2 M全量微调354.92M68.246.0
GPT-2 MAdapter0.37M66.342.4
GPT-2 MPrefix Tuning0.35M69.745.7
GPT-2 MLoRA0.35M70.447.1
GPT-2 L全量微调774.03M68.546.5
GPT-2 LLoRA0.77M70.447.5

微软官方 README 的总结原文:「LoRA 通过在冻结原始权重的同时学习一对秩分解矩阵来减少可训练参数数量。这大幅降低了大语言模型适配特定任务的存储需求,支持部署时高效的任务切换,且完全不引入推理延迟。LoRA 的表现优于 adapter、prefix-tuning 和全量微调等多种适配方法。」

三、官方实现 loralib 快速上手

微软官方发布了 loralib 包(现主要由 Hugging Face PEFT 库接管),四步接入:

# 1. 安装
pip install loralib

# 2. 替换需要适配的层为 LoRA 版本(支持 nn.Linear / nn.Embedding / nn.Conv2d)
import loralib as lora
# 层定义对比:
# Before: layer = nn.Linear(in_features, out_features)
# After:  layer = lora.Linear(in_features, out_features, r=16)  # rank r=16

# 3. 只把 LoRA 参数标记为可训练
model = BigModel()
lora.mark_only_lora_as_trainable(model)

# 4. 保存 checkpoint 时只保存 LoRA 参数
torch.save(lora.lora_state_dict(model), checkpoint_path)
# 加载时记得 strict=False

官方实现细节(原文要点):

  • 论文示例聚焦在只适配注意力层的 qv 投影,但「LoRA 可以应用于预训练权重的任意子集」,最优配置因模型架构和任务而异;
  • 调用 model.eval() 会触发 LoRA 参数与预训练权重的合并,消除后续前向传播的额外延迟;model.train() 会撤销合并;
  • 与 LoRA 并行训练 bias 向量(bias='all''lora_only')是榨取额外任务性能的低成本手段。

四、Hugging Face PEFT:事实标准

2023 年 2 月起,LoRA 已被 Hugging Face 的 PEFT(Parameter-Efficient Fine-Tuning)库原生支持,成为社区事实标准。PEFT 提供统一接口 get_peft_model(),一行代码即可把任意 transformers 模型包装为可训练的 LoRA 模型。官方 README 给出的示例中,对一个 10 亿参数模型应用 LoRA 后可训练参数仅剩 0.19%

除 LoRA 外,PEFT 还支持 QLoRA、Prefix Tuning、P-Tuning、Prompt Tuning、IA³、AdaLoRA 等参数高效微调方法,覆盖 Transformer、扩散模型等架构,并与 transformers、accelerate、trl 等库无缝集成。

五、QLoRA:单卡 24GB 微调 65B 模型

2023 年 5 月,Tim Dettmers 等人提出 QLoRA,把 LoRA 推到了新的极限。论文摘要原文要点:

「QLoRA 将梯度反向传播穿过一个冻结的 4-bit 量化预训练语言模型、传入低秩适配器(LoRA)……使在单张 48GB GPU 上微调 65B 参数模型成为可能,同时保持完整的 16-bit 微调任务性能。我们最好的模型家族 Guanaco 在 Vicuna 基准上超越此前所有公开模型,达到 ChatGPT 性能水平的 99.3%,而仅需单张 GPU 上 24 小时的微调。」

QLoRA 的三项核心创新(原文):

  • 4-bit NormalFloat(NF4):一种信息论上对正态分布权重最优的新数据类型;
  • 双重量化(Double Quantization):对量化常数再量化,进一步降低平均显存占用;
  • 分页优化器(Paged Optimizers):管理显存峰值,避免长序列训练时 OOM。

研究团队用 QLoRA 微调了超过 1000 个模型,覆盖 8 个指令数据集与多种模型类型和规模,结论是:在小而高质量的数据集上做 QLoRA 微调即可达到最先进效果

六、实践建议

  • 秩 r:常见取值 8~64,论文实验表明很多任务的增量矩阵「内在秩」很低,r 不需要太大;
  • 目标模块:默认适配注意力的 q/v 投影,追求更高效果可扩展到全部线性层;
  • 显存不够:优先考虑 QLoRA(4-bit 量化 + LoRA),消费级显卡即可微调 7B~70B 模型;
  • 训练框架:Hugging Face PEFT 之外,Axolotl、Unsloth、LLaMA-Factory、Swift 等框架都内置了 LoRA/QLoRA 训练模板。

参考来源

  • LoRA 论文:Hu et al., “LoRA: Low-Rank Adaptation of Large Language Models”(arXiv:2106.09685,ICLR 2022)
  • 微软官方 LoRA 仓库(github.com/microsoft/LoRA)
  • QLoRA 论文:Dettmers et al., “QLoRA: Efficient Finetuning of Quantized LLMs”(arXiv:2305.14314)
  • Hugging Face PEFT 官方文档与 GitHub 仓库(github.com/huggingface/peft)

本文为技术文档摘录整理,内容合并自下列官方资料(官方文档、官方 GitHub 仓库、论文与权威媒体报道),技术数字以官方原文为准,版权归原作者所有。

主要菜单