peft target_modules 与 merge
LoRA 只训低秩增量矩阵,省显存防 catastrophic——rank 和 target modules 决定 capacity,全量微调仍可能在数据足时更强。

1. LoRA 训完没提升,trainable 参数是 0
LLM 下游分类,挂 PEFT LoRA 训 3 epoch,metric 与 frozen backbone 一样——print_trainable_parameters() 显示 trainable 0%。target_modules=["q_proj","v_proj"] 与 HF 模型实际层名不一致,LoRA 根本没注入。比 rank 调参更先查:名字对不对、有没有真的在训。第一次挂 LoRA 的 PR 应强制贴 print_trainable_parameters 输出,trainable 0% 直接 reject。
2. 机制:低秩增量
,,,。只更新 ,base 冻结。有效缩放 \propto \text{lora_alpha}/r;lora_alpha=16, r=8 是常见起点。rank 加倍不等于 capacity 加倍——还受 target_modules 覆盖范围约束;只 inject q/v 与 inject q/k/v/o+MLP 是不同量级的可训子空间。
from peft import LoraConfig, get_peft_model
config = LoraConfig(
r=8, lora_alpha=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05, bias="none",
)
model = get_peft_model(base_model, config)
model.print_trainable_parameters()3. target_modules 与 capacity
Transformer 常 inject 到 q/k/v/o;MLP 层(gate_proj, up_proj, down_proj)对某些 task 也要开。r=4 欠拟合复杂 task;r=64 接近全量,显存与过拟合风险升。全量+LoRA 同时训 base(未 freeze)等价大 LR 毁预训练——要么 freeze base,要么分层 LR 且极小。用 named_modules() 打印线性层名,再填 target_modules,避免猜名字。
4. 训练接线
optimizer = torch.optim.AdamW(
filter(lambda p: p.requires_grad, model.parameters()), lr=2e-4)log loss、lr、grad_norm、AMP scale。小数据 early stop,别指望大 rank 自动泛化。adapter checkpoint 与 base 模型 ID 分开 version——部署加载错 base 是 silent 灾难。训练 config 记录 base_model_revision 与 adapter_hash。
5. 部署:merge 或 on-the-fly
from peft import PeftModel
model = PeftModel.from_pretrained(base, adapter_path)
merged = model.merge_and_unload()
merged.save_pretrained("merged")inference merge 减 latency;多 adapter 切换保留 PEFT。merge 后 ONNX export 更简单——仍要 ORT assert_allclose。多租户 on-the-fly 挂 adapter 要 profile 每 token 延迟,merge 常快 10–30%。
6. 与 full fine-tune 的取舍
数据足、budget 够、任务与预训练域差大时,full FT 仍可能更强。LoRA 胜在 显存、多任务 adapter 切换、防遗忘。同 GPU-hour budget 对比 LoRA rank sweep 与 full FT,报告 trainable 比例与 peak VRAM。小数据 + 大 rank LoRA 易过拟合,表现不如小 rank + 更强 augment。
7. 失败模式
| 现象 | 原因 |
|---|---|
| metric 不动 | target_modules 名错 |
| 过拟合小数据 | r 过大 |
| deploy 慢 | 未 merge |
8. 验收
trainable 比例与 print_trainable_parameters;下游 metric vs 同 budget full FT。val 存 best adapter → test 一次。改 rank 可单变量回滚复现。
9. 案例:层名猜错训空转
7B 模型实际 linear 名带 self_attn.q_proj 前缀,config 写 q_proj 未匹配,trainable 0% 训满 3 epoch loss 几乎不变。fix 后 trainable 0.8% metric 升 4 pt。教训:LoRA PR checklist 第一条 print_trainable_parameters,第二条 layer 名 grep 对照。
10. 多 adapter 与路由
SaaS 场景一 base 多 adapter,路由按 tenant 加载不同 adapter path。on-the-fly 要测 cold load 与 switch 延迟;QPS 高时 merge 多个 adapter 不现实,要 cache 已加载 adapter。版本矩阵:base v2 不兼容 adapter v1 时,部署脚本应 assert 配对,避免 silent 降 metric。
11. 与 QLoRA / 量化训练
QLoRA 在 4bit base 上训 LoRA,export 与 merge 路径更绕——merge 后是否仍 int4 取决于框架。部署前明确:服务跑 merged fp16 还是 adapter on-the-fly on quant base。训练验收仍看 task metric 与 trainable 比例;export 验收另走 ORT 链。instruction tuning 时常开 LoRA 只训 attention,但 reasoning 任务可能需 MLP adapter——target_modules 空配是 task 相关决策,不是默认 q/v 就够。rank sweep 应用相同 data seed 与 early stop 规则,否则比较不公平。多 task adapter 并存时,每个 adapter 单独 val best,禁止共用一个 early stop 计数器。LoRA dropout 在极小数据上可能必要,但 deploy merge 前确认 eval 模式 dropout 关闭。Instruction 数据含 long context 时,LoRA rank 与 cutoff len 联动调——rank 大但 context 截断仍欠拟合。Adapter 文件体积小,artifact 仓库要与 base 分目录,防止 deploy 脚本 pull 错路径。Full FT 对照实验用相同 early stop 与 augment,报告 GPU-hour 与 peak VRAM,LoRA 优势才可辩护。
12. 案例:rank 16 仍不如 full FT
100k 样本分类,LoRA r=16 trainable 1.2%,val 比 full FT 低 2 pt 同 GPU-hour。加 MLP target + r=32 后追平;说明 capacity 不够时加 rank 与加 target 都要试。报告写清 trainable% 与 GPU-hour,避免只吹 LoRA 省显存。QLoRA 4bit base 上 eval merge 路径与 fp16 LoRA 不同,deploy 文档单列一节。Adapter 热切换要测 LRU 缓存 miss 延迟;merge 模型适合固定 tenant,多 tenant 仍用 PEFT 动态加载。Rank 与 alpha 联动:增 rank 不增 alpha 时 effective 更新幅度降,需同比例调 alpha 或 LR。Freeze bias 与 freeze norm 策略写进 config,避免「训了 LoRA 但 norm 漂移」。SFT 数据混 base 对话时,LoRA 只训 assistant 段的 mask 与 shape assert 在 collate 层做。Multi-adapter serving 文档写清 load 顺序与 LRU 上限,防 OOM swap thrash。Eval 时 model.eval() 且 LoRA dropout 关闭,merge 前后各跑一次 val 确保 parity。Instruction tuning 数据格式变(chat template)时 re-check target_modules 是否仍匹配新模块名。Rank sweep 实验记录 peak VRAM 与 wall-clock,选型给 infra 审而不只给 research slide。Legal/compliance 要求 retain adapter 训练数据清单时,LoRA 路径更易审计 trainable 子集。Merge 权重进 base 后 irreversible,保留 adapter 副本再 merge 便于 A/B 回滚。Peft 版本与 transformers 版本 pin 在 requirements,升级前跑 LoRA inject smoke。SFT 与 RLHF 挂 LoRA 时 reward model 与 policy 的 adapter 命名空间分开,防 load 错 adapter。Release trainable% 与 val metric 同表,rank 变更一行可审计。Hub 上 adapter card 写清 base model revision 与 eval metric,便于下游选型。
LoRA 是 capacity–成本旋钮——先确认注入成功,再谈 rank。
相关
也可以看看
- ·4 分钟阅读
freeze_bn 与 target 域 stats
小 batch 微调时 BatchNorm 统计量噪声大——freeze backbone BN、换 SyncBN 或 GroupNorm 往往比盲目加大 batch 更实际。
- ·3 分钟阅读
微调:冻哪些层
数据少时一次解冻全网易过拟合+毁 pretrained 特征——先训 head、再逐层解冻是稳妥默认,LR 分组随解冻调整。
- ·16 分钟阅读
KV cache 分页与前缀复用:吞吐上去后正确性怎么验
沿 block table、前缀哈希与抢占回收拆开缓存一致性风险,说明错页复用为何表现为「偶发胡话」;用确定性前缀集、强制抢占和逐 token 对照验收。
johan's blog