LoRA
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 | 任务梯度被限制在低秩子空间 |
训练与部署检查
- 训练前打印命中的模块名、可训练参数量和 dtype;没有命中 target module 时“成功训练”可能只是零更新。
- 训练中同时看 adapter 梯度范数、基座回归集和目标任务,避免只追踪训练 loss。
- 部署时分别验证 adapter 模式与 merge 模式;量化基座、不同 kernel 或导出格式可能造成小幅 logits 漂移。
相关节点:PEFT、QLoRA、Training 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、量化导出三条路径,把数值漂移和训练质量问题拆开。