LoRA

LoRA 冻结原权重 W,学习低秩更新:

$$W’ = W + \Delta W,\qquad \Delta W = sBA$$

其中 rank r 远小于输入、输出维度,s 常与 alpha/r 等 scaling 约定有关。

关键决策

  • target modules:应从实际模型的 named_modules() 确认,不能把 q_proj/v_proj/o_proj 当成所有架构的固定名称。
  • rank:更高通常增加容量和训练参数,但并非越高越好。
  • alpha/scaling:与初始化、rank、学习率和实现共同作用,不能简单说“越大收敛越快”。
  • merge:需区分保存 adapter、加载 base、merge_and_unload 与保存 merged model。

常见误区

  • 标准 LoRA 不要求先对 W 做 SVD。
  • LoRA 不等同于 QLoRA;QLoRA 还量化了冻结的基础模型权重。
  • adapter 小并不意味着训练激活和 KV 等其他内存开销消失。

为什么低秩更新可能有效

LoRA 假设任务相关的权重变化落在较低维子空间,因此用 B∈R^{d_out×r}A∈R^{r×d_in} 近似完整更新。参数量从 d_out·d_in 变成 r(d_in+d_out);这解释了存储和优化器状态的下降,但也说明 rank 太小会形成容量瓶颈。

因果链是:

1
2
3
4
任务梯度被限制在低秩子空间
→ 更新成本下降、多个任务可复用基座
→ 表达容量受 rank/target modules 约束
→ 用验证集决定是否增 rank 或扩大注入位置

训练与部署检查

  • 训练前打印命中的模块名、可训练参数量和 dtype;没有命中 target module 时“成功训练”可能只是零更新。
  • 训练中同时看 adapter 梯度范数、基座回归集和目标任务,避免只追踪训练 loss。
  • 部署时分别验证 adapter 模式与 merge 模式;量化基座、不同 kernel 或导出格式可能造成小幅 logits 漂移。

相关节点:PEFTQLoRATraining Memory Accounting

rank 不是越大越接近全参微调

r 增大确实增加 A/B 的自由度,但有效容量还取决于注入了哪些层、数据是否覆盖任务变化以及优化是否稳定。只给 attention 的 Q/V 投影可能足够改变风格或格式,却不足以学习复杂领域映射;把 LoRA 盲目加到所有线性层会增加激活和优化成本,也可能更快遗忘基座行为。更有信息量的实验是固定 token 预算,做 rank × target modules 的小矩阵,并报告目标集、基座回归集和峰值显存。

初始化还影响“训练一开始是否改变基座”。常见做法令一侧矩阵为零,使初始 ΔW 为零;若自定义初始化让两侧都非零,模型在第一个 optimizer step 前就已经偏离基座。学习率应按 adapter 参数和有效 batch 重新校准,不能直接照搬全参微调的值。

失败时先证明 adapter 真在工作

一个可操作的最小检查是:打印命中的模块数量、可训练参数量、每个目标模块的梯度范数,并在训练前后对同一输入比较 Δlogits。若 loss 下降而 Δlogits≈0,可能 target name 没命中、参数被冻结或 optimizer 没接到 adapter;若所有层梯度爆炸,检查 scaling、学习率和混合精度。部署时再对比未 merge、merge、量化导出三条路径,把数值漂移和训练质量问题拆开。