年份与会议
2021 · ICLR
用低秩分解近似全量权重更新,把大模型微调从高门槛 GPU 任务,变成更可复现、更可扩展的工程实践。
年份与会议
2021 · ICLR
作者
Edward J. Hu、Yelong Shen、Phillip Wallis、Zeyuan Allen-Zhu、et al.
主题
高效微调
阅读时长
约 3 分钟
收录时间
2021/06/17
大模型时代有一个很现实的问题:基座模型越来越大,可真正能负担全量微调的团队却没有同比增加。
全量微调的问题包括:
LoRA 的重要性就在于,它没有试图重新定义微调,而是给出了一个更务实的答案:
如果真正需要学习的更新本身具有低秩结构,那我们就没必要为每次任务都更新整块大矩阵。
这个想法一旦成立,大模型适配的门槛就会显著下降。
LoRA 的基本观察是:在很多下游任务中,模型权重的有效更新其实可能落在一个相对低维的子空间里。也就是说,你不一定需要对完整权重矩阵 W 做自由更新,而可以把更新项写成:
ΔW = BA
其中:
A 和 B 是两个较小的矩阵r 远小于原矩阵维度W 保持冻结最终实际使用时,线性层从 xW 变成 x(W + BA)。这样模型就只需要学习较小的低秩更新,而不需要改动整个大权重矩阵。
把这个公式翻成工程图,会更容易理解 LoRA 为什么能把“全量微调”换成“冻结底座 + 训练小增量”:
<g>
<rect x="36" y="84" width="280" height="234" rx="24" fill="#f6f9ff" stroke="#d7e2f1" />
<text x="66" y="118" font-size="20" font-weight="700">基础模型线性层</text>
<rect x="120" y="144" width="120" height="134" rx="16" fill="#e8f1ff" stroke="#98b7e1" />
<text x="180" y="210" text-anchor="middle" font-size="26" font-weight="700">W</text>
<text x="180" y="236" text-anchor="middle" font-size="13" fill="#4b5563">大矩阵,保持冻结</text>
<rect x="76" y="286" width="200" height="18" rx="9" fill="#dbeafe" />
<text x="176" y="300" text-anchor="middle" font-size="12" fill="#4b5563">不更新预训练知识本体</text>
</g>
<g>
<rect x="350" y="84" width="288" height="234" rx="24" fill="#f8fbf4" stroke="#d5e4c6" />
<text x="380" y="118" font-size="20" font-weight="700">LoRA 低秩分解</text>
<rect x="398" y="154" width="62" height="114" rx="14" fill="#eef6e8" stroke="#a8c48e" />
<text x="429" y="215" text-anchor="middle" font-size="24" font-weight="700">B</text>
<rect x="504" y="154" width="110" height="114" rx="14" fill="#fff4dc" stroke="#e2c36f" />
<text x="559" y="215" text-anchor="middle" font-size="24" font-weight="700">A</text>
<text x="492" y="222" font-size="22" font-weight="700">×</text>
<text x="494" y="296" font-size="13" fill="#4b5563">秩 r 很小,只训练 A 和 B</text>
</g>
<g>
<rect x="672" y="84" width="272" height="234" rx="24" fill="#fff8ef" stroke="#eed6a0" />
<text x="702" y="118" font-size="20" font-weight="700">推理时的有效权重</text>
<rect x="714" y="160" width="70" height="110" rx="14" fill="#e8f1ff" stroke="#98b7e1" />
<text x="749" y="220" text-anchor="middle" font-size="24" font-weight="700">W</text>
<text x="800" y="218" font-size="22" font-weight="700">+</text>
<rect x="830" y="172" width="78" height="86" rx="14" fill="#fce7ef" stroke="#e2a8bd" />
<text x="869" y="220" text-anchor="middle" font-size="22" font-weight="700">BA</text>
<text x="808" y="294" text-anchor="middle" font-size="13" fill="#4b5563">x(W + BA) 完成任务适配</text>
</g>
<line x1="316" y1="202" x2="350" y2="202" stroke="#5b6b7f" stroke-width="3" marker-end="url(#lora-arrow)" />
<line x1="638" y1="202" x2="672" y2="202" stroke="#5b6b7f" stroke-width="3" marker-end="url(#lora-arrow)" />
<text x="384" y="328" font-size="13" fill="#64748b">训练成本下降:参数量少、优化器状态少、任务切换时只需保存 adapter</text>
</g>
LoRA 能显著降低成本,原因有三层:
冻结原始模型后,训练时只更新少量低秩矩阵,参数量会比全量微调小很多。
训练中不仅要存参数,还要存梯度、动量、二阶统计等优化器状态。可训练参数少了,这部分开销会同步下降。
你不需要为每个任务保存一整份完整模型,只需保存对应的 LoRA adapter 权重。部署、存储和版本管理都会轻松很多。
这也是为什么 LoRA 很快从“论文技巧”变成“工程默认选项”。
LoRA 最常见的做法,是把低秩更新插入到 Transformer 中的线性变换层里,特别是注意力相关投影层,例如:
W_qW_kW_vW_o有时也会扩展到前馈层。不同实现的差别主要体现在:
r 取多大这些设计决定了效果、显存和训练稳定性之间的平衡。
LoRA 最让人惊喜的地方在于,参数省了很多,但效果往往并没有按比例大幅下降。原因可以这样理解:
从这个角度看,LoRA 并不是“削弱版微调”,而是更接近一种结构化更新方式。它利用了基座模型本来就很强这一前提。
LoRA 的工程价值不只体现在节省显存,更在于它改变了实验组织方式:
这也是 LoRA 能迅速成为 Hugging Face、PEFT、开源微调社区基础设施的原因。
LoRA 并不是参数高效微调的唯一路线。和其他方法相比,可以这样粗略理解:
LoRA 之所以后来成为默认方案,很大程度上是因为它在“效果、实现复杂度、部署便利性”之间取得了很好的平衡。
LoRA 的爆发,和开源强基座模型的出现几乎是同步的。尤其在 LLaMA 之后,这个组合迅速成为默认工作流:
这让大量团队第一次有机会在自己可承受的资源范围内做模型微调。很多“行业专用大模型”的早期版本,本质上就是“基座模型 + LoRA 适配”的产品化形态。
虽然 LoRA 非常实用,但也不能把它神化。它的边界包括:
此外,LoRA 主要解决的是“适配成本”,不是“数据质量”和“评测体系”问题。数据差、目标不清、评测不严,即便用了 LoRA 也不会自动得到好结果。
LoRA 之后,高效微调生态几乎进入加速状态:
可以说,LoRA 让“微调大模型”从少数团队专属能力,变成更多工程团队能参与的日常实践。
如果你只想带走最关键的东西,请记住:
这三点理解清楚后,你再去看 QLoRA、Adapter merging、多任务适配,都会更容易。
沿着相近主题继续阅读,加深对方法边界与实践场景的理解。