内存层次与 HBM
上一章讲了 GPU 的计算单元。这一章讲数据从哪来。一个反复被低估的事实是:现代 AI 加速器最稀缺的资源不是算力,是显存带宽。 从 V100 到 B200,算力涨了约 18 倍,带宽只涨了约 9 倍——差距越拉越大,"内存墙"越来越厚。
四层层次,两个数量级的悬崖
Section titled “四层层次,两个数量级的悬崖”以 H100 SXM 为例,从里到外:
| 层次 | 容量 | 延迟(周期) | 带宽(单 SM / 全片) | 管理方式 |
|---|---|---|---|---|
| 寄存器 | 256 KB / SM | 0 | ~100+ TB/s(聚合) | 编译器分配 |
| 共享内存 | 228 KB / SM | ~30 | ~33 TB/s(聚合) | 程序员显式管理 |
| L2 缓存 | 50 MB | ~200 | ~7 TB/s | 硬件自动 |
| HBM3 显存 | 80 GB | ~500 | 3.35 TB/s | 硬件自动 |
规律一目了然:每往外一层,容量大两个数量级,带宽小一个数量级,延迟大一个数量级。 这个"带宽悬崖"结构不是 GPU 特有的(CPU 的 L1/L2/L3/DRAM 一模一样),GPU 只是把它推得更极端。
为什么必须分层:物理上,快的东西又小又贵,大的东西又慢又便宜。SRAM(寄存器/共享内存/L2)一个 bit 要 6 个晶体管;DRAM(HBM)一个 bit 一个晶体管加一个电容。SRAM 密度低 ~8 倍、贵 ~8 倍。想在 80 GB 的容量上拿到 3.35 TB/s,就必须用 DRAM 堆叠(HBM);想拿到 33 TB/s,就只能靠 228 KB 的小 SRAM。没有例外,所有芯片都活在这个约束里。
HBM:带宽是怎么堆出来的
Section titled “HBM:带宽是怎么堆出来的”传统 GDDR 显存靠提高单针脚速率,HBM 的思路完全不同:把 DRAM 芯片切薄、堆叠、用硅穿孔(TSV)连起来,做成一条超宽的总线。
- H100:5 个 HBM3 堆栈,每个堆栈 1024-bit 总线,全片 5120-bit,速率 8 Gbps/pin → TB/s
- H200:同样算力,堆栈升级 HBM3e、容量翻倍到 141 GB,带宽 4.8 TB/s
- B200:8 个 HBM3e 堆栈,192 GB,8 TB/s
三个工程含义:
一、带宽换容量是免费的,容量换带宽不是。 H200 与 H100 算力相同、显存更大——厂商清楚推理负载的瓶颈在容量和带宽,不在算力。
二、HBM 发热与良率是成本大头。 堆叠让散热路径变差,HBM3e 只能跑到与 GDDR 相近的频率,靠宽度取胜;堆叠层数越高良率越低,这是 HBM 每GB价格数倍于 GDDR 的原因,也是大显存卡贵的主因之一。
三、有效带宽 < 峰值带宽。 峰值 3.35 TB/s 是理论引脚速率。访问不连续、读写切换、ECC 开销都会打折。高性能内核实测能到峰值的 80–90%(TMA + 合并访存),写得差只有 30–50%。
延迟与带宽是两件事
Section titled “延迟与带宽是两件事”一个常见混淆:HBM 延迟 ~500 周期(约 300 ns)听起来很小,为什么是灾难?因为单次访问只能取一个数据,带宽要靠大量并发访问堆出来。
用 Little 定律算清楚需要多少"在途数据"才能打满带宽:
要打满 HBM,必须同时有约 2.7 MB 的访存在途。 换算成并发:一个 warp 一次取 128 字节,需要约 21000 个独立访存在路上——这就是为什么 GPU 要几千个常驻线程,为什么占用率低的访存内核一定跑不满带宽。延迟藏不住,一切免谈。
缓存在 AI 负载里的实际角色
Section titled “缓存在 AI 负载里的实际角色”L2 的 50 MB 相对模型动辄几十 GB 显得很小,但命中率对性能影响巨大:
| 数据 | 大小 | 缓存行为 |
|---|---|---|
| 逐层权重(7B 模型一层 ~500 MB) | ≫ L2 | 基本不命中,从 HBM 直接读 |
| 激活 tile(矩阵乘的分块) | KB–MB 级 | 高命中,靠分块控制 |
| embedding 表(词表 15 万 × 4096 × 2B ≈ 1.2 GB) | ≫ L2 | 散乱访问,命中率取决于局部性 |
| KV cache(解码中反复读) | 随序列增长 | batch 内多次复用,批处理提高命中 |
设计含义:大权重从 HBM 读一遍是省不掉的(融合与分块只能省激活的往返),所以推理的吞吐上限由带宽决定;而激活可以靠分块装进片上存储,所以训练的大矩阵乘能接近算力上限。
数据搬运的完整成本
Section titled “数据搬运的完整成本”分层存储的真正代价在"层间搬运"。一个 tile 从 HBM 到 Tensor Core 要经过 HBM → L2 → 共享内存 → 寄存器三跳,每跳都有固定开销与带宽损耗。数一遍一个 transformer 前向的显存流量:
| 流量 | 大小(7B 模型,batch 8,seqlen 4096) |
|---|---|
| 读权重(必付,与 batch 无关) | ~14 GB |
| 读+写激活(与 batch × seqlen 成正比) | 数十 GB |
| 读+写 KV cache | 数 GB |
| 优化器状态下(训练)再乘 12–16 倍 | 见激活内存 |
三个推论:
一、推理 batch 越大,权重流量的"摊薄"越彻底。 单请求读 14 GB 权重只产出一个 token;batch 64 时同样 14 GB 服务 64 个 token——连续批处理的收益根源。
二、训练的显存流量远大于推理。 前向 + 反向 + 优化器,每参数总流量约 16 字节/step(16 位训练)。14 GB 权重意味着一步 ~224 GB 流量,3.35 TB/s 的带宽给了 ~67 ms 的纯访存下限——大模型 step 时间里算力反而常常不是第一约束。
三、跨层复用靠不住,片上复用才是真的。 L2 只有 50 MB,跨 kernel 的数据很难活着留在 L2 里。真正可控的复用只有共享内存里的分块复用——这是所有 GEMM 优化和 FlashAttention 的核心手法。
未来的两条出路
Section titled “未来的两条出路”在存算(PIM / near-memory computing):把计算单元放进 HBM 堆栈里,数据不动计算动。三星 HBM-PIM、UPMEM 已有产品;对 embedding 查表、推荐系统这类纯访存负载收益显著,但通用性还差。
更大的片上存储:每代芯片共享内存都在涨(A100 164 KB → H100 228 KB),Blackwell 引入 TMEM(tensor memory)。方向明确:SRAM 与 DRAM 的鸿沟靠"把常用数据尽量留在离计算近的地方"来填。
- 四层层次:寄存器 → 共享内存 → L2 → HBM,每层容量 ×100、带宽 ÷10、延迟 ×10。
- HBM 靠堆叠 + 超宽总线(H100 5120-bit)换带宽;带宽比算力涨得慢,内存墙逐代变厚。
- 打满带宽需要 ~2.7 MB 在途数据(Little 定律)——延迟靠并发隐藏,藏不住就跑不满。
- L2 太小,跨层复用靠不住;激活复用必须靠显式分块装进共享内存。
- 推理:权重流量靠 batch 摊薄;训练:每步 ~16 B/参数的流量让带宽常成第一约束。
- 出路:算子融合省往返、量化省字节、批处理提高每字节收益——全都是"省带宽"。
- GPU 架构 — 上一章:数据要喂给谁
- 算术强度与 Roofline — 带宽如何决定性能上限
- 节点内互连 — 下一章:显存之外的第二条数据通道
- KV Cache 与 PagedAttention — 推理侧的显存管理