从 Bit 到 AGI第九章:GPU

为什么显存这么重要

7B 与 70B 模型在不同精度下占多少 GB,以及 KV Cache 如何吃掉剩余显存

作者 David更新于 第 139 篇(共 186 篇)

「这张卡 24 GB 显存,能跑 7B 吗?」——这是入门 LLM 最常问的问题。显存(VRAM,即 GPU 上的 HBM)同时存放 模型权重、优化器状态(训练)、激活(训练)和 KV Cache(推理)。容量不够,要么量化压缩,要么多卡切分,要么直接 OOM。本章用 7B / 70B 两张表把数字算清楚。

OOM(Out Of Memory)报错是 LLM 实践中最常见的硬件错误之一。PyTorch 的报错栈往往指向最后一层 linear,但真正原因是 前面已分配的权重 + KV 之和超过 HBM。学会 先算表再跑模型,比反复 empty_cache() 有效得多。

直觉

显存像 GPU 工位上的 桌面:桌面越大,能同时摊开的文件(权重)和草稿纸(中间结果、KV Cache)越多。桌面满了,你不能把书放在走廊(CPU 内存)上慢慢翻——PCIe 太慢,推理会卡到不可用。70B 模型的 FP16 权重 alone 就要 140 GB,已经超过单张 80 GB H100——所以 大模型必然涉及多卡或量化。

定义

参数量 → 权重大小(仅权重,不含 KV Cache):

权重 (bytes)=P×bytes_per_param\text{权重 (bytes)} = P \times \text{bytes\_per\_param}
精度bytes/param说明
FP324全精度
FP16 / BF162训练/推理常用
INT81权重量化
INT40.5GPTQ/AWQ 等

训练额外占用(同一 GPU 上,粗算):

  • 优化器(Adam):FP32 动量 + 方差 ≈ 8× 参数量 bytes(仅 optimizer states,不含 master weights 变体)。
  • 梯度:常与参数同精度,约 2× bytes(FP16 训练)。
  • 激活:与 batch、sequence length、层数相关,可用 gradient checkpointing 换时间。

推理额外占用:

  • KV Cache:每层、每个 token 存 Key 和 Value。
KV (bytes)≈2×L×Hkv×D×T×bytes\text{KV (bytes)} \approx 2 \times L \times H_{\text{kv}} \times D \times T \times \text{bytes}

其中 LL = 层数,HkvH_{\text{kv}} = KV 头数,DD = head dim,TT = 序列长度,系数 2 为 K 与 V。

例子:7B 与 70B 权重大小表

假设 纯权重,Llama 类 7B / 70B 参数量取整。

表 1 — 7B 模型权重大小

精度计算权重大小
FP327×109×47 \times 10^9 \times 4 B28 GB
FP16 / BF167×109×27 \times 10^9 \times 2 B14 GB
INT87×109×17 \times 10^9 \times 1 B7 GB
INT47×109×0.57 \times 10^9 \times 0.5 B3.5 GB

表 2 — 70B 模型权重大小

精度计算权重大小
FP3270×109×470 \times 10^9 \times 4 B280 GB
FP16 / BF1670×109×270 \times 10^9 \times 2 B140 GB
INT870×109×170 \times 10^9 \times 1 B70 GB
INT470×109×0.570 \times 10^9 \times 0.5 B35 GB

表 3 — 能否放进常见单卡显存?(仅权重)

GPU 显存7B FP16 (14 GB)7B INT4 (3.5 GB)70B FP16 (140 GB)70B INT4 (35 GB)
12 GB (3060)❌ 紧/需量化✅ 有余量❌❌
24 GB (4090/3090)✅✅❌✅ 权重可装,KV 另算
48 GB (L40S 等)✅✅❌✅
80 GB (A100/H100)✅✅❌ 需 2 卡+✅ 权重可装

70B FP16 需要至少 2× 80 GB 卡 做张量并行(或 140 GB 单卡不存在于消费级),且几乎无 KV Cache 余量。

表 4 — KV Cache 示例(Llama-2 7B 结构:L=32L=32, Hkv=32H_{\text{kv}}=32, D=128D=128, FP16)

单条序列,T=4096T = 4096 tokens:

2×32×32×128×4096×2≈2.1 GB2 \times 32 \times 32 \times 128 \times 4096 \times 2 \approx 2.1 \text{ GB}

T=8192T = 8192 → 约 4.2 GB。batch=8 并发 → ×8。推理 serving 显存常 权重 + KV 占满,故 PagedAttention 做碎片整理。

量化

  • 训练 7B FP16 + Adam(单卡粗算):权重 14 GB + optimizer ~56 GB + 梯度 14 GB + 激活(视 batch)→ 远超 24 GB,故 7B 全参微调通常要 多卡或 LoRA(见第七章)。
  • 推理 7B FP16 on 24 GB:14 GB 权重 + 2–4 GB KV + 1–2 GB 运行时 ≈ 17–20 GB → 4090 可跑,但 context 长或 batch 大仍 OOM。
  • 推理 70B INT4 on 48 GB:35 GB 权重 + KV → 紧张;80 GB 卡更从容。

表 5 — 训练时 Adam 优化器状态(单参数粗算)

组件bytes/param(Adam FP32 states)
权重 FP162
Master weight FP32(可选)4
一阶矩 m4
二阶矩 v4
合计(常见混合精度)~10–12+

7B 全参 Adam 训练:远超单卡 80 GB,必须 ZeRO 分片、FSDP、或 LoRA——显存规划不能只看权重的 14 GB。

表 6 — 不同 context 下 7B KV Cache(FP16,batch=1)

Sequence TTKV Cache(约)
2048~1.0 GB
4096~2.1 GB
8192~4.2 GB
32768~17 GB

长 context 服务时,KV 可 超过权重——PagedAttention 与 Prefix Caching 直接针对显存碎片与复用。

量化部署决策树

  1. 参数量 PP → 查表得 FP16 / INT4 权重大小
  2. 加 KV:TT、batch、层数 → 用上节公式
  3. 加 runtime overhead ~10–20%
  4. 若 sum > 单卡 HBM → 量化 / 多卡 / 减 TT / 减 batch

例:70B INT4 35 GB + 8k context KV(单请求数 GB 级)+ overhead → 48 GB 卡紧张,80 GB 推荐。

常见误区

误区:「7B 模型 = 7 GB 显存」 — 7B 是 参数个数,不是 GB;FP16 约 14 GB 仅权重。

误区:「量化到 INT4 无损」 — 显存减半有余,但精度下降;任务敏感场景需评测 perplexity / 下游指标。

误区:「显存空着就浪费」 — 预留 KV 与 CUDA workspace;nvidia-smi 显示 100% 使用可能是 cache,也可能是 OOM 前兆。

动手试一试

# 估算权重大小(不含 KV)
def weight_gb(params_b: float, bytes_per_param: float) -> float:
    return params_b * 1e9 * bytes_per_param / 1e9

for name, p in [("7B", 7), ("70B", 70)]:
    print(f"{name} FP16: {weight_gb(p, 2):.1f} GB")
    print(f"{name} INT4: {weight_gb(p, 0.5):.1f} GB")
# 估算 KV Cache(FP16)
def kv_cache_gb(layers, kv_heads, head_dim, seq_len, batch=1, bytes_per=2):
    return 2 * layers * kv_heads * head_dim * seq_len * batch * bytes_per / 1e9

print("7B @ 4096 ctx:", kv_cache_gb(32, 32, 128, 4096), "GB")
print("7B @ 8192 ctx:", kv_cache_gb(32, 32, 128, 8192), "GB")

加载模型时用 nvidia-smi 观察显存台阶:from_pretrained 后跳变 ≈ 权重大小。

MoE 与显存:专家并行的额外维度

Mixture of Experts(MoE) 模型总参数量大,但 每 token 只激活部分专家。显存需存放 全部专家权重(或 offload 未用专家),激活计算量小于 dense 同参数量——「参数量」与「激活参数量」要分开看。例如 Mixtral 8×7B 总参数 ~47B,激活约 13B/ token,但 INT4 权重仍接近 ~24 GB 级,加 KV 后 24 GB 消费卡依然紧张。

部署 MoE 前:查 总权重(决定 HBM)、查 激活宽度(决定算力),两者都不等于 marketing 里的「7B」单数字。

回顾与自测

Q:24 GB 卡跑 7B FP16,还能开 8k context 吗?
A:权重 14 GB + KV ~4 GB + overhead → 紧张但可能;更长 context 或更大 batch 需量化或换 48 GB 卡。

Q:QLoRA 训练为何省显存?
A:基座 4-bit 量化 + 仅训练 LoRA 适配器 + 优化器只跟 adapter 参数——详见 LoRA 篇。

Q:torch.cuda.max_memory_allocated() 代表什么?
A:PyTorch 分配器峰值;nvidia-smi 还含 CUDA context 与碎片,二者可能差几 GB。

Q:两张 24 GB 卡能跑 70B INT4 吗?
A:权重 35 GB 可切到两卡,但需张量并行框架支持且无 NVLink 时延迟高;80 GB 单卡更省心。

工程师备忘录

  • 7B FP16 权重 14 GB;70B FP16 140 GB;INT4 约 ÷4。
  • 训练 Adam:optimizer states 常 >> 权重 → 多卡 / LoRA / ZeRO。
  • KV Cache 随 层数 × 头数 × head_dim × seq × batch 线性涨。
  • OOM 前先 算表:权重 + KV + 20% 余量。

显存规划是 上线前 checklist 第一项:比选模型、调 prompt 都应更早完成。团队内建议维护一张「模型 × 精度 × 卡型 × 最大 context」对照表,避免每次部署临时试错 OOM。

量化(INT4/INT8)是 用精度换容量与带宽 的杠杆;多卡并行是 用互联换容量 的杠杆。二者组合使用时有精度与延迟 trade-off,没有免费午餐——但表 1–6 至少能告诉你 lunch 标价在哪。

小结

显存决定 能跑多大的模型、多长 context、多大 batch。7B FP16 权重 14 GB,70B FP16 140 GB;INT4 约减半再减半。训练还要 optimizer 与梯度;推理还要 KV Cache。买卡或租集群前,先用表格算一遍 权重 + KV + 余量,比背「几 B 用几 G 卡」更可靠。

下一篇:本章总结

本页目录