M37:LoRA 最小机制:冻结权重上的低秩更新
LoRA 冻结原始线性层权重 `W₀`,用两个较小矩阵的乘积 `BA` 表示可训练更新,从而以较少参数改变该层行为。
内容类型:预习教材(不代表已完成)
日期:2026-09-29
阶段:P1 · AI Model Engineering 90
周次:W6 · SFT、LoRA/PEFT 与领域适配
节奏:周二最小实现
状态:教材已备;学习未完成
标签:lora、low-rank、peft、linear-algebra、parameter-count
一句话定义
LoRA 冻结原始线性层权重 W₀,用两个较小矩阵的乘积 BA 表示可训练更新,从而以较少参数改变该层行为。
学习目标
- 能从 shape 推导 LoRA 的参数量与 forward。
- 理解 rank、缩放系数、初始化和 target module 的作用。
- 能写出一个不依赖完整训练框架的最小 LoRA 线性层。
核心知识
原始线性层令 W₀ ∈ R^(d_out×d_in),普通全参微调需要更新 d_out×d_in 个权重。LoRA 令:
W = W₀ + (α/r)BA
其中 A ∈ R^(r×d_in),B ∈ R^(d_out×r),rank r 通常远小于输入和输出维度。可训练参数量为 r(d_in+d_out)。例如 4096×4096 的层有约 1678 万参数;若 r=8,LoRA 只需 65536 个参数,约为 0.39%。
α/r 控制增量尺度。常见初始化让其中一个矩阵为零,使训练开始时 ΔW=0,模型初始输出与基座一致;另一个矩阵使用小随机值,保证后续梯度能传播。实际库的 A/B 命名与矩阵方向可能不同,判断时以 shape 与 forward 为准。
机制/推导
输入 x ∈ R^(batch×d_in) 时,可写:
y = xW₀ᵀ + (α/r)(xAᵀ)Bᵀ
先把 d_in 投影到低维 r,再投影到 d_out。计算和存储增量都随 r 线性增长。LoRA 假设任务所需权重变化在较低维子空间内可近似表示;这是工程假设,不意味着原始权重本身低秩,也不保证任意任务都可用很小 rank 表达。
若 r ≥ min(d_in,d_out),表达能力接近一般矩阵分解,参数优势消失。rank 太小可能欠表达,太大则增加成本和过拟合空间。target module 决定把更新放在哪些线性变换中,如 attention 的 q/v 或更多投影;位置和数据共同决定结果,不能只看参数总数。
最小练习或观察步骤
- 设
d_in=4、d_out=3、r=2,在纸上写出W₀、A、B的 shape。 - 手算 LoRA 参数量
2×(4+3)=14,并与全权重 12 比较:这个玩具尺寸下 LoRA 反而不省,说明优势依赖大维度。 - 实现一个
FrozenLinearWithLoRA:冻结W₀,创建 A/B,只将 A/B 交给 optimizer。 - 用固定小输入分别计算 base output、delta 与 combined output,检查三者 shape。
- 在训练前验证 combined 与 base 是否一致;不要预写验证结果。
- 打印 trainable parameter 名称与数量,确认原权重没有梯度更新。
常见误区
- 把 rank 当作“保留多少原模型知识”的百分比。
- 只设置
requires_grad=False,却把不该训练的 bias 或 head 留在 optimizer 中。 - 认为参数少就必然显存很低;激活、序列长度和 batch 仍占主要空间。
- 忽略缩放与初始化,导致适配器一开始就扰动基座输出。
- 玩具矩阵中参数不省便否定 LoRA;应按真实层维度计算。
金融 / Web3 / 文档场景连接
LoRA 可用于学习稳定的文档分类格式、机构术语或证据摘要风格,但实时规则、黑名单和链上状态不应依赖适配器记忆。适配器版本必须绑定基座版本与训练数据范围,否则即使 shape 兼容,行为也可能不可比较。
自检问题
- 给定
d_in、d_out、r,如何计算 LoRA 参数量? - 为什么常让初始
ΔW=0? - LoRA 节省了哪些参数,又没有自动节省哪些资源?
- target module 与 rank 分别控制什么?
专业课程对齐
- 必读 HF PEFT LoRA 的
LoraConfig,逐项对照r、lora_alpha、lora_dropout、target_modules、bias与use_rslora。 - 精读 Stanford CS336 中 Transformer 线性层、参数与训练内存相关课题,将 LoRA 放回 attention/MLP 投影矩阵的真实 shape 中。
- 选读 PyTorch Tutorials 的
nn.Module、autograd 与 parameter 管理主题,检查冻结权重与 adapter 梯度。
深入学习提示
先手算 ΔW=(α/r)BA,对 W∈R^{d_out×d_in} 确认 A∈R^{r×d_in}、B∈R^{d_out×r} 和可训参数 r(d_in+d_out),再对照 PEFT 实现。代码上沿 named modules 找到 q/k/v/o 或 MLP 投影,核对设置 adapter 后可训参数比例与梯度非零位置。资源比较要分开参数存储、激活和优化器状态;LoRA 不会按参数比例等比降低全部内存。反例是 rank 越大就必然越好,或 adapter loss 下降就证明低秩假设对任务成立。
学后填写区
- 玩具层 shape:
- 手算参数量:
- 实现中实际 trainable 参数:
- 尚未理解的梯度路径:
- 想在 M38 观察的一个问题: