LoRA: Low-Rank Adaptation of Large Language Models
为什么这篇论文重要
2021 年 Microsoft 这篇 LoRA 论文—— 让”普通人微调 GPT-3 类大模型”成为可能。
之前—— 微调 175B 的 GPT-3:
- 显存:700GB+(多卡)
- 计算:和重训差不多
- 储存:每个微调版本 350GB
- 成本:每次几千美元
LoRA 之后:
- 显存:~50GB(单卡)
- 计算:1/100
- 储存:每个微调 <100MB
- 成本:每次几十美元
没有 LoRA—— LLM 应用层根本起不来。
核心洞察
观察:微调 LLM 时—— 参数变化矩阵 是”低秩”的。
什么意思?
完整变化矩阵: ΔW ∈ R^(4096 × 4096) → 1700 万参数
低秩分解: ΔW = A · B
A ∈ R^(4096 × 8) → 32K
B ∈ R^(8 × 4096) → 32K
合计:64K 参数
少了 250 倍!
叫”秩”(rank),通常 4-64。 越大效果越好,但参数越多。
为什么”低秩”假设成立
实验观察:
- 微调改变模型的”行为”——
- 但不改变模型的”基础知识”——
- 所以实际改变的”自由度”很低
类比:你不是重写整个 OS——只装一个新 App。 大部分系统不变——只需描述”差异”。
LoRA 的工作原理
标准 fine-tuning
# 训练所有参数
W_new = W_pretrained
W_new.requires_grad = True # 所有参数都训
显存:W + W_梯度 + Adam 状态——巨大。
LoRA
# 冻结原始 W
W = W_pretrained
W.requires_grad = False # ← 关键
# 加 2 个小矩阵
r = 8 # rank
A = nn.Parameter(torch.randn(d, r)) # 训这个
B = nn.Parameter(torch.zeros(r, d)) # 训这个(初始化为 0,保持原始行为)
# Forward
def forward(x):
return x @ (W + A @ B) # W 不变 + A·B 提供 delta
只训 A 和 B——
- 参数:从 4096×4096 → 2 × 4096×8 = 256× 少
- 显存:原始 W 冻结,不存梯度
- Adam 状态:只对 A、B 存——巨大节省
实验结果
与全量 fine-tuning 对比
GPT-3 175B 在多个任务上:
| 方法 | 训练参数 | 性能(vs full FT) |
|---|---|---|
| Full Fine-tuning | 175B (100%) | 100% |
| Adapter | 38M (0.02%) | 98% |
| Prefix Tuning | 0.04M | 95% |
| LoRA | 4.7M (0.003%) | 101% |
最少参数 + 性能略超 full FT!
为什么 LoRA 不仅没差还略好?
- 防过拟合(参数少)
- 训练稳定(影响小)
- “限制”实际上有正则化效果
工程优势
1. 显存大幅省
训 7B 模型 LoRA:
- 不用 GPU offload —— 24GB GPU 够
- 不用 multi-GPU —— 单 RTX 4090 / A6000 行
2. 切换微调超快
A、B 加载/卸载只要几秒—— 同一个 base 模型 + N 个 LoRA adapters:
Base Model (Llama-3-70B)
├── LoRA: 法律领域
├── LoRA: 医疗领域
├── LoRA: 客户 A 风格
├── LoRA: 客户 B 风格
└── ...
Multi-LoRA 部署 —— 一个模型服务无数定制化。
3. 储存友好
完整模型 7B → 14GB LoRA adapter → ~30MB
1 万个微调版本 = 300GB(vs 全量 140TB)—— 1000× 节省。
4. 可组合
理论上:
- LoRA-A: 学到”代码风格”
- LoRA-B: 学到”中文”
- A + B 同时加载 = “中文代码助手”
实际工程中有效—— 但不完美(互相干扰可能)。
QLoRA(2023 升级)
LoRA + 量化 = QLoRA:
# Base 模型 4-bit 量化(不可训)
base = load_4bit_model("Llama-3-70B")
# 加 LoRA(FP16)
lora_config = LoraConfig(r=16, lora_alpha=32)
model = get_peft_model(base, lora_config)
# 训练
trainer.train()
70B 模型用 ~40GB 显存 —— 单卡 H100 (80GB) 微调 70B! 这在 LoRA 之前不可能。
详见 L4-05 LoRA 微调入门 + L7-04 量化。
后续 PEFT 家族
LoRA 启发了一系列 “Parameter-Efficient Fine-Tuning” 方法:
| 方法 | 思路 | 特点 |
|---|---|---|
| LoRA | 低秩矩阵分解 | 经典 |
| DoRA (2024) | 分解 magnitude + direction | LoRA 改进版 |
| VeRA (2024) | 共享 LoRA 矩阵 + 缩放向量 | 更少参数 |
| PiSSA (2024) | 用 SVD 初始化 LoRA | 训练快 |
| OFT | 正交微调 | 不同思路 |
| (IA)³ | 元素级缩放 | 极少参数 |
LoRA 仍是事实标准—— 其它是渐进改进。
工业采用
开源生态
几乎所有开源微调 都用 LoRA:
- Civitai 上的所有 Stable Diffusion fine-tunes
- HuggingFace 上 LLM 的 finetune
- Adobe / Canva 等的”自定义风格”
- OpenAI 的 fine-tuning API(部分用 LoRA 类技术)
Salesforce 的案例
Salesforce Einstein GPT —— 为每个企业客户微调一个 LoRA:
- 同一个 base model(GPT-4 类)
- 每个客户一个 LoRA adapter (~30MB)
- 服务时动态加载
一个 base 模型 = 服务几百个企业客户。
一些反思
”LoRA 是不是万能”
不是—— LoRA 的局限:
- 知识注入:不擅长教模型”新事实”(更好用 RAG)
- 大幅风格变:可能需要 r 很大
- 特殊任务:某些任务 full FT 仍略好
起步用 LoRA + RAG—— 不够再考虑 full FT。
“为什么这么晚才出”
LoRA 数学并不新—— “低秩矩阵分解”是经典线代。
但应用到 LLM fine-tuning 是 Microsoft 2021 第一个系统提出。 正确的时机 + 正确的应用 —— 让简单想法成为革命。
现代变种
DoRA 等改进版性能更好—— 但 LoRA 仍是最广泛用的。 因为:
- 工具链成熟
- 社区习惯
- 改进的差距不大
实战中”最强”和”最广泛”不一定一致。
用 PEFT 库
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
# 加载 base model
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3-8B")
# 配置 LoRA
config = LoraConfig(
r=16, # rank
lora_alpha=32, # scaling
target_modules=["q_proj", "v_proj"], # 通常只对 Q, V 加 LoRA
lora_dropout=0.1,
bias="none",
)
# 应用 LoRA
model = get_peft_model(model, config)
model.print_trainable_parameters()
# trainable params: 4M / 8B = 0.05%
# 训练(就像普通 fine-tuning)
trainer = Trainer(model=model, ...)
trainer.train()
# 保存(只保存 LoRA,不是整个模型!)
model.save_pretrained("./my_lora_adapter") # 仅几十 MB
这就是 2026 年所有微调的标准流程—— 极简、高效、便宜。
推荐配套阅读
- HelloAI: L4-05 LoRA 微调 + L7-04 量化深度
- LoRA 原论文(ICLR 2022)
- QLoRA 论文(2023)
- PEFT 库(HuggingFace)
- DoRA 论文(2024)—— LoRA 改进
LoRA 让 “AI 民主化” 真正落地:
- 个人开发者能训自己的模型
- 小公司能定制 LLM
- 任何垂直行业都能做”专用 AI”
没有 LoRA —— 微调还是大公司专利。 有了 LoRA —— 任何人 + 1 张消费级显卡 + 1 天时间 = 你的专用模型。
这是论文影响力的真正衡量—— 重塑一个时代的可能性。
想要更多论文精读
订阅每周精选 —— 下一篇论文笔记直接送邮箱。
讨论区
· 用 GitHub 账号登录评论src/components/Comments.astro 顶部填入
仓库 ID 和分类 ID(见组件注释里的配置步骤)。