LoRA 低秩适配
五层读懂一个词。这次拆的是:LoRA(Low-Rank Adaptation)--冻结原模型,只训一对小矩阵 $BA$,用 0.1% 的参数量逼近全参微调。现在微调 LLM 的事实标准。
L1 · 一句话点破
LoRA = 冻结预训练权重 $W$ + 注入可训低秩增量 $\Delta W = BA$。$B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times d}$、$r \ll d$,只训 $A$ 和 $B$,参数量从 $O(d^2)$ 降到 $O(rd)$,推理时 $BA$ 可合并回 $W$ 零额外开销。
L2 · 通俗类比
全参微调像把整本书重写一遍来适应新需求--改的地方其实不多,但每个字都要重新过一遍梯度。70B 模型 700 亿参数全训,显存爆炸、存储爆炸、训完每个任务存一份 140GB 权重,不现实。
LoRA 的洞察:模型适应新任务时,权重更新的"信息量"其实很低。论文实验发现,微调的 $\Delta W$ 的内在秩(intrinsic rank)远小于 $d$。既然如此,不用学一个满秩的 $\Delta W$,学一个低秩近似就够了。
具体做法:原权重 $W$ 冻住不动,在旁边并一条"小路" $\Delta W = BA$,$B$ 和 $A$ 是两个瘦矩阵,中间维度 $r$ 很小(比如 8 / 16 / 64)。前向变成 $h = Wx + BAx$。只训 $A$、$B$,参数量从 $d^2$ 降到 $2rd$。
数字感受(LLaMA-7B,$d=4096$,$r=8$):
- 全参微调一层:$4096 \times 4096 = 16.7M$ 参数
- LoRA 一层:$2 \times 8 \times 4096 = 65K$ 参数
- 压缩比:256 倍
额外好处:
- 多个任务可以共享原模型,每个任务只存一份几十 MB 的 LoRA 适配器,切换任务就是换 $BA$
- 推理时把 $BA$ 加到 $W$ 上($W_{new} = W + BA$),零额外推理开销,不像 Adapter 要多算一层
- 原模型冻结,不用担心灾难性遗忘
代价:表达能力上限低于全参微调(毕竟是低秩近似);$r$ 选小了欠拟合,选大了又失去参数优势;不是所有层都适合加 LoRA(通常只加 attention 的 $W_q, W_v$)。
L3 · 正经定义
LoRA(Low-Rank Adaptation):Hu et al. (ICLR 2022) 提出,参数高效微调方法。假设预训练权重的任务适配增量 $\Delta W$ 具有低内在秩,将 $\Delta W$ 分解为两个低秩矩阵的乘积 $\Delta W = BA$,其中 $B \in \mathbb{R}^{d \times r}$、$A \in \mathbb{R}^{r \times d}$、$r \ll d$。训练时冻结 $W$,只更新 $A$、$B$。
数学形式:
$$ h = Wx + \Delta Wx = Wx + BAx $$
初始化:
- $A$:高斯随机初始化
- $B$:零初始化
- 保证训练开始时 $\Delta W = BA = 0$,模型从预训练状态出发
缩放因子:
$$ h = Wx + \frac{\alpha}{r} BAx $$
$\alpha$ 是缩放超参,作用是解耦 $r$ 与学习率--调 $r$ 时不用重新调学习率。常用 $\alpha = 2r$ 或 $\alpha = r$。
应用位置:原论文只在 attention 的 $W_q$、$W_v$ 加 LoRA。后续工作发现 $W_k$、$W_o$、FFN 的 $W_{up}$、$W_{down}$ 也加效果更好,但参数量上升。
参考资料:
- 📄 Hu et al., LoRA: Low-Rank Adaptation of Large Language Models, ICLR 2022, arXiv:2106.09685
- 🔧 HuggingFace PEFT 库:https://github.com/huggingface/peft
- 📄 QLoRA paper(对比工作)
- 📄 Aghajanyan et al., Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning, ACL 2020(LoRA 理论基础)
L4 · 原理深挖
4.1 为什么低秩近似有效
LoRA 的核心假设:微调的 $\Delta W$ 内在秩低。这个假设有理论和实验支撑。
理论:Aghajanyan et al. (ACL 2020) 发现,预训练模型的微调更新 $\Delta W$ 的内在维度(intrinsic dimension)远小于参数维度。BERT-large 微调的内在维度只有几百,远小于 3.4 亿参数量。
直觉:预训练已经学了通用表示,微调只是在这个表示空间里做小幅调整。这个调整不需要满秩自由度,低秩子空间够用。
实验验证(LoRA 原论文):
| 方法 | GPT-3 175B 可训参数 | WikiSQL F1 |
|---|---|---|
| 全参微调 | 175B | 74.0 |
| LoRA $r=2$ | 4.7M | 73.3 |
| LoRA $r=4$ | 9.4M | 73.5 |
| LoRA $r=8$ | 18.8M | 73.9 |
| LoRA $r=64$ | 150M | 73.7 |
$r=8$(0.01% 参数)就能逼近全参微调。$r$ 再大反而过拟合,效果不再提升。
4.2 LoRA 的前向与反向
前向:
def lora_forward(x, W, A, B, alpha, r):
# 原路径(冻结)
h = x @ W.T
# LoRA 路径
lora_out = (x @ A.T) @ B.T # 先 A 降维到 r,再 B 升维回 d
h = h + (alpha / r) * lora_out
return h关键:$BAx$ 的计算顺序是 $A$ 先把 $x$ 从 $d$ 维降到 $r$ 维,再由 $B$ 升回 $d$ 维。中间 $r$ 维是"瓶颈",强制 $\Delta W$ 低秩。
反向:只对 $A$、$B$ 算梯度,$W$ 冻结无梯度。显存占用从全参的 $\Delta W$ 梯度($d^2$)降到 $A$、$B$ 梯度($2rd$)。
4.3 缩放因子 $\alpha$ 的作用
$$ \Delta W_{eff} = \frac{\alpha}{r} BA $$
问题:如果直接用 $BA$,调 $r$ 时 $\Delta W$ 的量级会变($r$ 大则 $BA$ 的期望范数大),要重新调学习率。
解法:引入 $\alpha/r$ 缩放,让 $\Delta W$ 的量级与 $r$ 解耦。调 $r$ 时学习率不用动。
实践:
- $\alpha = r$:缩放后 $\Delta W = BA$,最保守
- $\alpha = 2r$:$\Delta W = 2BA$,放大适配强度,常用
- $\alpha$ 固定,调 $r$:主流做法
4.4 应用在哪些层
原论文配置:只在 $W_q$、$W_v$ 加 LoRA。
后续实践(QLoRA / 社区经验):
| 配置 | 加在哪 | 参数量 | 效果 |
|---|---|---|---|
| 最小 | $W_q, W_v$ | 0.2% | 基线 |
| 常用 | $W_q, W_k, W_v, W_o$ | 0.4% | 更好 |
| 激进 | + FFN $W_{up}, W_{down}, W_{gate}$ | 1-2% | 最好,但接近全参 |
| embedding | $W_e$(token embedding) | 大 | 多语言/新词任务需要 |
经验:
- 通用任务:attention 的 $W_q, W_v$ 够用
- 复杂任务(代码、数学):加 FFN 层
- 多语言 / 新词:加 embedding 层(但参数量大)
4.5 LoRA 的合并与切换
合并(merge):推理时把 $BA$ 加回 $W$:
def merge_lora(W, A, B, alpha, r):
W_merged = W + (alpha / r) * (B @ A)
return W_merged合并后模型结构和原模型完全一样,零额外推理开销。这是 LoRA 相对 Adapter 的关键优势。
切换(swap):多任务共享原模型,切换只换 $BA$:
# 任务 A 推理
merge_lora(W, A_A, B_A); generate()
# 切换到任务 B
restore(W); merge_lora(W, A_B, B_B); generate()一个 70B 基座模型 + 10 个任务的 LoRA 适配器,总存储 = 140GB + 10 × 200MB ≈ 142GB。而全参微调要 10 × 140GB = 1.4TB。
4.6 LoRA 的训练显存分析
全参微调显存(70B 模型,Adam 优化器):
| 组件 | 显存 |
|---|---|
| 权重 $W$(BF16) | 140 GB |
| 梯度(BF16) | 140 GB |
| Adam 状态 $m, v$(FP32) | 560 GB |
| 激活值 | ~50 GB |
| 合计 | ~890 GB |
LoRA 显存($r=8$,只加 attention):
| 组件 | 显存 |
|---|---|
| 权重 $W$(BF16,冻结) | 140 GB |
| LoRA 参数 $A, B$(BF16) | 0.2 GB |
| LoRA 梯度 | 0.2 GB |
| Adam 状态(仅 LoRA) | 0.8 GB |
| 激活值 | ~50 GB |
| 合计 | ~191 GB |
省的不是权重本身(原模型还得加载),省的是梯度和优化器状态。再配合 QLoRA 的 4bit 量化(下一节展开),权重从 140GB 压到 35GB,总显存降到 ~90GB,单卡 A100 80G 可训 70B。
4.7 LoRA 的局限
局限 1:表达能力上限。低秩近似本质是约束,复杂任务(领域大跨度、新语言)可能欠拟合。实验显示全参微调在某些任务上确实优于 LoRA。
局限 2:$r$ 调参敏感。$r$ 太小欠拟合,太大过拟合且失去参数优势。通常 $r \in [8, 64]$,要在验证集上调。
局限 3:层级选择。只加 attention 可能不够,加 FFN 又增加参数。最优配置因任务而异。
局限 4:多 LoRA 冲突。同时加载多个 LoRA(如多任务推理)时,如果它们的适配方向冲突,合并会互相干扰。
局限 5:训练效率。LoRA 省显存但不一定省时间。前向计算量几乎不变(原 $W$ 还得算),反向只省了 $W$ 的梯度,但激活值还得存。
4.8 LoRA 的变体
LoRA 之后涌现大量变体,主要方向:
- QLoRA:LoRA + 4bit 量化,进一步省显存(详见下一篇)
- AdaLoRA:自适应分配 $r$,重要层给大 $r$
- LoRA+:$A$、$B$ 用不同学习率($B$ 学得快)
- DoRA:分解 $\Delta W$ 为方向 + 幅度,分别适配
- MoLoRA / LoRA Mixture:多个 LoRA 专家混合
- LongLoRA:LoRA + Shifted Sparse Attention,高效长上下文微调
4.9 何时用 LoRA
适合:
- 指令跟随、对话风格微调(小幅度适配)
- 多任务共享基座
- 显存受限(消费级 GPU)
- 快速迭代实验
不适合:
- 领域大跨度(医疗、法律从零学)
- 新语言 / 新词表
- 极致性能追求(全参微调上限更高)
- 需要改架构的任务
实践建议:
- 先用 LoRA 跑通,效果不够再上全参
- $r=8$ 起步,不够加到 16/32/64
- $\alpha = 2r$ 是安全默认
- 加在 $W_q, W_v$ 起步,不够加 $W_k, W_o$,再不够加 FFN
L5 · 沿革与坑
5.1 沿革
- 2020:Aghajanyan 发现微调内在维度低,奠定理论基础
- 2021-06:LoRA 论文 arXiv 发布
- 2022-02:LoRA 被 ICLR 接收,社区开始大规模采用
- 2023-05:QLoRA 发布,4bit 量化 + LoRA,消费级 GPU 微调 70B 成为可能
- 2023 下半年:HuggingFace PEFT 库集成 LoRA,成为事实标准
- 2024:DoRA / AdaLoRA / LoRA+ 等变体涌现,LoRA 持续演进
- 2025:LoRA 成为 LLM 微调默认方案,全参微调退居高性能场景
5.2 常见坑
坑 1:$r$ 调太大。$r=256$ 还不如全参微调,参数优势没了,效果也没更好。$r \in [8, 64]$ 是甜蜜点。
坑 2:$\alpha$ 没设对。$\alpha$ 太小适配强度不足,太大训练不稳定。$\alpha = 2r$ 是经验默认。
坑 3:只加 $W_q, W_v$ 效果差就放弃。先试加 $W_k, W_o$,再试加 FFN,不要一上来就否定 LoRA。
坑 4:学习率用全参的。LoRA 的有效学习率通常比全参大 5-10 倍(因为参数少,梯度更新幅度要大)。全参 $2e-5$,LoRA 常用 $1e-4$ 到 $2e-4$。
坑 5:忘了合并就部署。推理时如果 LoRA 没合并,每次前向都要多算 $BAx$,延迟增加。生产环境要 merge。
坑 6:合并精度丢失。BF16 训练的 LoRA 合并到 BF16 权重,精度损失累积。合并时建议升到 FP32 算再转回。
坑 7:embedding 层加 LoRA 参数爆炸。token embedding 维度 $|V| \times d$,$|V|=50000$ 时一层就很大。多语言任务才加,通用任务别加。
坑 8:多 LoRA 合并冲突。多个任务的 LoRA 直接相加会互相干扰,要用 LoRA Hub / 任务路由。
坑 9:LoRA 和量化耦合出错。QLoRA 场景下,4bit 权重 + LoRA 合并时量化误差和 LoRA 误差叠加,要做校准。
坑 10:评估只看 loss。LoRA 的 loss 下降快但泛化可能差,要看下游任务指标。
坑 11:忘了 dropout。LoRA 路径要加 dropout(通常 0.05-0.1)防过拟合,直接训容易过拟合。
坑 12:batch size 太小。LoRA 参数少,小 batch 梯度噪声大。建议 batch size ≥ 8 或用梯度累积。
5.3 面试怎么考
- LoRA 的核心思想? 答:假设微调增量 $\Delta W$ 低秩,分解为 $BA$,$r \ll d$,只训 $A, B$,参数量降 $d/r$ 倍。
- LoRA 为什么有效? 答:预训练模型微调的内在维度低,低秩近似够用;实验显示 $r=8$ 就能逼近全参。
- LoRA 的初始化? 答:$A$ 高斯随机,$B$ 零,保证训练开始 $\Delta W = 0$。
- LoRA 相比 Adapter 的优势? 答:推理时可合并回 $W$,零额外开销;Adapter 要多算一层。
- LoRA 加在哪些层? 答:attention 的 $W_q, W_v$ 起步,不够加 $W_k, W_o$,再不够加 FFN。
- $\alpha$ 的作用? 答:缩放因子,解耦 $r$ 和学习率,常用 $\alpha = 2r$。
速记卡
| 组件 | 形状 | 是否训练 |
|---|---|---|
| $W$ | $d \times d$ | 冻结 |
| $A$ | $r \times d$ | 训练 |
| $B$ | $d \times r$ | 训练 |
| $\Delta W = BA$ | $d \times d$ | 低秩近似 |
关键参数:
| 参数 | 典型值 | 影响 |
|---|---|---|
| $r$ | 8 / 16 / 32 / 64 | 表达能力 vs 参数量 |
| $\alpha$ | $2r$ | 适配强度 |
| 学习率 | $1e-4$ ~ $2e-4$ | 比全参大 5-10x |
| 应用层 | $W_q, W_v$ 起步 | 覆盖范围 |
| dropout | 0.05-0.1 | 防过拟合 |
显存对比(70B 模型):
| 方法 | 显存 |
|---|---|
| 全参微调 | ~890 GB |
| LoRA | ~191 GB |
| QLoRA | ~90 GB |
一句话记忆:LoRA = 冻结 $W$ + 训低秩 $BA$($r \ll d$),参数量降 $d/r$ 倍,推理可合并零开销。$r=8$ 逼近全参,$\alpha=2r$ 是默认,学习率比全参大 5-10 倍。现在 LLM 微调的事实标准,多任务共享基座只存几十 MB 适配器。
上一篇:量化(INT8 / INT4) -- 推理侧的压缩,LoRA 是训练侧的高效。下一篇:QLoRA 量化低秩适配 -- 4bit 量化 + LoRA,消费级 GPU 微调 70B 的关键。