跳转至

显存计算

显存预算至少包含四部分:模型权重、KV Cache、运行时工作区和训练状态。只用“参数量乘位宽”会低估真实需求。

推理权重

基础公式:

权重显存 GB ~= 参数量(十亿) x 每参数字节
精度 每参数字节 7B 14B 32B 70B
FP32 4 28GB 56GB 128GB 280GB
FP16/BF16 2 14GB 28GB 64GB 140GB
INT8/FP8 1 7GB 14GB 32GB 70GB
INT4 理论值 0.5 3.5GB 7GB 16GB 35GB

实际量化模型还含 scales、zero points、未量化层和框架开销。保守地给权重理论值增加 10% 到 25%,再加 KV Cache 和运行时余量。

KV Cache

KV Cache 随层数、KV heads、head dimension、序列长度、并发数和缓存精度增长。GQA/MQA 模型比传统多头注意力节省很多。

通用估算:

KV bytes ~= 2 x layers x kv_heads x head_dim x tokens x concurrent_sequences x dtype_bytes

其中 2 代表 Key 和 Value。上下文从 8K 增到 128K,在其他条件不变时,KV Cache 大约增长 16 倍。模型“支持 128K”不代表你的显卡和并发配置能经济地跑 128K。

推理安全余量

建议按以下流程:

  1. 计算权重实际大小。
  2. 用目标上下文和最大并发计算 KV Cache。
  3. 为 CUDA graph、临时张量、量化内核和碎片预留 10% 到 20%。
  4. 在服务器上保留可观测余量,不长期卡在 99% 显存。

例 1:32B 4-bit 单卡推理

理论权重:32 x 0.5 = 16GB
量化元数据与未量化层:约 2 到 4GB
KV Cache、运行时与余量:取决于上下文和并发,常需 6GB 以上
结论:24GB 可能在短上下文低并发下运行,32GB 更有调参空间

例 2:70B 4-bit

理论权重:70 x 0.5 = 35GB
加格式开销后通常超过 38GB
再加 KV Cache 和运行时:48GB 属于紧凑起点,80GB/96GB 更稳妥

这些是容量估算,不是对任意模型和框架的保证。MoE 模型还要区分总参数与每 token 激活参数。显存通常需要容纳全部驻留权重,不能只按激活参数算。

训练显存

全参数 AdamW 训练常需要权重、梯度、优化器状态和主权重,未计激活时就可能接近每参数 16 字节;激活、长序列和批量会继续增加。ZeRO/FSDP 可以在多卡间切分,但不会让总资源消失。

LoRA 冻结基础权重,只训练低秩适配器。QLoRA 再把基础权重量化到 4-bit,显著降低门槛。它仍需要:

  • 量化基础权重。
  • LoRA 参数、梯度和优化器状态。
  • 前向与反向激活。
  • 数据批次、序列与框架工作区。

因此不能把 7B 的 QLoRA 简化为 3.5GB。经验起点是在目标配置上从 batch_size=1、较短序列和梯度累积开始,记录峰值后再扩大。

降低显存的顺序

  1. 缩短真实上下文,移除重复模板和无效检索文本。
  2. 降低并发或批量,使用队列保持稳定。
  3. 采用 GQA/MQA 模型或降低 KV Cache 精度。
  4. 使用经过任务评测的 8-bit/4-bit 量化。
  5. 训练时用梯度检查点、LoRA/QLoRA、FSDP/ZeRO。
  6. 必要时做 CPU offload,但接受明显的时延代价。
  7. 最后再增加 GPU 或换更大显存。

验证命令

nvidia-smi --query-gpu=name,memory.total,memory.used,utilization.gpu,power.draw --format=csv -l 1

不要只观察模型加载后的显存。至少覆盖最长输入、最大输出、目标并发和一次峰值流量。

量化选型可参考 Hugging Face 官方指南。该指南强调 8-bit 通常约节省 2 倍权重内存,4-bit 约节省 4 倍,但必须在实际任务和硬件上同时验证准确率与速度。

KV Cache 完整算例

假设模型有 64 层、8 个 KV heads、每个 head 维度 128,KV 使用 BF16。单 token、单序列的缓存是:

2 x 64 x 8 x 128 x 2 bytes = 262,144 bytes = 256 KiB

于是容量近似为:

上下文 并发序列 KV Cache
4,096 1 1 GiB
8,192 1 2 GiB
8,192 8 16 GiB
32,768 8 64 GiB

这说明同一个 4-bit 模型,单人聊天可以装进 48GB 卡,并不代表 8 路长上下文服务也能装下。真实引擎可能分页分配并复用空闲块,但容量规划仍应按峰值活跃 token 估算。

从业务流量反推显存

先把“100 个用户”换成同时驻留在 GPU 上的序列数:

活跃并发 ~= 每秒到达请求数 x 平均服务时间(秒)
目标并发 = 活跃并发 x 峰值系数

例如平均 2 请求/秒、一次生成平均占用 6 秒,基础活跃并发约为 12。取 1.5 倍峰值系数后按 18 路估算。随后分别计算典型输入、P95 输入和硬性最大输入,而不是所有请求都按标称上下文长度计算。

权重
模型文件加载后的真实 GPU 占用,不只看参数量理论值。
KV Cache
按目标活跃 token 与并发估算,区分 prefill 与 decode 队列。
工作区
CUDA graph、通信 buffer、临时张量和量化 kernel 开销。
安全余量
建议稳定峰值不超过可用显存的 85% 到 90%,再用压力测试确认。

容量试验表

固定模型、引擎、量化、输入和输出分布,逐级提高并发。每轮至少记录:

轮次 输入 P50/P95 输出 P50/P95 并发 TTFT P95 TPOT P95 tokens/s 峰值显存 OOM/错误
基线 512/2K 128/512 1
目标 512/2K 128/512 8
峰值 512/2K 128/512 16
极限 2K/8K 512/2K 16

极限轮用于发现保护阈值,不是生产目标。达到 OOM 前通常已经出现排队、TPOT 抖动或超时,应以业务 SLO 决定上限。

估算误差清单

  • 把十进制 GB 与二进制 GiB 混用,导致约 7% 的误差。
  • 用模型总上下文代替流量中的实际 token 分布。
  • MoE 只按激活参数算权重,忽略全部专家的驻留需求。
  • 多卡只除以卡数,忽略每卡重复层、通信 buffer 和不均匀切分。
  • 忘记视觉编码器、Embedding 模型、重排模型或同机其他进程。
  • 只测冷启动后的单请求,没有覆盖连续批处理的峰值。

本章实践

选一个 32B 或 70B 模型,先在表格中预测四项占用,再部署并测量。最终提交“估算值、实测值、误差比例、误差原因、下一版安全系数”五列;只有这样,经验才会转化为下次可复用的容量模型。