深度解读 📅 2026-10-23 ✍️ MagicNetWorld 编辑部

一次 decode 步的逐周期账:单颗 LPU 跑一层 FFN 时,算力、SRAM 带宽与静态排程到底谁卡住谁

以 Groq 第一代 TSP 论文的每周期参数估算:一层 Llama-3-8B FFN(1.762 亿个 int8 权重)、批 1 时,算力下界约 430 个周期;按双向流寄存器的理论峰值,权重搬运下界约 8,602 个周期,后者为前者的 20 倍。文中推出这台机器的算术强度平衡点 40 ops/字节与平衡批大小 20 条,并说明三点:芯片里最窄的一段是 SRAM 到 MXM 的流寄存器通路(每周期 20,480 字节),MXM 只能装 409,600 个权重所以必须分块重搬,静态排程把「每一个错位」都变成编译器必须满足的逐周期对齐约束。以上均为理想下界(批内权重只搬一次、搬运与计算理想重叠、不计其他流量与启动收尾),不是实测延迟。

推理硬件LPU静态排程SRAM 带宽算术强度FFN逐周期预算

除另行标注外,本文引用的外部事实与页面核验均以 2026-10-23(北京时间)为时点;文中所有「本文自行推导」的算式都写清了假设与中间值,可以自己按一遍。本文只算一层 FFN、一次 decode 步,不算 attention、不算 LM head、不算 KV cache 的读写时序。

一、先把答案放在最前面

本节三个数都是理想预算(一层 FFN、int8 权重、批 1、流寄存器按标注的方向取峰值),不是实测延迟。 后面全篇是在证明这三个数:

  • 430 个周期:一层 Llama-3-8B 的 FFN(1.762 亿个 int8 权重)在一次 decode 步里需要的算力周期,按 4 个 MXM 阵列每周期 409,600 次乘加折算。
  • 8,602 个周期:同一层权重从 SRAM 搬进 4 个 MXM 阵列的周期下界,按片内流寄存器的双向理论峰值(每周期 20,480 字节)折算。
  • 20 倍:搬运周期 ÷ 算力周期。

也就是说,在批量为 1 的那一步里,卡住这台机器的既不是 SRAM 的铭牌带宽,也不是矩阵单元的算力,而是「MXM 只有 409,600 个权重的寄存器容量」逼出来的分块重搬——寄存器容量决定必须分块,装载路径的吞吐决定分块要花多久。SRAM 有 220 MiB,装得下整层;但 MXM 每次只认 409,600 个权重,所以「装得下」不等于「不用重搬」。

三个角色各让一步的结论是:在本文这个算例里,算力不是第一个撞墙的;SRAM 容量也不是;第一个撞墙的是 SRAM 到 MXM 之间那条单向 32 条流宽的路。 这一点只有在把账算到「周期」这一级才看得见,用「算力/带宽」的宏观比值会被铭牌数字掩盖。

下面按「符号约定 → 一个周期能买什么 → 一层 FFN 的账 → 批量化怎么把 20 倍差距摊掉 → 容量反算 → 静态排程的代价 → 与 GPU 的对照 → 三个常见误算 → 边界」走一遍。

二、符号约定与术语表

先补三条单位与精度约定:MB / TB 为十进制(10610^6、101210^{12}),MiB 为二进制(2202^{20});int8 权重按 1 字节/权重计;周期数与时钟无关,纳秒数一律按 900 MHz 折算。

三个容易混掉的带宽口径先摆在一起,后文一律按此使用:

  • 56,320 字节/周期:论文式 2 的 SRAM 阵列聚合口径,本文只用来算「一次完整装载在存储侧要占多少」。
  • 20,480 字节/周期:论文式 1 的流寄存器口径(东西两向合计),本文所有搬运周期都用它做分母;单向为它的一半,10,240 字节/周期。
  • 80 TB/s:2025 年厂商博客对片内 SRAM 的相对量级说法,不是本文的逐周期输入,也不能用来证明第一代 TSP 的参数;本文只在「三个常见误算」里引用它。
符号含义取值 / 单位来源
PFFNP_{\mathrm{FFN}}一层 FFN 的权重个数(SwiGLU 三矩阵)176,160,768 个本文自行推导(按 4096/14336 配置)
AA每个 MXM 平面的乘加阵列边长320ISCA 2020
NMXMN_{\mathrm{MXM}}MXM 平面数4ISCA 2020
RMACR_{\mathrm{MAC}}每周期可完成的 int8 乘加次数409,600本文自行推导(4×32024\times320^2)
RopR_{\mathrm{op}}每周期可完成的运算次数(1 次乘加 = 2 次运算)819,200本文自行推导
BstreamB_{\mathrm{stream}}片内流寄存器的双向合计理论峰值(东西两向相加)20,480 字节/周期本文自行推导(2×32×3202\times32\times320,对应论文式 1)
BsramB_{\mathrm{sram}}片内 SRAM 阵列的聚合读写带宽56,320 字节/周期本文自行推导(对应论文式 2)
BB一次 decode 步里同时处理的 token 数(批大小)条—
CcompC_{\mathrm{comp}}一层 FFN 每 token 的算力周期数430.1 周期本文自行推导
CfeedC_{\mathrm{feed}}一层 FFN 权重的一次完整搬运周期数8,601.6 周期本文自行推导
静态排程指令的执行时刻在编译期全部确定,运行期无仲裁、无缓存、无重放—ISCA 2020
MXM / VXM / MEM矩阵执行模块 / 向量执行模块 / 内存切片—ISCA 2020
lane(通道)片内并行的数据通道,一条 lane 每周期走 1 个字节的流数据320 条ISCA 2020
supercell(计算子阵列)MXM 内的 16×16 乘加单元,每周期算一个部分和并传给相邻单元16×16ISCA 2020
tile(切片内空间单元)功能切片内纵向排列的计算单元,一个切片 20 个20 个/切片ISCA 2020
超车道(superlane)16 条 lane 构成的横截面,芯片最小计算颗粒16 元素ISCA 2020

两个词要分清:「流寄存器带宽」是 SRAM 到功能单元那一段的上限,「SRAM 带宽」是存储阵列自己的上限,前者比后者窄得多。混着用就会得出「搬 176 MB 只要 2.2 微秒」这种在同一模型里根本对不上的结论。

三、一个周期能买什么:把论文数字译成周期

3.1 算力:一个周期 409,600 次乘加

论文给出的 MXM 是 4 个独立的 320×320320\times320 乘加平面,每个平面每周期产出一组新的 int32 点积。所以每周期能同时进行的乘加次数是:

RMAC=NMXM×A2=4×320×320=409,600R_{\mathrm{MAC}} = N_{\mathrm{MXM}} \times A^{2} = 4 \times 320 \times 320 = 409{,}600

把「一次乘加算两次运算」算进去:

Rop=2×RMAC=819,200 op/周期R_{\mathrm{op}} = 2 \times R_{\mathrm{MAC}} = 819{,}200\ \text{op/周期}

这个数能不能对上论文自己报的峰值?论文在讨论节写「第一代 Groq TSP(1 GHz)峰值 820 TeraOps/s,26.8B 晶体管」。按每周期 819,200 次运算反推:

f=820×1012819,200≈1.001×109 Hz≈1 GHzf = \frac{820\times10^{12}}{819{,}200} \approx 1.001\times10^{9}\ \text{Hz} \approx 1\ \text{GHz}

与论文写明的「1 GHz」完全对上——这说明「4 个 320×320 平面每周期一次乘加」的读法是对的,820 TeraOps/s 这个数就是按每周期 819,200 次运算、1 GHz 算出来的。同时论文摘要写的是「标称时钟 900 MHz」,正文讲存储时又有一句「为便于说明,假设核心时钟 1 GHz」。所以同一篇论文里有两个时钟:900 MHz 是 ASIC 标称,1 GHz 是算峰值时的说明性假设。按 900 MHz 折算,同一台机器的峰值是 819,200 × 900 MHz ≈ 737 TOPS。

本文全篇取 900 MHz 做纳秒换算(保守一侧),周期数不受时钟影响——这也是我全程用周期讲结论的原因。

3.2 访存:三条宽度不同的路

这是全文最需要小心的地方,因为有三个数字都长得像「带宽」。前两条是论文给的,可以互相校验:

第一条是 SRAM 阵列自己的聚合带宽。论文式 2 是「2 个半球 × 44 个切片 × 2 个 bank × 每周期 320 字节」:

Bsram=2×44×2×320=56,320 字节/周期B_{\mathrm{sram}} = 2 \times 44 \times 2 \times 320 = 56{,}320\ \text{字节/周期}

第二条是 流寄存器(stream register)带宽。论文式 1 是「2 个方向 × 每 lane 32 字节 × 320 条 lane」:

Bstream=2×32×320=20,480 字节/周期B_{\mathrm{stream}} = 2 \times 32 \times 320 = 20{,}480\ \text{字节/周期}

第三条是 2025 年厂商博客里的「片内 SRAM 带宽高达 80 TB/s」。三者关系是:

  • BstreamB_{\mathrm{stream}} 只有 BsramB_{\mathrm{sram}} 的 36%——存储阵列能供 56,320 字节/周期,但流寄存器一层只收 20,480 字节/周期。这个比值是本文全部搬运账的基础:装得下不等于喂得进。
  • 80 TB/s 若按 1 GHz 折算,相当于每周期 80,000 字节,是论文式 2 那个 56,320 的 1.42 倍;若按 900 MHz 折算,则是每周期 88,889 字节,1.58 倍。
  • 要让 80 TB/s 与式 2 在同一个每周期模型里自洽,等效频率得是 1.42 GHz(80×1012/56,32080\times10^{12}/56{,}320)。

于是必须说清一件口径上的事:这两个数来自不同来源(2020 年的会议论文 vs 2025 年的厂商博客),不能让它们在同一个每周期模型里直接合并。 仅凭我打开的这些材料,无法判定差异来自时钟、产品代际,还是「带宽」的统计范围(例如是否把多端口、多 bank 的并行度都算了进去)。所以本文的处理是:用论文的每周期口径算流水,80 TB/s 只当作「厂商宣称的量级」,不参与任何推导;上面那个 1.42 GHz 是反推等效频率,不是已确认的工作时钟。

把一个来源的算力除以另一个来源的带宽,得到的「平衡点」是假的——这是本文在方法上最想说的一句话。

3.3 用论文自己的锚点校验装载速率

论文里有一个很硬的锚点:「用上每个方向全部 32 条流,可以把 409,600 个权重全部装进 4 个 320×320 阵列,含 SRAM 读取与片上网状传输延迟,用不到 40 个周期」。

409,600 个 int8 权重在论文式 1 的双向峰值下,纯传输下界是:

Cinstall≥409,60020,480=20 周期C_{\mathrm{install}} \ge \frac{409{,}600}{20{,}480} = 20\ \text{周期}

也就是说,20 个周期是这个装载模型的理论下界,而「不到 40 周期」是论文给出的含传输延迟的工程上界,两者差一倍,正好是作者给自己留的余量。请注意措辞:论文没有说实测均值是 40,也没有说实际能做到 20;我能确定的只有 20 ≤ 实际 ≤ 40 这个区间。

这条锚点还确认了一件事:装载速率的物理上限就是流寄存器那条路,不是 SRAM 阵列。SRAM 阵列能供 56,320 字节/周期,但权重必须先经过流寄存器才能进 MXM,所以那 20,480 才是真正的分母。

图 1 把这三条路的宽度画在一起,说明「SRAM 装得下」与「喂得进」是两件事。

flowchart LR
  SRAM["SRAM 220 MiB<br/>一层 FFN 权重 176.2 MB"]
  STREAM["流寄存器<br/>单向 10,240 B/周期<br/>双向 20,480 B/周期"]
  MXM["4 × MXM 320×320<br/>寄存器容量 409,600 权重"]
  VXM["VXM 4×4 ALU 网格<br/>SiLU 与逐元素乘"]
  OUT["写回 SRAM<br/>中间激活 14,336 个"]

  SRAM -->|"受限于 bank 并发 56,320 B/周期"| STREAM
  STREAM -->|"每周期装 409,600 权重的 1/20"| MXM
  MXM -->|"每周期一组 int32 点积"| VXM
  VXM -->|"激活与门控相乘"| MXM
  MXM --> OUT

这张图想说明的是:从 SRAM 到 MXM 之间有一段只能按 2 万字节/周期走的窄路,MXM 的 40 万权重寄存器是一个必须反复灌满的小水池,而不是可以一次装下整层的仓库。

3.4 还有两样东西在抢这块 SRAM

先给一个后面要用的数字,免得读者回读:按 int8 权重 176.2 MB、片内 SRAM 220 MiB(约 230.7 MB)作容量账,一层 FFN 占 76.4%,未扣其他占用的剩余约 54.5 MB(算式见 4.1 节)。

讨论「220 MiB 能装多少权重」时容易忘掉另外两个占用者,它们都走同一条通道:

  1. 指令文本。论文把片内存储描述为「参数与指令文本」共用,所有功能切片都从同一条流里取指令;一条 Ifetch 一次拉 640 字节(两条 320 字节向量的宽度)。一层 FFN 的指令量公开材料没有给,但它是与权重争 SRAM 与流带宽的第三份账。
  2. 中间激活与写回。SwiGLU 的中间张量是 14,336 个元素,int8 下约 14 KB/token;批 20 就是 287 KB。相对 176 MB 可忽略,但它与权重读共用同一批 bank,论文提到最多 176 路 bank 并发、并把 bank 位暴露给编译器,正是为了让这两股流量错峰。

所以「一层 FFN 占 76.4%」是容量上的乐观估计;真实部署还要再扣掉指令文本与激活的驻留,可用余量比 54.5 MB 更小。

四、一层 FFN 的逐周期账

4.1 先确定这一层有多大

用 Llama-3-8B 的公开配置:hidden size 4096、intermediate size 14336、32 层、32 个注意力头、8 个 KV 头。SwiGLU 结构的 FFN 有三个矩阵——gate(4096×14336)、up(4096×14336)、down(14336×4096)——权重个数为:

PFFN=3×4096×14336=176,160,768P_{\mathrm{FFN}} = 3 \times 4096 \times 14336 = 176{,}160{,}768

int8 量化下占 176,160,768 字节 = 176.2 MB。对照 220 MiB = 230,686,720 字节 ≈ 230.7 MB 的片内 SRAM:

176,160,768230,686,720=76.4%\frac{176{,}160{,}768}{230{,}686{,}720} = 76.4\%

剩余 230,686,720 − 176,160,768 = 54,525,952 字节 ≈ 54.5 MB(52.0 MiB)。所以「单颗 LPU 跑一层 FFN」在容量上是成立的,这正是题目成立的前提。

4.2 算力侧:430 个周期

decode 一步只处理一个 token,FFN 的乘加次数等于权重个数(每个权重参与一次乘加),运算次数翻倍:

Ccomp=2×PFFNRop=352,321,536819,200=430.1 周期C_{\mathrm{comp}} = \frac{2 \times P_{\mathrm{FFN}}}{R_{\mathrm{op}}} = \frac{352{,}321{,}536}{819{,}200} = 430.1\ \text{周期}

按 900 MHz 折算,477.9 纳秒。一个 token 穿过一层 FFN 的算力时间不到半微秒——如果世界到此为止,这台机器就是完美的。

4.3 搬运侧:8,602 个周期(理想下界)

问题在于 MXM 只能装 409,600 个权重(约 0.4 MB),而这一层有 1.762 亿个。一次 decode 步要把整层推过窄路:

Cfeed=PFFNBstream,双向=176,160,76820,480=8,601.6 周期C_{\mathrm{feed}} = \frac{P_{\mathrm{FFN}}}{B_{\mathrm{stream,双向}}} = \frac{176{,}160{,}768}{20{,}480} = 8{,}601.6\ \text{周期}

按 900 MHz 折算,9.56 微秒。这是双向流寄存器理论峰值下的时间下界:不含启动收尾、不含其他流量、假设装载与计算理想重叠。若只能用单方向(单向 10,240 字节/周期),这个数翻倍到 17,203 个周期、19.1 微秒。

两者相除:

CfeedCcomp=8,601.6430.1=20.0\frac{C_{\mathrm{feed}}}{C_{\mathrm{comp}}} = \frac{8{,}601.6}{430.1} = 20.0

整 20 倍,而且是个干净的整数——这不是巧合。把两项的表达式写开就看得出来:

P/Bstream2P/Rop=Rop2Bstream=819,2002×20,480=20\frac{P/B_{\mathrm{stream}}}{2P/R_{\mathrm{op}}} = \frac{R_{\mathrm{op}}}{2B_{\mathrm{stream}}} = \frac{819{,}200}{2 \times 20{,}480} = 20

权重个数 PP 被约掉了。这意味着:这个 20 倍与模型多大、层多宽无关,它只由这台机器的两个每周期参数决定。换句话说,「每字节能算多少次运算」的门槛是 40 op/字节(819,200/20,480819{,}200/20{,}480),而 int8 权重流能提供的算术强度恒为 2 op/字节(每个权重 1 字节、做 1 次乘加 = 2 次运算),差 20 倍。

换一种更工程化的说法:要让 4 个 MXM 每周期都吃满,每周期必须送入 409,600 个 int8 权重;按 900 MHz 就是 368.6 TB/s 的权重供给。流寄存器那条路按 900 MHz 是 18.4 TB/s。 缺口的倍数同样是 20。厂商说的「片内带宽优势 10 倍」讲的是 SRAM 阵列对 HBM 的对比;到 MXM 嘴边的这一段,是 18.4 TB/s 的量级。

4.4 把一层切成约 430 块:块级账

MXM 一次只装 409,600 个权重,所以一层 176,160,768 个权重必须分块:

Nblock=PFFNRMAC=176,160,768409,600=430.08 块N_{\mathrm{block}} = \frac{P_{\mathrm{FFN}}}{R_{\mathrm{MAC}}} = \frac{176{,}160{,}768}{409{,}600} = 430.08\ \text{块}

即约 430 个满块当量(实际分块还含尾块与填充,尾块不满时也按一块计)。

这个数撞上了另一个数字:一层每 token 的算力周期 Ccomp=430.1C_{\mathrm{comp}} = 430.1。这不是巧合——因为一个 token 在每个块上的乘加次数恰好等于块内权重数(409,600 次乘加 = 819,200 次运算 = 一个周期的峰值运算量),所以「满块当量」与「每 token 的算力周期数」在数值上相等:每块每 token 正好花 1 个周期。

于是单块的账非常简单:

块内动作周期数口径
把 409,600 个 int8 权重装进 4 个平面20(双向理论下界)/ 不到 40(论文含传输延迟的上界)409,600 ÷ 20,480
1 个 token 在这一块上的乘加1819,200 ÷ 819,200
20 个 token 在这一块上的乘加20线性
430 个满块当量合计(B = 20)8,600与 4.3 节的 8,601.6 一致(取整差)

表里有三个「20」,但它们来自不同地方,不能混成一个因果故事:

  • 装载一块要 20 个周期:这是 409,600 ÷ 20,480 的除法结果,属于本文的装载模型;
  • 一个点积在 MXM 里跨 20 个 supercell 级联:这是论文的硬件参数(每个平面 20 个 16×16 supercell);
  • 填平装载与算力所需的批大小也是 20:这是两个下界之比。

它们在数值上相等,是因为 409,600/20,480=320/16=20409{,}600/20{,}480 = 320/16 = 20、而 819,200/(2×20,480)819{,}200/(2\times20{,}480) 也化简成同一个比——同一组硬件常数在不同位置反复出现。但不能仅凭数值相同就推定「批 20 时一定没有气泡」:真正的空泡取决于编译器能否把 20 条互不依赖的点积排进那 20 级流水,这属于排程问题,要实测排程器才能确认。

4.5 换算备忘:把数字钉在周期上

因为周期数与时钟无关、纳秒数随时钟变,本文所有结论都以周期为主单位。下面这张表把关键数字一次列全(时间按 900 MHz):

量周期时间(900 MHz)
一个 MXM 平面的点积延迟2022.2 ns
装满 4 个平面(409,600 权重)20(理论下界)/ 不到 40(论文上界)22.2 / 44.4 ns
一层 FFN 每 token 的算力430.1477.9 ns
一层 FFN 的一次完整装载8,601.69.56 µs
一层 FFN 在批 20 下的单步时间8,601.69.56 µs
一层 FFN 在批 64 下的单步时间27,525.130.58 µs
70B 一层 FFN 的一次完整装载(配置与容量限制见 6.3 节,此行仅列同口径预算)34,406.438.2 µs

五、批量化:把 20 倍差距摊到 B 个 token 上

5.1 权重只在批内搬一次

上面那段账有一个前提:每个 token 单独把权重推一遍。而矩阵乘的批处理恰好能消掉这个前提——同一批权重要和 B 个 token 的激活相乘,权重只需装载一次,MXM 里的乘法器对每个 token 复用。于是总时间变成两个下界的较大者:

T(B)=max⁡(B⋅Ccomp, Cfeed)=max⁡(430.1B, 8,601.6) 周期T(B) = \max\left(B \cdot C_{\mathrm{comp}},\ C_{\mathrm{feed}}\right) = \max\left(430.1B,\ 8{,}601.6\right)\ \text{周期}

令两者相等,得到平衡批大小:

B∗=CfeedCcomp=Rop2Bstream=20B^{*} = \frac{C_{\mathrm{feed}}}{C_{\mathrm{comp}}} = \frac{R_{\mathrm{op}}}{2B_{\mathrm{stream}}} = 20

又是同一个数。20 既是「差距的倍数」,也是「填平差距所需的批大小」——因为两者本来就是同一个比值的两种读法。

批大小 B总周期理想峰值利用率时间(900 MHz)谁在限制
18,601.65.0%9.56 µs搬运(流寄存器 → MXM)
48,601.620.0%9.56 µs搬运
88,601.640.0%9.56 µs搬运
168,601.680.0%9.56 µs搬运
208,601.6100.0%9.56 µs恰好平衡
3213,762.6100.0%15.29 µs算力
6427,525.1100.0%30.58 µs算力
12855,050.2100.0%61.17 µs算力

这张表要读出的不是「批越大越好」,而是在本理想模型内,批 1 到批 20 之间加批不增加单步时间:9.56 微秒能处理 1 个 token,也能处理 20 个。这就是为什么这类机器的 decode 必须靠大批量撑吞吐——它的性价比拐点不在「延迟」,而在「把已经付掉的搬运成本摊薄」。

5.2 为什么这个结论不能直接推到所有模型

B∗=20B^{*}=20 与模型无关,这一点很反直觉,但它依赖两个假设,必须写明:

  1. 一整层的权重确实被搬进 MXM 一次,而不是被切成小片、多次往返。 如果编译器为了配合 409,600 的寄存器容量把权重切块(实际上必然要切,因为 MXM 一次只装 40 万权重,而一层有 1.7 亿),块与块之间仍然各自只搬一次,结论不变。
  2. 搬运与计算可以重叠。 论文的流模型允许生产者—消费者流水,把「装下一块权重」与「算上一块」叠起来。作为对照:若完全不重叠,B = 1 的总时间是两者相加 430.1 + 8,601.6 = 9,031.7 周期,比 8,601.6 多 5%;一般批大小要写成 Tno overlap(B)=430.1B+8,601.6T_{\mathrm{no\,overlap}}(B) = 430.1B + 8{,}601.6,此式下不存在与前文同义的「平衡点」,本文不沿用那个概念。

真正会改变结论的是激活流量被忽略这件事。一个 token 的中间激活是 14,336 个元素,int8 下约 14 KB,相对 176 MB 的权重可以忽略;但当 batch 到几百、上下文很长时,KV cache 与激活的读写会挤占同一条流寄存器通路,那时 20 这个数字要重算。

5.3 把它折成 token/s 会得到什么

一个常见的追问是「那单颗芯片一秒能出多少 token」。按上面的账,假设整模型的权重都驻留在一颗芯片上(这对 8B 不成立,原因见第八节的容量对照行,这里只为给出一个上界),顺序跑 32 层 FFN:

单 token 延迟=32×8,601.6=275,251 周期≈305.8 μs\text{单 token 延迟} = 32 \times 8{,}601.6 = 275{,}251\ \text{周期} \approx 305.8\ \mu s

按批 20 摊:一份 275,251 周期的时间产出 20 个 token,折合约 65,400 token/s。这个数的口径必须写全:32 层、仅 FFN、批 20、900 MHz、假设权重全部驻留单芯片的聚合吞吐上界,不是单请求生成速度,也不是端到端服务指标。它与线上实测之间的落差来自四处:模型装不下一颗芯片(要切几十颗、引入片间通信)、LM head 与 attention 也要时间、真实服务里批大小经常到不了 20、以及启动收尾与调度开销。上界与实测之间的落差,正好标出了这篇账没有覆盖的边界。

5.4 时间线长什么样

图 2 画的是批大小 20 时,一层 FFN 在时间轴上的稳态形状:前 8,602 个周期,MXM 一边装权重一边算,权重走完时 20 个 token 的乘加也刚做完。

sequenceDiagram
    participant C as 编译器排程(编译期)
    participant M as MEM 切片
    participant X as MXM 4 平面
    participant V as VXM

    C->>M: 第 0 周期:下发权重装载(每方向 32 条流 × 320 字节)
    M->>X: 每 20 周期装满 4 个平面合计 409,600 权重
    C->>X: 第 20 周期起:token 点积进入流水(每周期一组)
    X->>V: 第 20 周期起:激活下泄(延迟 20 周期)
    V->>X: 每周期回送门控乘积
    Note over M,X: 8,602 周期:整层权重走完
    Note over X,V: 稳态下界:20 token × 430 周期 ≈ 8,600 周期
    M->>C: 无仲裁、无缓存、无重放:时刻由编译期固定

这张图是稳态下界示意,不是完整逐周期排程:它只画装载与算力两条带在理想重叠下的相对长度(约 20 比 1),启动与收尾未计入前述下界,7.4 节会把启动、下泄、收尾单独摆出来。

六、容量的反向账:230 MB 到底装得下什么

前面说「一层 FFN 占 76.4%」,这只是最省的一种用法。真实的部署要同时装三样东西:权重、这一层的 KV cache、指令文本。

6.1 一层 FFN + 这一层的 KV

Llama-3-8B 用 8 个 KV 头、每头 128 维,每个 token 每层的 KV 是:

KVtoken,layer=2×8×128×1 字节=2,048 字节\text{KV}_{\text{token,layer}} = 2 \times 8 \times 128 \times 1\ \text{字节} = 2{,}048\ \text{字节}

(int8;fp16 则翻倍到 4,096 字节。)按剩余 54,525,952 字节算:

54,525,9522,048=26,624 个 token\frac{54{,}525{,}952}{2{,}048} = 26{,}624\ \text{个 token}

这个数的口径要说清三件事:它是「仅按剩余 SRAM 估算的 KV token 容量」,不是模型支持的上下文上限;它是按层分片(每颗芯片只存自己那一层)时的数;批内各序列共享这份容量,还要再扣指令、激活与其他驻留。同一条剩余空间,如果按「整模型 32 层 KV 全集中在一颗芯片」算,只有 54,525,95232×2,048=832\frac{54{,}525{,}952}{32 \times 2{,}048} = 832 个 token(见 6.2 节)。两种切法差 32 倍。

也就是说,一层一芯片的按层流水,是这类机器把 220 MiB 用出 2.6 万 token 量级 KV 余量的前提;丢掉这个前提,同一个容量只能算 800 出头。

6.2 如果按「整模型 KV 都放一颗芯片」算,结论完全不同

54,525,95232×2,048=832 个 token\frac{54{,}525{,}952}{32 \times 2{,}048} = 832\ \text{个 token}

同一个容量,两种切法差 32 倍。 这是本文特意摆出来的口径陷阱:谈「SRAM 装得下多长上下文」时,必须先说清 KV 是按层分片还是整模型集中;把 832 当成这类机器的上下文能力,是把按层流水的前提丢掉后算出来的假数。

6.3 换成一个 70B 模型的 FFN

Llama-3-70B 的配置是 hidden 8192、intermediate 28672,一层 FFN 的权重是:

PFFN70B=3×8192×28672=704,643,072P_{\mathrm{FFN}}^{70B} = 3 \times 8192 \times 28672 = 704{,}643{,}072

int8 下 704.6 MB,是 230.7 MB 的 3.05 倍,至少 4 颗芯片才干得完一层 FFN 的权重。而按上面的推导,它的算力周期是 1,720、搬运周期是 34,406,比值还是 20——模型放大 4 倍,账的形状一点没变,因为 20 这个数只由机器决定。这也是为什么这类架构的扩展方式是「往横向加芯片、把权重切细」,而不是「让单芯片装更大的模型」:单芯片装不下是容量问题,装下了也还是 20 倍搬运问题。

七、静态排程的代价:编译器必须满足的逐周期对齐约束

到这里,答案的前两半(算力、带宽)已经清楚了。第三半「静态排程谁卡住谁」需要换一个角度看:在这台机器上,时间不是「跑出来的」,是「编出来的」。

7.1 硬件里没有能「等一等」的东西

论文的架构选择是把仲裁器和缓存全部去掉:功能切片之间的同步靠 Sync/Notify 指令做一次全局屏障,之后靠流寄存器按固定时刻传递数据,程序正确性用一个简单的时间模型推导。这句话的工程含义很重:

  • GPU 上「访存延迟被缓存的并发掩盖」这件事不存在。这里没有缓存,SRAM 是显式编址的暂存。
  • 「某个单元忙了,指令等一等」也不存在。没有仲裁器,就没有重排。
  • 于是每一条指令的延迟都是编译期已知的常量,唯一能插入的就是 NOP:论文明确说重复 NOP 指令让编译器能做逐周期控制,比如 OpA NOP(N) OpB 就是「A 与 B 之间精确隔 N 个周期」。

7.2 三个具体的周期常量

要排一层 FFN 的流水,编译器得把下面三件事对上:

  1. 一条 MXM 指令要跨 20 个 supercell 级联。每个平面由 20 个 16×16 的 supercell 组成,每个 supercell 每周期产出一个部分和传给相邻的 supercell,所以一个 320 元素的点积延迟是 20 个周期。流水线可以让新的一组点积每周期进入,但在飞的点积要有 20 组,否则 MXM 的空转周期无法被别的活填上。
  2. 指令在一个切片里要「北向流」20 个周期才走完 20 个 tile,操作数与结果因此出现 1 个周期一格的「空间错位」(论文称为 stagger)。编译器必须让操作数到达时刻与这条错位对齐——对不齐不是变慢,是算错。
  3. 144 条指令队列每周期都得有指令。论文的原话是要让「指令队列永不空」,否则「逻辑时间」在芯片上就不再统一。这意味着空闲的切片也得喂 NOP:空转是有明确周期成本的,而且这个成本写在程序里,不出现在任何性能计数器上。

把这三条合起来看,「静态排程谁卡住谁」的答案是:它不卡峰值,它卡的是弹性。算力与带宽定下了 20 这个比值,静态排程决定了这 20 倍里的每一格都要由编译器提前填好——填不满就是浪费,填错了就是错误结果,没有第三种状态。

7.3 排程约束示意:一层 FFN 要同时满足什么

按批 20、一层 FFN 来排,编译器要同时对上的几股流量大致是这样(本文自行推导,仅示数量级与约束类型):

  • MXM 侧:每个 supercell 每周期要 16 条流 × 16 字节 = 256 个 int8 权重,一个平面 20 个 supercell 就是 5,120 字节/周期,4 个平面合计 20,480 字节/周期——正好等于双向流寄存器的峰值。这也是为什么 4.3 节把它当分母:它是理论上限,不是留有余量的带宽。
  • VXM 侧:每个 token 的 14,336 个中间元素要做 SiLU 与逐元素乘,4×4 ALU 网格按 lane 并行;这部分被压在 MXM 下泄的 20 周期延迟之后,编译器要让它与下一块权重的装载重叠。
  • 写回侧:down 矩阵的结果是 4,096 个数,走 SRAM 写通道,与权重读通道争同一批 bank——论文提到最多 176 路 bank 并发,编译器要靠暴露 bank 位来避开冲突。

这三条如果有一条对不上,表现不是「慢了 20%」,而是要么多出成片的 NOP(浪费),要么数据错位(错)。这就是确定性架构的取舍:把「运行期的随机」换成「编译期的责任」。

7.4 一个块在时间轴上长什么样

把 4.4 节的块级账画成排程,大致是这样(示意,非论文给出的实测排程;周期数以 900 MHz、双向流为准):

周期区间MXM 在做什么流寄存器在做什么编译器必须保证
0–19装满 4 个平面的 409,600 权重32 条流双向全开,每周期 20,480 字节队列不空,装载指令按 20 周期错位对齐
20–39第 1 个 token 的点积在 20 级 supercell 中下泄开始装下一块权重的前半操作数到达时刻与级联深度对齐
20–39(并行)第 2–20 个 token 陆续进入同一批权重不重复搬累加器在每个 token 上独立复位
40–59本块 20 个 token 收尾,下一块已就位无缝切换到下一块块间无气泡:一格的 NOP 都算过
约 430 个满块当量一层结束,写回 4,096 个 down 结果与写回通道争 bank暴露 bank 位避冲突

这张表里的启动段与收尾段,都不在 4.3 / 5.1 那两个下界里:下界只算「权重走完」的那段时间,而真实排程还要付第一块的预热与最后一块的排空。所以 8,601.6 是账的下沿,不是实测值。

这张表要说明的是「静态排程的成本长在哪里」:GPU 上这些对齐由硬件动态完成,编译器可以粗糙;这里每一个错位都要在程序里写出来,写漏了就错,写多了就是空泡。所以同一份模型,在两台机器上编译出来的「指令数」不是一个量级的事——LPU 的程序里包含了本该由硬件承担的那部分调度信息。

八、和 GPU 摆在一起:为什么「平衡点」这个数才是架构差异

同样的算法,放到 H100 SXM 上,账会变成另一个形状。按 NVIDIA 公开规格:int8 Tensor Core 稠密 1,979 TOPS(带稀疏 3,958)、HBM3 80 GB、带宽 3.35 TB/s。

平衡点H100=1,979×10123.35×1012≈591 op/字节\text{平衡点}_{\text{H100}} = \frac{1{,}979\times10^{12}}{3.35\times10^{12}} \approx 591\ \text{op/字节}

(若用带稀疏的 3,958 TOPS,则是 1,181 op/字节。)

而 LPU 按前面推导是 40 op/字节。两者差约 15 倍,含义也相反:平衡点越低,越容易被批量化满足。

下面的表要先说一句前提:LPU 的流寄存器与 H100 的 HBM 不在同一个存储层级,两列数字来自不同层级、不同来源,本表是「在所选带宽上限下」的简化对照,不是到矩阵单元的实测供给对照。

维度单颗 LPU(第一代 TSP)单张 H100 SXM说明
int8 峰值约 737 TOPS(4 阵列 × 900 MHz 推导)/ 820 TeraOps/s(论文按 1 GHz 报的峰值)1,979 TOPS(稠密)口径已在 3.1 节说明
片内/板上存储220 MiB SRAM,全片上80 GB HBM3,板外差约 350 倍容量
本文选用的带宽上限(存储层级不同)约 18.4 TB/s(流寄存器口径,900 MHz)3.35 TB/s(HBM 铭牌)差约 5.5 倍,不可直接当同类指标
算术强度平衡点40 op/字节591 op/字节差约 15 倍
吃满算力所需批大小(int8 权重流,2 op/字节)约 20约 295同一个公式,两种机器
容量能装下的模型一层 FFN(176 MB)+该层 KV整个 8B 模型(int8 约 8 GB)架构取向不同

这张表要说明的是一件常被说反的事:LPU 的「带宽优势」不是因为它比 GPU 的带宽绝对值大得多,而是因为它的平衡点低到 40,而 int8 权重流的强度是 2——所以它只需要批 20 就能把搬运摊平;GPU 的平衡点 591,同样 2 op/字节的权重流要批到近 300 才能摊平。 反过来说,GPU 的容量优势让它能一次装下整个模型、用大 batch 摊平访存;LPU 的容量劣势逼它把模型切成很多片、按层流水,用芯片数换容量。两条路都能到「算力打满」,代价不同:一个付容量,一个付并发。

顺带说一句论文里的实测锚点,用来校准「这些账靠不靠谱」:ResNet50、批大小 1、单张图推理不到 49 微秒、折合每秒 20.4K 张。一个 batch-1 的卷积网络能跑出这个数,正说明在小 batch 下把搬运压到极致的做法是有效的——但那是卷积,权重小、复用高,与本文这层 176 MB 的 FFN 不是一回事。

九、三个常见的误算

这三个错法都是在同一处踩空:把「铭牌」当成「到功能单元那一段」的带宽,或者把不同时钟、不同精度的数字混在一张表里。列出来供对照。

9.1 误算一:用 80 TB/s 算一层权重的搬运,得出「只差 4.6 倍」

按铭牌,176.2 MB ÷ 80 TB/s = 2.20 微秒;算力侧 352.3 Mops ÷ 737 TOPS = 0.48 微秒;两者比 4.6,于是结论变成「搬运是算力的 4.6 倍」。这个结论推导上有两处错:

  • 80 TB/s 是另一个来源(2025 年厂商博客)对 SRAM 阵列的铭牌说法,不是流寄存器到 MXM 那一段的带宽;两者的口径差别已在 3.2 节说明,且不能确认是同一代产品。
  • 它还会让读者以为「提高存储带宽就能提高吞吐」。寄存器容量决定必须分块,装载路径的吞吐决定分块要花多久——这两件事不能互相替代:即使供给再宽,MXM 每次也只认 409,600 个权重,权重仍然要按块反复装入。
  • 正确的分母是 20,480 字节/周期(18.4 TB/s),正确的比值是 20,而不是 4.6。

9.2 误算二:拿 fp16 的权重流量套 int8 的周期数

论文的 MXM 用两个 320×320 的 byte-plane 并联来支持 fp16,这意味着 fp16 下同一层权重的字节数翻倍,装载周期从 8,601.6 变成 17,203.2,平衡批大小从 20 变成 40。把「20」这个数直接搬到 fp16 部署上,会把所需批大小低估一半——而批大小恰恰是这类机器最贵的资源之一。

同理,拿「参数个数」当「字节数」在 fp16 下会低估一倍流量;拿「int8 权重 176 MB」去和「fp16 显存 16 GB」比较模型能不能装下,也是两套口径。

9.3 误算三:把一层 FFN 的 9.56 微秒当成单步延迟

本文算的 9.56 微秒是一层 FFN、批 1、理想流水的时间,不含 attention、不含 LM head、不含 KV 读写、不含片间通信。Llama-3-8B 的 LM head 是 128,256 × 4096 = 525,336,576 个权重,约为该层 FFN 的 3 倍;把它漏掉,整机单步延迟会被低估一大截。同理,按层切到几十颗芯片后,片间的 3.84 Tb/s(16×4 条 30 Gbps 链路、双向合计)会成为新的窄路,那笔账本文没有做。

一句话总结这三个错法:先问「这个带宽是到哪一段的」,再问「这个时钟是哪一档的」,最后问「这个数含了哪些部分」。 三问都答清了,账才对得上。

十、边界、未解与我不确定的地方

写清边界比结论更重要,这一节列的都是会改变上面数字的地方:

  1. 只算了一层 FFN 的一次 decode 步。 没算 attention(它的权重小但激活依赖上下文长度)、没算 LM head(Llama-3-8B 的词表 128,256 × 4096 = 525,336,576 个权重,约为该层 FFN 的 3 倍)、没算 KV 读写与写回带宽的争用。
  2. 时钟口径。 论文摘要写 900 MHz 标称,正文另有一句「为便于说明假设 1 GHz」,讨论节的 820 TeraOps/s 是按 1 GHz 算的。本文一律取 900 MHz;若按 1 GHz,所有微秒数缩小 10%,周期数不变。
  3. 80 TB/s 与论文式 2 不能在同一模型里合并(要么时钟是 1.42 GHz,要么代际/统计口径不同),本文没有把 80 TB/s 用于任何推导,也没有断言差异来源。厂商博客里「GPU 的 HBM 约 8 TB/s」同样是厂商对比口径,不是特定型号规格;本文对照表用的是 NVIDIA 官网的 3.35 TB/s。
  4. 「不到 40 周期」是含传输延迟的工程上界,不是实测均值;20 周期是纯传输下界。真实编译器能达到多少,取决于 bank 冲突与指令队列占用,公开材料没给这个数。
  5. 权重分块的真实开销未知。 一层 1.7 亿权重要切成约 430 个满块当量(每块 40 万)才能过 MXM,块间的流调度、累加器复位、跨块的部分和驻留,公开论文没给逐项周期。本文的 8,601.6 是「无额外开销」的理想下界。
  6. int8 只是算例。 论文的 MXM 同时支持 int8 与 fp16(fp16 用两个 byte-plane 并联),fp16 下权重流量翻倍,20 这个比值变成 40——结论方向不变,数字要重算。
  7. 多芯片的那部分账本文没做。 单芯片内部的偏置是 20 倍搬运;一旦按层切到几十颗芯片上,片间链路(16 × 4 条 30 Gbps 链路、双向合计 3.84 Tb/s)就成为新的窄路,那笔账要单独算。
  8. 静态排程的收益本文没有量化。 「无仲裁、无缓存」带来的确定性优势(可预测、无抖动)是真的,但本文只算了它的代价(每格都要对齐),没有算它省下的调度开销——那需要同一模型在两种硬件上的实测对比,公开材料里我没有找到可比的数字。

十一、小结:三句话与一条判断规则

第一句:在本文这个批 1 算例里,算力不是第一个撞墙的。 一层 176 MB 的 FFN 只需要 430 个周期就算完,但要把权重喂进去要 8,602 个周期。

第二句:在本文口径下,真正的窄路是 SRAM 到 MXM 那 2 万字节/周期,不是 SRAM 的铭牌带宽。 存储阵列能给 56,320 字节/周期,流寄存器只收 20,480,而要让 4 个 MXM 吃满,每周期需要 409,600 字节的权重。这三个数不是同一口径,不能混用;混用的后果是相差 3 倍以上。

第三句:在本文 int8、权重单次装载与所选带宽口径下,20 这个倍数是机器的常数,不是模型的属性。 因为它是「每周期运算数 ÷(每周期字节数 × 权重强度)」,模型规模在分子分母里被约掉了。模型放大到 70B,账的形状不变,只是要多切 4 颗芯片。

一条可以带走的判断规则:看到「片内带宽 80 TB/s」这类数字时,先问一句「到矩阵单元的最后一公里有多宽」。 存储容量决定你装得下什么,流带宽决定你喂得进什么,寄存器容量决定你要重复喂多少次。这类机器的故事是后两项写成的,而它对外讲的是第一项。

📋 来源与核验记录

以下来源均为本轮真实打开的页面或 PDF,核验时点 2026-10-23(北京时间)。凡标了章节 / 式号 / 页面的,都是按该定位逐条比对过的。

  1. Dennis Abts 等,《Think Fast: A Tensor Streaming Processor (TSP) for Accelerating Deep Learning Workloads》,ISCA 2020,pp. 145–158,DOI 10.1109/ISCA45697.2020.00023。全文 PDF(10 页)https://groq.com/isca-2020-conference ——本文引用并逐条比对过的位置:摘要(标称 900 MHz、25×29 mm、14nm、ResNet50 20.4K IPS);第三节 C 的特性清单(220 MiB、44 切片/半球、每切片 2.5 MiB、88 切片、每切片 20 tile × 16 lane、maxVL 320、144 条指令队列、64 条逻辑流 32 东 32 西、2 方向 × 32 字节/lane × 320 lane);第三节 B(式 2:2 半球 × 44 切片 × 2 bank × 320 字节/周期,含 1 GHz 说明性假设、Ifetch 640 字节、176 路 bank 并发、指令北向 20 周期、NOP 逐周期控制);第三节 D(4 个 320×320 平面、每平面 20 个 16×16 supercell、每 supercell 每周期 16 流 × 16 字节 = 256 权重、每方向 32 条流装全部 409,600 权重「不到 40 周期(含 SRAM 与片上网络传输延迟)」);第六节讨论(第一代 TSP 在 1 GHz 下 820 TeraOps/s、26.8B 晶体管);C2C(16 × 4 条 30 Gbps 链路、双向 3.84 Tb/s)。
  2. Groq 官方博客《What is a Language Processing Unit?》,2025-03-07,https://groq.com/blog/the-groq-lpu-explained ——引用的「片内 SRAM 带宽高达 80 TB/s」「GPU 的 HBM 约 8 TB/s」「确定性:每个执行步可预测到时钟周期」「无仲裁、无缓存的汇编线式架构」出自此文,均为厂商口径;该文发表于 2025 年,本文没有用它证明第一代 TSP 的具体参数。
  3. NVIDIA H100 Tensor Core GPU 官方规格页,https://www.nvidia.com/en-us/data-center/h100/ ——int8 Tensor Core 3,958 TOPS(带稀疏)/ 稠密 1,979 TOPS、FP16 1,979 teraFLOPS(带稀疏)、80 GB、3.35 TB/s、H100 NVL 94 GB / 3.9 TB/s 出自此页;稀疏标记按页面星号注记理解。
  4. Meta Llama 3 8B 模型配置(NousResearch 公开镜像,读取时为 main 分支的原始 config.json),https://huggingface.co/NousResearch/Meta-Llama-3-8B/raw/main/config.json ——hidden_size 4096、intermediate_size 14336、num_hidden_layers 32、num_attention_heads 32、num_key_value_heads 8、vocab_size 128256、hidden_act silu。镜像只作配置字段来源,不代表原始模型以 int8 发布。
  5. Meta Llama 3 70B 模型配置(同一镜像路径),https://huggingface.co/NousResearch/Meta-Llama-3-70B/raw/main/config.json ——用于本文第 6.3 节的 hidden 8192 / intermediate 28672 取值;同样只作字段来源。

本文自行推导(与上述官方数字分列,公式与假设见正文):

  • 每周期 409,600 次乘加、819,200 次运算:由 4 × 320² 与「一次乘加两次运算」得出;按 1 GHz 折算即 819.2 TeraOps/s,与论文的 820 TeraOps/s 互相印证。
  • 一层 Llama-3-8B FFN 权重 176,160,768 个(3 × 4096 × 14336),int8 占 176.2 MB,占 220 MiB(230,686,720 字节)的 76.4%,剩余 54,525,952 字节(54.5 MB / 52.0 MiB)。
  • 算力周期 430.1、搬运周期 8,601.6(双向)/17,203.2(单向)、比值 20.0,以及平衡批大小 20:假设权重在批内只搬一次、搬运与计算理想重叠。
  • 平衡点 40 op/字节与 591 op/字节(H100 稠密 int8):按各自的「每周期运算数 ÷ 每周期字节数」得出,未计入缓存复用与稀疏。
  • 80 TB/s 折算出的每周期 80,000 字节(1 GHz)/88,889 字节(900 MHz)与等效频率 1.42 GHz:只用于说明跨来源口径不能直接合并,不作为推导输入,也不代表已确认的产品工作时钟。
  • KV 每 token 每层 2,048 字节(int8);剩余 54,525,952 字节按层分片可容 26,624 个 token、整模型 KV 集中可容 832 个 token——两种切法的对照,均不含指令、激活与其他驻留。
  • 70B 一层 FFN 704,643,072 个权重(704.6 MB,为 230.7 MB 的 3.05 倍)、需 4 颗芯片、算力 1,720 周期、搬运 34,406 周期、比值仍为 20。
  • 批大小 1/4/8/16/20/32/64/128 的总周期与理想峰值利用率表:按 T(B) = max(430.1B, 8601.6) 计算。
  • 32 层仅 FFN、批 20 的聚合吞吐上界约 65,400 token/s:假设权重全驻留单芯片,非单请求生成速度。
  • LM head 权重 128,256 × 4096 = 525,336,576 个(约为该层 FFN 的 3 倍)。