Skip to content

Roofline 分析深度指南

本文基于 How to Scale Your Model 系列整理,聚焦于 Pallas kernel 开发中最实用的 Roofline 分析方法。


1. 核心模型

1.1 时间分解

任何算子的执行时间受三个硬件约束限制:

Tmath=FLOPsAccelerator FLOPs/sTcomms=BytesBandwidth Bytes/s

当计算与通信可以重叠时:

Tlower=max(Tmath,Tcomms)Tupper=Tmath+Tcomms

上下界最多相差 2×。

  • Tmath>Tcommscompute-bound,硬件利用率高
  • Tcomms>Tmathmemory/communication-bound,算力被浪费

1.2 Arithmetic Intensity(算术强度)

AI=FLOPsBytes

当 AI > 硬件临界强度时,算子为 compute-bound:

AI(算子)>Accelerator FLOPs/sBandwidth Bytes/s=AI(硬件)

1.3 各硬件临界强度

硬件bf16 FLOPs/sHBM 带宽临界 AI备注
TPU v5e1.97×10¹⁴8.1×10¹¹240推理优化芯片
TPU v5p4.59×10¹⁴2.8×10¹²164训练芯片
TPU v6e9.20×10¹⁴1.6×10¹²575当前主力
H100 SXM~1.0×10¹⁵3.35×10¹²298去除 sparsity 2×

从 VMEM 读取时:VMEM 带宽约为 HBM 的 22×,临界 AI 降至 ~10–20,几乎所有 matmul 都是 compute-bound。这是 Pallas kernel 中 tiling 到 VMEM 的核心优势。


2. 矩阵乘法 Roofline

2.1 基础公式

对于 X[B,D]×Y[D,F]Z[B,F](bf16):

指标公式
FLOPs2×B×D×F
读取字节2(BD+DF)
写入字节2BF
总字节2(BD+DF+BF)
AIBDFBD+DF+BF

2.2 简化情况:BD,F

分母中 DF 项主导:

AIBDFDF=B

关键结论:bf16 matmul 在 B > 临界 AI 时 compute-bound。

硬件临界 batch size
TPU v5e~240 tokens
TPU v6e~575 tokens
H100~298 tokens

这里 B 是 per-replica 的 token 数(非 sequence 数),且与 sharding 无关(sharding 等比缩放计算和带宽)。

2.3 不同精度组合

权重精度激活精度计算精度临界 batch
bf16bf16bf16~240 (v5e)
int8int8int8~243 (v5e)
int8bf16bf16~120 (v5e)

int8 权重 + bf16 激活的组合最有利:权重字节减半,但计算速率不变,使得临界 batch 减半。

2.4 Tiling 强度

大 matmul 被分块为 tile 放入 VMEM。对于 tile 尺寸 (bm,bk,bn)

AI(tile)bm×bnbm+bn

例如 bm=bn=128AI=64bm=bn=256AI=128

在 Pallas kernel 中选择 tile 尺寸时,应确保 tile AI 大于 VMEM↔MXU 临界强度(~10–20),通常 128×128 已足够。


3. 逐元素运算 Roofline

3.1 Dot Product

对于 xy(bf16[N], bf16[N] → bf16[1]):

AI=2N14N+212 as N

结论:dot product 永远是 communication-bound(AI = 0.5 远低于任何硬件的临界值)。

3.2 通用逐元素运算

所有 elementwise 运算(ReLU、add、multiply 等)AI ≈ 1,始终 memory-bound

优化策略:将逐元素运算与相邻的 matmul 融合(fuse),避免额外的 HBM 往返。


4. 注意力机制 Roofline

4.1 单头注意力算术强度

对于 Flash Attention 融合后的注意力(查询 T tokens,KV 缓存 S tokens):

AI=STS+T
场景STAI结论
Prefill/训练= TTT/2T > ~480 时 compute-bound
解码生成≫ 11≈ 1永远 memory-bound

4.2 GQA 对推理的影响

使用 Grouped Query Attention(G = N/K 个 Q 头共享一组 KV):

  • 生成时 AI → G(当 S 很大)
  • 增大 G(更多 Q 头共享 KV)可提升算术强度,但仍难以达到 compute-bound

4.3 注意力 vs MLP FLOPs 占比

attention FLOPsMLP FLOPs=T8D

T>8D 时注意力 FLOPs 占主导。对于 D=8192,阈值约 64K tokens。


5. 多芯片通信 Roofline

5.1 ICI 通信临界强度

对于跨 ICI 的 sharded matmul:

硬件bf16 FLOPs/sICI 双向带宽临界 AI
TPU v5e1.97×10¹⁴9.0×10¹⁰~2,200
TPU v5p4.59×10¹⁴1.8×10¹¹~2,550
TPU v6e9.20×10¹⁴1.8×10¹¹~5,100

5.2 DP 临界 batch

纯数据并行(AllReduce 梯度)compute-bound 条件:

BX>CWici÷MX

其中 MX 是 ICI 轴数量。TPU v5p 三轴:每芯片最低 ~850 tokens。

5.3 TP 临界条件(与 batch 无关)

Y<F×MYC/Wici

TPU v5p:Y<F/2550。对于 F=28672(LLaMA-70B):最多 ~11 路 TP。

5.4 DCN 跨 pod 临界强度

CWdcn4.59×10146.25×10973,440

跨 pod 通信极其昂贵,要求每 slice 至少 ~73K tokens。


6. 实用 Roofline 分析流程

6.1 Kernel 开发前分析

  1. 计算 FLOPs2×(contracting dims)×(batch/output dims)
  2. 计算访存字节:所有输入和输出的 size×bytes_per_element
  3. 算 AI:FLOPs / Bytes
  4. 对比硬件临界 AI:确定 compute-bound 还是 memory-bound
  5. 选择优化方向
    • Compute-bound → 提升 MXU 利用率(增大 tile、减少 pipeline bubble)
    • Memory-bound → 减少访存(fuse ops、减少精度、增大 batch)

6.2 Roofline 绘图

python
import matplotlib.pyplot as plt
import numpy as np

def roofline_plot(B_range, D, F, flops_s, hbm_bw, label):
    total_flops = 2 * B_range * D * F
    flops_time = total_flops / flops_s
    comms_time = (2 * B_range * D + D * F + 2 * B_range * F) / hbm_bw
    total_time = np.maximum(flops_time, comms_time)
    return total_flops / total_time

bs = np.arange(1, 1024)

# TPU v6e
perf_v6e = roofline_plot(bs, 4096, 4096, 9.2e14, 1.6e12, 'v6e')

plt.figure(figsize=(10, 5))
plt.plot(bs, perf_v6e / 1e12, label='D=F=4096, TPU v6e')
plt.axhline(y=920, color='r', linestyle='--', label='Peak (920 TFLOPS)')
plt.xlabel('Batch Size (tokens)')
plt.ylabel('Achievable TFLOPS')
plt.legend()
plt.grid(True)
plt.title('Matmul Roofline')

7. 参考链接