如何扩展你的模型(2):认识 TPU
中英对照第 2 篇:从一颗 TPU 芯片的内部结构(MXU/VPU/VMEM/HBM)讲到 ICI 互联、机架与 Pod,解释这些硬件事实如何决定了你能训练和部署什么样的模型。左栏原文,右栏译文,配图保留。
本篇属于系列 如何扩展你的模型(How To Scale Your Model) · 第 2 篇
原文:How To Scale Your Model(Google DeepMind,作者 Jacob Austin、Sholto Douglas、Roy Frostig、Anselm Levskaya、Charlie Chen、Sharad Vikram、Federico Lebron、Peter Choy、Vinay Ramasesh、Albert Webson、Reiner Pope)。
本站是中英对照排版:左栏是英文原文,右栏是对应的中文译文。不好直译的术语(roofline、strong scaling、ICI、MXU、KV cache、FSDP、TP 等)保留英文写法;原文配图全部保留。
本文是系列《如何扩展你的模型(How To Scale Your Model)》的第 2 篇,共 13 篇。系列目录。
原文以 MIT 许可证发布,版权归 Google LLC;本译文仅作学习交流之用,如有错漏以原文为准。
You might also enjoy reading the new Section 12 on NVIDIA GPUs!
你可能也会喜欢新写的第 12 节:关于 NVIDIA GPU!
What Is a TPU?
什么是 TPU?
A TPU is basically a compute core that specializes in matrix multiplication (called a TensorCore) attached to a stack of fast memory (called high-bandwidth memory or HBM)[tpu_paper]. Here’s a diagram:
TPU 本质上就是一个专门做矩阵乘法的计算核心(称为 TensorCore),外面接了一堆快速内存(称为高带宽内存,HBM)[tpu_paper]。 下图是一个示意:
You can think of the TensorCore as basically just being a really good matrix multiplication machine, but it has a few other functions worth noting. The TensorCore has three key units:
你可以把 TensorCore 大致理解为一台非常擅长矩阵乘法的机器,但它还有几个值得注意的功能。TensorCore 有三个关键单元:
- The MXU (Matrix Multiply Unit) is the core of the TensorCore. For most TPU generations, it performs one
bf16[8,128] @ bf16[128,128] -> f32[8,128]matrix multiply (TPU v6e (Trillium) has a 256x256 MXU, while all previous generations use 128x128.) every 8 cycles using a systolic array (see Appendix B for details).- This is about
5e13bf16 FLOPs/s per MXU at 1.5GHz on TPU v5e. Most TensorCores have 2 or 4 MXUs, so e.g. the total bf16 FLOPs/s for TPU v5e is2e14. - TPUs also support lower precision matmuls with higher throughput (e.g. each TPU v5e chip can do
4e14int8 OPs/s).
- This is about
- MXU(Matrix Multiply Unit,矩阵乘法单元)是 TensorCore 的核心。对大多数 TPU 世代,它每 8 个周期用脉动阵列完成一次
bf16[8,128] @ bf16[128,128] -> f32[8,128]的矩阵乘法(TPU v6e(Trillium)是 256x256 的 MXU,此前所有世代都是 128x128。)(细节见 附录 B)。- 在 TPU v5e 上,1.5GHz 时每个 MXU 约
5e13bf16 FLOPs/s。大多数 TensorCore 有 2 或 4 个 MXU,例如 TPU v5e 的 bf16 FLOPs/s 合计是2e14。 - TPU 也支持更低精度、吞吐更高的矩阵乘法(例如每块 TPU v5e 芯片能做
4e14int8 OPs/s)。
- 在 TPU v5e 上,1.5GHz 时每个 MXU 约
- The VPU (Vector Processing Unit) performs general mathematical operations like ReLU activations or pointwise addition or multiplication between vectors. Reductions (sums) are also performed here. Appendix A provides more details.
- VMEM (Vector Memory) is an on-chip scratchpad located in the TensorCore, close to the compute units. It is much smaller than HBM (for example, 128 MiB on TPU v5e) but has a much higher bandwidth to the MXU. VMEM operates somewhat like an L1/L2 cache on CPUs but is much larger and programmer-controlled. Data in HBM needs to be copied into VMEM before the TensorCore can do any computation with it.
- VPU(Vector Processing Unit,向量处理单元)执行通用的数学运算,比如 ReLU 激活、向量之间的逐点加/乘。归约(求和)也在这里做。附录 A 有更多细节。
- VMEM(Vector Memory,向量内存)是位于 TensorCore 内、靠近计算单元的片上暂存器。它比 HBM 小得多(例如 TPU v5e 上是 128 MiB),但到 MXU 的带宽高得多。VMEM 的工作方式有点像 CPU 的 L1/L2 cache,但更大且由程序员控制。HBM 里的数据必须先拷进 VMEM,TensorCore 才能拿它做计算。
TPUs are very, very fast at matrix multiplication. It’s mainly what they do and they do it well. TPU v5p, one of the most powerful TPUs to date, can do 2.5e14 bf16 FLOPs / second / core or 5e14 bf16 FLOPs / sec / chip. A single pod of 8960 chips can do 4 bf16 exaFLOPs/s. That’s a lot. That’s one of the most powerful supercomputers in the world. And Google has a lot of them. (TPUs, and their systolic arrays in particular, are such powerful hardware accelerators because matrix multiplication is one of the few algorithms that uses $O(n^3)$ compute for $O(n^2)$ bytes. That makes it very easy for an ordinary ALU to be bottlenecked by compute and not by memory bandwidth.)
TPU 做矩阵乘法非常、非常快。这基本就是它们的工作,而且做得很好。TPU v5p 是迄今最强的 TPU 之一,每核能做 2.5e14 bf16 FLOPs/秒,每芯片 5e14 bf16 FLOPs/秒。一个 8960 芯片的 pod 能做 4 bf16 exaFLOPs/s。那是非常大的算力——属于世界上最强的超级计算机之一。而且 Google 有很多这样的机器。(TPU、尤其是其脉动阵列之所以是强大的硬件加速器,是因为矩阵乘法是为数不多的、用 $O(n^2)$ 字节做 $O(n^3)$ 计算的算法之一。这让普通 ALU 很容易受限于算力而非内存带宽。)
The diagram above also includes a few other components like SMEM and the scalar unit, which are used for control flow handling and are discussed briefly in Appendix A, but aren’t crucial to understand. On the other hand, HBM is important and fairly simple:
上图还包含 SMEM 和标量单元等组件,它们用于控制流处理,附录 A 有简要讨论,但不是必须理解的部分。另一方面,HBM 很重要且相当简单:
- HBM (High Bandwidth Memory) is a big chunk of fast memory that stores tensors for use by the TensorCore. HBM usually has capacity on the order of tens of gigabytes (for example, TPU v5e has 16GiB of HBM).
- HBM(High Bandwidth Memory,高带宽内存)是一大块快速内存,用来存放供 TensorCore 使用的张量。HBM 容量通常在几十 GB 量级(例如 TPU v5e 有 16GiB HBM)。
- When needed for a computation, tensors are streamed out of HBM through VMEM (see below) into the MXU and the result is written from VMEM back to HBM.
- 需要做计算时,张量会经过 VMEM(见下)从 HBM 流进 MXU,结果再从 VMEM 写回 HBM。
- The bandwidth between HBM and the TensorCore (through VMEM) is known as “HBM bandwidth” (usually around 1-2TB/sec) and limits how fast computation can be done in memory-bound workloads.
- HBM 与 TensorCore 之间(经由 VMEM)的带宽称为「HBM 带宽」(通常在 1–2TB/秒 左右),它决定了内存受限型负载中计算能做多快。
Generally, all TPU operations are pipelined and overlapped. To perform a matmul $X \cdot A \to Y$, a TPU would first need to copy chunks of matrices $A$ and $X$ from HBM into VMEM, then load them into the MXU which multiplies chunks of 8x128 (for $X$) and 128x128 (for $A$), then copy the result chunk by chunk back to HBM. To do this efficiently, the matmul is pipelined so the copies to/from VMEM are overlapped with the MXU work. This allows the MXU to continue working instead of waiting on memory transfers, keeping matmuls compute-bound, not memory-bound.
一般来说,TPU 上的所有操作都是流水线化、相互重叠的。 要做一个 matmul $X \cdot A \to Y$,TPU 需要先把矩阵 $A$ 和 $X$ 的块从 HBM 拷进 VMEM,再把它们载入 MXU(MXU 对 $X$ 以 8x128、对 $A$ 以 128x128 为单位做乘法),然后把结果一块块拷回 HBM。为了高效,matmul 是流水线化的:进出 VMEM 的拷贝与 MXU 的计算重叠。这样 MXU 可以持续工作,而不是等内存传输,从而让 matmul 保持计算受限,而不是内存受限。
Here’s an example of how you might perform an elementwise product from HBM:
下面是一个从 HBM 做逐元素乘法的示例:
A matmul would look nearly identical except it would load into the MXU instead of the VPU/Vector unit, and the loads and stores would occur in a different order, since the same weight chunk is used for multiple chunks of activations. You can see chunks of data streaming into VMEM, then into the VREGs (vector registers), then into the Vector Unit, then back into VMEM and HBM. As we’re about to see, if the load from HBM to VMEM is slower than the FLOPs in the Vector Unit (or MXU), we become “bandwidth bound” since we’re starving the VPU or MXU of work.
一个 matmul 看起来几乎一样,只是数据会载入 MXU 而不是 VPU/向量单元,而且读写顺序不同,因为同一块权重会被多块激活复用。你可以看到数据块先流进 VMEM,再进 VREGs(向量寄存器),再进向量单元,然后回到 VMEM 和 HBM。接下来我们就会看到:如果 HBM 到 VMEM 的加载比向量单元(或 MXU)的 FLOPs 更慢,我们就会「带宽受限」,因为 VPU 或 MXU 被饿着了。
Key takeaway: TPUs are very simple. They load weights from HBM into VMEM, then from VMEM into a systolic array which can perform around 200 trillion multiply-adds per second. The HBM $\leftrightarrow$ VMEM and VMEM $\leftrightarrow$ systolic array bandwidths set fundamental limits on what computations TPUs can do efficiently.
关键结论: TPU 非常简单。它们把权重从 HBM 载入 VMEM,再从 VMEM 载入脉动阵列,后者每秒能做大约 200 万亿次乘加。HBM $\leftrightarrow$ VMEM 以及 VMEM $\leftrightarrow$ 脉动阵列的带宽,决定了 TPU 能高效完成哪些计算的根本上限。
VMEM and arithmetic intensity: VMEM is much smaller than HBM but it has a much higher bandwidth to the MXU. As we saw in Section 1, this means if an algorithm can fit all its inputs/outputs in VMEM, it’s much less likely to hit communication bottlenecks. This is particularly helpful when a computation has poor arithmetic intensity: VMEM bandwidth is around 22x higher than HBM bandwidth which means an MXU operation reading from/writing to VMEM requires an arithmetic intensity of only 10-20 to achieve peak FLOPs utilization. That means if we can fit our weights into VMEM instead of HBM, our matrix multiplications can be FLOPs bound at much smaller batch sizes. And it means algorithms that fundamentally have a lower arithmetic intensity can still be efficient. VMEM is just so small this is often a challenge. (We sometimes talk about VMEM prefetching, which refers to loading weights ahead of time in VMEM so we can mask the cost of loading for our matmuls. For instance, in a normal Transformer we can sometimes load our big feed-forward weights into VMEM during attention, which can hide the cost of the weight load if we’re memory bandwidth bound. This requires our weights to be small enough or sharded enough to fit a single layer into VMEM with space to spare.)
VMEM 与算术强度: VMEM 比 HBM 小得多,但到 MXU 的带宽高得多。正如第 1 节所见,这意味着如果一个算法能把所有输入/输出放进 VMEM,它就不太容易撞上通信瓶颈。当一个计算的算术强度很差时,这尤其有帮助:VMEM 带宽约为 HBM 的 22 倍,也就是说,一个从 VMEM 读写的 MXU 操作只要算术强度达到 10–20 就能用满峰值 FLOPs。这意味着,如果我们能把权重放进 VMEM 而不是 HBM,矩阵乘法就能在更小的 batch size 下达到计算受限;也意味着那些算术强度天然较低的算法仍能高效。只是 VMEM 实在太小,这往往是难点。(我们有时会提 VMEM 预取,指的是提前把权重载入 VMEM,以掩盖为 matmul 加载权重的开销。例如在普通 Transformer 里,我们有时能在做 attention 的时候把大的前馈权重载入 VMEM,从而在内存带宽受限时把权重加载的开销藏起来。这要求权重足够小、或分片得足够多,能让一层连同富余空间一起放进 VMEM。)
A TPU chip typically (but not always) consists of two TPU cores which share memory and can be thought of as one large accelerator with twice the FLOPs (known as a “megacore” configuration). This is true for v4, v5, and v6 TPUs (TPU v7 removes megacore and instead has a high-bandwidth link between the two cores). Older TPU chips have separate memory and are regarded as two separate accelerators (TPU v3 and older). Inference-optimized chips like the TPU v5e only have one TPU core per chip.
一块 TPU 芯片通常(但不总是)由两个 TPU core 组成,它们共享内存,可以看作是一个算力翻倍的大加速器(称为「megacore」配置)。v4、v5、v6 的 TPU 都是如此(TPU v7 去掉了 megacore,改为在两个 core 之间提供一条高带宽链路)。更老的 TPU 芯片内存相互独立,被当作两个独立加速器(TPU v3 及更早)。像 TPU v5e 这种为推理优化的芯片,每块只有 1 个 TPU core。
Chips are arranged in sets of 4 on a ‘tray’ connected to a CPU host via PCIe network. This is the format most readers will be familiar with, 4 chips (8 cores, though usually treated as 4 logical megacores) exposed through Colab or a single TPU-VM. For inference chips like the TPU v5e, we have 2 trays per host, instead of 1, but also only 1 core per chip, giving us 8 chips = 8 cores. (On Cloud TPU VMs, each tray is exposed as part of a separate VM, so there are once again 4 cores visible.)
芯片以 4 颗为一组安装在「tray」上,通过 PCIe 网络连接到 CPU host。 这是大多数读者最熟悉的形态:4 颗芯片(8 个 core,但通常当作 4 个逻辑 megacore)通过 Colab 或单个 TPU-VM 暴露出来。对于 TPU v5e 这类推理芯片,每个 host 有 2 个 tray(而非 1 个),但每颗芯片只有 1 个 core,于是 8 颗芯片 = 8 个 core。(在 Cloud TPU VM 上,每个 tray 作为独立 VM 的一部分暴露,所以又是 4 个可见 core。)
PCIe bandwidth is limited: Like the HBM $\leftrightarrow$ VMEM link, the CPU $\leftrightarrow$ HBM PCIe connection has a specific bandwidth that limits how quickly you can load from host memory to HBM or vice-versa. PCIe bandwidth for TPU v4 is 16GB / second each way, for example, so close to 100x slower than HBM. We can load/offload data into the host (CPU) RAM, but not very quickly.
PCIe 带宽有限: 和 HBM $\leftrightarrow$ VMEM 链路一样,CPU $\leftrightarrow$ HBM 的 PCIe 连接也有固定的带宽,限制了从 host 内存加载到 HBM(或反向)的速度。例如 TPU v4 的 PCIe 带宽是每方向 16GB/秒,比 HBM 慢近 100 倍。我们可以把数据载入/卸载到 host(CPU)RAM,但速度不快。
TPU Networking
TPU 组网
Chips are connected to each other through the ICI network in a Pod. In older generations (TPU v2 and TPU v3), inference chips (e.g., TPU v5e), and Trillium (TPU v6e), ICI (“inter-chip interconnects”) connects the 4 nearest neighbors (with edge links to form a 2D torus). TPU v4 and TPU v5p are connected to the nearest 6 neighbors (forming a 3D torus). Note these connections do not go through their hosts, they are direct links between chips.
芯片之间通过 Pod 内的 ICI 网络互连。在更早的世代(TPU v2、TPU v3)、推理芯片(如 TPU v5e)和 Trillium(TPU v6e)中,ICI(inter-chip interconnect,片间互连)连接最近的 4 个邻居(边缘链路构成 2D 环面 torus)。TPU v4 和 TPU v5p 连接最近的 6 个邻居(构成 3D 环面)。注意这些连接不经过各自的 host,而是芯片之间的直连。
The toroidal structure reduces the maximum distance between any two nodes from $N$ to $N / 2$, making communication much faster. TPUs also have a “twisted torus” configuration that wraps the torus in a Mobius-strip like topology to further reduce the average distance between nodes.
环面结构把任意两个节点之间的最大距离从 $N$ 降到 $N / 2$,让通信快得多。TPU 还有一种「twisted torus」配置,把环面以类似莫比乌斯带的方式缠绕,进一步降低节点间的平均距离。
TPU pods (connected by ICI) can get really big: the maximum pod size (called a superpod) is 16x16x16 for TPU v4 and 16x20x28 for TPU v5p. These large pods are composed of reconfigurable cubes of 4x4x4 chips connected by optical wraparound links (The optical switch is simply a reconfigurable connection with the same ICI bandwidth. It just lets us connect cubes while retaining a wraparound link.) that we can reconfigure to connect very large topologies.
由 ICI 连接的 TPU pod 可以非常大: 最大 pod 尺寸(称为 superpod)在 TPU v4 上是 16x16x16,在 TPU v5p 上是 16x20x28。这些大 pod 由可重构的 4x4x4 芯片立方体组成,立方体之间用光学绕回链路连接(光交换只是一个可重构、带宽与 ICI 相同的连接,它让我们在连接立方体的同时保留绕回链路。),从而能拼出非常大的拓扑。
Smaller topologies (e.g. 2x2x1, 2x2x2) can also be requested, albeit with no wraparounds. This is an important caveat, since it typically doubles the time of most communication. Any multiple of a full cube (e.g. 4x4x4 or 4x4x8) will have wraparounds provided by the optical switches. (Note that a 2x2x4 won’t have any wraparounds since they are provided by the optical switches which are only available on a full cube. A TPU v5e 8x16 will have a wraparound on the longer axis, however, since it doesn’t use reconfigurable optical networking.)
也可以申请更小的拓扑(如 2x2x1、2x2x2),但没有绕回(wraparound)。这是个重要注意点:没有绕回通常会让大多数通信时间翻倍。任何完整立方体的倍数(如 4x4x4 或 4x4x8)都能获得光交换提供的绕回。(注意 2x2x4 没有绕回,因为绕回由光交换提供,而光交换只有在完整立方体上才有。不过 TPU v5e 的 8x16 会在较长轴上有绕回,因为它不用可重构光网络。)
TPU v5e and Trillium pods consist of a single 16x16 2D torus with wraparounds along any axis of size 16 (meaning an 8x16 has a wraparound on the long axis). TPUs v5e and v6e (Trillium) cannot expand beyond a 16x16 torus but pods can still communicate with each other over standard data-center networking (DCN), which connects TPU hosts to each other. Again, smaller topologies can be requested without wraps on dims $<16$.
TPU v5e 和 Trillium 的 pod 是单个 16x16 的 2D 环面,任何尺寸为 16 的轴上都有绕回(也就是说 8x16 在长轴上有绕回)。TPU v5e、v6e(Trillium)无法扩展到 16x16 之外,但 pod 之间仍可通过标准数据中心网络(DCN)通信,DCN 连接各 TPU host。同样,小于 16 的维度上申请的更小拓扑没有绕回。
This nearest-neighbor connectivity is a key difference between TPUs and GPUs. GPUs are connected with a hierarchy of switches that approximate a point-to-point connection between every GPU, rather than using local connections like a TPU. Typically, GPUs within a node (8 GPUs for H100 or as many as 72 for B200 NVL72) are directly connected, while larger topologies require O(log(N)) hops between each GPU. On the one hand, that means GPUs can send arbitrary data within a small number of hops. On the other hand, TPUs are dramatically cheaper (since NVLink switches are expensive), simpler to wire together, and can scale to much larger topologies because the number of links per device and the bandwidth per device is constant. Read more here.
这种最近邻连接是 TPU 与 GPU 的关键差别。 GPU 用一层层交换机构成的层级结构,近似实现每块 GPU 之间的点对点连接,而不是像 TPU 那样使用本地连接。通常,一个节点内的 GPU(H100 是 8 块,B200 NVL72 多达 72 块)是直连的,而更大的拓扑需要每块 GPU 之间 O(log(N)) 跳。一方面,这意味着 GPU 能在很少的跳数内发送任意数据;另一方面,TPU 便宜得多(NVLink 交换机很贵)、接线更简单,而且能扩展到非常大的拓扑,因为每台设备的链路数和每台设备的带宽是恒定的。更多内容见这里。
ICI is very fast relative to DCN, but is still slower than HBM bandwidth. For instance, a TPU v5p has:
ICI 相对 DCN 非常快,但仍慢于 HBM 带宽。 例如,一块 TPU v5p 有:
2.8e12bytes/s (2.8 TB/s) of HBM bandwidth per chip.9e10bytes/s (90 GB/s) of ICI bandwidth per axis, with 3 axes per chip. (The page above lists 100 GB/s of bandwidth, which is slightly different from what’s listed here. TPU ICI links have slightly different bandwidths depending on the operation being performed. You can generally use the numbers in this doc without worry.)6.25e9bytes/s (6.25 GB/s) of DCN (egress) bandwidth per TPU (via 1-2 NICs on each host). (TPU v6e and TPU7x have 12.5e9 bytes/s and v5e has 3.125e9 bytes/s.)
- 每芯片
2.8e12bytes/s(2.8 TB/s)的 HBM 带宽。 - 每个轴
9e10bytes/s(90 GB/s)的 ICI 带宽,每芯片 3 个轴。(上面那个页面写的是 100 GB/s,和这里略有出入。TPU ICI 链路的带宽会因执行的操作而略有不同。一般可以直接用本文的数字,不必担心。) - 每 TPU
6.25e9bytes/s(6.25 GB/s)的 DCN(出向)带宽(每个 host 1–2 张 NIC)。(TPU v6e 和 TPU7x 是 12.5e9 bytes/s,v5e 是 3.125e9 bytes/s。)
This means that when we split models across multiple chips, we need to be careful to avoid bottlenecking the MXU with slower cross-device communication.
这意味着,当我们把模型切分到多颗芯片上时,必须小心别让较慢的跨设备通信成为 MXU 的瓶颈。
Multi-slice training: A set of ICI-connected TPUs is called a slice. Different slices can be connected between each other using DCN, for instance to link slices on different pods. Since DCN is a much slower connection than ICI, we should try to limit how much our computation has to wait for data from DCN. DCN is host-to-host, so to transfer buffers from TPU to TPU over DCN, we first need to transfer over PCIe to the host, then egress over the network, then ingress over the target host network, then over PCIe into HBM.
多 slice 训练: 一组由 ICI 连接的 TPU 称为一个 slice。不同 slice 之间可以用 DCN 连接,例如把不同 pod 上的 slice 连起来。由于 DCN 比 ICI 慢得多,我们应尽量减少计算等待 DCN 数据的程度。DCN 是 host 到 host 的,所以要通过 DCN 把 buffer 从一块 TPU 传到另一块,得先经 PCIe 传到 host,再出向进入网络,再入向到目标 host 网络,最后经 PCIe 进入 HBM。
Key Takeaways
关键结论
- TPUs are simple and can in most cases be thought of as a matrix multiply unit connected to memory (super fast), other chips over ICI (rather fast), and the rest of the datacenter over DCN (somewhat fast).
- TPU 很简单,大多数情况下可以把它理解为:一个连着内存(超快)、连着其他芯片的 ICI(相当快)、以及连着数据中心其余部分的 DCN(还算快)的矩阵乘法单元。
- Communication is limited by our various network bandwidths in order of speed:
- HBM bandwidth: Between a TensorCore and its associated HBM.
- ICI bandwidth: Between a TPU chip and its nearest 4 or 6 neighbors.
- PCIe bandwidth: Between a CPU host and its associated tray(s) of chips.
- DCN bandwidth: Between multiple CPU hosts, typically hosts not connected by ICI.
- 通信受限于各级网络带宽,按速度从快到慢:
- HBM 带宽:TensorCore 与其对应 HBM 之间。
- ICI 带宽:一块 TPU 芯片与其最近 4 或 6 个邻居之间。
- PCIe 带宽:一个 CPU host 与其对应的 tray 芯片之间。
- DCN 带宽:多个 CPU host 之间,通常是没有 ICI 相连的 host。
- Within a slice, TPUs are only connected to their nearest neighbors via ICI. This means communication over ICI between distant chips in a slice needs to hop over the intervening chips first.
- 在一个 slice 内,TPU 只通过 ICI 与最近邻居相连。 这意味着 slice 内相距较远的芯片做 ICI 通信时,需要先经过中间的芯片逐跳转发。
- Weight matrices need to be padded to at least size 128 (256 on TPU v6e) in both dimensions to fill up the MXU (in fact, smaller axes are padded to 128).
- 权重矩阵的两个维度都需要填充到至少 128(TPU v6e 上是 256)才能填满 MXU(实际上更小的轴会被填充到 128)。
- Lower precision matrix multiplication tends to be faster. TPUs can do int8 or int4 OPs roughly 2x/4x faster than bfloat16 FLOPs for generations that support it. VPU operations are still performed in fp32.
- 更低精度的矩阵乘法通常更快。 在支持的世代上,TPU 做 int8 或 int4 OP 比 bfloat16 FLOPs 大约快 2 倍/4 倍。VPU 的运算仍以 fp32 执行。
- To avoid bottlenecking the TPU compute unit, we need to make sure the amount of communication across each channel is proportional to its speed.
- 为避免成为 TPU 计算单元的瓶颈,我们需要确保每条通道上的通信量与其速度成正比。
TPU specs
TPU 规格
Here are some specific numbers for our chips:
下面是我们芯片的一些具体数字:
| Model | Pod size | Host size | HBM capacity/chip | HBM BW/chip (bytes/s) | FLOPs/s/chip (bf16) | FLOPs/s/chip (int8) |
|---|---|---|---|---|---|---|
| TPU v3 | 32x32 | 4x2 | 32GB | 9.0e11 | 1.4e14 | 1.4e14 |
| TPU v4p | 16x16x16 | 2x2x1 | 32GB | 1.2e12 | 2.75e14 | 2.75e14 |
| TPU v5p | 16x20x28 | 2x2x1 | 96GB | 2.8e12 | 4.59e14 | 9.18e14 |
| TPU v5e | 16x16 | 4x2 | 16GB | 8.2e11 | 1.97e14 | 3.94e14 |
| TPU v6e | 16x16 | 4x2 | 32GB | 1.6e12 | 9.20e14 | 1.84e15 |
| TPU7x | 4x4x576 | 2x2x1 | 192GB | 7.4e12 | 2.30e15 | 4.61e15 |
| 型号 | Pod 尺寸 | Host 尺寸 | 每芯片 HBM 容量 | 每芯片 HBM 带宽 (bytes/s) | 每芯片 FLOPs/s (bf16) | 每芯片 FLOPs/s (int8) |
|---|---|---|---|---|---|---|
| TPU v3 | 32x32 | 4x2 | 32GB | 9.0e11 | 1.4e14 | 1.4e14 |
| TPU v4p | 16x16x16 | 2x2x1 | 32GB | 1.2e12 | 2.75e14 | 2.75e14 |
| TPU v5p | 16x20x28 | 2x2x1 | 96GB | 2.8e12 | 4.59e14 | 9.18e14 |
| TPU v5e | 16x16 | 4x2 | 16GB | 8.2e11 | 1.97e14 | 3.94e14 |
| TPU v6e | 16x16 | 4x2 | 32GB | 1.6e12 | 9.20e14 | 1.84e15 |
| TPU7x | 4x4x576 | 2x2x1 | 192GB | 7.4e12 | 2.30e15 | 4.61e15 |
Host size refers to the topology of TPUs connected to a single host (e.g. TPU v5e has a single CPU host connected to 8 TPUs in a 4x2 topology). See the TPU7x documentation for more details on the latest generation. Here are interconnect figures:
Host 尺寸指的是连接到单个 host 的 TPU 拓扑(例如 TPU v5e 是单个 CPU host 以 4x2 拓扑连接 8 块 TPU)。最新世代的更多细节见 TPU7x 文档。互连的数字如下:
| Model | ICI BW/link (one-way, bytes/s) | ICI BW/link (bidi, bytes/s) |
|---|---|---|
| TPU v3 | 1.0e11 | 2.0e11 |
| TPU v4p | 4.5e10 | 9.0e10 |
| TPU v5p | 9.0e10 | 1.8e11 |
| TPU v5e | 4.5e10 | 9.0e10 |
| TPU v6e | 9.0e10 | 1.8e11 |
| TPU7x | 9.0e10 | 1.8e11 |
| 型号 | 每链路 ICI 带宽(单向,bytes/s) | 每链路 ICI 带宽(双向,bytes/s) |
|---|---|---|
| TPU v3 | 1.0e11 | 2.0e11 |
| TPU v4p | 4.5e10 | 9.0e10 |
| TPU v5p | 9.0e10 | 1.8e11 |
| TPU v5e | 4.5e10 | 9.0e10 |
| TPU v6e | 9.0e10 | 1.8e11 |
| TPU7x | 9.0e10 | 1.8e11 |
We include both one-way (unidirectional) bandwidth and bidi (bidirectional) bandwidth since unidirectional bandwidth is more true to the hardware but bidirectional bandwidth occurs more often in equations involving a full ring. (By bidi (bidirectional) bandwidth we mean the total bytes that can be sent along a single link in both directions, or equally, the total number of outgoing bytes from a single TPU along a particular axis, assuming we can use both links efficiently. This is true when we have a functioning ring, AKA when we have a wraparound connection on the particular axis. This occurs on inference chips when we have a full 16 axis, or on training chips (v*p) when we have an axis which is a multiple of 4. We prefer to use the bidirectional bandwidth because it appears frequently in calculations involving bidirectional comms.)
我们同时给出单向带宽和双向带宽,因为单向带宽更贴近硬件,而双向带宽更常出现在涉及完整环的公式里。(双向带宽指的是单条链路上两个方向合计可发送的字节数;等价地说,是单块 TPU 沿某一轴出向字节的总数(假设两条链路都能高效使用)。当存在一个正常工作的环(即在对应轴上有绕回连接)时成立;推理芯片在完整的 16 轴、训练芯片(v*p)在轴长为 4 的倍数时满足。我们更常用双向带宽,因为它频繁出现在双向通信的计算中。)
PCIe bandwidth is typically around 1.6e10 bytes / second per TPU (3.2e10 for TPU v6e), while DCN bandwidth is typically around 6.25e9 bytes / second per TPU (12.5e9 for TPU v6e and TPU7x, and 3.125e9 for TPU v5e).
PCIe 带宽通常约为每 TPU 1.6e10 bytes/秒(TPU v6e 是 3.2e10),DCN 带宽通常约为每 TPU 6.25e9 bytes/秒(TPU v6e 和 TPU7x 是 12.5e9,TPU v5e 是 3.125e9)。
Worked Problems
习题演练
These numbers are a little dry, but they let you make basic roofline estimates for model performance. Let’s work a few problems to explain why this is useful. You’ll see more examples in Part 3.
这些数字有点枯燥,但它们能让你对模型性能做基本的 roofline 估计。我们来做几道题说明这有什么用。第 3 部分还有更多例子。
Question 1 [bounding LLM latency]: Say you want to sample from a 200B parameter model in bf16 that’s split across 32 TPU v4p. How long would it take to load all the parameters from HBM into the systolic array? Hint: use the numbers above.
问题 1 [给 LLM 延迟定下界]: 假设你想从一个 bf16 的 200B 参数模型采样,模型分布在 32 块 TPU v4p 上。把所有参数从 HBM 载入脉动阵列要多久?提示:用上面的数字。
Click here for the answer.
点这里看答案。
Answer: We’re loading sizeof(bf16) * 200e9 = 400e9 bytes on 32 chips, meaning 12.5e9 bytes / chip, each with an HBM bandwidth of 1.23e12. So the load takes around 10ms.
答案: 我们要在 32 块芯片上加载 sizeof(bf16) * 200e9 = 400e9 字节,即每芯片 12.5e9 字节,而每芯片 HBM 带宽为 1.23e12。所以加载大约要 10ms。
That’s pretty cool, because that’s a reasonable lower bound on the latency of sampling from the model. Each sampling step needs to load all parameters from HBM, so it cannot take less than 10 ms. In practice, at small batch sizes, this is close to being achievable.
这挺酷的,因为这是从该模型采样延迟的合理下界。每个采样步都要从 HBM 加载全部参数,所以不可能低于 10ms。实践中,小 batch size 下已经接近这个下界。
Question 2 [TPU details]: Consider a full TPU v5e pod. How many total CPU hosts are there? How many TPU TensorCores? What is the total FLOPs/s for the whole pod? What is the total HBM? Do the same exercise for TPU v5p pod.
问题 2 [TPU 细节]: 考虑一个完整的 TPU v5e pod。一共有多少个 CPU host?多少个 TPU TensorCore?整个 pod 的总 FLOPs/s 是多少?总 HBM 是多少?对 TPU v5p pod 做同样的练习。
Click here for the answer.
点这里看答案。
Answer: For TPU v5e, each pod is 16x16 and each host is a 4x2 slice, so we have 16*16 / 8 = 32 hosts. For TPU v5e, each TPU has only one core, so we have 256 TensorCores. The total FLOPs/s is 16*16*2e14 = 5.1e16 in bfloat16. Each chip has 16GB of HBM, so that’s 256 * 16 = 4TB of memory.
答案: 对 TPU v5e,每个 pod 是 16x16,每个 host 是 4x2 的 slice,所以有 16*16 / 8 = 32 个 host。TPU v5e 每块 TPU 只有 1 个 core,所以有 256 个 TensorCore。总 FLOPs/s 是 16*16*2e14 = 5.1e16(bfloat16)。每芯片 16GB HBM,所以是 256 * 16 = 4TB 内存。
For a full TPU v5p pod, we have 16x20x28 chips and each host is 2x2x1, so we have (16*20*28) / (2*2) = 2,240 hosts. For TPU v5p, each TPU has two TensorCores, so we have 8960 * 2 = 17,920 cores. The total FLOPs/s is 8960 * 4.59e14 = 4.1e18 in bfloat16. Each chip has 96GB of HBM, so that’s 8960 * 96 = 860TB of memory.
对完整的 TPU v5p pod,有 16x20x28 颗芯片,每个 host 是 2x2x1,所以有 (16*20*28) / (2*2) = 2,240 个 host。TPU v5p 每块有 2 个 TensorCore,所以有 8960 * 2 = 17,920 个 core。总 FLOPs/s 是 8960 * 4.59e14 = 4.1e18(bfloat16)。每芯片 96GB HBM,所以是 8960 * 96 = 860TB 内存。
Question 3 [PCIe operational intensity]: Imagine we’re forced to store a big weight matrix $A$ of type $\text{bf16}[D, F]$, and a batch of activations $x$ of type $\text{bf16}[B, D]$ in host DRAM and want to do a matrix multiplication on them. This is running on a single host, and we’re using a single TPU v6e chip attached to it. You can assume $B \ll D$, and $F = 4D$ (we’ll see in future chapters why these are reasonable assumptions). What is the smallest batch size $B$ we need to remain FLOPs bound over PCIe? Assume PCIe bandwidth of 1.6e10 bytes / second.
问题 3 [PCIe 运算强度]: 假设我们被迫把一个大权重矩阵 $A$(类型 $\text{bf16}[D, F]$)和一批激活 $x$(类型 $\text{bf16}[B, D]$)存放在 host DRAM 里,并想对它们做矩阵乘法。这运行在单个 host 上,使用挂在它上面的一块 TPU v6e 芯片。可假设 $B \ll D$、$F = 4D$(后面章节会解释为什么这些假设合理)。要保持在 PCIe 上计算受限,所需的最小 batch size $B$ 是多少?假设 PCIe 带宽为 1.6e10 bytes/秒。
Click here for the answer.
点这里看答案。
Answer: We have to perform $2BDF$ floating point operations, and each chip can perform 9.2e14 floating point operations per second. This then requires $2BDF / 9.2e14$ seconds to perform. We have to load $2DF + 2BD$ bytes from DRAM, and write $2BF$ bytes back to it. We are bottlenecked by PCIe transfer speeds, so we need $2 \cdot (BD + DF + BF) / 1.6e10$ seconds to transfer data to and from the TPU. Since we want computation to take longer than weight loading, assuming we can overlap all weight loading with computation, we want $2BDF / 9.2e14 > 2 \cdot (BD + DF + BF) / 1.6e10$. We can simplify this using our assumptions that $B \ll D$, and $F = 4D$, to get
答案: 我们要做 $2BDF$ 次浮点运算,每块芯片每秒能做 9.2e14 次浮点运算。因此需要 $2BDF / 9.2e14$ 秒。我们要从 DRAM 加载 $2DF + 2BD$ 字节,并写回 $2BF$ 字节。由于受 PCIe 传输速度限制,往 TPU 来回传数据需要 $2 \cdot (BD + DF + BF) / 1.6e10$ 秒。我们希望计算时间长于权重加载;假设权重加载能与计算完全重叠,则希望 $2BDF / 9.2e14 > 2 \cdot (BD + DF + BF) / 1.6e10$。利用 $B \ll D$、$F = 4D$ 的假设化简,得到
$$\frac{8BD^2}{9.2 \times 10^{14}} > \frac{8D^2}{1.6 \times 10^{10}}$$
or
或
$$B > \frac{9.2 \times 10^{14}}{1.6 \times 10^{10}} \simeq 57{,}500$$
Question 4 [general matmul latency]: Let’s say we want to multiply a weight matrix int8[16384, 4096] by an activation matrix of size int8[B, 4096] where B is some unknown batch size. Let’s say we’re on 1 TPU v5e to start.
问题 4 [一般 matmul 的延迟]: 假设我们要把一个 int8[16384, 4096] 的权重矩阵乘以一个大小为 int8[B, 4096] 的激活矩阵,B 是未知的 batch size。先假设我们在 1 块 TPU v5e 上。
- How long will this multiplication take as a function of B? Hint: it may help to calculate how long it will take to load the arrays from HBM and how long the multiplication will actually take. Which is bottlenecking you?
- What if we wanted to run this operation out of VMEM? How long would it take as a function of B?
- 这个乘法作为 B 的函数要花多久?提示:可以先算从 HBM 加载数组要多久,以及乘法本身要多久。谁才是瓶颈?
- 如果把这个运算放到 VMEM 上跑呢?作为 B 的函数要多久?
Click here for the answer.
点这里看答案。
Answer: (1) The number of operations we need to perform is $2 \cdot 4096 \cdot 16384 \cdot B = 1.3 \times 10^{8} \cdot B$. So $T_{\text{math}} = (1.3 \times 10^{8} \cdot B) / 3.94 \times 10^{14}$ seconds. We need to load $16384 \cdot 4096 + 4096 \cdot B$ bytes from HBM to VMEM, and write back $16384 \cdot B$ bytes from VMEM to HBM. This means $T_{\text{comms}} = (6.7 \times 10^{7} + 2 \times 10^{4} \cdot B) / 8.2 \times 10^{11}$ seconds. Assuming as much overlap of communication and computation as possible, the whole multiplication will take approximately
答案:(1)需要执行的运算数是 $2 \cdot 4096 \cdot 16384 \cdot B = 1.3 \times 10^{8} \cdot B$。所以 $T_{\text{math}} = (1.3 \times 10^{8} \cdot B) / 3.94 \times 10^{14}$ 秒。我们需要从 HBM 到 VMEM 加载 $16384 \cdot 4096 + 4096 \cdot B$ 字节,并从 VMEM 写回 $16384 \cdot B$ 字节到 HBM。因此 $T_{\text{comms}} = (6.7 \times 10^{7} + 2 \times 10^{4} \cdot B) / 8.2 \times 10^{11}$ 秒。假设通信与计算尽可能重叠,整个乘法大约花
$$\max\{T_{\text{math}}, T_{\text{comms}}\} = \max\left\{\frac{1.3 \times 10^{8} \cdot B}{3.94 \times 10^{14}}, \frac{6.7 \times 10^{7} + 2 \times 10^{4} \cdot B}{8.2 \times 10^{11}}\right\}$$
We’ll be FLOPs-bound when $\frac{6.7 \times 10^{7} + 2 \times 10^{4} \cdot B}{8.2 \times 10^{11}} < \frac{1.3 \times 10^{8} \cdot B}{3.94 \times 10^{14}}$, or equivalently, $B > 267$. This is slightly larger than the 240 number we derive in Section 1 because we factor in the full impact of $D$ and $F$.
当 $\frac{6.7 \times 10^{7} + 2 \times 10^{4} \cdot B}{8.2 \times 10^{11}} < \frac{1.3 \times 10^{8} \cdot B}{3.94 \times 10^{14}}$,即 $B > 267$ 时,我们处于 FLOPs 受限。这比第 1 节推出的 240 略大,因为我们把 $D$ 和 $F$ 的完整影响考虑进来了。
(2) If instead we are loading from VMEM, let’s consider VMEM bandwidth to the MXU as 22 times the HBM $\leftrightarrow$ VMEM bandwidth. This turns our data loading denominator from 8.2e11 to 1.80e13, and we get $B > 11$. Note that in practice, we cannot dedicate all of our VMEM bandwidth to loading the weight matrix, so in practice it will be closer to 20.
(2)如果改为从 VMEM 加载,设 VMEM 到 MXU 的带宽是 HBM $\leftrightarrow$ VMEM 带宽的 22 倍。这把加载分母从 8.2e11 变成 1.80e13,得到 $B > 11$。注意实践中我们无法把所有 VMEM 带宽都用于加载权重矩阵,所以实际上会更接近 20。
Question 5 [ICI bandwidth]: Let’s say we have a TPU v5e 4x4 slice. Let’s say we want to send an array of type bf16[8, 128, 8192] from TPU{0,0} to TPU{3, 3}. Let’s say the per-hop latency for TPU v5e is $1\mu s$.
问题 5 [ICI 带宽]: 假设我们有 TPU v5e 的 4x4 slice。想把一个 bf16[8, 128, 8192] 的数组从 TPU{0,0} 发送到 TPU{3, 3}。设 TPU v5e 每跳延迟为 $1\mu s$。
- How soon will the first byte arrive at its destination?
- How long will the total transfer take?
- 第一个字节多久到达目的地?
- 整个传输要多久?
Click here for the answer.
点这里看答案。
Answer: In a TPU v5e we have 2D connectivity. Because we have only a 4x4 slice (with no axes of size 16), we have no wraparound connections. Thus there are two ports from which our target chip can receive data, and likewise two ports from which our source chip can send data. The amount of data we have to transfer is 2 * 8 * 128 * 8192 = 1.7e7 bytes. We can transfer from both ports simultaneously (i.e. send half the array right and half down), so we get 2 * 4.5e10 = 9e10 bytes transferred per second, which means it’ll take about 1.7e7 / 9e10 = 188us to transfer the whole array through (assuming we’re bandwidth bound). In a 4x4 slice, we have six hops between chips $(0, 0)$ and $(3, 3)$, since there are no wraparound links for axes with fewer than 16 chips. Since the latency of each hop is about $1\mu s$, the first byte will arrive in about 6us and the total transfer will take about 188 + 6 = 194us, since the last byte must likewise traverse the six hops after it leaves the source (in general, the latency and bandwidth terms are additive, though here the latency is a small correction).
答案: TPU v5e 是 2D 连接。因为我们只有 4x4 slice(没有长度为 16 的轴),所以没有绕回连接。因此目标芯片有 2 个端口可以收数据,源芯片同样有 2 个端口可以发数据。要传的数据量是 2 * 8 * 128 * 8192 = 1.7e7 字节。我们可以同时从两个端口发(向右发一半、向下发一半),于是 2 * 4.5e10 = 9e10 bytes/s,传完整个数组大约要 1.7e7 / 9e10 = 188us(假设带宽受限)。在 4x4 slice 中,芯片 $(0,0)$ 到 $(3,3)$ 之间有 6 跳(因为小于 16 的轴没有绕回链路)。每跳延迟约 $1\mu s$,所以第一个字节约 6us 到达,总传输约 188 + 6 = 194us——因为最后一个字节离开源后同样要穿过 6 跳(一般来说,延迟项和带宽项是相加的,只是这里的延迟是个小修正)。
Question 6 [pulling it all together, hard]: Imagine you have a big matrix A: int8[128 * 1024, 128 * 1024] sharded evenly across a TPU v5e 4x4 slice but offloaded to host DRAM on each chip. Let’s say you want to copy the entire array to TPU{0, 0} and multiply it by a vector bf16[8, 128 * 1024]. How long will this take? Hint: use the numbers above.
问题 6 [综合题,困难]: 假设你有一个大矩阵 A:int8[128 * 1024, 128 * 1024],均匀分片在一个 TPU v5e 4x4 slice 上,但被卸载到各芯片的 host DRAM。你想把整个数组拷到 TPU{0, 0},再乘以一个向量 bf16[8, 128 * 1024]。这要多久?提示:用上面的数字。
Click here for the answer.
点这里看答案。
Answer: Let’s start by outlining the operations we have to perform. Our array is about 16GB. From the table above, a TPU v5e host has a 4x2 topology, so a 4x4 has 2 hosts. Thus, since our array is evenly sharded, each host effectively contains a chunk of 1/2 of the array, or 8GB. We need to copy these chunks all to TPU{0,0}, which gives us two options:
答案: 先梳理要执行的操作。我们的数组约 16GB。从上表看,TPU v5e 的 host 是 4x2 拓扑,所以 4x4 有 2 个 host。由于数组均匀分片,每个 host 实际上持有 1/2 的数组,即 8GB。我们要把这些块全拷到 TPU{0,0},有两个选择:
- We can copy over DCN and then load the entire unsharded array over PCIe into HBM.
- We can load our sharded arrays onto their corresponding TPUs, then perform a gather over ICI, then perform the matmul on TPU{0,0}.
- 走 DCN 拷贝,再经 PCIe 把整个未分片数组载入 HBM。
- 先把各自的分片加载到对应 TPU,再通过 ICI 做一次 gather,然后在 TPU{0,0} 上做 matmul。
It should be clear that option (2) is better. DCN is slow compared to ICI and we’d much prefer to load a big array over many PCIe links rather than just a few (the 8 on host 0). Here’s a diagram of part of the system. As described above, note that TPUs are connected to their neighbors by ICI (even across hosts), all TPUs are connected to their host CPU (via PCIe), and hosts are connected by DCN.
显然选择(2)更好。DCN 相对 ICI 很慢,我们更愿意用很多条 PCIe 链路(host 0 上的 8 条)来加载一个大数组,而不是只用少数几条。下图是系统的一部分。如上所述,注意 TPU 通过 ICI 与邻居相连(甚至跨 host),所有 TPU 都通过 PCIe 连到各自的 host CPU,host 之间由 DCN 相连。
Now let’s work through how long each piece will take:
现在来算每一部分要多久:
- PCIe load: we’re loading chunks of 16GB over 16 PCIe links, each of which has
1.6e10bytes/second bandwidth. Thus this will take about 63ms.
- PCIe 加载:我们要通过 16 条 PCIe 链路加载 16GB 的数据块,每条带宽
1.6e10bytes/秒。因此约需 63ms。
- ICI copy: each TPU now has 16GB / 16 = 1GB of our array. Our ICI bandwidth is 9e10 bytes/second per link bidirectional, and you’ll notice from the above diagram that only 2 of the 4 ICI links on the TPU v5e are in use in this topology for TPU{0,0}. Since TPU{0,0} needs to receive a total of 15GB along 2 axes at
4.5e10bytes/s/link, we can lower bound the time by15e9 / (4.5e10 * 2) = 167ms. In practice this probably isn’t achievable because the load is very uneven, but it’s probably within a factor of 2. As you’ll see in Section 3, performing a full AllGather would also take roughly16e9 / (4.5e10 * 2), so this is close to optimal.
- ICI 拷贝: 现在每块 TPU 持有 16GB / 16 = 1GB。我们的 ICI 带宽是每链路双向 9e10 bytes/秒,而从上面的图可以看到,TPU v5e 的 4 条 ICI 链路中,在这个拓扑里 TPU{0,0} 只用到 2 条。由于 TPU{0,0} 需要沿 2 个轴、以
4.5e10bytes/s/链路 接收共 15GB,下界是15e9 / (4.5e10 * 2) = 167ms。实践中由于负载很不均匀,这可能达不到,但大概在 2 倍以内。第 3 节你会看到,做一次完整的 AllGather 也大约是16e9 / (4.5e10 * 2),所以这接近最优。
- HBM $\rightarrow$ MXU load: to perform our final matmul, we need to load these 16e9 bytes plus the bf16[8, 128 * 1024] array (another 2MB, so negligible) over HBM bandwidth into the MXU, which will take
16e9 / 8.2e11 = 20ms.
- HBM $\rightarrow$ MXU 加载: 为了做最后的 matmul,我们需要把这 16e9 字节加上 bf16[8, 128 * 1024] 数组(再加 2MB,可忽略)经 HBM 带宽载入 MXU,这要
16e9 / 8.2e11 = 20ms。
- FLOPs: we’re performing a total of $$2 \cdot 8 \cdot 128 \cdot 1024 \cdot 128 \cdot 1024 = 2.7 \times 10^{11}$$ FLOPs, and since we can perform
1.97e14bf16 FLOPs/s, we get 1.4ms.
- FLOPs: 总共执行 $$2 \cdot 8 \cdot 128 \cdot 1024 \cdot 128 \cdot 1024 = 2.7 \times 10^{11}$$ 次 FLOPs,而 bf16 是
1.97e14FLOPs/s,所以是 1.4ms。
An upper bound for the total time is the sum of all of these times, but since the TPU can typically overlap these operations, we can think of this as a pipelining problem that’s bottlenecked by the slowest piece. Assuming that’s true, then the answer is at least 167ms, likely closer to 200ms with imperfect overlapping.
总时间的上界是以上各项之和;但既然 TPU 通常能重叠这些操作,可以把它看成一个由最慢部分卡住的流水线问题。若如此,答案至少是 167ms,重叠不完美的话可能接近 200ms。
That’s it for Part 2! For Part 3, covering partitioning and cross-TPU communication, click here.
第 2 部分就到这里!第 3 部分讲分区与跨 TPU 通信,点这里。
Appendix
附录
Appendix A: More on TPU internals
附录 A:TPU 内部细节补充
Here we’ll dive more deeply into the internal operations of a TPU. Unless otherwise noted, we’ll provide specs for a TPU v5p.
这里我们更深入地看 TPU 的内部运作。除非特别说明,规格以 TPU v5p 为准。
VPU
VPU
The VPU is the TPU’s vector arithmetic core. The VPU consists of a two dimensional SIMD vector machine (the VPU) that performs elementwise arithmetic operations like vadd (vector addition) or vmax (elementwise max) and a set of vector registers called VREGs that hold data for the VPU and MXU.
VPU 是 TPU 的向量运算核心。VPU 由一个二维 SIMD 向量机(即 VPU)和一组称为 VREGs 的向量寄存器组成;前者执行 vadd(向量加)、vmax(逐元素取最大)这类逐元素运算,后者为 VPU 和 MXU 保存数据。
VREGs: Each TPU v5p core has 64 32-bit VREGs (32 in TPU v4), giving us a total of about 64 * 8 * 128 * 4 = 256kB of VREG memory per core (or 2x this for the whole chip since we have two cores). A TPU v5p can load 3 registers from VMEM each cycle, and write 1 register to VMEM each cycle.
VREGs: 每个 TPU v5p core 有 64 个 32 位 VREG(TPU v4 是 32 个),每 core 合计约 64 * 8 * 128 * 4 = 256kB 的 VREG 内存(整块芯片有两个 core,所以是 2 倍)。TPU v5p 每周期可从 VMEM 加载 3 个寄存器,每周期可写回 1 个寄存器到 VMEM。
VPU: The VPU is a 2D vector arithmetic unit of shape (8, 128) where the 128 dimension is referred to as lane axis and the dimension of 8 is referred to as the sublane axis. Each (lane, sublane) pair on v5 contains 4 standard floating-point ALUs which are independent of each other. The VPU executes most arithmetic instructions in one cycle in each of its ALUs (like vadd or vector add) with a latency of 2 cycles, so e.g. in v5 you can add 4 pairs of f32 values together from VREGs in each cycle. A typical VPU instruction might look like {v2 = vadd.8x128.f32 v0, v1} where v0 and v1 are input VREGs and v2 is an output VREG.
VPU: VPU 是一个形状为 (8, 128) 的二维向量运算单元,其中 128 维称为 lane 轴,8 维称为 sublane 轴。在 v5 上,每个 (lane, sublane) 对含有 4 个彼此独立的浮点 ALU。VPU 在大多数算术指令上做到每 ALU 每周期执行一次(如 vadd),延迟 2 个周期;例如在 v5 上,每周期可以从 VREGs 里把 4 对 f32 值相加。一条典型的 VPU 指令可能形如 {v2 = vadd.8x128.f32 v0, v1},其中 v0、v1 是输入 VREG,v2 是输出 VREG。
All lanes and sublanes execute the same program every cycle in a pure SIMD manner, but each ALU can perform a different operation. So we can e.g. process 1 vadd and 1 vsub in a single cycle, each of which operates on two full VREGs and writes the output to a third.
所有 lane 和 sublane 每个周期都以纯 SIMD 方式执行同一程序,但每个 ALU 可以执行不同的操作。所以我们可以例如在一个周期里处理 1 个 vadd 和 1 个 vsub,各自作用于两个完整的 VREG 并把结果写到第三个。
Pop Quiz [Calculating VPU throughput]: Using the above information, calculate how many vector FLOPs/s a TPU v5p can perform. A TPU v5p has a clock speed of about 1.75GHz.
随堂测验 [计算 VPU 吞吐]: 用上面的信息,计算一块 TPU v5p 每秒能做多少次向量 FLOPs。TPU v5p 的时钟频率约为 1.75GHz。
Click here for the answer.
点这里看答案。
Answer: Each cycle, each core can execute 4 vector instructions on 8 * 128 ALUs. This gives us 8 * 128 * 4 FLOPs/cycle per core, or 8 * 128 * 4 * 1.75e9 = 7e12 FLOPs/s. Note how much smaller this is than the MXU FLOPs/s of about 2e14 per core (roughly 30x).
答案:每周期每 core 在 8 * 128 个 ALU 上执行 4 条向量指令。于是每 core 每周期 8 * 128 * 4 次 FLOPs,即 8 * 128 * 4 * 1.75e9 = 7e12 FLOPs/s。注意这比每 core 约 2e14 的 MXU FLOPs/s 小得多(大约 30 倍)。
Reductions: Generally, communication or reduction across the sublane dimension is easier than across the lane dimension. For instance, the VPU supports an intra-lane shuffle operation that can roll along the axis of size 8 in about a cycle. This can be used to perform efficient reductions along the sublane dimension (just shuffle by 4, 2, and 1 and do 3 pairs of elementwise sums).
归约: 一般来说,跨 sublane 维的通信或归约比跨 lane 维更容易。例如 VPU 支持一种 intra-lane shuffle 操作,可以在一周期左右沿长度 8 的轴滚动。这可用于高效地做 sublane 维上的归约(按 4、2、1 各 shuffle 一次,再做 3 对逐元素求和)。
Cross-lane reductions are much harder and involve a separate hardware unit called the XLU or “cross lane unit”, which is slow and fairly expensive.
跨 lane 归约难得多,要用一个独立硬件单元 XLU(cross lane unit),它较慢且相当昂贵。
Comparison to GPUs: For those familiar with NVIDIA GPUs, each ALU in the VPU is analogous to a CUDA core, and a single VPU lane is analogous to a “Warp Scheduler”, i.e. the set of usually 32 CUDA Cores that perform SIMD arithmetic. Reductions within the lane are pretty easy, but if we need to cross lanes, we need to transit at least VMEM/XLU/SMEM which is much slower. See the GPU section for more details.
与 GPU 对比: 熟悉 NVIDIA GPU 的读者可以这样类比:VPU 里的每个 ALU 相当于一个 CUDA core,一条 VPU lane 相当于一个「Warp Scheduler」,也就是那组通常 32 个做 SIMD 运算的 CUDA core。lane 内的归约很容易,但如果要跨 lane,就至少要经过 VMEM/XLU/SMEM,慢得多。更多细节见 GPU 一节。
Scalar Core
标量核心(Scalar Core)
The scalar core is the control unit of the TPU. It fetches and dispatches all instructions and executes transfers from HBM into VMEM, and can be programmed to do scalar metadata work. Because the scalar core is single-threaded, one side-effect of this is that each core of the TPU is only capable of creating one DMA request per cycle.
标量核心是 TPU 的控制单元。它取指并派发所有指令,执行 HBM 到 VMEM 的传输,也可编程做标量元数据工作。由于标量核心是单线程的,一个副作用是:TPU 的每个 core 每周期只能发起一个 DMA 请求。
To put this in context, a single scalar core controls a VPU (consisting of 4096 ALUs), 4 MXUs, 2 XLUs, and multiple DMA engines. The highly skewed nature of control per unit compute is a source of hardware efficiency, but also limits the ability to do data dependent vectorization in any interesting way.
作为对照:单个标量核心控制着一个 VPU(含 4096 个 ALU)、4 个 MXU、2 个 XLU 和多个 DMA 引擎。每个计算单元对应的控制开销严重不对称,这既带来硬件效率,也限制了以有趣的方式做数据相关的向量化。
Appendix B: How does a systolic array work?
附录 B:脉动阵列如何工作?
At the core of the TPU MXU is a 128x128 systolic array (256x256 on TPU v6e). When fully saturated the systolic array can perform one bf16[8,128] @ bf16[128,128] -> f32[8,128] (If you are not familiar with this notation, it means: multiplying a 8x128 matrix with bfloat16 elements by a 128x128 matrix with bfloat16 elements and storing the results in a 8x128 matrix with float32 elements.) multiplication per 8 clock cycles.
TPU MXU 的核心是一个 128x128 的脉动阵列(TPU v6e 是 256x256)。完全饱和时,脉动阵列每 8 个时钟周期可完成一次 bf16[8,128] @ bf16[128,128] -> f32[8,128](如果你不熟悉这个记号,它的意思是:把一个元素为 bfloat16 的 8x128 矩阵与一个元素为 bfloat16 的 128x128 矩阵相乘,结果存进元素为 float32 的 8x128 矩阵。)乘法。
- At its core, the systolic array is a 2D
128x128(=16,384) grid of ALUs each capable of performing a multiply and add operation. - Weights (W, the
128x128input) are passed down from above (called the RHS) while inputs (X, the8x128input) are passed in from the left (called the LHS).
- 脉动阵列的核心是一个二维
128x128(=16,384)的 ALU 网格,每个 ALU 能完成一次乘加。 - 权重(W,
128x128的输入)从上方传入(称为 RHS),输入(X,8x128的输入)从左侧传入(称为 LHS)。
Here is a simplified animation of multiplying a set of weights (blue) with a set of activations (green). You’ll notice that the weights (RHS) are partially loaded first, diagonally, and then the activations are fed in, also diagonally. In each frame below, we multiply all the overlapped green and blue units, sum the result with any residual passed in from above, and then pass the result in turn down one unit.
下面是一个简化动画,展示用一组权重(蓝色)乘以一组激活(绿色)。你会注意到权重(RHS)先对角式地部分加载,然后激活也以对角方式送入。在下面每一帧里,我们把所有重叠的绿色与蓝色单元相乘,与从上方传入的残差求和,再把结果向下交给下一个单元。
Here’s a more general version of this animation showing the output being streamed out of computation:
这是同一动画更一般的版本,展示了输出如何从计算中流出:
Here’s a diagram showing how this can be pipelined across multiple RHS and LHS arrays:
这张图展示它如何在多个 RHS 和 LHS 数组之间流水线化:
There is an initial pipeline bubble as the weights (RHS) and activations (LHS) are loaded. After that initial bubble, new inputs and weights can be loaded in without an additional bubble.
在权重(RHS)和激活(LHS)加载时,会有一个初始的流水线气泡。气泡之后,新输入和权重可以无额外气泡地载入。
Here’s a bad animation of a bf16[2, 3] x bf16[3, 3] matrix multiplication, which you could imagine as a matmul of a 2x3 weight matrix with an input activation of batch 1 and size 3. This is rotated compared to the previous slides and inputs flow out to the right instead of down, but you can roughly see the structure.
下面是一个不太精致的动画,演示 bf16[2, 3] x bf16[3, 3] 矩阵乘法,你可以把它想象成 2x3 权重矩阵与 batch 为 1、大小为 3 的输入激活做 matmul。它相对前面的图旋转了,输入向右流出而不是向下,但大致能看出结构。
We can efficiently pipeline this to multiply large matrices without too large a pipeline bubble. With that said, it’s important that our matrices have shapes larger than the side dimension of the MXU, which is generally 128x128. Some TPUs (since TPU v3) have multiple MXUs, either 2 for TPU v3 or 4 for TPU v4/5, so we need to ensure tiling dimensions are larger than 128 * number of MXUs. Here’s a good animation for this.
我们可以高效地把它流水线化,用来乘大矩阵,而不会有太大的流水线气泡。话虽如此,矩阵的形状必须大于 MXU 的边长(一般是 128x128)。一些 TPU(从 TPU v3 起)有多个 MXU:TPU v3 有 2 个,TPU v4/5 有 4 个,所以我们要确保 tile 维度大于 128 * MXU 数量。这里有一个很好的动画。
Trillium (TPU v6e) has a 256x256 systolic array, which means it can perform 4x more FLOPs / cycle. This also means the dimensions of your tensors need to be twice as large to utilize the MXU fully.
Trillium(TPU v6e)有 256x256 的脉动阵列,意味着每周期能多做 4 倍 FLOPs。这也意味着张量的维度要翻倍才能用满 MXU。
This blog post has another excellent animation of a systolic array multiplication for a fixed weight matrix.
这篇博客还有另一个很棒的动画,演示固定权重矩阵下的脉动阵列乘法。
讨论
用 GitHub 账号留言;评论保存在公开仓库chengshu-blog-discussions的 Discussions 里。也可通过 RSS 订阅后续文章。