LoRA 微调实战 - 显存、标签掩码与合并部署的踩坑记录(附清单)

运营上周提了个需求。客服机器人要能答一批内部产品术语,通用模型答得含糊。想全量微调,一算显存就放弃了,6B 的模型全参训练,优化器状态加梯度缓存,80GB 的卡都紧张。最后用 LoRA 在单卡 24GB 上跑通。从装环境到出第一个 adapter 用了两天,大头全在排错。这篇把配置和三个坑整理出来,照着走能少绕路。

先给结论

方案 可训练参数占比 显存占用(6B,bf16) 适用场景
全量微调 100% 80GB 起,需多卡 预算充足,追求极限
LoRA 1%~2% 16~22GB 通用指令微调,性价比首选
QLoRA 1%~2%(基座 4bit) 10~14GB 消费级显卡

QLoRA 会略微增加推理延迟。快速验证领域适配效果时,LoRA 更划算。

环境先锁版本

微调代码死于版本不兼容的,比死于调参的多。transformers、peft、torch 三者的接口一直在动,老代码在新环境里经常直接报错。我锁的组合是 torch 2.1.2、transformers 4.38、peft 0.8,装完先跑一行确认 CUDA 可用,再往下走。

基座模型要单独跑通一次推理。ChatGLM 这类模型需要 trust_remote_code=True,模型结构和特殊 token 都在官方远程脚本里定义,缺了这个参数加载直接失败。推理用 bf16,fp16 在小数值上容易溢出,生成会出乱码。

三个真实的坑

坑一,target_modules 配错是静默失败。 ChatGLM 的注意力层把 Q、K、V 合在一个线性层里,名字是 query_key_value。照网上 Llama 的写法填 q_proj、v_proj,PEFT 找不到目标层,不报错,照样开训,只是什么都没学。跑训练前先看 print_trainable_parameters() 的输出,可训练参数占比应该在 1% 上下,打印出来是 0 就回头查配置。

坑二,padding 的标签没置 -100。 症状是 loss 长期降不动,曲线来回震荡。Trainer 默认对所有 token 算交叉熵,padding 位置要手动设成 -100 让损失计算跳过。这个坑在数据预处理阶段埋下,很多人以为是学习率的问题,往小调了半天没效果。

坑三,训练几百步后 OOM。 显存曲线本来平稳,某一步突然跳涨爆掉。排查下来是 DataLoader 的 num_workers 大于 0,子进程共享 CUDA context,collate 时产生隐式显存拷贝,攒到阈值就爆。处理顺序是先设 num_workers=0 验证归因,再开 pin_memory 和 persistent_workers。手动 empty_cache() 只能临时腾出一点空间,稳当的做法是检查张量生命周期,别让它们跨 batch 泄漏。

训练参数这么设

参数 取值 说明
per_device_train_batch_size 2 显存吃紧时先动它
gradient_accumulation_steps 8 等效 batch 16,不增加峰值显存
learning_rate 2e-4 LoRA 用比全量大一档的 lr
r / lora_alpha 8 / 16 alpha 取 r 的两倍
gradient_checkpointing true 峰值再降 20%~30%,训练时间加 15%

我用 24GB 卡、等效 batch 16,峰值显存 19.3GB。梯度累积是关键,它把峰值压在单个 micro batch 上,显存不够就加累积步数,慢一点但能跑。

数据量少于 2000 条时,max_steps 控制在 1000 以内,调度器换 linear,防止后期把参数拖进平坦区。

训练完怎么部署

产物是 adapter_model.bin,只有几十 MB,两种用法。

动态挂载走 PeftModel.from_pretrained,基座不动,随时换 adapter,适合灰度和多任务切换。合并走 merge_and_unload(),把 LoRA 权重算回基座,推理快 5%~8%。合并时 dtype 要和训练时一致,bf16 训的就 bf16 存,强转 fp32 会放大量化误差。

结合系列

  • 训练前后的显存估算和量化版本选型,见《模型量化部署实战》
  • 微调数据里的 JSON 类输出,先过结构化校验再进训练集,见《结构化输出实战》
  • LoRA 和 prompt 模板是绑定的,换模板等于换任务,上线策略参考《Prompt 管理实战》
  • 微调效果好不好,要和通用模型跑同口径评测,见《LLM 评测》篇

写在最后。LoRA 本身是成熟技术,时间都花在周边工程细节上。版本对齐、标签掩码、显存峰值,每一处都能让训练白跑。开跑前逐项过一遍,省下的都是排查的时间。

下一篇写 RAG 和微调混合的实践,检索召回为主,模型训练为辅。觉得有用的话点个关注,有问题评论区聊。

参考《从零开始大模型微调(基于 PyTorch 与 ChatGLM 的 LoRA 实践)》,作者 打工仔折腾 AI。结构借鉴,配置和数据结论经过独立验证。

相关推荐
Smoothcloud润云1 小时前
GPU算力平台跑知识库问答,模型回答总跑偏?先排查检索链路
人工智能·python·深度学习·gpu算力·gpu
AI人工智能+2 小时前
通用表格识别技术如何通过五步AI流程,实现对复杂真实表格的智能解析
人工智能·深度学习·ocr·表格识别
LaughingZhu2 小时前
Product Hunt 热榜 2026-10-20:Beam.win、Figma Specs、readywhen
人工智能·深度学习·神经网络·搜索引擎·百度
frankzch2 小时前
HybridAgent 拆解:在潜空间想,动手时才出字
人工智能·深度学习·语言模型
小李同学_LHY2 小时前
大白话模型第三章:深度学习
人工智能·深度学习
星核0penstarry4 小时前
宕机那天 API 还能用,所以模型是假的?
运维·服务器·人工智能·大模型·ai编程·模型指纹
碧海银沙音频科技研究院4 小时前
基于ATS308X的无线语音交互对话功能实现
人工智能·嵌入式硬件·深度学习·算法
遇码4 小时前
Rust 桌面应用自托管自动更新:latest.json 清单 + minisign 签名校验的完整做法
人工智能·ai·rust·大模型·agent