LLM 推理中,给定模型和硬件,理论上最快能跑多快?Roofline 模型是回答这个问题最简洁的分析框架:用两个硬件参数和一个比值,就能判断计算任务的性能瓶颈在哪。
这篇文章先介绍 Roofline 的基本原理,再回顾一次把它用于资源预估的尝试:为什么单阶段压测可以拟合,总工作量也没有算错,最后仍然低估了混部成本。
Roofline 如何判断瓶颈
任何计算任务在硬件上执行,受两个基本约束1:
- 算力(Math):芯片每秒能完成多少浮点运算(Peak FLOPs/s)
- 带宽(Bandwidth):HBM 每秒能搬运多少字节(Bytes/s)
运算需要算力来做数学计算,同时需要带宽来搬运数据。两者各自的耗时:
如果计算和访存能理想地重叠,Roofline 给出的时间下界是:
如果两者完全串行,已建模部分的耗时是:
最多是 的两倍,但这个两倍只描述「完全重叠」与「完全串行」两个极端的差异。真实执行还包含 kernel 效率、同步和调度等开销,实际时间可以超过 。Roofline 描述的是硬件资源约束下的理论下界,不是对真实执行时间的上下界承诺。
算术强度与瓶颈判定
为了快速判断瓶颈在哪一侧,定义算术强度(Arithmetic Intensity),即每搬运一个字节需要做多少次运算:
同时,硬件有一个固有的临界强度:
两者的比较:
- :算力瓶颈(Compute-bound),硬件满载计算,带宽有余
- :带宽瓶颈(Memory-bound),算力闲置,等数据搬运
这个比值判定就是 Roofline 的核心。
用矩阵乘法理解临界点
矩阵乘法是 Transformer 的计算主体,也是最经典的 Roofline 分析对象。
考虑 bf16 矩阵乘法 ,其中 : bf16[, ],: bf16[, ],: bf16[, ]:
- FLOPs:
- Bytes:(bf16 每元素 2 字节,读入两个矩阵 + 写回结果)
算术强度:
在推理场景中,(token batch size)通常远小于 和 (隐层维度,通常数千到上万),分母中 项占主导:
矩阵乘法的算术强度近似等于 batch size 。
以 NVIDIA H100 SXM 为例:
| 指标 | 数值 |
|---|---|
| bf16 密集算力 | FLOPs/s |
| HBM 带宽 | Bytes/s |
| 临界算术强度 | FLOPs/Byte |
注意:NVIDIA 官方标称 H100 的 bf16 算力为 1.979 PFLOPs,但这个数字包含了 2:4 结构化稀疏加速。绝大多数 LLM 推理负载无法利用结构化稀疏,实际可用的密集算力是标称值的一半1。
因此,bf16 矩阵乘法在 H100 上 compute-bound 的条件为 。低于这个阈值,GPU 大量时间在等数据从 HBM 搬进来,算力被浪费。
还有一个容易混淆的细节:这里的 是 token 级 batch size,不是 sequence 级。一个 batch 包含 4 条长度 1024 的序列,,远超 295,稳稳地 compute-bound。而且这里说的是 per-replica 的 batch size:如果通过模型切分把一次矩阵乘法分到多张卡上,参与这份权重副本计算的总算力和总带宽会一起扩展,所以临界 batch size 仍然按每份独立模型权重副本来算1。
LLM Decode 为什么是带宽瓶颈
Transformer 的计算主体是矩阵乘法,所以上面的结论可以直接套用:Decode 阶段每步只处理 1 个新 Token(或 batch 中的 个),算术强度 。 当 时,强度仅为 1,远低于 H100 的临界值 295。Decode 在典型并发下几乎总是带宽瓶颈。
这直接解释了两个常见的工程实践:
量化降低 Decode 延迟。 bf16→int8 将权重搬运量减半,bf16→int4 减至四分之一。在带宽瓶颈下,搬运量的减少几乎等比地转化为延迟降低2。
增大 batch size 提升吞吐。 增大 使算术强度线性上升,逐步逼近 compute-bound 区域,更充分地利用算力。这是 continuous batching 和 vLLM 等推理引擎追求高并发的核心动机之一。
作为对比,Prefill 阶段一次性处理整个 prompt, 等于 prompt 中的 token 数(通常数百到数千),天然容易 compute-bound。这是 Prefill 和 Decode 在性能特征上的本质差异,也是 Prefill-Decode 分离调度(Disaggregated Serving)架构的理论基础。
从 Roofline 到 GPU 资源预估
这是一个探索议题,源于:既然 Roofline 能做性能分析,能不能拓展到资源预估?判断瓶颈方向和预估 GPU 数是两个不同的问题。前者是定性分析,后者则是定量分析,同时还要考虑结论能否外推。
实验设计:用单阶段能力检验 mixed E2E
这次实验先不逐项分析执行开销,而是把 mixed E2E 数据留作最后验证:
- 分别压测 Prefill-only 和 Decode-only,标定两个阶段的独立服务成本。
- 用综合效率把理论计算量和数据搬运量校准到实测能力。
- 根据 Roofline 推导 Prefill 在 Decode 中的 。
- 比较同并发下 Decode-only 与 E2E 的 TPOT,并比较相同 TPOT 阈值下的 output TPS。
第一步压测得到的计算/带宽综合效率为:
和 分别是标定 workload 的 Prefill 计算量与 Decode 数据搬运量, 和 是对应的实测时间。 与 吸收了标定工况下的各类执行开销,表示综合有效计算效率与带宽效率。它们用于校准单阶段能力,并不分别度量每一项开销。
Prefill 只可能在同一个 mixed step 内隐藏
用 表示每个 Prefill token 的平均计算量, 表示每个 Decode token 的平均数据搬运量,两者近似为常数。 和 是单阶段标定出的有效算力与带宽。记 、,分别表示 Prefill-only 每 input token、Decode-only 每 output token 的处理时间。令一个 mixed step 同时处理 个 Prefill token 和 个 Decode token。若两类工作处于同一个可重叠的执行窗口,理想 step 时间为:
第一个时间小于等于第二个时间时,Prefill 计算延迟可以被 Decode 隐藏,由此得到隐藏的边界情况:
表示同一个 mixed step 内最多能够隐藏的 Prefill/Decode token 比例。它给出资源互补条件下的理想边界,成立还要求两类工作确实共享可重叠的执行窗口,并且单阶段效率在 mixed step 中保持适用。
长期 input/output 比例仍然有用。设 为扣除 prefix cache 后需要实际计算的 input token 数, 为 output token 数, 决定系统长期需要完成多少 Prefill 和 Decode 工作。我们假设 。不过,scheduler 决定这些工作如何分布为逐 step 的 。相同的总量比例可以形成不同的 mixed step 序列,也会得到不同的重叠效果。
实验结果:无干扰近似过于乐观
在同一局部有效口径下,边界也可以直接由单阶段吞吐换算:
本次压测的 input/output 比例约为 8。若把长期工作量均匀摊入每个 mixed step,Prefill 应当可以完全隐藏,即同一并发下 E2E 相对 Decode-only 的 TPOT 增量应接近零。但压测测得的增量约为 7% 至 10%;对两条曲线在同一 TPOT 阈值处插值后,E2E output TPS 比 Decode-only 低约 19%。
这可能是由于 的比例实际上一直在变化。带 Prefill 的 step 中 可以达到数十以上,超过约 30 的边界。没有 Prefill 的 step 即使留下算力,也不能跨 step 补偿。长期比例约为 8,并不意味着每个 mixed step 的比例都是 8。完全串行时,单位 output token 的耗时为 。由此预测的 output TPS 仅比实测低约 3%,说明大部分 Prefill 成本没有被隐藏。
分析:长期比例不能代替逐 step 比例
Decode 受带宽约束、Prefill 受算力约束,只说明两类工作在同一个 step 内可能重叠。令 和 表示第 个 step 中两类工作的理想耗时。先汇总长期工作量再取一次 ,会允许空闲资源跨 step 转移;真实执行则要对每个 step 分别取 :
因此,单阶段能力可以给出完全隐藏与完全串行两个端点,却不能单独确定 E2E 落在什么位置。
要继续做白盒预估,还需要从 workload 推出逐 step 的组成。PD 分离下,两阶段不共享 mixed step,单阶段标定也更容易用于各阶段资源量的线性外推。
结语
Roofline Model 是一个极简但有力的分析框架:两个硬件参数,一个强度比值,就能判断计算卡在哪。它直接解释了 LLM 推理中的一系列工程决策:为什么低 batch 的 Decode 容易进入带宽瓶颈、为什么量化有效、为什么增大 batch 能提升硬件利用率。
这次探索了 Roofline 在资源预估中的使用边界。Roofline 可以计算已知 mixed step 的理论下界,也可以给出理想条件下的资源重叠边界。要把它用于资源预估,还不够精细。