外观
显存层次与带宽墙
概念定义:为什么 LLM 推理这么"吃"显存
GPU 的算力(TFLOPS)这些年涨了几个数量级,但显存带宽的涨幅慢得多。结果就是——LLM 推理在 decode 阶段几乎跑不满算力,瓶颈全在显存带宽上。这就是所谓的带宽墙(bandwidth wall)。
理解带宽墙的两个关键认知:
- GPU 的显存是分层的——HBM(大但慢)→ L2 cache(小但快)→ shared memory/SRAM(最小最快),越往上越快越贵;
- LLM decode 是天然 memory-bound——每生成 1 个 token 都要把整个模型权重从 HBM 读一遍(权重太大塞不进 SRAM),算力大量闲置。
这是为什么权重量化(把权重从 FP16 压到 INT4)能让 decode 吞吐翻几倍——带宽墙的问题,靠减少要读的字节数解决。也是为什么vLLM PagedAttention要花大力气优化 KV cache 显存——KV cache 占的显存越多,能容纳的并发请求就越少。
一、显存层次结构
GPU 的存储是金字塔结构,越往上越快但容量越小、越贵:
text
┌─────────────────────────────┐
│ Registers / SRAM │ ← 最快(~20 TB/s),容量 ~256KB/SM
├─────────────────────────────┤
│ L2 Cache │ → 快(~5-12 TB/s),容量 ~40-100MB
├─────────────────────────────┤
│ HBM (High Bandwidth Memory)│ → 慢(~2-5 TB/s),容量 40-141GB
├─────────────────────────────┤
│ PCIe / Host Memory │ → 最慢(~30-60 GB/s),容量无限
└─────────────────────────────┘| 层 | 作用 | 容量(H100 量级) | 带宽 | 访问延迟 |
|---|---|---|---|---|
| Register / SRAM | 单线程私有、warp 共享 | 256KB / SM | ~20 TB/s(片内) | 几个 cycle |
| Shared Memory | block 内共享 | 228KB / SM(可配) | ~10 TB/s | ~10-20 cycle |
| L2 Cache | 全 SM 共享 | 50 MB | ~5-7 TB/s | ~50-100 cycle |
| HBM | 主显存 | 80 GB | ~3.35 TB/s | ~200-400 cycle |
| Host Memory(CPU DDR) | 通过 PCIe 传输 | 任意 | ~60 GB/s(PCIe4) | ~1000+ cycle |
为什么层次这么重要
CPU/GPU 计算速度远快于显存供给速度——把数据从 HBM 喂到 SM 的速度,决定了算力能不能跑满。所有 GPU 优化本质都是在和数据搬运做斗争:把热数据尽量留在 SRAM(算子融合)、用 coalesced access 减少 HBM 读次数、用 shared memory tiling 减少重复加载。详见GPU 体系结构与优化。
二、各代 GPU 的显存与带宽参数
LLM 推理选 GPU,最关心的两个参数是 HBM 带宽(决定 decode 速度)和 HBM 容量(决定能放多大的模型和多少 KV cache):
| GPU | 显存类型 | 容量 | 带宽 | BF16 算力 | 备注 |
|---|---|---|---|---|---|
| A100 80GB | HBM2e | 80 GB | ~2.0 TB/s | 312 TF | 上一代旗舰,仍主流 |
| A100 40GB | HBM2e | 40 GB | ~1.55 TB/s | 312 TF | 同型号小显存版 |
| H100 SXM5 | HBM3 | 80 GB | ~3.35 TB/s | 989 TF | 当代主力 |
| H100 PCIe | HBM3 | 80 GB | ~2 TB/s | 989 TF | 带宽被砍的 PCIe 版 |
| H200 SXM | HBM3e | 141 GB | ~4.8 TB/s | 989 TF | 大显存 + 高带宽 |
| H20 | HBM3 | 96 GB | ~4 TB/s | 148 TF(FP16) | 算力受限的合规版 |
| L40S | GDDR6 | 48 GB | ~0.866 TB/s | 362 TF | 推理特化,性价比 |
| B200 SXM | HBM3e | 192 GB | ~8 TB/s | 2.25 PF (FP4) | Blackwell 旗舰 |
| B100 | HBM3e | 192 GB | ~8 TB/s | 1.8 PF | Blackwell 中档 |
选卡的简单决策
- 预算充足 + 极致延迟 → H200(带宽 4.8TB/s + 141GB 显存,LLM 推理甜点)
- 大并发在线服务 → H100 SXM5(带宽够、生态成熟)
- 离线批处理 → A100 80GB(性价比仍不错)
- 显存不够就量化 → W4A16 量化能让 70B 模型塞进单张 H100 80GB
更多选型细节见硬件入门与benchmark 数据。
三、带宽墙:decode 阶段的核心瓶颈
算一笔账
以 Llama-2-70B 为例(参数量 70B,FP16 权重 ≈ 140GB):
- decode 时每生成 1 个 token,要把所有权重从 HBM 读到 SM 至少一次;
- 权重总量 140GB,H100 带宽 3.35TB/s → 理论最快 ~42ms/token;
- 折算吞吐 ≈ 24 tokens/s(单请求、单 GPU 上限)。
而 H100 的 BF16 算力是 989 TFLOPS,70B 模型每个 token 大约要 140 GFLOPS——算力只需 0.14ms 就能跑完一个 token。算力和带宽差了 300 倍,这就是带宽墙的本质:
text
算力理论延迟: 0.14 ms/token (989 TFLOPS ÷ 140 GFLOPS)
带宽理论延迟: 42 ms/token (140GB ÷ 3.35 TB/s)
实际延迟: 45-50 ms/token (带宽墙主导,算力闲置 99%)别被"99% 算力闲置"骗了
这是 LLM 推理的结构性事实,不是优化没做好——单请求 decode 阶段算力就是用不满。唯一对策是堆 batch:32 个并发请求一起 decode,算力被分摊 32 倍,每 token 还是只要读一次权重(多请求共享权重),吞吐瞬间翻 30 倍。这就是 continuous batching 的原理。
decode 的算术强度
用 Roofline 模型分析更精确——一个算子的算术强度(Arithmetic Intensity, AI)= FLOPS / Bytes。decode 阶段每个 token:
- FLOPS:每个权重做 2 次运算(乘加)≈ 140 GFLOPS;
- Bytes:从 HBM 读 140GB 权重 ≈ 280 GB(FP16,每参数 2 字节);
- AI = 140 / 280 ≈ 0.5 FLOPS/Byte。
而 H100 的拐点(ridge point)≈ 算力 / 带宽 = 989 TFLOPS / 3.35 TB/s ≈ 295 FLOPS/Byte。decode 的 AI 远低于拐点 → 强烈 memory-bound。对比之下,matmul 大 batch 的 AI 可达数百,是 compute-bound。
四、KV cache:显存的另一个大头
除了权重,LLM 推理还要为每个活跃请求保留一份 KV cache——每生成一个 token 都要查询历史 token 的 K、V 向量。KV cache 的显存占用公式:
text
KV_cache_bytes = 2 × seq_len × batch × num_layers × num_heads × head_dim × dtype_bytes
↑ ↑ ↑ ↑ ↑ ↑ ↑
K和V 已生成长度 并发数 transformer层数 注意力头数 每头维度 FP16=2,INT8=1以 Llama-2-70B(80 层、64 头、每头 128 维)为例,FP16 下每个请求:
text
2 × 2048 × 1 × 80 × 64 × 128 × 2 = 5.4 GB / 请求一个 2048 长度的请求要占 5.4GB 显存!10 个并发就是 54GB——和权重 140GB 一比,显存被 KV cache 吃掉相当大一块,这直接限制了并发数。
几种压缩 KV cache 的办法
五、内存密集 vs 计算密集:判定方法
判定一个算子或阶段是 memory-bound 还是 compute-bound,用 Roofline 的算术强度 AI:
| 算子 | AI(FLOPS/Byte) | 类型 | 说明 |
|---|---|---|---|
| Elementwise(add, relu, scale) | ~1 | memory-bound | 每读 1 byte 算 1 次 |
| LayerNorm | ~2-5 | memory-bound | 减少算子+读写多次 |
| Activation(GELU, Softmax) | ~1-5 | memory-bound | 同上 |
| Vector-Vector op(小向量加) | ~1 | memory-bound | 完全读多算少 |
| matmul(小 batch decode) | ~1-10 | memory-bound | decode 阶段典型 |
| matmul(大 batch prefill) | 数百 | compute-bound | prefill 阶段 |
| Tensor Core matmul(M=N=K=8192) | 几千 | compute-bound | 几乎跑满算力 |
简单的判定口诀
算得太少的(elementwise、小 batch matmul)→ memory-bound;算得满满的(大 GEMM)→ compute-bound。 优化方向:
六、突破带宽墙的工程手段
带宽墙不是不可破——只是要用对工具:
| 手段 | 原理 | 收益 | 详见 |
|---|---|---|---|
| 权重量化(W4A16) | 权重 4 bit,要读的字节减 4 倍 | decode 吞吐 ~3-4 倍 | 权重量化与混合精度 |
| KV cache 量化 | KV 用 FP8/INT8 | 显存翻倍,并发翻倍 | 量化基础 |
| 算子融合 | 多个 elementwise 合一个 kernel,少读几遍 | 减少 HBM 读写 | 算子融合 |
| FlashAttention | 把 attention 中间结果留 SRAM 不写回 HBM | 长 context 显存/速度双赢 | 算子融合 |
| PagedAttention | 分页管理 KV,消除碎片 | 实际可用并发 +30-60% | vLLM 案例研究 |
| Continuous batching | decode 阶段塞满 batch 把带宽榨干 | 单 GPU 吞吐 ~30 倍 | 批处理与调度 |
| Speculative decoding | 小模型先生成候选,大模型批量验证 | 减少 decode 步数 | 投机采样案例 |
工程顺序建议:先 量化(最省事)→ 再算子融合/FlashAttention(推理引擎已内置)→ 最后 continuous batching(上 vLLM)。
七、权衡与取舍
- 带宽 vs 算力:选 GPU 要看你的瓶颈。LLM 推理选高带宽卡(H100/H200);训练选高算力卡(B200);边缘部署选性价比(L40S);
- 显存容量 vs 带宽:H200 141GB > H100 80GB,但带宽只多 1.4 倍——大模型首选 H200,小模型选 H100 反而带宽利用率更高;
- 精度 vs 速度:FP16 → INT8 → INT4,每降一档带宽压力减半,但精度也有损失——权重量化的 W4A16 是当前甜点;
- 硬件 vs 编译:花钱买 H200 还是花时间上 vLLM + AWQ?小团队先优化软件,再考虑升级硬件。
延伸阅读
- Roofline 模型与算力分析——用 AI 定量判定 memory vs compute bound
- 权重量化与混合精度——突破带宽墙的第一手段
- 算子融合与自定义核——FlashAttention 如何避开 HBM 读写
- 批处理与请求调度——堆并发榨干带宽
- GPU 体系结构与优化——SM/warp/shared memory 的底层视角
- vLLM 案例研究——PagedAttention 解决 KV 显存碎片
- 硬件入门——GPU 选型与配置
参考资料
- NVIDIA H100 White Paper —— H100 架构与 HBM3 参数官方文档
- NVIDIA H200 Datasheet —— H200 HBM3e 141GB 参数
- NVIDIA H100 Memory Bandwidth Analysis(Markomanlicious blog) —— 各级显存层次实测数据
- Pope et al. Efficiently Scaling Transformer Inference(MLSys 2023) —— LLM 推理显存墙的系统化分析
- Kwon et al. Efficient Memory Management for Large Language Model Serving with PagedAttention(SOSP 2023) —— KV cache 显存管理与 PagedAttention
- Dao et al. FlashAttention: Fast and Memory-Efficient Exact Attention(NeurIPS 2022) —— 突破 HBM 带宽墙的里程碑算法