课程/M11/LoRA:低秩假设的工程化
M11 · 大模型专题核心约 35 分钟

11.8 LoRA:低秩假设的工程化

本节位置:模块 11 · 大模型专题 | 前置:7.3、11.2 | 预计:35 分钟

一句话:LoRA 冻结原权重,只学习一个低秩更新 ;它假设「任务适配所需的变化,落在一个很小的子空间里」。

0. 场景引入

你在一家模型微调平台上值班:一个 7B 基座,fp16 权重 14 GB,单张 80 GB 的卡(可用约 74 GiB),对外承诺「训一个你自己的适配器」。

全参数微调一个 7B 模型:权重 14 GB(fp16),梯度 14 GB,Adam 优化器状态约 56 GB,再加激活——单任务峰值超过 90 GB,一张卡装不下一个任务,40 个租户排队就得 40 张卡。

但你真的需要改动全部 70 亿个参数吗?也许只需要在少数方向上调整。

LoRA 的做法:冻结 ,只学两个瘦矩阵 、, 或 。参数量从 降到 ,对 ,只有原来的 0.39%。

放到 7B 的具体账上,只挂每层 attention 的 Q、V,取 :

fp16 只有 17 MB,Adam 状态约 100 MB,单任务峰值降到 14 GB 权重 + 0.1 GB 适配器 + 约 6 GB 激活 GB。

于是决定很具体:一张卡放 3 个租户,还是 4 个? 3 个是 60 GB,稳;4 个是 80 GB,已经越过 74 GiB 的可用线,只能靠运气。

代价两边都有:放 3 个,40 个租户按每任务 38 分钟算,队列约 8.4 小时;放 4 个能压到 6.3 小时,赌的是激活峰值不抖——赌输一次 OOM,四个租户的任务一起失败。

读完本节,你能回答的三个问题是:

  1. 为什么 只跟 成正比,跟 无关?
  2. 的秩为什么一定不超过 ?
  3. 多租户服务时,什么时候该合并进基座,什么时候必须保持未合并?

1. 直觉

把全参数更新想成「给整个矩阵每个元素都动一点」;LoRA 想成「只允许在 个方向上调整」。

  • 把输入从 维压到 维(提取任务相关特征);
  • 把 维再升回 维(生成更新方向);
  • 两者相乘,得到秩至多 的更新矩阵。

💡 一句话直觉:LoRA = 用「降维-升维」的瓶颈结构,近似一个大的权重更新。

LoRA:冻结 W,只训练降维 A 与升维 B 的瓶颈结构

图:全参数微调要改整个 矩阵;LoRA 冻结 ,只训练 ()和 (),参数量 。 时是 131,072,约 。

类比边界:低秩是假设,不是定理。任务越复杂、与预训练分布差得越远,可能需要更大的 或更多可训练模块。

1.1 它在现实世界里对应什么

工程上,LoRA 是给一台已经调好的机器加一组微调旋钮:基座那排主推子锁死不动,每个租户只在自己那几个旋钮上做记号——换租户只换旋钮的刻度,机器本身不变,所以同一台机器能同时服务很多租户。

量级算式:整个矩阵有 个自由度,LoRA 只放开 个:

换句话说,它赌的是「任务适配只需要在 维的空间里挑 16 个方向」。

这个类比在哪里失效:旋钮出厂时就被设计成互相独立、各管一段频率,而 LoRA 的 16 个方向( 的行空间)是训练自己找出来的,彼此不正交、也没有可解释的含义;两个租户的 LoRA 更落在不同子空间里,所以不能把两个 取平均当作「两种风格的折中」——平均后的秩可能到 ,装不进 。

2. 定义

2.1 低秩更新

对冻结的 :

其中

是缩放超参, 是秩。

2.2 前向

2.3 初始化

  • :随机高斯(或 Kaiming);
  • :零矩阵。

这样训练开始时 ,模型行为与预训练完全一致,避免初始扰动。

2.4 合并

推理时可以把更新合并回原权重:

合并后前向与普通线性层相同,没有额外延迟。

3. 为什么这样定义

为什么低秩? 基于内在维度(intrinsic dimension)的假设:预训练模型已经学到通用表示,下游任务只需要在低维子空间里调整。SVD 分析也显示许多权重更新/权重本身的谱快速衰减(第 7.3 节)。

为什么冻结 ? 减少可训练参数与优化器状态;避免灾难性遗忘;让多个适配器共享同一个基座。

为什么用 而不是直接学一个低秩矩阵? 任何秩 的矩阵都能写成 ;参数化后可用标准梯度下降,且 的分解天然满足秩约束。

3.1 反事实: 不置零会怎样, 太小/太大各差在哪

反事实一:、 都随机初始化。 取 §5.2 那组数 、、、,训练第一步就有

这些元素的量级是 2 到 4,而 7B 的权重按初始化尺度 估算,量级只有 0.016——更新比基座本身大一百倍以上。第一步的输出分布就被整体推歪,loss 先跳高再慢慢爬回来,训练不稳、也容易把基座原本会的任务忘掉。

的全部意义就是让 在 严格为零:初始状态与预训练逐位相同,这是「从基座行为出发」的唯一保证。

反事实二: 太小。 时 是秩 1,对任何落在 的行空间正交补里的输入 ,都有 。用同一组数, 得到 ——第二维输入完全没被适配。一个任务若同时要改「语气」和「输出 JSON 格式」两件事, 只能二选一。

反事实三: 太大。 取 ,参数量变成 ,是原矩阵 的两倍; 也是满秩,等价于全参数微调,显存、过拟合、灾难性遗忘的代价全部回来。LoRA 相对全参数的唯一优势——参数少、一份基座服务多个租户——在这个 上消失了。

4. 性质与推导

4.1 秩上界

4.2 参数量

若 ,则为 。

4.3 计算量

前向额外计算: 是 , 是 ,合计 ,远小于 。

4.4 缩放

固定 时,增大 会让每个方向的更新幅度变小(因为除以 )。常见做法是令 或固定 ,以控制有效学习率。

4.5 合并的代价

合并后无法再切换适配器;多任务服务通常保留未合并形式,按请求动态加载 LoRA。

5. 例子

5.1 手算:参数量

,:

全参数 ,比例

5.2 手算:低秩更新的作用

设 ,,,:

秩 1。它只修改输入的第一维所对应的两个输出方向;第二维输入完全不受影响。

5.3 场景:多适配器服务

基座模型加载一次,不同用户加载不同 LoRA。每个 LoRA 只有几十 MB,切换成本低。 若把所有 LoRA 合并进基座,就无法同时服务多个任务——这是「合并」与「动态加载」的权衡。

5.4 场景闭环:一张卡放几个租户

输入:7B 基座 fp16 14 GB、32 层、,单卡 80 GB(可用约 74 GiB);LoRA 只挂 Q、V,、;每任务 batch token、2000 步。每个任务按独立进程估算,各占一份权重副本。

计算:

  • 参数量:,fp16 约 17 MB;Adam 的 fp32 主权重加两个动量按 12 字节/参数估算约 100 MB。
  • 显存:14 GB 权重 + 0.1 GB 适配器与优化器 + 约 6 GB 激活与临时量 GB/任务。3 个任务 60 GB,4 个任务 80 GB,已越过 74 GiB 的可用线。
  • 算力:LoRA 并不减少前向/反向的 FLOPs——基座仍然全量参与,按「每 token 每参数约 6 次浮点运算」估算,每步 FLOPs;按有效 300 TFLOP/s 约 1.1 s/步,2000 步约 38 分钟。

输出决策:每卡 3 个并发(留约 14 GiB 给激活抖动与碎片), 起步;先给一个租户跑 2000 步看验证集,再决定这个租户要不要升到 。

成本:40 个租户、每任务 38 分钟、每卡 3 并发 分钟,约 8.4 小时;改成 4 并发约 6.3 小时,但余量为负。真正的杠杆不是并发数,而是每任务步数:步数减半,队列时间就减半。

失败条件与兜底:

  • 任务要的是「记住新知识」而不是「改变风格」时,低秩更新装不下,验证集 loss 会停在明显高于训练 loss 的位置——兜底是升 或改检索(RAG),而不是继续加步数。
  • 序列长度从 2048 提到 8192,激活涨 4 倍,20 GB 变 38 GB,3 并发立刻 OOM——兜底是梯度检查点,用约 30% 的额外计算换显存。
  • 多租户热切换时,若请求路由与 的加载没有原子绑定,A 租户的客服口吻会出现在 B 租户的回答里——这种串台比 OOM 更难排查。

6. 常见误区

  1. 误区:LoRA 把原权重变成低秩矩阵。 纠正:原权重 不变;低秩的是更新 。

  2. 误区: 越大越好。 纠正: 增大提升容量,也增加参数、过拟合风险和显存;很多任务 足够。

  3. 误区:LoRA 推理一定没有额外成本。 纠正:合并后没有;未合并时每层多两次小矩阵乘,且多适配器切换有开销。

  4. 误区:LoRA 只能用于线性层。 纠正:原则上可作用于任何权重矩阵(attention 的 QKV/O、FFN、甚至 embedding);实际选择取决于任务。

7. 概念网络

8. 通往大模型:变体与工程

方法核心改动
LoRA
QLoRA基座 4-bit 量化 + LoRA
DoRA把权重分解为幅度/方向,分别更新
AdaLoRA动态分配各层的秩
VeRA共享随机投影,只学缩放

可检验结论:对 ,LoRA 参数 ,约为全参数的 ;若 ,缩放因子 。

注意:LoRA 的「低秩」是更新的低秩,不是权重的低秩。二者相关但不等价。

算错时用户看到什么: 忘了置零,租户在控制台上看到的是「微调把模型弄傻了」——基座原本会的任务也不会了,而且重跑一次还是这样。把「参数少」误当成「算得少」,给租户承诺 1 小时训完,实际每步的 FLOPs 由基座决定、要跑 8 小时,用户看到的是「预计 1 小时」的进度条在第 12 小时还没走完。合并回基座时漏掉 这个因子,更新会被放大或缩小 倍,用户看到的是「语气过猛」或「完全没效果」——而 loss 曲线可能一直很正常。

9. 练习

  1. 概念:为什么 LoRA 初始化时令 ?如果 都随机初始化会怎样?
  2. 计算:,(FFN 上投影),,求 LoRA 参数量与占比。
  3. 计算:,,, 的最大值是多少?
  4. 场景:为什么多租户 Serving 更愿意保留未合并的 LoRA?
  5. 开放:如果任务需要改变模型的行为风格(而不是知识),低秩假设还成立吗?如何验证?
参考答案
  1. 保证初始 ,模型从预训练行为开始;若都随机,初始输出被扰动,可能破坏基座能力、训练不稳定。
  2. ;全参数 ,占比约 。
  3. 最大 8。
  4. 可以共享基座、动态切换适配器;合并后每个任务需一份完整权重,显存/切换成本高。
  5. 不一定;风格/行为可能涉及较多方向。可通过增大 、适配更多层,或比较不同 的验证集表现来验证。

10. 一页速记

  • ,,。
  • 参数量 ;秩至多 。
  • 初始化保证从基座行为开始。
  • 可合并,合并后无推理延迟;未合并可多适配器切换。
  • QLoRA = 量化基座 + LoRA。
  • 物理意义 / 现实对应:给锁死的基座加一组低秩旋钮;放开 个自由度,占 的 (、 时约 0.78%)。

11. 参考文献与致谢

这一页的知识不是凭空来的。下面列出本页直接借用的原始工作与权威整理;正文中的人名、定理名已链接到对应条目。链接优先指向 DOI、arXiv 或可长期访问的原文存档。

  • Hu 等(2021):LoRA: Low-Rank Adaptation of Large Language Models。LoRA 的原始论文:冻结 ,只训练 (秩至多 ),并给出把更新合并回原权重的做法;本页 2.1 的 与 2.4 的合并式都出自这里。arXiv:2106.09685
  • Aghajanyan 等(2020):Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning。用「内在维度」衡量微调所需子空间的大小,发现它远小于参数量——这是本页第 3 节「为什么低秩」的实验依据。arXiv:2012.13255
  • Dettmers 等(2023):QLoRA: Efficient Finetuning of Quantized LLMs。把基座量化到 4-bit 后在其上训练 LoRA,并引入分页优化器;本页第 8 节表格里的 QLoRA 即此。arXiv:2305.14314

下一篇 → 11.9 量化:缩放因子与矩阵误差

返回 M11 导览去练习场

随堂测 · 3 题

数值难度 1第 1 / 3 题
、,LoRA 在单个 线性层上新增多少参数?

源文件:11-大模型专题/08-LoRA.md

输入关键词开始搜索