多模态微调实战(04):小规模 LoRA 试跑,先证明流程可用
在上全量之前,先用 两千级样本 把 LoRA 跑通。这一步的目标不是刷榜,而是回答三个问题:命令能不能跑完?显存是否稳定?验证指标有没有「方向正确」的提升?
这是「多模态微调实战」的第 04 篇。先小后大的「小」,就在这一篇。
一、训练命令骨架
核心是 swift sft。下面是一组在约 16GB 单卡上验证过的参数思路:
1 | PYTORCH_ALLOC_CONF=expandable_segments:True \ |
实践中通常包一层脚本,例如 bash script/train_lora.sh。
二、超参怎么理解
| 参数 | 取值思路 | 为什么 |
|---|---|---|
tuner_type=lora |
LoRA | 16GB 友好 |
freeze_vit / freeze_aligner |
true | OCR 更偏「读图后对齐文本」,先冻视觉侧降显存、稳训练 |
lora_rank / alpha |
8 / 32 | 常见起点;不够再加大 rank |
batch=1 + grad_accum=8 |
等效 8 | 显存不够就堆累积步数 |
gradient_checkpointing |
true | 用时间换显存 |
IMAGE_MAX_TOKEN_NUM |
512 | 限制视觉 token,防 OOM |
MAX_PIXELS |
~80 万 | 约 896×896 量级;OOM 可减半 |
attn_impl |
sdpa |
无 flash-attn 时的稳妥选择 |
epochs |
3 | 小数据集足够观察收敛 |
三、显存与耗时量级
一次演示集实践的观察(供对照):
| 项目 | 量级 |
|---|---|
| 峰值显存 | 约 9GB / 16GB |
| 数据规模 | 2k 训练 × 3 epoch |
| 耗时 | 大约几十分钟 |
若一上来就 OOM,按这个顺序降级:
MAX_PIXELS降到约一半;IMAGE_MAX_TOKEN_NUM再降;lora_rank降到 4;- 确认没有其他进程占 GPU。
四、训练过程你会看到什么
正常日志大致包括:
- 加载基座与 processor;
- 注入 LoRA(可训练参数通常只有总参数的很小比例);
- 周期性打印
loss/token_acc/learning_rate; - 按
save_steps写出checkpoint-xxx。
输出目录示例:
1 | output/ocr_plate_lora/ |
LoRA checkpoint 内通常有:
adapter_model.safetensorsadapter_config.jsontrainer_state.json- (完整续训还需要)
optimizer.pt/scheduler.pt等
五、小规模成功的判定
不要只看 loss 下降。至少做三件事:
- 训练能完整跑完,无 CUDA error;
- 验证集上用同一脚本评测(见下一篇);
- 抽几张图人工看输出是否「格式正确」。
若演示集 Exact Match 从个位数飙到接近满分,通常说明:提示词与标签格式对齐了,模型学会了「按你的规范吐车牌」。但这不能直接等价于全量场景的泛化,它只证明:流水线是通的。
六、小结
小规模试跑完成标志:
- 有可用的 LoRA checkpoint;
- 显存策略已确认;
- 准备进入「前后对比评测」。
多模态微调实战第 04 篇完。下一篇:把「微调前 vs 微调后」用同一套指标摆到一张表上。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 WALL-E's Blog!











