第 1 章 — Token 生成的机制
《LLM Primer VI: Scaling AI Systems》章节走读的第一篇。这一章要说的是:LLM serving 里几乎每一个难题,都能追溯到同一件事 —— 生成每一个 token 的那个循环是内存带宽受限的,你花大价钱买回来的算力,有 99.7% 的时间在空转。
这一章为什么存在
一个 LLM,运行起来就是一个包在循环里的 next-token 预测器。token 进去,一份关于下一个 token 的概率分布出来,挑一个,拼上去,循环再跑一次。推理栈里每一个有意思的性质 —— batching、量化、KV cache、投机解码、拆分部署 —— 都来自对这个循环的仔细端详。这个循环藏着两种共用同一段代码路径但对硬件施加相反压力的工作负载。一种是 compute-bound。另一种是 bandwidth-bound。在同一块 H100 上,同一次前向传播里。把这个分岔精确地命名出来,是整本书的第一个动作,也是后面每一章都要回过头来引用的那个框架。
1.1 自回归循环的顺序性是被数学强制的
token t+1 是截至并包括 t 的每一个 token 的函数。模型没办法在 t+1 被采样出来之前预测 t+2,因为对 t+2 的预测需要 t+1 已经进入输入。没有哪一个巧妙的 kernel 能把同一段序列里相邻两个 token 的生成并行掉;这个顺序性是被计算的依赖结构强制的。生成一段 N 个 token 的回答,墙钟时间是 N 倍的单步成本加上固定开销。后面书里那些优化 —— 更大的 batch、超前于当前轨迹去投机、更便宜的每步算术 —— 都是对这样一个问题的部分回答:"既然循环必须一个 token 一个 token 地走,那我们怎么让每一步更快、或者让每一 batch 更大?" 模型也没有外部的草稿本:它靠往外吐 token 来"思考"。这个循环是模型唯一可以"多想一会儿"的机制,这也是为什么 chain-of-thought 和投机解码都属于同一本账。
1.2 Prefill 和 decoding 对芯片施加相反的压力
循环里藏着两个阶段。Prefill 是第一次前向传播,消费用户的 prompt,形状是 [batch, sequence_length, hidden_dim]。每一次矩阵乘一次性对所有序列位置操作;算术随序列长度线性增长;权重从 HBM 里读一次,套到很多行工作上。算术强度高。Prefill 是 compute-bound 的,可以用到 H100 那 989 BF16 TFLOP/s。Decoding 是之后每一次前向传播。输入的形状塌成 [batch, 1, hidden_dim]。每一层的权重仍然要从 HBM 流出来,但只对它做一行算术。算术强度掉了三个数量级。Decoding 是内存带宽受限的。70B 模型 BF16 的例子里,一段 2,000 token 的 prompt 做 prefill,能贴着芯片的算力上限跑;紧接着的下一次前向传播 —— 第一次 decode 步 —— 对同样 140 GB 的权重再走一遍,产出一个 token。芯片没变,工作负载变了。
1.3 单用户会让 H100 空转 99.7%
结论是:单用户实时生成,是顶级加速器最糟糕的场景。一块 H100 SXM 上跑 BF16 的 70B 模型,大约每秒 decode 24 个 token —— 用户读起来算流畅,芯片的 HBM3 3.35 TB/s 带宽被彻底用满,每一个 token 都要搬 140 GB 的权重。可就在那个速率下,计算单元只跑到 3.36 TFLOP/s,而它能跑 989。算力利用率是 0.34%。物理芯片没配错;每一个 SM 都在满速读、满速乘,但 tensor core 是被设计来在同一份 weight tile 上消费很多行的,而单 token 的前向传播只给它一行。算力容量的计量单位(每加载一字节做多少 op)是这个工作负载产不出来的。整块芯片一小时四到八美元照付。LLM serving 的经济学,由此变成"给那些被停在原地的算力找活"的经济学 —— 靠 batching、靠更便宜的每 token 带宽、靠投机、靠那些天平点更贴近工作负载的硬件。
第 1 章为下面铺了什么
本书剩下的每一章都是对这一章命名的这份不对称性的回应。第 2 章拆开 KV cache —— 那个让 decoding 避免二次方级重算的数据结构,同时也是 serving 集群里 VRAM 的最大单一消费者。第 3、4 章带着"带宽对算力"这副眼镜走遍硬件底座。第 5、6 章通过缩小权重本身来缩小每 token 的带宽负担。第 7 章走 batching —— 系统层的那根杠杆,把带宽受限造成的浪费换成吞吐。第 8、9 章通过 paged KV 管理和投机解码改变工作本身的形状。每一个动作,都能被读成对这一章刚刚测出来的那段空转算力的填补尝试。
下一章 — 第 2 章:KV Cache 的挑战。那个让 decoding 便宜下来的工作区,以及那道能解释"为什么 serving 集群总是先耗尽 VRAM 而不是算力"的内存公式。
decode_regime 和 measure_decode_utilization 两个能把数字落到真实系统上的小工具,以及本文只做了摘要的 In Plain English 边栏。在 Amazon 上查看 LLM Primer VI →