LoRA 微调实测:24GB 显卡上的三组超参和一条被忽略的清洗规则

举报
yd_238528621 发表于 2026/10/26 12:45:23 2026/10/26
【摘要】 三周七次 LoRA 微调只有两次上线,七成时间花在数据与评估口径上。记录 24GB 单卡上的显存账、三组学习率对照、验证集切分踩的坑,以及上线前的 adapter 合并、精度漂移与回归三步,附最终参数组合与单次训练成本。

三周七次微调,只有两次上线

我这边三周一共跑了 7 次 LoRA 微调,只有 2 次真正上线。剩下 5 次里,3 次训崩,2 次训完还不如基座。事后复盘,花在调参上的时间不到三成,七成耗在数据清洗和评估口径上。

这篇不给入门教程,只把那张 24GB 显卡上的账摊开:显存怎么算、超参怎么试、哪一步最容易被忽略。

环境与显存账:先算清能开多大

开始前别急着改学习率,先把显存预算算出来,它决定了后面所有参数的可行域。

  • 基座与量化:7B 模型,4bit nf4 加载,double quant 打开,计算精度 bf16,单卡 24GB。量化后权重约占 4.5GB,剩下的 19.5GB 才是激活值、梯度和优化器状态的战场。
  • 三档 r 的真实占用:r=8 显存峰值 14.2GB,余量很宽,batch 可以开到 4;r=16 峰值 16.8GB;r=32 在 batch=2、gradient accumulation=8、序列长度 2048 时峰值 23.6GB,再塞一个样本立刻 OOM。可训练参数从 0.4% 涨到 1.6%,显存和单步耗时几乎线性上涨,效果却完全不线性。
  • 先定序列长度:4200 条样本长度中位数只有 380 token,但最长 2900。统一截到 2048 而不是 4096,显存直接省下约 4GB,被截掉的样本只有 60 多条,代价可控。
  • checkpoint 也占盘:每 200 步存一次 adapter,三个 epoch 下来约 3GB。它不占显存,但写入会拖慢训练节奏,尤其放在机械盘上。
  • 激活值重计算换显存:开启 gradient checkpointing 后,r=32 那组的显存峰值从 23.6GB 降到 18.9GB,代价是单步耗时多约 18%。不打开它,这一组只能把序列砍到 1536,长样本全被截断。
  • batch 与 accum 的等效并不相等:等效 batch 16 可以拆成 batch=2 配 accum=8,也可以拆成 batch=8 配 accum=2。前者省显存,但每步多跑 8 次前向,单个 epoch 慢 12 分钟;后者快,可 batch=8 在 2048 长度下直接 OOM。显存不够时,慢一点是唯一选择。

三组超参:同一份数据的不同命运

超参我只动学习率,其余固定。变量一多就无法归因,这是我在第二次失败后才想明白的。

  • 3e-4 直接发散:第一个 epoch 前 100 步 loss 从 1.9 掉到 1.1,第 130 步附近跳到 3.4 再没下来,梯度范数一度到 12。LoRA 可训练参数少,不等于更新幅度可以放大。
  • 2e-4 抖但能收敛:loss 在第二个 epoch 中段从 0.92 抖到 1.4 又回落到 0.88,加 5% warmup 与 cosine 衰减后曲线平稳,最终 eval loss 0.87,三个 epoch 单次约 2 小时 40 分。
  • 1e-4 稳但欠拟合:曲线很漂亮,eval loss 卡在 1.12 下不去,人工盲评也对不出和基座的差别,等于白训两小时。
  • 最终配置:r=16、alpha=32、lr=2e-4、warmup 5%、cosine、batch=2 配 accum=8(等效 batch 16)、3 epoch。别人的经验值只能当起点,这套参数是在自己数据上跑出来的。
  • 评估频率与早停:每 100 步跑一次 eval,eval loss 连续三次不降就停。r=16 那组实际在 2.6 个 epoch 收敛,第三轮基本白跑,早停省下约 25 分钟,也避免了后期开始背训练集里的句式。

数据:训练集里的「漂亮答案」是最大隐患

前三次失败里,有两次数据看着很干净,问题恰恰出在太干净。

  • 风格过于统一:4200 条里有 1300 条是人工改写的标准答案,句式整齐、长度集中在 120 到 160 字。训完模型确实礼貌,但回答长度分布明显变窄,遇到复杂问题就开始说套话。
  • 混入真实对话:补了 800 条线上真实样本,含口语、错别字、半截话和追问,长度从 80 字拉到 700 字。同一评估集上人工盲评从 4.1 分到 4.6 分(5 分制,两人交叉评)。
  • 去重必须做:相似度 0.95 以上去掉 300 条,eval 提升不明显,但训练时间少 20 分钟。更重要的是评估时的重复命中消失了,否则指标会虚高。
  • 清洗规则写进脚本:长度下限、相似度阈值、字段完整性、敏感词,全部固定成脚本参数,跑一次存一次。靠人眼过一遍的清洗,下次复现不出来,我在这上面栽过。
  • 验证集不能从训练集里随机抽:我第一次从 4200 条里随机抽 300 条当验证集,eval loss 一路降到 0.6,上线表现一塌糊涂。同一批样本训练时见过,测出来的是记忆不是泛化。改按业务场景切分之后,eval loss 回到 1.0 附近,才对得上线上真实水平。
  • 别留「一问一答的孤岛」:不少样本只有单轮问答,模型学不会追问和多轮衔接。我按会话 ID 把 240 条孤岛样本配对成 120 组多轮对话,训完后连续追问场景的可用率明显改善,这也是人工盲评里提升最直接的一项。

上线前的三件事:合并、精度、回归

训练完到真能用,还有一段容易翻车的地方。

  • adapter 还是全量合并:保留 adapter 动态加载,回滚快,但每次推理多约 60ms;合并进权重后延迟基本和基座一致,版本管理却更麻烦。我选合并上线加 adapter 备份,线上出问题直接切回。
  • bf16 训练、fp16 推理的漂移:同一批 200 条回归样本,两种精度下答案不一致率约 3%,多数是措辞差异,但有两条把结论说反了。要么推理也走 bf16,要么把不一致样本补回训练集。
  • 评估集必须钉死:固定 200 条样本、固定评分 prompt、固定评审人。我第二次上线前换了评估 prompt,得出「相对提升 12%」,一周后发现是评分标准变松,实际提升不到 3%。
  • 成本口径:单次训练 2 小时 40 分,按每小时 6 元算约 16 元,一天跑五轮对照实验也就 80 元。真正贵的是标注与评估,4200 条清洗改写的人工成本远高于算力。
  • 停止符要对齐:微调后模型爱在答案末尾续写「如果还有问题请随时联系」,根因是训练样本里带了客服话术。除了清洗数据,推理时也要把停止符配全,否则单次输出凭空多出 80 个 token,延迟和成本一起涨。

小结

七次里能上线的两次,差别不在 r 和 lr,而在于我先钉死了评估集、先把数据洗到位,再开始调参。

顺序建议:定评估集、洗数据、调超参、上线回归。反过来做,大部分时间都会花在「为什么这次指标又变了」。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。