内存墙 HBM 带宽:为什么 AI 芯片算得快却喂不饱
更新时间:2026-09-25。HBM GDDR 显存讲了 GPU 显存的两条封装路线,这一篇回答一个更尖锐的问题:芯片的浮点算力每年大幅增长,为什么大模型推理速度却没有同比例变快?答案是数据搬不动——模型权重、KV cache 都躺在 HBM 里,计算单元每走一步都要回头取数。算力增长快、带宽增长慢,两者之间的剪刀差就是「内存墙」。这一篇从屋顶线模型出发,给出算术强度随 batch 变化的推导,再用 LLaMA 的参数量和 HBM3 的 3TB/s 把 token/s 算出来。加速器内部如何把数据搬到计算单元,可配合阅读加速器 SRAM NoC 数据供给;注意力内核里 KV cache 的具体算子,见 Transformer Attention 内核。
本文要回答的问题
- 什么是内存墙?为什么说 AI 芯片算力涨得比带宽快,最终被带宽卡住?
- 权重、激活、KV cache 三类数据各自的访存模式有什么不同?
- 算术强度是什么?为什么 batch=1 推理几乎纯带宽 bound,增大 batch 就能转向计算 bound?
- 用 LLaMA-7B、FP16(每参数 2 字节)、HBM3 带宽 3TB/s,token/s 的理论上限是多少?
- HBM 容量和带宽分别卡住什么:谁决定模型多大、上下文多长,谁决定生成速度?
- 工程上有哪些绕墙的办法:量化、GQA、分页 KV、连续批处理各自省了什么?
一、剪刀差:算力增长快,带宽增长慢
先看两组以十年为尺度的数字。2012 年前后的顶级计算卡浮点算力在 1 TFLOPS 上下、显存带宽约 200GB/s;到 2024 年的旗舰 AI 加速器,FP16 稠密算力约 1000 TFLOPS、显存带宽约 3.35TB/s。十二年间,算力涨了约 1000 倍,带宽只涨了约 16 倍。差距背后是两类完全不同的物理:算力靠晶体管数量、靠张量核这样的专用阵列、靠架构堆叠,每代工艺和设计都能兑现可观提升;而 HBM 带宽受限于 DRAM 阵列本身的速度,提升只能靠加宽总线(1024-bit 堆栈)、堆更多堆栈(从 4 栈到 8 栈)和加高层数(8-Hi 到 12-Hi),每一步都要封装工艺买单。
DRAM 为什么天生慢,值得多说一句。存储单元是一个电容加一个晶体管,读数据要先把整行充进灵敏放大器、再按列读出,每次行激活都伴随物理的充放电,阵列内部频率被这个过程钉死,几十年只缓慢提升。HBM 的做法不是让阵列变快,而是让几千个 I/O 并排同时输出,用空间换带宽——每个堆栈约 1024 个数据引脚同时工作,引脚只需要以几 Gbps 的温和速率翻转。这种结构同时解释了功耗优势:HBM 搬运每 bit 约 2~3pJ,因为引脚驱动的是中介层上距离极短、负载极轻的硅布线;引脚速率和负载都压不下来的方案,每 bit 能耗要高出两三倍。代际路线图上,HBM3e 把单栈推到约 1.2TB/s,HBM4 计划把单栈接口宽度翻倍并引入更多堆栈,但每一次提升都同步抬高对中介层尺寸、基板层数和供电散热的要求,带宽的每一步都比算力昂贵。
剪刀差的直接后果是:每搬 1 字节数据进芯片,计算单元理论上能做的运算越来越多,但工作负载需要的字节数并没有减少——大模型的权重反而从几十亿参数涨到几千亿。于是 AI 加速器在大部分时间里不是在算,而是在等数据从 HBM 流上来。这就是内存墙(memory wall)一词在 AI 时代的含义:算力屋顶越抬越高,带宽斜线却抬得很慢,越来越多的工作负载被压在斜线一侧。
二、屋顶线与算术强度:batch 决定你在哪一侧
判断一个内核被算力还是带宽卡住,用屋顶线模型。机器存在一个拐点(ridge point):
- 拐点 = 峰值算力 ÷ 峰值带宽。
以 FP16 算力约 1000 TFLOPS、带宽 3TB/s 的加速器为例,拐点约为 1000000 ÷ 3000 ≈ 333 FLOP/byte。内核的算术强度(每搬 1 字节做多少次浮点运算)低于这个数,性能 = 带宽 × 算术强度,与算力无关;高于这个数,才摸得到算力屋顶。
大模型的解码(decode)阶段恰好是算术强度极低的工作。自回归生成每个 token 时,模型对每个权重参数大约做 2 次浮点运算(一次矩阵乘的乘加),而 FP16 下每个参数占 2 字节。若只处理一个序列,权重每 token 都要从 HBM 完整读一遍,那么:
- 算术强度 ≈ 2N 次 FLOP ÷ 2N 字节 = 1 FLOP/byte。
1 对 333——差了两个半数量级。所以单条序列的解码几乎是纯带宽 bound,再强的张量核也只能干等。
转机来自 batch。权重读一次可以同时喂给 B 个序列(或 B 个待生成 token),权重搬运被 B 份计算摊薄:
- 每 token 的总 FLOP ≈ 2NB(B 条序列各做一份);
- 每 token 的访存 ≈ 2N(权重读一次)+ B 条序列各自的 KV cache 读取;
- 算术强度 ≈ B FLOP/byte(忽略 KV 项时)。
也就是说算术强度大致随 batch 线性上升:B=1 时约 1,B=64 时约 64,B=256 以上才开始接近拐点。这里还不能忘记公式里被忽略的 KV 项:解码时除了读权重,每条序列还要读取与其上下文等长的历史 KV,上下文越长、KV 字节越多,算术强度的上升斜率就越平缓,batch 的实际收益打折。预填充(prefill)阶段处理一条长序列的全部 prompt token,权重同样只读一次、被成百上千个 token 摊薄,此时算术强度约等于 prompt 的 token 数,因此天然是计算 bound;而逐 token 的解码没有这份摊薄,必须靠多序列拼 batch 才能把算术强度抬起来。这解释了推理服务为什么拼命把多个用户的请求拼在一起跑,以及为什么离线大批量推理的芯片利用率远高于单用户聊天。
需要区分延迟和带宽两件事。一次 HBM 访问的延迟有几百个周期,GPU 可以用大量线程切换、用别人的请求填补等待,把延迟藏起来;但单位时间能搬进芯片的总字节数是硬上限,线程再多也变不出字节。batch 拼的不是延迟,而是把「权重读一次」的成本摊给更多计算——这是唯一合法的「省字节」方式。屋顶线还给出一个推论:在带宽斜线上,优化算力(换更快的张量核、提频率)完全不改变性能,只有减少字节数或增加带宽有效供给才有用,这决定了后面所有工程对策的方向。
三、权重、激活、KV cache:三类数据三种访存模式
大模型推理读写的数据可以分成三类,它们在存储层级中的位置和流动方向如下,容量、复用方式和带宽压力各不相同:
| 数据类型 | 存放与体量 | 访存模式 | 主要瓶颈 |
|---|---|---|---|
| 权重 weights | FP16 约 2 字节/参数,7B 模型 14GB;占显存大头 | 每 token 全量顺序读一遍,多 batch 共享同一份读取 | 解码带宽 |
| 激活 activations | 与 batch、序列长度、隐藏维相关,预填充时较大 | 层间流动,可在片上 SRAM 中尽量停留 | 片上容量、预填充带宽 |
| KV cache | 每 token 每一层存 K/V 两张量表,随上下文线性增长 | 每个新 token 都要读取历史全部 KV 做注意力 | 容量与带宽同时受压 |
权重的特点是只读、体量大、解码时复用率低——读一次只换来一个 token 的计算,是带宽消耗的第一大户。实际执行按层推进:7B 模型共 32 层,每层约 2.2 亿参数、约 438MB,逐层从 HBM 流式读入、用完即弃,因此不需要把全部权重同时放进片上 SRAM,但也意味着每 token 的 HBM 读取总量就是全部 14GB,一层都省不掉。多 batch 之所以有效,是因为同一层的 438MB 读入后,可以连续对 B 条序列各算一遍再换下一层,字节不变、运算翻倍。
激活是各层中间结果,调度得当时只在片上 SRAM 层级流动、不必落 HBM;真正被迫写回 HBM 往往发生在预填充长序列(中间激活总量随序列长度线性增长,片上放不下)或张量并行切分边界(层间规约要跨卡交换),详见加速器 SRAM NoC 数据供给中的数据供给设计。算子融合(把矩阵乘、偏置、归一化、激活函数拼成一个内核)的核心收益就是让激活留在寄存器和 SRAM 里,避免为每个小算子往返 HBM。
KV cache 最特殊:注意力机制要求每个新 token 与之前所有 token 的 K、V 交互,因此历史 KV 必须保存下来、每步重读,其算子级细节见 Transformer Attention 内核。按公式估算,每层每个 token 的 KV 占用为 2(K/V 两张量)× 每 KV 头维度 × 2 字节,再乘以层数。以 LLaMA-7B 为例,32 层、隐藏维 4096、无 GQA:
- KV 占用 ≈ 2 × 32 × 4096 × 2 ≈ 0.5MB/token。
上下文 8192 个 token 时,单条序列的 KV cache 约 4GB;上下文拉到 32K 则约 16GB——还没算权重和激活。访存模式上,KV 是「边写边反复读」:每生成一个新 token,写入它自己的一份 KV(仅约 0.5MB),同时要把此前全部历史 KV 读出来做注意力,读取量随上下文线性增长,到长上下文阶段会超过权重读取、成为带宽账里的主要新增项。长上下文模型引入 GQA(分组查询注意力,多个查询头共享一组 KV 头),把 KV 维度缩小数倍,正是为了压低这项开销。以采用 GQA 的 70B 模型为例,80 层、KV 头维度合计 1024,每 token KV 约 2×80×1024×2 ≈ 0.33MB,反而低于 7B 无 GQA 的水平,可见架构设计对字节数的影响之大。
四、算例:LLaMA-7B 在 3TB/s 下能跑多少 token/s
把前面的数字落成一道完整的账。设模型 70 亿参数、FP16 部署(每参数 2 字节),加速器 HBM3 带宽 3TB/s,batch=1 解码:
- 权重总量 = 7×10⁹ × 2 字节 = 14×10⁹ 字节 ≈ 14GB;
- 每个 token 至少读一遍全部权重(14GB),外加读历史 KV cache;
- 理论 token/s 上限 ≈ 3000GB/s ÷ 14GB ≈ 214 token/s。
214 token/s 是只计权重、且假设带宽 100% 利用的理想值;实际还要读 KV cache(长上下文时不可忽略)、存在调度与访存粒度损耗,工程实测通常落在几十到一百多 token/s。把 KV 项算进去更贴近现实:8192 上下文时,每 token 额外读取约 4GB 历史 KV,总读取约 18GB,上限降到约 3000÷18 ≈ 167 token/s;上下文拉到 32K 时仅 KV 就读 16GB,上限被压到约 100 token/s——同一个模型,上下文越长生成越慢,根源就在这里。换 13B 模型,26GB 权重对应上限约 3000÷26 ≈ 115 token/s;70B 模型 140GB 权重,单流理论上限仅约 21 token/s,必须多卡张量并行、把多卡带宽聚合起来才有实用速度,而跨卡每多一层切分又会引入额外通信。模型翻倍、token/s 大致减半——带宽决定速度这一点体现得非常直白。
再算算力侧是否真的闲着。7B 模型每 token 约 2N = 1.4×10¹⁰ 次 FLOP,以约 200 token/s 计,实际算力消耗约 2.8 TFLOPS,而机器峰值约 1000 TFLOPS,利用率不到 0.3%。这不是优化不力,而是 batch=1 解码的本质:算术强度只有约 1 FLOP/byte,机器运行在屋顶线的带宽斜线上,峰值算力在此场景下本来就无法兑现。
batch 的收益同样可以算。B=64 条序列共享一次权重读取,总 token/s(所有序列合计)仍受同一道带宽账约束,即约 200 token/s 量级的总量,但每条序列摊到约 3 token/s,总算力利用率随算术强度(约 64 FLOP/byte)上升而明显提高;当 batch 继续加大使强度逼近 333 的拐点,性能才开始受算力钳制。注意此时每条序列的 KV cache 读取叠加进来,会把实际拐点往左拉,因此真实系统常在几十到一两百的 batch 之间达到平衡。
五、容量墙:带宽决定多快,容量决定能跑什么
HBM 对大模型的约束其实是两道墙。带宽墙决定生成速度;容量墙决定哪些模型和多长的上下文根本放不进去。算几笔容量账:
- 7B 模型 FP16 权重 14GB,一张 80GB 卡绰绰有余,还能放约 10 万 token 的 KV cache(按 0.5MB/token);
- 70B 模型 FP16 权重约 140GB,单张 80GB 卡放不下,必须张量并行拆到多张卡,或用 INT8/INT4 量化压到 70GB/35GB;
- 长上下文场景下 KV cache 反客为主:32K 上下文、单序列 KV 约 16GB(7B),多序列并发时 KV 总量可以超过权重。
所以容量配置遵循「权重 + 最大并发序列数 × 每序列 KV 长度 + 激活」的加和。以 80GB 单卡跑 7B FP16 为例,14GB 权重之外,若每序列 KV 按 8192 上下文 4GB 计,留给并发的空间约 60GB,即大约 15 条满长度序列;想提高并发,要么缩短上下文上限,要么压缩 KV。显存不够,对策不是提速而是换模型:多卡拆分引入跨卡搬运、反而增加带宽压力;量化把每参数从 2 字节压到 1 字节甚至 0.5 字节,同时减轻容量与两道带宽账,是性价比最高的绕墙手段之一。70B 模型 INT4 量化后约 35GB,单张 80GB 卡即可承载并留出可观的 KV 空间,这就是今天消费级和轻量数据中心部署大量转向 4 位权重的直接原因;代价是少量精度损失,需要配合校准方法控制输出质量。
还要注意容量与带宽在多用户场景下的联动:单条序列的 KV 占 0.5MB/token 看似不大,但几十条并发、上万上下文叠加后就是几十 GB,容量先告急;而这些 KV 在解码时被各序列反复读取,又持续占用带宽。两道墙不是独立存在的,长上下文高并发服务会同时撞上两者。
六、算力 vs 带宽:增长趋势、瓶颈与工程对策
面对内存墙,软件和架构层面的对策可以按「省字节、摊字节、少搬字节」三类归纳:
| 对比维度 | 算力侧 | 带宽侧 |
|---|---|---|
| 近年增长 | 每 2 年数倍,张量核与专用架构驱动 | 每代仅小幅提升,受 DRAM 阵列与封装限制 |
| 瓶颈本质 | 利用率低:batch=1 时峰值算力无法兑现 | 物理上限:权重每 token 重读、KV 随上下文膨胀 |
| 主要对策 | 增大 batch、连续批处理、算子融合 | FP16→INT8/INT4 量化、GQA/MQA 压缩 KV、分页 KV cache、权重常驻与片上复用 |
| 架构方向 | 脉动阵列、更多张量核 | 近存计算、HBM 堆栈扩容、片上 SRAM 层级与 NoC 喂数优化 |
| 效果 | 提升有效占用,但解不了带宽 bound | 直接减少字节数,对解码 token/s 近线性受益 |
具体说几项关键技术。投机解码(speculative decoding)用一个小模型先起草多个候选 token、再让大模型一次验证,大模型的一次权重读取因此摊到多个被接受的 token 上,等效抬高了解码的算术强度——它用相对廉价的草稿算力,换掉昂贵的权重重读。连续批处理(continuous batching)在请求粒度动态拼 batch、某条序列生成结束立即补入新请求,让权重读取尽量被多份计算摊薄,是推理服务把算术强度抬起来的主要手段。分页 KV(PagedAttention)把 KV cache 像虚拟内存一样分页管理,消除碎片、显著提升单卡可容纳的并发序列数。量化同时缩小权重与 KV(KV 可按 8 位存储),对带宽墙的收益最直接:INT8 下 7B 权重降到 7GB,3TB/s 上的 token/s 理论上限从约 214 抬到约 428。GQA/MQA 压缩 KV 头数量,直接降低长上下文的 KV 字节数。硬件层面,加速器把更多 SRAM 放到离阵列最近处、用 NoC 持续喂数,并探索近存/存内计算减少 HBM 往返——这些是把带宽斜线往上抬的长期努力。
这一篇在知识体系里的位置
- 想理解 HBM 的堆栈、TSV、单栈带宽如何凑出 3TB/s → HBM GDDR 显存;
- 想知道数据进入芯片后如何经 SRAM 与 NoC 喂给计算阵列 → 加速器 SRAM NoC 数据供给;
- 想看 KV cache 在注意力算子中的具体读写与融合 → Transformer Attention 内核;
- 想看张量核与矩阵乘怎样吃掉计算密集阶段 → Tensor Core 矩阵加速;
- 想看屋顶线模型在 GPU 性能分析中的完整用法 → GPU 屋顶线模型。
总结
内存墙 HBM 带宽是 AI 时代的硬约束:十二年里算力涨约 1000 倍、显存带宽只涨约 16 倍,拐点被抬到约 333 FLOP/byte,而大模型 batch=1 解码每生成一个 token 要把全部权重重读一遍、算术强度只有约 1 FLOP/byte,几乎纯带宽 bound,算术强度随 batch 近似线性上升、到几百才接近算力屋顶;LLaMA-7B 的 FP16 权重 14GB,在 HBM3 3TB/s 上 token/s 上限约 3000÷14≈214,13B 降到约 115,长上下文还要叠加约 0.5MB/token 的 KV cache 读取——带宽决定 token/s,容量(权重加并发 KV)决定能放多大模型和多长上下文,对策是量化、GQA、分页 KV 与连续批处理等省字节、摊字节的组合。