一次 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 个权重所以必须分块重搬,静态排程把「每一个错位」都变成编译器必须满足的逐周期对齐约束。以上均为理想下界(批内权重只搬一次、搬运与计算理想重叠、不计其他流量与启动收尾),不是实测延迟。
除另行标注外,本文引用的外部事实与页面核验均以 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 为十进制(、),MiB 为二进制();int8 权重按 1 字节/权重计;周期数与时钟无关,纳秒数一律按 900 MHz 折算。
三个容易混掉的带宽口径先摆在一起,后文一律按此使用:
- 56,320 字节/周期:论文式 2 的 SRAM 阵列聚合口径,本文只用来算「一次完整装载在存储侧要占多少」。
- 20,480 字节/周期:论文式 1 的流寄存器口径(东西两向合计),本文所有搬运周期都用它做分母;单向为它的一半,10,240 字节/周期。
- 80 TB/s:2025 年厂商博客对片内 SRAM 的相对量级说法,不是本文的逐周期输入,也不能用来证明第一代 TSP 的参数;本文只在「三个常见误算」里引用它。
| 符号 | 含义 | 取值 / 单位 | 来源 |
|---|---|---|---|
| 一层 FFN 的权重个数(SwiGLU 三矩阵) | 176,160,768 个 | 本文自行推导(按 4096/14336 配置) | |
| 每个 MXM 平面的乘加阵列边长 | 320 | ISCA 2020 | |
| MXM 平面数 | 4 | ISCA 2020 | |
| 每周期可完成的 int8 乘加次数 | 409,600 | 本文自行推导() | |
| 每周期可完成的运算次数(1 次乘加 = 2 次运算) | 819,200 | 本文自行推导 | |
| 片内流寄存器的双向合计理论峰值(东西两向相加) | 20,480 字节/周期 | 本文自行推导(,对应论文式 1) | |
| 片内 SRAM 阵列的聚合读写带宽 | 56,320 字节/周期 | 本文自行推导(对应论文式 2) | |
| 一次 decode 步里同时处理的 token 数(批大小) | 条 | — | |
| 一层 FFN 每 token 的算力周期数 | 430.1 周期 | 本文自行推导 | |
| 一层 FFN 权重的一次完整搬运周期数 | 8,601.6 周期 | 本文自行推导 | |
| 静态排程 | 指令的执行时刻在编译期全部确定,运行期无仲裁、无缓存、无重放 | — | ISCA 2020 |
| MXM / VXM / MEM | 矩阵执行模块 / 向量执行模块 / 内存切片 | — | ISCA 2020 |
| lane(通道) | 片内并行的数据通道,一条 lane 每周期走 1 个字节的流数据 | 320 条 | ISCA 2020 |
| supercell(计算子阵列) | MXM 内的 16×16 乘加单元,每周期算一个部分和并传给相邻单元 | 16×16 | ISCA 2020 |
| tile(切片内空间单元) | 功能切片内纵向排列的计算单元,一个切片 20 个 | 20 个/切片 | ISCA 2020 |
| 超车道(superlane) | 16 条 lane 构成的横截面,芯片最小计算颗粒 | 16 元素 | ISCA 2020 |
两个词要分清:「流寄存器带宽」是 SRAM 到功能单元那一段的上限,「SRAM 带宽」是存储阵列自己的上限,前者比后者窄得多。混着用就会得出「搬 176 MB 只要 2.2 微秒」这种在同一模型里根本对不上的结论。
三、一个周期能买什么:把论文数字译成周期
3.1 算力:一个周期 409,600 次乘加
论文给出的 MXM 是 4 个独立的 乘加平面,每个平面每周期产出一组新的 int32 点积。所以每周期能同时进行的乘加次数是:
把「一次乘加算两次运算」算进去:
这个数能不能对上论文自己报的峰值?论文在讨论节写「第一代 Groq TSP(1 GHz)峰值 820 TeraOps/s,26.8B 晶体管」。按每周期 819,200 次运算反推:
与论文写明的「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 字节」:
第二条是 流寄存器(stream register)带宽。论文式 1 是「2 个方向 × 每 lane 32 字节 × 320 条 lane」:
第三条是 2025 年厂商博客里的「片内 SRAM 带宽高达 80 TB/s」。三者关系是:
- 只有 的 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()。
于是必须说清一件口径上的事:这两个数来自不同来源(2020 年的会议论文 vs 2025 年的厂商博客),不能让它们在同一个每周期模型里直接合并。 仅凭我打开的这些材料,无法判定差异来自时钟、产品代际,还是「带宽」的统计范围(例如是否把多端口、多 bank 的并行度都算了进去)。所以本文的处理是:用论文的每周期口径算流水,80 TB/s 只当作「厂商宣称的量级」,不参与任何推导;上面那个 1.42 GHz 是反推等效频率,不是已确认的工作时钟。
把一个来源的算力除以另一个来源的带宽,得到的「平衡点」是假的——这是本文在方法上最想说的一句话。
3.3 用论文自己的锚点校验装载速率
论文里有一个很硬的锚点:「用上每个方向全部 32 条流,可以把 409,600 个权重全部装进 4 个 320×320 阵列,含 SRAM 读取与片上网状传输延迟,用不到 40 个周期」。
409,600 个 int8 权重在论文式 1 的双向峰值下,纯传输下界是:
也就是说,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 能装多少权重」时容易忘掉另外两个占用者,它们都走同一条通道:
- 指令文本。论文把片内存储描述为「参数与指令文本」共用,所有功能切片都从同一条流里取指令;一条 Ifetch 一次拉 640 字节(两条 320 字节向量的宽度)。一层 FFN 的指令量公开材料没有给,但它是与权重争 SRAM 与流带宽的第三份账。
- 中间激活与写回。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)——权重个数为:
int8 量化下占 176,160,768 字节 = 176.2 MB。对照 220 MiB = 230,686,720 字节 ≈ 230.7 MB 的片内 SRAM:
剩余 230,686,720 − 176,160,768 = 54,525,952 字节 ≈ 54.5 MB(52.0 MiB)。所以「单颗 LPU 跑一层 FFN」在容量上是成立的,这正是题目成立的前提。
4.2 算力侧:430 个周期
decode 一步只处理一个 token,FFN 的乘加次数等于权重个数(每个权重参与一次乘加),运算次数翻倍:
按 900 MHz 折算,477.9 纳秒。一个 token 穿过一层 FFN 的算力时间不到半微秒——如果世界到此为止,这台机器就是完美的。
4.3 搬运侧:8,602 个周期(理想下界)
问题在于 MXM 只能装 409,600 个权重(约 0.4 MB),而这一层有 1.762 亿个。一次 decode 步要把整层推过窄路:
按 900 MHz 折算,9.56 微秒。这是双向流寄存器理论峰值下的时间下界:不含启动收尾、不含其他流量、假设装载与计算理想重叠。若只能用单方向(单向 10,240 字节/周期),这个数翻倍到 17,203 个周期、19.1 微秒。
两者相除:
整 20 倍,而且是个干净的整数——这不是巧合。把两项的表达式写开就看得出来:
权重个数 被约掉了。这意味着:这个 20 倍与模型多大、层多宽无关,它只由这台机器的两个每周期参数决定。换句话说,「每字节能算多少次运算」的门槛是 40 op/字节(),而 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 个权重必须分块:
即约 430 个满块当量(实际分块还含尾块与填充,尾块不满时也按一块计)。
这个数撞上了另一个数字:一层每 token 的算力周期 。这不是巧合——因为一个 token 在每个块上的乘加次数恰好等于块内权重数(409,600 次乘加 = 819,200 次运算 = 一个周期的峰值运算量),所以「满块当量」与「每 token 的算力周期数」在数值上相等:每块每 token 正好花 1 个周期。
于是单块的账非常简单:
| 块内动作 | 周期数 | 口径 |
|---|---|---|
| 把 409,600 个 int8 权重装进 4 个平面 | 20(双向理论下界)/ 不到 40(论文含传输延迟的上界) | 409,600 ÷ 20,480 |
| 1 个 token 在这一块上的乘加 | 1 | 819,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:这是两个下界之比。
它们在数值上相等,是因为 、而 也化简成同一个比——同一组硬件常数在不同位置反复出现。但不能仅凭数值相同就推定「批 20 时一定没有气泡」:真正的空泡取决于编译器能否把 20 条互不依赖的点积排进那 20 级流水,这属于排程问题,要实测排程器才能确认。
4.5 换算备忘:把数字钉在周期上
因为周期数与时钟无关、纳秒数随时钟变,本文所有结论都以周期为主单位。下面这张表把关键数字一次列全(时间按 900 MHz):
| 量 | 周期 | 时间(900 MHz) |
|---|---|---|
| 一个 MXM 平面的点积延迟 | 20 | 22.2 ns |
| 装满 4 个平面(409,600 权重) | 20(理论下界)/ 不到 40(论文上界) | 22.2 / 44.4 ns |
| 一层 FFN 每 token 的算力 | 430.1 | 477.9 ns |
| 一层 FFN 的一次完整装载 | 8,601.6 | 9.56 µs |
| 一层 FFN 在批 20 下的单步时间 | 8,601.6 | 9.56 µs |
| 一层 FFN 在批 64 下的单步时间 | 27,525.1 | 30.58 µs |
| 70B 一层 FFN 的一次完整装载(配置与容量限制见 6.3 节,此行仅列同口径预算) | 34,406.4 | 38.2 µs |
五、批量化:把 20 倍差距摊到 B 个 token 上
5.1 权重只在批内搬一次
上面那段账有一个前提:每个 token 单独把权重推一遍。而矩阵乘的批处理恰好能消掉这个前提——同一批权重要和 B 个 token 的激活相乘,权重只需装载一次,MXM 里的乘法器对每个 token 复用。于是总时间变成两个下界的较大者:
令两者相等,得到平衡批大小:
又是同一个数。20 既是「差距的倍数」,也是「填平差距所需的批大小」——因为两者本来就是同一个比值的两种读法。
| 批大小 B | 总周期 | 理想峰值利用率 | 时间(900 MHz) | 谁在限制 |
|---|---|---|---|---|
| 1 | 8,601.6 | 5.0% | 9.56 µs | 搬运(流寄存器 → MXM) |
| 4 | 8,601.6 | 20.0% | 9.56 µs | 搬运 |
| 8 | 8,601.6 | 40.0% | 9.56 µs | 搬运 |
| 16 | 8,601.6 | 80.0% | 9.56 µs | 搬运 |
| 20 | 8,601.6 | 100.0% | 9.56 µs | 恰好平衡 |
| 32 | 13,762.6 | 100.0% | 15.29 µs | 算力 |
| 64 | 27,525.1 | 100.0% | 30.58 µs | 算力 |
| 128 | 55,050.2 | 100.0% | 61.17 µs | 算力 |
这张表要读出的不是「批越大越好」,而是在本理想模型内,批 1 到批 20 之间加批不增加单步时间:9.56 微秒能处理 1 个 token,也能处理 20 个。这就是为什么这类机器的 decode 必须靠大批量撑吞吐——它的性价比拐点不在「延迟」,而在「把已经付掉的搬运成本摊薄」。
5.2 为什么这个结论不能直接推到所有模型
与模型无关,这一点很反直觉,但它依赖两个假设,必须写明:
- 一整层的权重确实被搬进 MXM 一次,而不是被切成小片、多次往返。 如果编译器为了配合 409,600 的寄存器容量把权重切块(实际上必然要切,因为 MXM 一次只装 40 万权重,而一层有 1.7 亿),块与块之间仍然各自只搬一次,结论不变。
- 搬运与计算可以重叠。 论文的流模型允许生产者—消费者流水,把「装下一块权重」与「算上一块」叠起来。作为对照:若完全不重叠,B = 1 的总时间是两者相加 430.1 + 8,601.6 = 9,031.7 周期,比 8,601.6 多 5%;一般批大小要写成 ,此式下不存在与前文同义的「平衡点」,本文不沿用那个概念。
真正会改变结论的是激活流量被忽略这件事。一个 token 的中间激活是 14,336 个元素,int8 下约 14 KB,相对 176 MB 的权重可以忽略;但当 batch 到几百、上下文很长时,KV cache 与激活的读写会挤占同一条流寄存器通路,那时 20 这个数字要重算。
5.3 把它折成 token/s 会得到什么
一个常见的追问是「那单颗芯片一秒能出多少 token」。按上面的账,假设整模型的权重都驻留在一颗芯片上(这对 8B 不成立,原因见第八节的容量对照行,这里只为给出一个上界),顺序跑 32 层 FFN:
按批 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 是:
(int8;fp16 则翻倍到 4,096 字节。)按剩余 54,525,952 字节算:
这个数的口径要说清三件事:它是「仅按剩余 SRAM 估算的 KV token 容量」,不是模型支持的上下文上限;它是按层分片(每颗芯片只存自己那一层)时的数;批内各序列共享这份容量,还要再扣指令、激活与其他驻留。同一条剩余空间,如果按「整模型 32 层 KV 全集中在一颗芯片」算,只有 个 token(见 6.2 节)。两种切法差 32 倍。
也就是说,一层一芯片的按层流水,是这类机器把 220 MiB 用出 2.6 万 token 量级 KV 余量的前提;丢掉这个前提,同一个容量只能算 800 出头。
6.2 如果按「整模型 KV 都放一颗芯片」算,结论完全不同
同一个容量,两种切法差 32 倍。 这是本文特意摆出来的口径陷阱:谈「SRAM 装得下多长上下文」时,必须先说清 KV 是按层分片还是整模型集中;把 832 当成这类机器的上下文能力,是把按层流水的前提丢掉后算出来的假数。
6.3 换成一个 70B 模型的 FFN
Llama-3-70B 的配置是 hidden 8192、intermediate 28672,一层 FFN 的权重是:
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 的流水,编译器得把下面三件事对上:
- 一条 MXM 指令要跨 20 个 supercell 级联。每个平面由 20 个 16×16 的 supercell 组成,每个 supercell 每周期产出一个部分和传给相邻的 supercell,所以一个 320 元素的点积延迟是 20 个周期。流水线可以让新的一组点积每周期进入,但在飞的点积要有 20 组,否则 MXM 的空转周期无法被别的活填上。
- 指令在一个切片里要「北向流」20 个周期才走完 20 个 tile,操作数与结果因此出现 1 个周期一格的「空间错位」(论文称为 stagger)。编译器必须让操作数到达时刻与这条错位对齐——对不齐不是变慢,是算错。
- 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。
(若用带稀疏的 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 链路、双向合计)会成为新的窄路,那笔账本文没有做。
一句话总结这三个错法:先问「这个带宽是到哪一段的」,再问「这个时钟是哪一档的」,最后问「这个数含了哪些部分」。 三问都答清了,账才对得上。
十、边界、未解与我不确定的地方
写清边界比结论更重要,这一节列的都是会改变上面数字的地方:
- 只算了一层 FFN 的一次 decode 步。 没算 attention(它的权重小但激活依赖上下文长度)、没算 LM head(Llama-3-8B 的词表 128,256 × 4096 = 525,336,576 个权重,约为该层 FFN 的 3 倍)、没算 KV 读写与写回带宽的争用。
- 时钟口径。 论文摘要写 900 MHz 标称,正文另有一句「为便于说明假设 1 GHz」,讨论节的 820 TeraOps/s 是按 1 GHz 算的。本文一律取 900 MHz;若按 1 GHz,所有微秒数缩小 10%,周期数不变。
- 80 TB/s 与论文式 2 不能在同一模型里合并(要么时钟是 1.42 GHz,要么代际/统计口径不同),本文没有把 80 TB/s 用于任何推导,也没有断言差异来源。厂商博客里「GPU 的 HBM 约 8 TB/s」同样是厂商对比口径,不是特定型号规格;本文对照表用的是 NVIDIA 官网的 3.35 TB/s。
- 「不到 40 周期」是含传输延迟的工程上界,不是实测均值;20 周期是纯传输下界。真实编译器能达到多少,取决于 bank 冲突与指令队列占用,公开材料没给这个数。
- 权重分块的真实开销未知。 一层 1.7 亿权重要切成约 430 个满块当量(每块 40 万)才能过 MXM,块间的流调度、累加器复位、跨块的部分和驻留,公开论文没给逐项周期。本文的 8,601.6 是「无额外开销」的理想下界。
- int8 只是算例。 论文的 MXM 同时支持 int8 与 fp16(fp16 用两个 byte-plane 并联),fp16 下权重流量翻倍,20 这个比值变成 40——结论方向不变,数字要重算。
- 多芯片的那部分账本文没做。 单芯片内部的偏置是 20 倍搬运;一旦按层切到几十颗芯片上,片间链路(16 × 4 条 30 Gbps 链路、双向合计 3.84 Tb/s)就成为新的窄路,那笔账要单独算。
- 静态排程的收益本文没有量化。 「无仲裁、无缓存」带来的确定性优势(可预测、无抖动)是真的,但本文只算了它的代价(每格都要对齐),没有算它省下的调度开销——那需要同一模型在两种硬件上的实测对比,公开材料里我没有找到可比的数字。
十一、小结:三句话与一条判断规则
第一句:在本文这个批 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(北京时间)。凡标了章节 / 式号 / 页面的,都是按该定位逐条比对过的。
- 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)。
- 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 的具体参数。
- 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 出自此页;稀疏标记按页面星号注记理解。
- 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 发布。
- 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 倍)。