当前位置:首页 > AI其它类

大模型微调太贵?LoRA 参数高效微调原理拆解

5天前AI其它类22

想拿自己领域的数据去微调一个开源大模型,一上手就撞到一堵墙:全量微调要更新模型里的每一个参数,算力和显存都顶不住,普通团队玩不转。

LoRA 就是冲着这堵墙来的。它让"在大模型上做定制"这件事,从"搬不动"变成"轻拿轻放"。这篇拆它的思路和数学。

lora-cover_1.jpg

全量微调,贵在哪

先看它要解决什么。一个模型的权重是一堆矩阵。微调时,每次反向传播都要对这些矩阵算梯度,再用优化器更新它们。

这里头有三笔开销:权重本身占一份显存,梯度再占一份,优化器的动量、方差状态还要再占一份甚至更多。模型一大,这三份加起来就大到个人显卡装不下。更要命的是,你为每个下游任务都得存一份完整的微调权重,任务一多,存储也崩。

全量微调的账,就是这么被"参数规模"拖垮的。

LoRA 的假设:微调只是一次低秩「扰动」

LoRA 的作者提了一个关键观察:模型虽然参数海量,但适配某个具体下游任务时,权重实际发生的变化不需要那么"满"。这个变化量可以用一个低秩结构来表示。

翻译成白话:把"从通用模型到专用模型"的调整,看成在原权重上叠一个很小幅度的修正。这个修正不是随便一个大矩阵,而是能被压缩成两个瘦矩阵相乘的小东西。

数学上:W' = W + BA

设原来的权重矩阵是 W,微调后的权重是 W'。全量微调是直接改 W 里的每一个数。LoRA 的写法是把它拆开:

W' = W + ΔW
ΔW = B · A

其中 W 被冻住、一个数都不动;真正训练的只有 A 和 B 两个小矩阵。假设 W 的尺寸是 d×d,A 是 r×d,B 是 d×r,那么 ΔW 的秩不超过 r。参数数量从 d² 变成了 2dr。

关键就在 r:这个"秩"远小于 d。比如 d 是 4096,r 取 8,参数就从 1600 多万缩到 6 万多,直接砍掉几个数量级。训练时只回传 A、B 的梯度,显存里也不用再给整个 W 存优化器状态。

秩 r 是什么,怎么选

r 是这个方法里少有的一个超参,它控制"旁路"能表达多复杂的变化。r 越大,能学的调整越丰富,代价是参数越多、越接近全量;r 越小,越省,但可能装不下你想让模型学会的东西。

实践里 r 常用 8、16 这种小值,配合一个缩放系数一起调。很多人发现,很小的 r 在很多下游任务上就能拿到接近全量微调的效果——这反过来印证了"适配只需低秩扰动"的直觉,也解释了它为什么省而不太掉点。

省下来的,还有一层「可插拔」

光省显存还不够,LoRA 还带来一个好用的副产品:原模型那里只有一个,A、B 是为每个任务单独存的小插件。

于是同一个底座模型,可以挂一堆 LoRA 插件,用哪个任务就插哪个;换任务就换旁路,底座纹丝不动。训练一个任务,只产出一个几 MB 到几十 MB 的小权重文件,分享、切换都轻便。再配合量化(QLoRA),连这么小的旁路还能进一步压缩。

小结

把 LoRA 收一下:全量微调的贵,来自权重、梯度、优化器状态三座山;LoRA 假设"适配只是一次低秩扰动",把权重增量写成 ΔW = BA,冻住原权重只训练两个瘦矩阵,参数从 d² 降到 2dr,顺便还换来了底座复用和插件式切换。

它没有推翻微调,只是把"改整个模型"降级成"改一个低秩补丁"。算力不够的时候,先动这个补丁,往往就够用了。

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。