LoRA 的原理是什么?rank、alpha 和 target_modules 如何选择?
简化版
LoRA 冻结原权重,用两个可训练低秩矩阵表示任务权重增量,显著减少可训练参数和优化器状态。rank 控制增量容量,alpha 控制缩放,target_modules 决定把 LoRA 加到哪些线性层;它们没有跨模型通用的最优值,必须结合任务和评估选择。
详细版
对原权重矩阵 W,LoRA 使用:
W' = W + sBA
s = alpha / r
其中 A 和 B 的中间维度为 r。当 r 远小于输入、输出维度时,可训练参数约为 r(d_in + d_out),小于完整矩阵的 d_in × d_out。
- rank:越大容量和参数越多,但不保证效果单调提升;
- alpha:调节 LoRA 更新相对基座输出的尺度;
- target_modules:可只选注意力投影,也可覆盖更多线性层;
- dropout:小数据时可缓解过拟合;
- 初始化:通常让初始增量接近零,使训练从基座行为开始。
选参时先用较小 rank 建基线,再比较目标层覆盖、验证集效果、显存和延迟。
完整版教学
记忆钩子:rank 管低秩容量,alpha 管增量尺度,target_modules 决定能力改在哪里。
一、为什么低秩增量可能有效
微调虽然允许全部权重变化,但任务所需的有效变化可能集中在较低维子空间。LoRA 不直接压缩原模型,而是限制新增的权重变化为低秩形式。
这是一种建模假设,不是数学保证。任务差异越大,低秩空间越可能成为限制。
二、矩阵是怎么接入的
前向计算同时经过冻结的原线性层和 LoRA 分支,两路结果相加。反向传播只更新低秩矩阵,基座权重不保存梯度和优化器状态。
不同实现对两个矩阵的命名、形状和初始化方向可能相反,但“一个分支初始为零,使整体增量起步为零”的目标相同。
三、rank 与 alpha 不能分开看
rank 增加会提高参数量和表达容量;alpha 决定增量缩放。原始缩放为 alpha/r,部分变体采用其他缩放规则,因此复制配置时要同时确认实现。
高 rank 不等于“学到更多知识”,低 rank 也不天然防止过拟合。应观察验证指标和更新幅度。
四、目标模块怎么选
经典做法常选择注意力的 query、value 投影,现代实践也会覆盖 key、output 和 MLP 线性层。覆盖越广,可训练参数与容量越大。
模块名称依赖模型架构,配置写错可能导致没有层被训练。训练前应打印可训练参数及实际命中的模块。
五、合并与部署
训练后可保留“基座 + Adapter”,便于切换任务;也可把增量合并到基座权重,减少额外推理算子。合并后的模型体积接近完整模型,且必须记录对应基座版本。
多个 LoRA 可以组合,但简单相加可能互相干扰,需要单独评估。
六、常见排查
若损失不下降,先确认目标模块真实命中、参数需要梯度,再检查学习率、Mask 和数据格式;零个模块命中时训练脚本甚至可能不报明显错误。若训练集迅速变好而验证集恶化,优先降低学习率、rank 或训练步数。若训练与验证都欠拟合,再扩大模块覆盖或 rank,并用消融区分容量不足与数据不足。
七、手算一个 LoRA 层的参数量
对 W∈R^{4096×4096},rank=8 的 LoRA 使用 A∈R^{8×4096} 和 B∈R^{4096×8},新增参数为 65,536,仅占原矩阵 16,777,216 参数的约 0.39%。若覆盖 32 层的 q_proj 与 v_proj,总可训练参数约为 65,536×2×32=4.19M。
| 配置变化 | 容量/成本影响 | 需要观察 |
|---|---|---|
| rank 增大 | 参数与显存线性增加 | 验证集是否继续提升 |
| alpha 增大 | 增量缩放增强 | 更新是否过强 |
| 覆盖 FFN | 容量明显增加 | 领域效果与部署成本 |
W_eff = W_frozen + (alpha / rank) * B * A
rank、alpha 与 target_modules 必须联合实验。训练前打印实际命中的模块和可训练参数,训练后比较未合并与合并输出;否则配置拼错可能导致“训练完成但几乎没更新”或合并后数值漂移。
八、常见误区与追问
- 误区:rank 越大效果必然越好。 容量增加也会带来过拟合和成本,验证收益可能很快饱和。
- 追问:alpha 起什么作用? 它与 rank 共同决定低秩增量缩放,必须确认具体框架采用的 scaling 公式。
- 追问:target_modules 配错会怎样? 可能零层命中或改错模块;训练前应打印模块名和可训练参数。
- 误区:LoRA 只能加在 Q、V。 也可覆盖 K、O、FFN 等线性层,范围越广容量和成本越高。
- 追问:合并后为何还要回归? 精度转换、量化顺序和权重共享可能造成数值或行为差异。
九、加强记忆
LoRA 把权重更新限制为低秩乘积:rank 管容量,alpha 与 rank 一起管缩放,target_modules 决定把增量放在哪里。训练前确认模块真实命中和可训练参数,训练中用验证集判断容量是否足够,训练后核对合并前后数值与行为。参数少只是手段,能否稳定提升目标能力才是验收标准。