5.7 LoRA:给大模型贴便利贴
前六节讲的都是「大厂怎么做」
到这里,后训练这条流水线你已经全看过了:SFT 上示范课、RLHF 训裁判、PPO 拔河、DPO 抄近道、RLVR 逼出推理能力。
但有一件事一直没说破:这条流水线,你自己跑不动。
问题不在算法——SFT 的代码几十行就能写完。问题在显存。第 4 章算过预训练的账,微调的账其实同样吓人:一个 70 亿参数的模型,光是把它「摆开」准备训练,就要一百多 GB 显存。而 2026 年一张顶配消费级显卡只有二三十 GB。
差了整整一个数量级。
这一节和接下来两节,讲的就是怎么把这个数量级抹平——让一张卡、几个小时、几十块钱,也能把一个大模型调成你想要的样子。
为什么微调这么吃显存
先搞清楚显存到底被谁吃掉了。很多人以为「模型 14 GB,那微调就要 14 GB 多一点」——差得远。
训练时,每个参数身上挂着的不止它自己:
| 挂件 | 干什么用 | 占多少 |
|---|---|---|
| 参数本身 | 就是模型 | 2 字节 |
| 梯度 | 这一步该往哪调 | 2 字节 |
| 优化器状态 | Adam 记的「惯性」和「步长历史」,外加一份高精度参数副 本 | 12 字节 |
合计 16 字节/参数——参数本身只占了八分之一,剩下七份全是「为了训练它」而临时背上的行李。7B 模型于是从 14 GB 膨胀到 112 GB。
看清这笔账,省钱的思路就自己浮出来了:参数本身省不掉(模型总得装进显存),但那七份行李是按「要训练的参数个数」收费的。
如果只训练其中很小一部分呢?
便利贴的主意
2021 年,微软的研究者给出的答案叫 LoRA(Low-Rank Adaptation,低秩适配):
原来的参数一个都不动,全部冻结。另外贴一张薄薄的「修正贴纸」,只训练这张贴纸。
用石碑打比方:微调一个模型,就像修改一块刻好的石碑。全参微调是把整块石碑磨平重刻——费工费料。LoRA 的做法是在石碑旁边贴一张便利贴,写上「此处应改为……」。读的时候把石碑和便利贴一起读,效果等价;但你只需要写那张便利贴。
关键在于这张便利贴可以做得极薄。原本一个 4096 × 4096 的参数矩阵有 1600 万个数字,LoRA 用两个瘦长条替代它的修正量:一个 4096 × 8,一个 8 × 4096——加起来只有 6.5 万个数字,不到原来的 0.4%。
这个「8」就是 LoRA 的秩(rank,记作 ),是你唯一要调的核心旋钮: 越大,便利贴越厚、表达力越强、也越费显存。
亲手算这笔账
请按顺序做四个实验:
实验 ①:先看全参微调有多贵。 保持「7B」,点「全参微调(基准)」。看那个数字——110 GB 左右,一张 80 GB 的数据中心卡都装不下,得上两张。再看条形图:橙色那一大条就是「权重 + 梯度 + 优化器状态」,16 字节/参数的账全在这里。
实验 ②:换成 LoRA,看数字塌下来。 点「LoRA(底座 bf16)」。显存从 110 GB 掉到 约 16 GB——一张消费级卡就够了。注意条形图变了形状:紫色的「冻结底座」占了绝大部分,橙色的「可训练状态」缩成一条几乎看不见的线。这就是 LoRA 的全部秘密:底座省不掉,但行李没了。
实验 ③:拖动秩 r,感受它的分量。 把 r 从 1 拉到 256,盯着「可训练参数」和「显存」。你会发现一件重要的事:r 翻 32 倍,显存几乎没动——因为显存的大头是那个冻结的底座,便利贴再厚也只是零头。所以调 r 主要是在权衡「表达力 vs 过拟合」,而不是在省显存。
实验 ④:看适配器文件有多小。 保持 r = 8、「整个注意力」,看「适配器文件」那一栏——十几 MB。而完整模 型是 14 GB。这意味着你可以为一百个不同任务各训一张便利贴,全部加起来还不到底座的十分之一。
便利贴为什么够用
一个自然的疑问:把一个 1600 万参数的修正量,硬压成 6.5 万个数字,信息不会丢吗?
会丢,但丢的大多是你本来就不需要的。LoRA 论文的观察是:微调对模型做的改动,本身就集中在少数几个「方向」上——你教它说客服口吻,改的是一种整体倾向,不是一千六百万个互不相关的细节。既然改动本身就是「低秩」的,用低秩的贴纸去装它,自然装得下。
这也解释了 LoRA 的适用边界:改倾向很在行,灌知识很吃力(下一节和 5.9 节还会展开)。
还有两个白赚的好处:
- 推理时零额外开销:训完可以把便利贴的内容加回石碑( 合成一个 新矩阵),得到一个和原模型结构完全相同的模型,推理速度一模一样。
- 热插拔:也可以不合并,让一个底座同时挂多张便利贴——客服贴纸、翻译贴纸、写代码贴纸,按请求切换。服务一百个定制模型,显存里只有一份底座。
「贴便利贴」容易让人以为 LoRA 是在原有输出之外补一句话——不是。便利贴不是附加在结果后面,而是参与到每一层的运算里:石碑和便利贴的结果是逐层相加的,改的是模型的内部计算过程,不是最终答案的措辞。
另一个偏差:便利贴听起来「随便贴哪都行」,实际上贴在哪些矩阵上(只贴注意力?连 FFN 一起贴?)对效果影响不小,是要调的。最后,LoRA 也不是永远和全参微调等价——任务离底座原本的能力越远(比如教一门它几乎没见过的语言),低秩这个假设就越勉强,差距会显出来。