首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LoRA 实战复盘:7B 模型单卡微调的显存账、超参坑与适配器部署

LoRA 实战复盘:7B 模型单卡微调的显存账、超参坑与适配器部署

原创
作者头像
Archive
发布于 2026-10-08 12:08:40
发布于 2026-10-08 12:08:40
590
举报
文章被收录于专栏:随笔随笔

前阵子把手上一个 7B 底座拉出来做客服语气的适配,顺手把 LoRA 这条链路从头到尾跑了一遍。这篇不铺概念,按我实际踩坑的顺序讲:先算显存,再调超参,最后落到部署。

一、先算清楚:为什么全参跑不动、LoRA 能跑

全参微调不是我这种单卡能碰的。原因不在权重本身:fp16 的 7B 权重才 14GB 左右,真正吃显存的是它连带的东西——对应的梯度,加上 Adam 为每个参数保存的两份 fp32 状态。几项叠起来,总量就顶到 80GB 量级,一张 A100 80G 都很紧张,更别说消费卡。

LoRA 的思路是冻结原始权重 W₀,只在旁边挂两个低秩矩阵 A(r×k)和 B(d×r),训练时只更新 A、B。前向变成:

代码语言:shell
复制
h = W₀x + (α / r) · B A x

可训练参数从 d·k 掉到 r·(d+k),7B 上占比通常不到 1%。

这里有个初始化细节值得单独拎出来:B 是零初始化的。所以训练刚开始时 ΔW = 0,模型行为跟原来一模一样,是被训练一点点带偏的,不是接上去就崩。我理解这是 LoRA 相对"随便加一层再微调"最大的稳定性来源。

二、配超参:r 和 alpha 必须一起调

我一开始的配置用的是 peft:

代码语言:python
复制
from peft import LoraConfig, get_peft_model

cfg = LoraConfig(
    r=16,
    lora_alpha=32,              # 惯例:alpha = 2 * r
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
)

model = get_peft_model(base_model, cfg)
model.print_trainable_parameters()
# 示意输出(实际数值随底座规模变化):
# trainable params: ~16.8M || all params: 6.7B || trainable%: ~0.25%

target_modules 是第一个坑:不同底座的层命名不一样,q_proj 是 LLaMA 系的名字,换架构前先 print(dir(model)) 或遍历模块名确认一遍,填错会直接报找不到对应模块。

第二个坑在 r 和 alpha 的耦合:

  • 公式里真正起作用的是 α/r,不是 alpha 本身。
  • 我一开始把 r 从 8 拉到 32,alpha 没动,结果 loss 明显"温吞",等于反过来把补丁的音量调小了。把 alpha 一起设成 2r 之后才恢复正常。
  • 2023 年 rsLoRA 那篇建议用 α/√r 做秩稳定缩放,大 r 下更稳,值得一试。
  • 我在小样本上还试过 r=64,验证集直接掉——这是典型的把训练集背下来了。r 大不等于好。

r 的经验值我记的是这样:只改格式 / 语气,8 够;一般领域适应 16 起步;样本多、多任务再上 32 / 64。

显存我这边记的量级(框架和序列长度影响很大,仅供参考):

  • 全参微调:80GB+
  • LoRA r=8:约 16GB
  • LoRA r=16:约 18GB
  • LoRA r=64:约 24GB
  • QLoRA 4bit:约 8GB

三、部署:合并权重,还是挂适配器

两种都能用,看场景:

  • 合并:B·A 和 W₀ 形状一致,可以直接加回去生成一张新权重。合并后模型结构和原来完全一样,推理零额外开销、不降速。只有一个固定任务时,这样最干净。
  • 不合并(我更常用):适配器是独立的一个几十 MB 小文件,底座只加载一份,切换任务时换适配器就行。我用一个底座挂了客服口吻、合同抽取、周报格式三个适配器,合计多占不到 100MB,比养三个完整模型省太多。

引擎侧我用 vLLM 起服务,它支持多 LoRA 动态加载和卸载,切换在几十毫秒级,显存里同时塞十几个小适配器没压力。

对比每层插一个小模块(Adapter 类方案),LoRA 的杀手锏就是"可合并"——后者推理时模块一直在算,纯白增延迟。

四、最容易翻车的地方:LoRA 一样会过拟合、会遗忘

这块我要重点说,因为"LoRA 参数少所以不会过拟合"是我见过最多的错误说法,它不成立。参数少只是把过拟合的门槛抬高了一点,小数据上照样过拟合,还会灾难性遗忘——我拿几百条数据反复训,模型原本会的通用问答掉了一截,后来往训练集里掺了通用对话样本才缓过来。

验收必须两头看:

  • 新任务:格式、语气、拒答是不是符合预期;
  • 旧能力:通用问答、指令遵循有没有退化。

只测前者,上线才发现问题就晚了。另外还有两点最容易被漏:验证集一定要和训练集分开;训练用什么拼接格式,推理就得用同一个格式。

五、什么需求不该用 LoRA

关键先判断:模型是"不知道",还是"不会说"。

  • 不知道 → 是知识。制度、报价、库存这些会变、还要求能贴出处,训进权重等于焊死一个会过期的答案,改一次重训一次。这类应该交给 RAG 或提示词。
  • 不会说 → 才是微调的主场。固定格式、拟人语气、不确定时规范地说"不知道",这些提示词写不稳,训一版更省事。

最省力的顺序永远是:先把提示词写扎实,管不住了再上 LoRA。至于用云上 API 的场景,权重不在你手里,这条路直接排除。

小结

LoRA 省下的是训练成本(一张卡、几十分钟),但没省钱的地方是数据——那几百条干净样本的标注和审核,才是真正的瓶颈。如果这套数据你天天都在产生,微调很划算;一年才做几次、每次口径都不一样,那基本训不出来。

改口吻,别改知识;先提示词,顶不住再训。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、先算清楚:为什么全参跑不动、LoRA 能跑
  • 二、配超参:r 和 alpha 必须一起调
  • 三、部署:合并权重,还是挂适配器
  • 四、最容易翻车的地方:LoRA 一样会过拟合、会遗忘
  • 五、什么需求不该用 LoRA
  • 小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档