LoRA 微调显存测算与踩坑实录
经验驱动。微调前先算账——很多人显存爆了都不知道钱花在哪。下面是我本机按真实公式算出来的 7B 显存账,以及 27B 本机实战的踩坑。数字都是算出来的,不是拍脑袋。
先算账:7B 模型到底吃多少显存
以 bf16 精度、7B 参数为基准,显存主要由四块构成:基座权重 + 优化器状态 + 梯度 + 激活值。前三项只和参数量有关,先算清楚:
| 部分 | 计算 | 显存 |
|---|---|---|
| 基座权重(bf16) | 7e9 × 2 | 14.00 GB |
| 全量微调·优化器(AdamW) | 7e9 × 12 | 84.00 GB |
| 全量微调·梯度 | 7e9 × 2 | 14.00 GB |
| 全量微调合计 | 112.00 GB |
关键认知:全量微调的显存大头不是权重,是 AdamW 的优化器状态(fp32 主副本 + 一阶矩 m + 二阶矩 v,共 12 字节/参数)。所以 7B 全量微调要 112GB,单卡 80GB(A100)都吃紧。
LoRA 把账砍到哪了
LoRA 的核心思想:不训全量权重,只在权重旁挂一对低秩矩阵 A(r×d)、B(d×r),只训 A、B。以 r=8、目标模块 224 个(LLaMA 类每层 q/k/v/o/gate/up/down × 32 层)为例:
- 可训练参数 = 2 × r × hidden(4096) × 224 ≈ 14.7M,仅占 7B 的 **0.21%**;
- 优化器和梯度也只给这 14.7M 参数,基座冻结;
- LoRA 总显存(bf16 基座)= 14(基座)+ 0.18(LoRA 优化器+梯度)≈ 14.21 GB。
QLoRA:再把基座压到 4bit
如果连 14GB 都没有(比如我本机只有 12G 显存),用 QLoRA 把基座量化为 4bit:
- 基座 4bit = 7e9 × 0.5 = 3.5 GB;
- QLoRA 总显存 ≈ 3.5 + 0.18 ≈ 3.71 GB。
实测算出来的对比:
1 | 基座权重(bf16) : 14.00 GB |
27B 本机实战踩坑
我本机是 12G 显存,跑 27B 模型的相关实验时踩过这些:
- 12G 只能 QLoRA(r≤8)+ gradient_checkpointing。27B 基座 bf16 就要 54GB,全量微调更是不敢想——按上面的公式,27B 全量微调轻松破 430GB,得 8 张 A100 量级。
- 量化省的是基座,LoRA 参数仍是 bf16。QLoRA 的省显存上限就是基座那部分,别指望靠调 r 把 4bit 模型再省一截。
- 激活值显存随 batch × 序列长度涨。长文本(几 K context)比短文本吃好几倍显存,控制
max_seq_length和per_device_train_batch_size是直接有效的手段。 - gradient_checkpointing 用时间换显存。约多 30% 训练时间,但能省下一大块激活显存,12G 卡基本必开。
- PagedAdamW(bitsandbytes)能缓解峰值。它把优化器状态分块驻留,避免瞬时 OOM,QLoRA 默认走这个。
面试常考点
- LoRA 原理:对权重 ΔW 做低秩分解 ΔW = BA,B∈ℝ^{d×r}, A∈ℝ^{r×k},r≪d,训练参数量从 d×k 降到 r×(d+k)。
- 为什么 QLoRA 能在消费级卡跑大模型:基座 4bit 量化 + 只训 LoRA + 分页优化器,三者叠加。
- rank 怎么选:r 太小欠拟合、太大失去低秩意义且显存涨;常见 8/16/32/64,配合 α(通常 2r)。
- 显存构成:权重 + 优化器 + 梯度 + 激活,优化器(AdamW)是很多人忽略的大头。
小结
微调不是 lora=True 点一下就行。先把显存账算明白:全量微调的 112GB 里优化器占 84GB,LoRA 靠只训 0.21% 的参数把账砍到 14GB,QLoRA 再压到 3.7GB。本机 12G 只能走 QLoRA + 梯度检查点的组合拳,这些数字是真算出来的,面试时能直接摆。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 河岳日星的博客!

