大模型推理加速核心原理:分形方法与四类资源计算公式
本文根据腾讯云开发者社区文章整理与重写,重点对原文中的资源估算公式进行了 LaTeX 化、符号统一和边界补充。文末附有原文链接。
大模型推理优化看起来千头万绪:模型结构、GPU、显存、网络、推理框架、算子和服务目标都会影响最终结果。但如果把问题抽象一层,会发现不同尺度上的瓶颈具有相似结构:某种资源先达到上限,其他资源随之闲置。
因此,可以用一套递进的“分形方法”分析推理系统:
- 看清楚:计算或测量模型需要多少算力、显存、HBM 带宽和通信带宽;
- 避免浪费:消除重复计算、空泡、无效搬运和多余的 Kernel Launch;
- 提升利用率:调整并行、调度、负载均衡与通信重叠,让资源供需更加匹配;
- 节约资源:通过量化、低秩压缩和稀疏化,从源头减少资源需求。
这套方法既适用于整个集群,也适用于单机、单卡乃至一个算子。
一、先把问题放进四类资源模型
推理系统中需要优先观察四类资源:
| 资源 | 典型问题 | 主要观测指标 |
|---|
| 算力 | Tensor Core 是否吃满 | FLOPs、MFU、Kernel 执行时间 |
| 显存容量 | 模型和请求能否装下 | 权重、KV Cache、激活、运行时预留 |
| HBM 带宽 | 数据搬运是否压过计算 | 读写字节数、带宽利用率、算术强度 |
| 通信带宽 | 跨卡数据是否阻塞前向 | All-to-All、All-Reduce 流量和尾延迟 |
判断瓶颈时,不应只看“哪个利用率高”,而要比较不同资源各自完成任务所需的理论时间:
tcompute=CeffF,tHBM=BHBM,effDHBM,tcomm=Bcomm,effDcomm
其中,F 是计算量,D 是数据量,Ceff 和 Beff 是实测有效能力,而不是产品规格表上的峰值。
粗略地说,三者中最大的那个通常决定下界:
tstep≳max(tcompute, tHBM, tcomm)
如果计算与搬运没有重叠,实际时间会更接近三者之和;如果重叠充分,才可能逼近最大值。
二、示例模型与符号约定
原文以 DeepSeek V3/R1 为例:总参数约 671B,单 Token 激活参数约 37B;共有 61 层 Transformer,前 3 层使用稠密 FFN,后 58 层为 MoE。每个 MoE 层包含 256 个路由专家和 1 个共享专家,每个 Token 激活 8 个路由专家及 1 个共享专家。
下面统一使用这些符号:
| 符号 | 含义 | 示例值 |
|---|
| b | Batch Size | 由场景决定 |
| sq | 本次参与计算的 Query Token 数 | Prefill 时接近输入长度,Decode 时通常为 1 |
| sk | Query 能看到的平均 KV 长度 | 由上下文长度决定 |
| NL | Transformer 层数 | 61 |
| NMoE | MoE 层数 | 58 |
| dmodel | 隐藏维度 | 7168 |
| nh | 注意力头数 | 128 |
| dh | 单头维度 | 128 |
| dc | MLA KV 压缩维度 | 512 |
| dqc | MLA Query 压缩维度 | 1536 |
| dR | 解耦 RoPE 维度 | 64 |
| dmoe | 单专家中间维度 | 2048 |
| k | 单 Token 激活专家数 | 9 |
| p | 每个元素的字节数 | FP8 为 1,BF16 为 2 |
本文使用 230 把字节换算为 GiB。为了和工程口径保持一致,后文仍简写为 GB。
三、算力:先算 FLOPs,再谈卡数
1. 非注意力部分
线性层的一次乘加通常按 2 FLOPs 计算。设非注意力部分每个 Token 实际激活的参数量为 Pactive,则:
Fnon-attn≈2Pactivebsq
若用 GFLOPs 表示:
Fnon-attn(GFLOPs)≈1092Pactivebsq
这里必须使用“单 Token 实际激活参数量”,而不是 MoE 模型的总参数量。
2. 注意力部分
按原文的估算口径,传统多头注意力的主体计算量可写成:
FMHA≈2NLbsqsknh(2dh+dR)
采用 MLA 的低秩 KV 表示后,可近似写成:
FMLA≈2NLbsqsknh(2dc+dR)
于是两个阶段的总计算量可以统一表达为:
FPrefill≈Fnon-attn+Fattn,Prefill
FDecode/token≈Fnon-attn+Fattn,Decode
需要注意:MLA 是模型结构的一部分,并不是只在 Decode 阶段存在。上面的 MHA/MLA 区分是原文用于资源估算的简化口径,不能理解成同一个已训练模型在 Prefill 与 Decode 时任意切换注意力结构。
3. 从计算量估算最低耗时
如果一张卡的峰值算力为 Cpeak,实测 MFU 为 η,并行后每卡分到的计算量为 Fcard,则:
tcompute≈ηCpeakFcard
这解释了为什么“理论算得过来”不代表线上一定达标:形状太小、路由不均衡或调度空泡都会让 η 明显下降。
四、显存:权重、KV Cache、激活与预留
单卡显存可以拆成四部分:
Mtotal=Mweight+MKV+Mact+Mruntime
1. 权重显存
设稠密部分的 FP8 权重大小为 Sdense,MoE 部分的 FP8 权重大小为 SMoE;稠密部分使用 TP,专家部分使用 EP,并把 MoE 权重量化为 INT4,则原文给出的单卡近似值为:
Mweight≈TPSdense+2EPSMoE
分母中的 2 来自 FP8 到 INT4 的理论位宽减半。真实占用还会受到量化 scale、对齐、分片和框架元数据影响。
2. KV Cache 显存
MLA 每个 Token、每层需要保存约 dc+dR 个元素,因此:
MKV=230NLb(sinput+soutput)(dc+dR)pKVGB
这一式必须包含层数 NL。如果只写 b(sinput+soutput)(dc+dR),得到的只是单层 KV,而不是整个模型的 KV Cache。
3. 激活显存
未充分融合时,可以把激活近似拆成线性层、注意力分数和 FFN 中间结果:
Mact≈Mlinear+Mscore+MFFN
对 MLA,可用下面的单层峰值作粗估:
MactMLA≈2301[bsqdqc+bsq(dc+dR)+2bsqdmodel+2bnhsqsk+2bsqkdmoe]
对未做 FlashAttention 式优化的 MHA,可粗略写成:
MactMHA≈2301[6bsqdmodel+2bnhsq2+2bsqkdmoe]
这些式子只能作为上界式估算。算子融合、重计算、FlashAttention、缓冲区复用和数据类型都会改变峰值。
4. 总显存预算
把各部分合起来:
Mtotal≈TPSdense+2EPSMoE+MKV+Mact+Mruntime
原文示例把 CUDA Graph、通信缓冲区、内存池和系统运行时合计预留约 10 GB/卡。这个值与框架、捕获的 Batch 档位和部署参数有关,不能机械照搬。
五、HBM 带宽:Decode 为什么容易变成访存瓶颈
显存“装得下”只回答容量问题;每一步需要从 HBM 搬多少数据,决定了带宽问题。
总 HBM 流量可拆成:
DHBM=Dweight+DKV+Dact
1. 权重流量
设最忙的一张卡实际访问 kcard 个专家,粗略的单步权重读取量为:
Dweight≈TPSdense+257SMoE⋅2kcard
最不均衡时,kcard 可能接近 9;均衡分布时则更接近:
kcard≈1+EP8
权重读取对 Batch Size 并不线性增长。一次把权重读入片上缓存后,让更多 Token 复用,通常能提高算术强度。这正是 Decode 阶段扩大 Batch 的主要收益之一。
2. KV Cache 流量
Decode 每生成一个 Token,都要读取历史 KV。MLA 下的近似流量为:
DKV/token≈230NLbsk(dc+dR)pKVGB
它会随 Batch 和上下文长度线性增长,因此长上下文 Decode 即使 FLOPs 不高,也可能被 HBM 带宽限制。
3. 激活读写流量
如果中间结果都要落到 HBM,再被下一个 Kernel 读回,那么至少会产生一次写和一次读:
Dact≈2NL(Mlinear+Mscore+MFFN)
对未充分融合的 Prefill,可展开为:
DactPrefill≈2302NL[6bsqdmodel+2bnhsq2+2bsqkdmoe]
对 MLA Decode,可近似写成:
DactDecode≈2302NL[bsqdqc+bsq(dc+dR)+2bsqdmodel+2bnhsqsk+2bsqkdmoe]
这组公式也直接说明算子融合为什么有效:把临时数据留在寄存器、共享内存或 L2 中,可以删除一部分“写回 HBM,再读回来”的往返流量。
六、通信:EP 和 TP 的代价不能只看总带宽
假设 Prefill 使用 TP+EP,Decode 使用 DP+TP+EP,总通信量可拆成:
Dcomm=DEP+DTP
MoE 的 All-to-All 需要发送 Token 的隐藏状态。按“激活的其他专家都在远端”这一偏保守假设:
DEP≈230NMoE⋅2bsqdmodel(k−1)pGB
这里第一个 2 表示 dispatch 与 combine 两个方向。
TP 的 Reduce-Scatter 与 All-Gather 可近似为:
DTP≈230NL⋅2bsqdmodelp⋅TPTP−1GB
代入原文示例参数 NMoE=58、dmodel=7168、k=9、p=2,得到:
DEP≈0.012bsq GB
DTP≈0.00163bsqTPTP−1 GB
这些数值只表示通信量,不等于通信时间。还必须区分数据走的是机内 NVLink/NVSwitch,还是跨机 RDMA:
tcomm≈Bintra,effDintra+Binter,effDinter+tcollective
tcollective 包含协议、同步、小包和尾延迟等开销。EP 越大,单卡专家数越少,但跨机概率通常也越高;是否值得,必须把专家负载均衡、计算形状和网络拓扑放在一起测量。
七、第二步:先消除明显浪费
在扩卡或改并行策略之前,应先删除不产生有效 Token 的工作。
1. 避免重复 Prefill
当大量请求共享系统提示词、文档或会话前缀时,可以用分布式 KV Cache 复用已经完成的 Prefill。原文案例采用 vLLM、LMCache 与远端存储组合,并报告在某个“约 20% 输入重复”的场景中减少了约 16% Prefill 计算。
收益是否成立取决于前缀稳定性、块粒度、命中率、远端读取耗时和 KV 格式兼容性。缓存未命中或远端读取比重算更慢时,缓存本身也可能成为负担。
2. 填平 CPU—GPU 空泡
Decode 的单步很短,CPU 调度和 Kernel Launch 很容易暴露在关键路径上。常用方法包括:
- CUDA Graph 减少重复 Launch;
- Continuous Batching 保持可执行 Batch;
- 当前 Step 的 GPU 工作尚未结束时,CPU 提前准备下一步 Metadata;
- 把采样、停止条件和调度逻辑从 GPU 关键路径移开。
原文案例报告 CPU—GPU 重叠带来 Decode 10% 以上收益,但这不是任何框架、任何负载都能复现的固定数字。
3. 用融合减少 HBM 往返
MoE 路由常包含 GEMM、归一化、Top-K、排序和索引重排。如果每一步都是独立 Kernel,就会产生大量 Launch 和临时张量读写。将它们融合后,收益来自两部分:
Δt≈ΔNlaunchtlaunch+BHBM,effΔDHBM
同理,W4A8 的 Pre-Quant 与 Expand Row 如果能在寄存器或片上存储中完成,就不必把量化中间结果反复写回 HBM。
八、第三步:让不同资源相互匹配
1. P/D 分离
Prefill 更偏计算密集,Decode 更容易受 HBM 容量和带宽限制。P/D 分离的核心不是“拆成两个服务”本身,而是允许两类节点使用不同的并行度、Batch、调度和扩缩容策略:
请求 → Prefill 节点 → KV Cache 传输 → Decode 节点 → 流式输出
代价是新增 KV 传输、路由和一致性问题。因此只有当分阶段调优带来的收益大于传输与系统复杂度时,拆分才有价值。
2. KV 传输与计算重叠
如果先算完所有层,再一次性发送 KV,传输会直接进入关键路径。Layerwise 传输把过程改为“算完一层,异步发送一层”,理想情况下:
t_{\mathrm{Prefill+transfer}}
\approx \max\left(t_{\mathrm{Prefill}},t_{\mathrm{transfer}}
ight)
而不是:
tPrefill+transfer≈tPrefill+ttransfer
但短序列下,过多小包可能让协议开销占主导,因此需要在整块传输、分层传输和小包聚合之间动态选择。
3. 专家负载均衡
MoE 性能取决于最忙的 Rank,而不是平均 Rank。最简单的静态映射可以写成:
GPU_ID=Global_Expert_IDmodNGPU
但热门专家仍可能集中到少数 GPU。生产系统通常还需要专家复制、动态重排、路由约束或跨节点分层放置,并同时观察计算、显存和跨机通信的变化。
九、第四步:从算法层面减少资源需求
1. MLA:压缩 KV Cache
传统 MHA 的 KV Cache 大致随头数和单头维度增长:
MKVMHA∝NLbsknhdh
MLA 把 KV 压缩到低维潜变量:
MKVMLA∝NLbsk(dc+dR)
其主要价值不仅是“少占显存”,更是 Decode 时每个 Token 从 HBM 读取的历史状态显著减少。
2. W4A8 / FP8:压缩权重和搬运量
权重量化带来的理想容量比例为:
MFP8MINT4≈84=21
但端到端加速并不会自动达到 2 倍。反量化、scale 读取、Kernel 支持、GEMM 形状和精度回退都会侵蚀收益。原文提到的 W4A8 吞吐提升属于特定 H20 部署和测试条件,不能脱离模型、并行度与服务目标复用。
3. DSA:把二次复杂度中的大维度换成小维度
传统稠密注意力的主体计算近似为:
Fdense≈2bdmodels2
稀疏注意力先用较小的索引维度 dI 寻找候选,再只对 Top-K 位置做完整计算:
Findexer≈2bHIdIs2
Fsparse≈2bdmodelsK
在原文的 128K 上下文示例中,取 dI=128、dc=512、K=2048。传统 MLA 需要读取的相对数据量为:
DMLA=128000×512=65,536,000
DSA 的索引与稀疏读取量为:
DDSA=128000×128+2048×512=17,432,576
因此相对比例约为:
DMLADDSA≈26.6%
也就是理论读流量下降约 73.4%。这只是该参数组合下的量级估算;候选召回率、索引器成本、Kernel 实现和精度影响仍需实测。
4. mHC:不要只算新增 FLOPs
原文还讨论了 mHC 一类更复杂的残差连接。其额外计算可概括为:
FmHC≈2ndmodel(n2+3n+3)bs+2(n2+2n)+In2
附加状态规模约为:
MmHC≈2ndmodel+n2+2n
对应的读写量近似为:
DmHC≈[(8n+2)dmodel+2n2+4n]bs
这类结构在总 FLOPs 中占比可能不大,却可能受小算子、同步和 HBM 读写影响。评估新结构时,必须同时计算 FLOPs、临时状态和数据搬运,不能只看参数量。
十、把公式变成可执行的优化流程
一套更稳妥的实践顺序是:
- 固定模型、精度、输入/输出长度分布和 SLO;
- 用公式估算每请求的 FLOPs、显存、HBM 流量和通信量;
- 用 Profiler、GPU 指标和网络遥测校正有效算力与有效带宽;
- 判断瓶颈属于计算、容量、访存、通信还是调度空泡;
- 优先删除重复工作和无效搬运;
- 再调整 TP、EP、DP、Batch、Chunk 和专家放置;
- 最后评估量化、MLA、稀疏注意力等更深层改动;
- 每次优化都重新检查 TTFT、TPOT、吞吐、精度和尾延迟。
公式的价值不是给出一个绝对准确的线上数字,而是帮助我们提前排除不可能的方案、定位最值得测量的环节,并检查实测结果是否符合基本量纲。
参考