CH 6 | 实战——MiniMax M3 完整推演

以 MiniMax M3 为目标,从 config.json 出发,完整推演参数分解 → FLOPs 估算 → KV Cache → 推理显存 → 部署方案,覆盖 GQA + MSA + MoE + Vision + MTP 五种架构变体的计算。M3 是目前覆盖计算变体最多的开源模型——一个模型练完基本上所有架构你都会算了。

系列导航(一)预备知识与参数分解(二)FLOPs 估算(三)KV Cache 与推理显存 ← 当前 → (五)训练显存估算(六)通信与掩盖分析

本章使用的前置知识(如果你是跳读的,这些概念在这里能找到定义):

  • FLOPs = 2×m×n×k 及 MAC 概念 → CH 1.2
  • GQA 中 K/V 投影「变窄」→ CH 2.3.2(⚠️ 注意 H_kv × D_h ≠ d
  • SwiGLU 的 3 矩阵结构(gate/up/down)→ CH 2.4.2
  • 激活参 vs 总参(MoE 中每个 token 只激活 top-k 专家)→ CH 2.9
  • MSA 的 Index Branch 机制 → CH 3.3
  • MLA/标准 KV cache 公式 → CH 4.2CH 4.3

6.1 从 config.json 出发

打开 MiniMax-M3config.json,提取以下核心字段(text_config 为主,vision_config 为辅):

字段含义
hidden_size6144残差流维度 $d$
num_hidden_layers60总层数 $L$
num_attention_heads64Q 头数 $H_q$
num_key_value_heads4KV 头数 $H_{kv}$
head_dim128每头维度 $D_h$
vocab_size200,064词表大小 $V$
rope_theta5,000,000RoPE 基频
partial_rotary_factor0.5rotary_dim = 0.5 × 128 = 64
num_local_experts128路由专家数 $E$
num_experts_per_tok4每 token 激活专家 $k$
n_shared_experts1共享专家
intermediate_size3072MoE 专家中间维 $d_{moe\_ff}$
dense_intermediate_size12288Dense FFN 中间维(前 3 层)
shared_intermediate_size3072共享专家中间维
scoring_funcsigmoid路由评分函数
sparse_block_size128MSA block 大小
sparse_topk_blocks16每 query 选择 top-k blocks
sparse_num_index_heads4Index heads 数
sparse_index_dim128Index head_dim
sparse_disable_index_value[0,0,0,1,…1]层 0-2: Full Attn, 层 3-59: MSA
moe_layer_freq[0,0,0,1,…1]层 0-2: Dense FFN, 层 3-59: MoE
vision_config.hidden_size1280ViT 隐藏维度
vision_config.num_hidden_layers32ViT 层数
vision_config.num_attention_heads16ViT 头数
vision_config.patch_size14Patch 大小
vision_config.image_size2016输入图像尺寸
num_mtp_modules7MTP 模块数
max_position_embeddings1,048,576最大上下文 1M

层类型分配

层范围Attention 类型FFN 类型层数
0-2Full Attention (GQA 16:1)Dense FFN (SwiGLU-OAI, $d_{ff}=12288$)3
3-59MSA Sparse AttentionMoE (128E, top-4, sigmoid)57

6.2 参数分解

以下按模块逐一计算,所有数值均从 6.1 节的 config.json 字段推导。

Embedding 层

$$N_{\text{embed}} = V \times d = 200{,}064 \times 6144 = 1{,}229{,}193{,}216 \approx \mathbf{1.229\text{B}}$$

tie_word_embeddings=false → 输入 Embedding + 输出 LM Head 各一份:

$$N_{\text{embed+head}} = 2 \times 1.229\text{B} = \mathbf{2.458\text{B}}$$

Attention 模块(per layer, Full Attn / MSA 共享)

Q 投影:$d \times H_q \times D_h = 6144 \times 64 \times 128 = 50{,}331{,}648 \approx 50.3\text{M}$
K 投影:$d \times H_{kv} \times D_h = 6144 \times 4 \times 128 = 3{,}145{,}728 \approx 3.1\text{M}$
V 投影:$d \times H_{kv} \times D_h = 3{,}145{,}728 \approx 3.1\text{M}$
O 投影:$H_q \times D_h \times d = 64 \times 128 \times 6144 = 50{,}331{,}648 \approx 50.3\text{M}$

Per-layer Q/K/V/O 合计:$\approx \mathbf{107.0\text{M}}$

Indexer(仅 MSA 层 3-59,57 层)

Index Q 投影:$d \times H_{\text{idx}} \times D_{\text{idx}} = 6144 \times 4 \times 128 = 3{,}145{,}728 \approx 3.1\text{M}$
Index K 投影:$d \times 1 \times D_{\text{idx}} = 6144 \times 128 = 786{,}432 \approx 0.79\text{M}$
Index QK Norm:$2 \times (4 \times 128) + 2 \times 128 = 1{,}280$(可忽略)

Per-layer Indexer 合计:$\approx 3.93\text{M}$

Attention 总参

$$\begin{aligned} N_{\text{attn}} &= 3 \times 107.0\text{M} \quad \text{(层 0-2: Full Attn)} \\ &+ 57 \times (107.0\text{M} + 3.93\text{M}) \quad \text{(层 3-59: MSA + Indexer)} \\ &= 321.0\text{M} + 6{,}323.0\text{M} = \mathbf{6.644\text{B}} \end{aligned}$$

Dense FFN(层 0-2,SwiGLU-OAI,$d_{ff}=12288$)

Per layer(non-gated SwiGLU:gate_up 合并为 $6144 \to 2 \times 12288$):

$$N_{\text{gate\_up}} = 6144 \times 2 \times 12288 = 150{,}994{,}944$$


$$N_{\text{down}} = 12288 \times 6144 = 75{,}497{,}472$$

Per-layer 合计:$\approx 226.5\text{M}$。3 层汇总:$\mathbf{0.679\text{B}}$。

MoE 模块(层 3-59,57 层)

每个路由专家(SwiGLU-OAI,$d_{ff}=3072$):

$$N_{\text{expert}} = 6144 \times 2 \times 3072 + 3072 \times 6144 = 37{,}748{,}736 + 18{,}874{,}368 = 56{,}623{,}104 \approx 56.62\text{M}$$

每层 128 个路由专家

$$N_{\text{experts\_per\_layer}} = 128 \times 56.62\text{M} = 7{,}247{,}757{,}312 \approx 7.25\text{B}$$

共享专家(per layer, 1 个):

$$N_{\text{shared}} = 56.62\text{M} \quad (\text{维度与路由专家相同})$$

路由器(per layer):

$$N_{\text{router}} = d \times E = 6144 \times 128 = 786{,}432 \approx 0.79\text{M}$$

每层 MoE 合计:$7.25\text{B} + 0.057\text{B} + 0.0008\text{B} \approx 7.31\text{B}$

57 层 MoE 汇总:$57 \times 7.31\text{B} = \mathbf{416.6\text{B}}$

Vision(ViT + Projector)

ViT 32 层($d_{vit}=1280$, $H_{vit}=16$, $D_{vit}=80$, $d_{ff}^{vit}=5120$):

Per-layer Attention:$4 \times (1280 \times 16 \times 80) = 6.55\text{M}$
Per-layer MLP:$2 \times 1280 \times 5120 = 13.11\text{M}$
32 层合计:$32 \times 19.66\text{M} \approx 0.63\text{B}$
加 patch embedding + Pre-LN + 3D RoPE:$\approx \mathbf{0.65\text{B}}$

Projector(双阶段 MLP):

Stage 1:$1280 \times 6144 + 6144 \times 6144 \approx 45.6\text{M}$
Stage 2(spatial merge):$(4 \times 6144) \times 6144 + 6144 \times 6144 \approx 188.7\text{M}$
合计:$\approx \mathbf{0.23\text{B}}$

Vision 总计:$\mathbf{0.88\text{B}}$

汇总与自洽性验证

组件参数量 (B)占比
Embedding + LM Head2.4580.58%
Attention (Q/K/V/O × 60)6.4201.50%
Indexer (57 层 MSA)0.2240.05%
Dense FFN (3 层)0.6790.16%
MoE 路由专家 (128 × 57)413.2596.7%
MoE 共享专家3.2270.76%
MoE 路由器0.0450.01%
Vision (ViT + Projector)0.8800.21%
Norm 等~0.001~0%
直接求和~427.2100%
官方标称~428B

偏差 < 0.2%,自洽性验证通过。

一个 428B 参数的模型,96.7% 的参数在 MoE 专家里。Attention 只有 6.4B(1.5%)——所以"优化 Attention"(GQA、MSA、MLA)主要是优化计算量和 KV Cache,而不是参数量。参数量的主战场永远是 FFN/MoE。

激活参数

$$\begin{aligned} N_{\text{active}} &= N_{\text{embed}} + N_{\text{attn}} + N_{\text{dense\_ffn}} + N_{\text{shared}} + k \times N_{\text{expert}} \times 57 + N_{\text{router}} + N_{\text{head}} \\ &= 1.23 + 6.64 + 0.68 + 3.23 + (4/128) \times 413.25 + 0.045 + 1.23 \\ &= 1.23 + 6.64 + 0.68 + 3.23 + 12.91 + 0.045 + 1.23 \\ &\approx \mathbf{26.0\text{B}} \end{aligned}$$

加上 Vision 编码器(图像输入时激活 $\approx 0.88\text{B}$):$\approx 26.9\text{B}$。

官方标称 $\sim 23\text{B}$。差异可能来源:(1) Vision 编码器在纯文本推理时不激活;(2) 部分参数共享(如 non-gated SwiGLU 中 gate/up 共享投影可视为半激活)。

$$\text{激活率} = \frac{26}{428} \approx \mathbf{6.1\%}$$

6.3 FLOPs 估算(Decode, T=1M)

计算 M3 在 1M 上下文下 decode 单个 token 的 FLOPs,并对 MSA 和 Full Attention 做定量对比。理解 MSA 到底省了多少计算——不是省了几个百分点,而是省了几个数量级(在 Attention 计算部分)。

decode 阶段($T_{\text{new}} = 1$,$T_{\text{cached}} = 1{,}048{,}576$)为例,BF16 精度,统计 multiply-add 为 2 FLOPs。

6.3.1 Full Attention 层(3 层,层 0-2)

QK 点积(decode 时 Q 只有 1 token,K 有 T cached):

$$\begin{aligned} \text{FLOPs}_{\text{QK}} &= 2 \times H_q \times D_h \times T \\ &= 2 \times 64 \times 128 \times 1{,}048{,}576 \\ &= 16{,}384 \times 1{,}048{,}576 = 1.718 \times 10^{10} \approx \mathbf{17.2 \text{ GFLOPs}} \end{aligned}$$

Attention-V 加权

$$\begin{aligned} \text{FLOPs}_{\text{AttnV}} &= 2 \times H_q \times T \times D_h \\ &= 2 \times 64 \times 1{,}048{,}576 \times 128 = 17.2 \text{ GFLOPs} \end{aligned}$$

Per Full Attn layer decode FLOPs:$17.2 + 17.2 = \mathbf{34.4 \text{ GFLOPs}}$

3 层合计:$3 \times 34.4 = \mathbf{103.1 \text{ GFLOPs}}$

在 1M 上下文中,即使 Q 只有 1 个新 token,QK 点积也要算 1M 次内积(每个 cached K 对新 Q 算一次相似度)。64 个 Q 头 × 128 维 × 1M tokens × 2 = 16.4B 次运算。这就是 Full Attention 在长上下文 decode 中的致命弱点——每生成一个新 token,要跟之前所有 token 做一次全量比较。

6.3.2 MSA 层(57 层,层 3-59)

MSA 分为 Index Branch + Main Attention。

Index Branch

$$\begin{aligned} \text{FLOPs}_{\text{idx QK}} &= 2 \times H_{\text{idx}} \times D_{\text{idx}} \times T \\ &= 2 \times 4 \times 128 \times 1{,}048{,}576 = 1{,}024 \times 1{,}048{,}576 \\ &\approx \mathbf{1.074 \text{ GFLOPs}} \end{aligned}$$

Main Attention(仅在 $K = \text{topk\_blocks} \times \text{block\_size} = 16 \times 128 = 2{,}048$ 个 token 上做精确 attention):

$$\begin{aligned} \text{FLOPs}_{\text{main QK}} &= 2 \times H_q \times D_h \times K \\ &= 2 \times 64 \times 128 \times 2048 = 33{,}554{,}432 \approx \mathbf{33.6 \text{ MFLOPs}} \\ \text{FLOPs}_{\text{main AttnV}} &= 2 \times H_q \times K \times D_h = 33.6 \text{ MFLOPs} \end{aligned}$$

Per MSA layer decode FLOPs:$1{,}074 + 33.6 + 33.6 \approx \mathbf{1.14 \text{ GFLOPs}}$

57 层合计:$57 \times 1.14 = \mathbf{65.0 \text{ GFLOPs}}$

6.3.3 QK 加速比:Full Attn vs MSA

Attention QK 计算部分的加速比(只比较 QK 点积,不含线性投影):

$$\frac{\text{FLOPs}_{\text{QK}}^{\text{Full}}}{\text{FLOPs}_{\text{QK}}^{\text{MSA}}} = \frac{2 \times 64 \times 128 \times 1{,}048{,}576}{2 \times 64 \times 128 \times 2048} = \frac{1{,}048{,}576}{2{,}048} = \mathbf{512\times}$$

单层总 Attention FLOPs 加速比(含 Index Branch + Main Attention 的所有 attention 操作):

$$\frac{34.4 \text{ G}}{1.14 \text{ G}} \approx \mathbf{30.2\times}$$

为什么 512× 变成了 30×?因为 MSA 的 Index Branch 自身也有 FLOPs(1.07 GFLOPs),而且这 1.07G 在层总 FLOPs 中占比不小(1.07/1.14 ≈ 94%)。Index Branch 仍然需要 O(T) 的 QK 计算——它的目的是筛选 top-k blocks,而非跳过 QK 计算。

MSA 的 512× QK 加速是在 Main Branch 上实现的(2,048 vs 1M tokens),但 Index Branch 自身仍做 O(T) 扫描(只不过用了更少的 head:4 vs 64,所以也便宜了 16×)。总体效果约 30×,这意味着同样 1M 上下文,MSA 的 decode 比 Full Attention 快 30 倍——但仍然比短上下文(如 4K)的 Full Attention 要慢(因为 Index Branch 的 O(T) 扫描无法避免)。

6.3.4 线性投影 FLOPs(60 层共享)

Q、K、V、O 四个线性投影(per layer):

$$\begin{aligned} \text{Q proj} &= 2 \times 1 \times 6144 \times (64 \times 128) = 2 \times 6144 \times 8192 = 100.7 \text{ MFLOPs} \\ \text{K proj} &= 2 \times 1 \times 6144 \times (4 \times 128) = 2 \times 6144 \times 512 = 6.3 \text{ MFLOPs} \\ \text{V proj} &= 2 \times 1 \times 6144 \times 512 = 6.3 \text{ MFLOPs} \\ \text{O proj} &= 2 \times 1 \times (64 \times 128) \times 6144 = 100.7 \text{ MFLOPs} \end{aligned}$$

Per-layer 投影合计:$\approx 213.9 \text{ MFLOPs}$。60 层:$\mathbf{12.8 \text{ GFLOPs}}$。

6.3.5 MoE FFN FLOPs(57 层,per token)

共享专家(intermediate=3072,SwiGLU-OAI):

$$\begin{aligned} \text{gate\_up} &= 2 \times 1 \times 6144 \times (2 \times 3072) = 2 \times 6144 \times 6144 = 75.5 \text{ MFLOPs} \\ \text{down} &= 2 \times 1 \times 3072 \times 6144 = 37.7 \text{ MFLOPs} \\ \text{shared total} &= 75.5 + 37.7 = \mathbf{113.2 \text{ MFLOPs}} \end{aligned}$$

4 个路由专家

$$\text{routed total} = 4 \times 113.2 = \mathbf{452.8 \text{ MFLOPs}}$$

路由器:$2 \times 1 \times 6144 \times 128 = \mathbf{1.6 \text{ MFLOPs}}$

Per MoE layer decode FLOPs:$113.2 + 452.8 + 1.6 = \mathbf{567.6 \text{ MFLOPs}}$

57 层 MoE:$57 \times 0.5676 = \mathbf{32.4 \text{ GFLOPs}}$

6.3.6 Dense FFN FLOPs(3 层,per token)

Per layer(intermediate=12288):

$$\begin{aligned} \text{gate\_up} &= 2 \times 1 \times 6144 \times (2 \times 12288) = 2 \times 6144 \times 24576 = 302.0 \text{ MFLOPs} \\ \text{down} &= 2 \times 1 \times 12288 \times 6144 = 151.0 \text{ MFLOPs} \\ \text{per layer total} &= \mathbf{453.0 \text{ MFLOPs}} \end{aligned}$$

3 层合计:$\mathbf{1.36 \text{ GFLOPs}}$

6.3.7 MSA Indexer 投影 FLOPs(57 层)

Index Q 投影:$2 \times 1 \times 6144 \times (4 \times 128) = 6.3 \text{ MFLOPs}$
Index K 投影:$2 \times 1 \times 6144 \times 128 = 1.6 \text{ MFLOPs}$
Per-layer:$\approx 7.9 \text{ MFLOPs}$。57 层:$\mathbf{0.45 \text{ GFLOPs}}$

6.3.8 全模型 Decode FLOPs 汇总

组件层数Per-layer (GFLOPs)合计 (GFLOPs)
Full Attention (QK + AttnV)334.4103.1
MSA Attention (Idx + Main)571.1465.0
线性投影 (Q/K/V/O)600.21412.8
Dense FFN30.4531.36
MoE FFN (shared + 4 routed)570.56832.4
Indexer 投影570.0080.45
Embedding + LM Head1~0.02
Total per decode token @1M~215 GFLOPs

6.3.9 与"全 Full Attention M3"对比

如果 M3 的 57 个 MSA 层全部替换为 Full Attention(保持所有其它参数不变):

$$\begin{aligned} \text{FLOPs}_{\text{Full-only QK+AttnV}} &= 103.1 + 57 \times 34.4 = 103.1 + 1{,}960.8 = \mathbf{2{,}064 \text{ GFLOPs}} \\ \text{FLOPs}_{\text{MSA (actual)}} &= 103.1 + 65.0 = \mathbf{168.1 \text{ GFLOPs}} \end{aligned}$$$$\text{Attention 计算加速比} = \frac{2{,}064}{168.1} \approx \mathbf{12.3\times}$$

若计算全模型 FLOPs(含投影 + FFN):

$$\text{FLOPs}_{\text{Full-only total}} = 2{,}064 + 12.8 + 1.36 + 32.4 + 0.02 = 2{,}111 \text{ GFLOPs}$$$$\text{Overall speedup} = \frac{2{,}111}{215} \approx \mathbf{9.8\times}$$

Attention 计算加速 12.3×,但因线性投影和 FFN 不变,总体加速约 10×。M3 花了 57 层 Indexer 的代价(+0.224B 参数,占总参 0.05%),换来了约 10 倍的 decode 速度提升。这是 MSA 被称为 “architectural free lunch” 的原因。


6.4 KV Cache(T=1M)

Main KV Cache(60 层)

$$\begin{aligned} M_{\text{kv}}^{\text{main}} &= 60 \times 2 \times 4 \times 128 \times 1{,}048{,}576 \times 2 \\ &= 60 \times 2 \times 4 \times 128 \times 1{,}048{,}576 \times 2 \\ &= 128{,}849{,}018{,}880 \text{ bytes} \\ &\approx \mathbf{120.0 \text{ GiB}} \end{aligned}$$

Index K Cache(57 层 MSA)

$$\begin{aligned} M_{\text{kv}}^{\text{index}} &= 57 \times 1 \times 128 \times 1{,}048{,}576 \times 2 \\ &= 15{,}300{,}329{,}472 \text{ bytes} \\ &\approx \mathbf{14.3 \text{ GiB}} \end{aligned}$$

总 KV Cache(per sample, BF16)

$$M_{\text{kv}}^{(1)} = 120.0 + 14.3 = \mathbf{134.3 \text{ GiB}}$$

分项占比

KV Cache per sample @1M = 134.3 GiB
┌──────────────────────────────────────────────────────────┐
│████████████████████████████████████████████████          │ Main KV (120.0 GiB, 89.4%)
│██████                                                      │ Index K (14.3 GiB, 10.6%)
└──────────────────────────────────────────────────────────┘

MSA 的 KV Cache 与 Full Attention 完全相同——稀疏性只体现在计算(哪些 KV 被访问),不体现在存储(所有 KV 仍需缓存,因为不同 query 可能选择不同 blocks)。Index K Cache 额外增加了约 10.6% 的 KV Cache 开销。这是 MSA 与 sliding window attention 的本质区别——后者可以裁剪 KV Cache,但 MSA 不能(理论上可以 evict 从未被任何 query 选中的 block,但这需要额外的 bookkeeping)。

Batch Scaling

Batch SizeMain KV (GB)Index KV (GB)Total KV (GB)
1120.014.3134.3
2257.730.6288.3
4515.461.2576.6
81,030.7122.41,153.1

Batch=4 时 KV Cache 已超过 500 GiB——仅 KV Cache 就够塞满 4 张 H200。这是长上下文推理的核心瓶颈。


6.5 推理显存

BF16 精度,单样本,1M 上下文

$$\begin{aligned} M_{\text{weights}} &= 428 \times 10^9 \times 2 = \mathbf{856 \text{ GB}} \\ M_{\text{kv}} &= \mathbf{134.3 \text{ GiB}} \\ M_{\text{act+overhead}} &\approx \mathbf{5 \text{ GiB}} \\ M_{\text{total}}^{(1)} &= 856 + 134.3 + 5 \approx \mathbf{995 \text{ GB/GiB}} \quad (\text{权重 GB + 其余 GiB,单位混合,近似值}) \end{aligned}$$

硬件匹配

以 8 × H200(141 GiB/card,合计 1,128 GiB)为目标平台:

Step 1:权重装得下吗?

$$M_{\text{weights}} = 856 \text{ GB} < 1{,}128 \text{ GiB} \quad \checkmark$$

Step 2:可用显存

$$M_{\text{available}} = 1{,}128 - 856 = \mathbf{272 \text{ GiB}} \quad (\text{8 卡合计})$$

Step 3:最大并发 batch

$$B_{\text{max}} = \left\lfloor \frac{272}{134.3 + 5} \right\rfloor = \left\lfloor \frac{272}{139.3} \right\rfloor = \lfloor 1.82 \rfloor = \mathbf{1 \text{ sample}}$$

结论:BF16 下 8×H200 可以跑 M3 的 1M 上下文 BF16 推理,但只能支持最多 1 个并发请求。batch=2 理论上可能($272 / 139.3 \approx 1.8$),但接近显存上限,实际部署中不建议。

FP8 权重 + BF16 KV Cache

$$\begin{aligned} M_{\text{weights}} &= 428 \times 10^9 \times 1 = \mathbf{428 \text{ GB}} \\ M_{\text{available}} &= 1{,}128 - 428 = \mathbf{700 \text{ GiB}} \\ B_{\text{max}} &= \left\lfloor \frac{700}{139.3} \right\rfloor \approx \mathbf{4 \text{ samples}} \end{aligned}$$

FP8 权重 + FP8 KV Cache

$$\begin{aligned} M_{\text{kv}}^{(1)\text{ FP8}} &= 134.3 / 2 = \mathbf{67.15 \text{ GiB}} \\ M_{\text{available}} &= 1{,}128 - 428 = 700 \text{ GiB} \\ B_{\text{max}} &= \left\lfloor \frac{700}{67.15 + 5} \right\rfloor \approx \mathbf{9 \text{ samples}} \end{aligned}$$

汇总表

精度方案权重 (GB)KV/样本 (GB)可用 (GB)Max Batch @1M
BF16 W + BF16 KV856134.32721
FP8 W + BF16 KV428134.37004
FP8 W + FP8 KV42867.157009
INT4 W + FP8 KV21467.1591412

对比 Nemotron(5.7 节):Nemotron 从 BF16→FP8 后 batch 从 1→38,M3 只从 1→4。原因:M3 的 KV Cache 占比高(144 GiB/样本),量化权重解放的显存很快被 KV Cache 吃掉。M3 的显存瓶颈是双重的——权重和 KV Cache 都制约并发。


6.6 验算与交叉对比

与 M3 官方博客声明对照

M3 官方博客声称 MSA 在 1M 上下文下实现 ~30× decode 加速。本节 6.3.3 的直接计算给出:

$$\text{Per-layer Attention FLOPs ratio} = \frac{34.4 \text{ G}}{1.14 \text{ G}} \approx 30.2\times$$

全模型(含投影+FFN):$\approx 9.8\times$。

差异解释:官方的 30× 是指 Attention 计算部分(QK + AttnV),不含线性投影(Q/K/V/O)和 FFN。两者都是正确的——只是口径不同:

  • 30×:Attention 算子层面(孤立地看 MSA 替代 Full Attention 的效果)
  • 10×:端到端 decode 速度(含所有矩阵乘法和 FFN)

当别人说"MSA 让 M3 快了 30 倍",他说的是注意力计算。当你说"为什么我实测只快了 10 倍",因为你还算上了 FFN 和线性投影。两者都对,但需要明确口径。

与纯 Full Attention M3 的显存对比

如果 M3 不使用 MSA(即全部 60 层 Full Attention),KV Cache 变化:

$$\begin{aligned} M_{\text{kv}}^{\text{Full-only}} &= 60 \times 2 \times 4 \times 128 \times 1{,}048{,}576 \times 2 = 120.0 \text{ GiB} \\ M_{\text{kv}}^{\text{MSA (actual)}} &= 134.3 \text{ GiB} \end{aligned}$$

KV Cache 不降反增(+14.3 GiB Index K)——MSA 在显存上不是优化,是略微增加了开销。MSA 的价值在计算(FLOPs),不在存储(Memory)。

与 Nemotron 550B 的横向对比

维度Nemotron 550BMiniMax M3比值
总参550B428B1.29×
BF16 权重1,100 GB856 GB1.29×
KV Cache (1M, BF16)13 GiB144 GiB0.09×
KV/Weights 比1.2%16.8%14× 差异
Decode FLOPs/T~300G (estimate)~215G~1.4×
显存瓶颈类型纯权重权重 + KV Cache 双瓶颈
FP8 后 Batch (8×H200)3849.5× 差异

核心洞见:Nemotron 用 Mamba-2 置换 Attention 的策略,在 1M 上下文下产生了约 10× 的 KV Cache 优势。这个优势在短上下文(< 32K)下不明显(因为 KV Cache 本来就小),但随着上下文增长到 1M 时成为决定性的架构差异。MSA 解决了 Attention 的计算瓶颈,但没有解决存储瓶颈——在极端长上下文下,Mamba-2/MLA 的 KV Cache 优势会越来越明显。


CH 7 | Roofline 模型与推理延迟 —— 「算力够,为什么还是慢」

CH 3 给出了每 token 的 FLOPs,CH 6 算出了需要多少张卡。现在回答第三个问题:在这些卡上,每 token 实际要跑多少毫秒?

一个最直观的错误做法:把 FLOPs 除以 GPU 峰值算力。

以 M3 BF16 decode($T=1\text{M}$,8×H200,FP8 权重 + BF16 KV)为例:

$$\text{Naive latency} = \frac{215\text{G FLOPs/token}}{8 \times 989\text{ TFLOPS}} \approx 0.027\text{ ms}$$

如果真是 0.027 ms/token,那就是 37,000 tokens/s——没有任何 LLM 推理系统达到过这个速度。实际 M3 的 decode 延迟大约在 10-30 ms/token 量级。差了 200-1000 倍(取决于精度和配置)。

不是 FLOPs 算错了(前几章已经反复验证),而是前提错了:GPU 的峰值算力只有在算术强度足够高的 workload 上才能跑满。Decode 根本不具备这个条件。

7.1 算术强度:每次读一个字节的数据,能做多少 FLOPs

定义

$$\text{Arithmetic Intensity (AI)} = \frac{\text{Total FLOPs}}{\text{Total Bytes Read from HBM}}$$

单位是 FLOPs/byte。AI 高 → 算力瓶颈(compute-bound),AI 低 → 带宽瓶颈(memory-bound)。

GPU 可以同时视为两个设备:

  • 算力设备(Tensor Core):上限 = 峰值 FLOPs(如 H200 BF16 = 989 TFLOPS)
  • 带宽设备(HBM):上限 = 内存带宽(如 H200 = 4.8 TB/s)

实际能达到的算力由两者共同决定:

$$\text{Achievable TFLOPS} = \min(\text{Peak TFLOPS}, \text{AI} \times \text{Bandwidth})$$

这就是 Roofline 模型的核心公式。画成图是一条折线:低 AI 时是斜率为带宽的斜线,高 AI 时是峰值算力的天花板。拐点叫 Roofline Ridge

$$\text{AI}_{\text{ridge}} = \frac{\text{Peak TFLOPS}}{\text{Bandwidth}}$$

对 H200 BF16:$\text{AI}_{\text{ridge}} = \frac{989 \times 10^{12}}{4.8 \times 10^{12}} \approx 206 \text{ FLOPs/byte}$。

这意味着:任何 AI < 206 FLOPs/byte 的 workload 都跑不满 H200 的算力——它被带宽卡住了。AI 越低,利用率越惨。

关键 GPU 的 Roofline 参数

GPUBF16 PeakHBM BWAI_ridge (BF16)FP8 PeakAI_ridge (FP8)
H100 SXM989 TFLOPS3.35 TB/s2951,979 TFLOPS591
H200 SXM989 TFLOPS4.8 TB/s2061,979 TFLOPS412
B200~2,250 TFLOPS8 TB/s281~4,500 TFLOPS562
A100 SXM312 TFLOPS2.0 TB/s156

注意:H200 的算力与 H100 相同,但带宽高 43%。Ridge 从 295 降到 206——更容易进入 memory-bound 了。这是因为 H200 的"带宽提升"跑赢了"算力不变"。

7.2 Decode 为什么一定 memory-bound

7.2.1 关键观察:每生成一个 token,要读一遍所有权重

Decode 是逐 token 生成的。每生成一个新 token,整个模型的所有层都要算一遍 forward pass。每次 forward pass 必须从 HBM 读取权重(假设不在 cache 中)。

密集模型(如一个 70B Dense 模型,BF16):

$$\text{AI}_{\text{decode}} \approx \frac{2N}{N \times \text{bytes\_per\_param}} = \frac{2}{\text{bytes\_per\_param}}$$

其中 $2N$ 是因为每个参数约对应 2 次 FLOPs(1 multiply + 1 add per MAC),$N \times \text{bytes\_per\_param}$ 是把所有权重读一遍的字节数。

代入 BF16:

$$\text{AI}_{\text{decode}} \approx \frac{2}{2} = 1 \text{ FLOPs/byte}$$

1 FLOPs/byte。 对比 H200 的 ridge = 206。差了 200 倍。Decoder-only 模型的 decode 阶段天生 memory-bound,这不是实现问题,是架构决定的。

更精确地算,需要考虑 Attention 部分(QK 点积要读 KV cache),但对大模型来说 FFN 权重占绝对主导,AI ≈ 1 是很好的近似。

7.2.2 MoE 稀疏化的帮助

MoE 改变了这个情况。每 token 只激活 $k$ 个专家,所以需要读的权重少了:

$$\text{AI}_{\text{decode}}^{\text{MoE}} \approx \frac{2N_{\text{active}}}{N_{\text{active}} \times \text{bytes\_per\_param}} = \frac{2}{\text{bytes\_per\_param}}$$

等等——公式和密集模型一样?是的,因为活跃 FLOPs 和活跃字节数同比缩放。MoE 不改变每活跃参数的 Arithmetic Intensity。

但 MoE 改变了什么?**改变了总计算量和延迟的绝对值。**因为活跃参是总参的 ~5-10%,所以虽然 AI 还是 ~1,但 workload 变小了——读 23B 参的权重比读 428B 参的权重快 18.6×。

换一个角度:MoE 的密集等价模型(Dense model with same FLOPs)的 AI 相同,延迟也相同。MoE 用更少的活跃参达到同等的模型能力,从而用更小的 HBM 读取量实现了更低的延迟。

7.2.3 Prefill 为什么不同

Prefill(首次处理整个 prompt)的 FLOPs 包含 Attention 的 $O(T^2)$ 项:

$$\text{AI}_{\text{prefill}} \approx \frac{2N + O(T^2 \cdot H \cdot D)}{N \times \text{bytes\_per\_param}}$$

当 $T$ 较大时(对 70B 模型约 $T > 100\text{K}$,具体 crossover 点取决于 $N/(H_q \cdot D_h \cdot L)$),Attention QK 点积的 FLOPs($O(T^2)$)超过线性投影的 FLOPs($O(T)$)。此时 FLOPs 急剧增长但权重读取不变,AI 飙升,prefill 会从 memory-bound 转为 compute-bound

这就是为什么 prefill 的 MFU 可以到 40-50%,而 decode 的 MFU 通常只有 1-5%——不是 decode 写得差,是 decode 的算术强度决定了它只能在带宽限制内跑。

7.3 从 AI 到延迟——三步推导法

给定一个模型和一个 GPU,推导 decode 延迟只需三步。

第一步:算出一个 token 要读多少字节

$$\text{Bytes}_{\text{HBM}} = \underbrace{N_{\text{active}} \times \text{bytes\_per\_param}}_{\text{权重}} + \underbrace{\text{KV\_bytes\_per\_token}}_{\text{KV Cache 读取}}$$

对密集模型,$N_{\text{active}} = N$。对 MoE,$N_{\text{active}}$ = 非 MoE 参数 + $k \times$ 每专家参数。

KV Cache 读取是 attention 计算的一部分——需要把缓存的所有 K 和 V 读出来做点积。对 GQA,全序列 attention 的 KV 读取量 = $H_{kv} \times D \times T \times \text{bytes\_per\_elem} \times 2$(K+V)。当 $T$ 很大时,这一项不可忽略。

第二步:用 Roofline 算 achievable TFLOPS

$$\text{Achievable TFLOPS} = \min\left(\text{Peak TFLOPS}, \frac{\text{FLOPs}}{\text{Bytes}_{\text{HBM}}} \times \text{Bandwidth}\right)$$

对 decode,由于 AI ≈ 1–5 « 206,一定取右边(memory-bound):

$$\text{Achievable TFLOPS} = \text{AI} \times \text{Bandwidth}$$

第三步:算延迟下限

$$T_{\text{per\_token}} \geq \frac{\text{FLOPs\_per\_token}}{\text{Achievable TFLOPS}} = \frac{\text{Bytes}_{\text{HBM}}}{\text{Bandwidth}}$$

最后一个等号在 memory-bound 时成立。直觉:memory-bound 时延迟不由 FLOPs 决定,而由"读完所有权重要多久"决定。

7.4 案例:70B Dense 模型 on 1×H200(BF16)

这是最简单的情况,用来建立直觉。

模型:Llama-3 70B 级别,$d = 8192$,$L = 80$,GQA 8:1。

每 token 权重读取:$70 \times 10^9 \times 2 = 140 \text{ GB}$

每 token FLOPs:$\approx 2 \times 70 \times 10^9 = 140 \text{ GFLOPs}$

KV Cache 读取(per layer,$T = 128\text{K} = 131,072$):

$$\text{KV\_read} = H_{kv} \times D \times T \times 2 \times 2 \text{ (K + V, BF16)} = 8 \times 128 \times 131{,}072 \times 2 \times 2 \approx 5.4 \times 10^8 = 0.54 \text{ GB}$$

对比:每层权重读取 $\approx 70\text{B} / 80 \times 2 \approx 1.75 \text{ GB}$。每层 KV 读取约为权重读取的 30%——不算完全可忽略,但为简化推导我们先用权重主导近似($\text{AI} \approx 1$),更精确计算($\text{AI} \approx 0.76$)不改变 memory-bound 结论。

算术强度

$$\text{AI} = \frac{140 \times 10^9}{140 \times 10^9} = 1.0 \text{ FLOPs/byte}$$

H200 Roofline:AI = 1 ≪ 206 → memory-bound。

$$\text{Achievable TFLOPS} = 1.0 \times 4.8 \times 10^{12} = 4.8 \text{ TFLOPS}$$

实际 MFU:$4.8 / 989 = 0.49\%$。不到 1%。

延迟

$$T_{\text{per\_token}} \approx \frac{140 \times 10^9}{4.8 \times 10^{12}} \approx 29 \text{ ms}$$

对应 34 tokens/s。如果 naive 地用 FLOPs / peak:$140\text{G} / 989\text{T} ≈ 0.14\text{ ms}$——差了 200×。

为什么实际可能比 29ms 略慢

  • 权重可能读不到完整的 4.8 TB/s 带宽(实际 ~70-80%)
  • 存在 kernel launch overhead
  • Attention 计算本身有额外的 HBM 访问模式不连续(GQA gather)
  • 实际项目中还会有采样、KV cache 管理等开销

实测 Llama-3 70B 在单卡 H200 上的 decode 延迟约为 35-45 ms/token,与我们的理论下限 29 ms 在同一量级。

7.5 案例:M3 MoE BF16 Decode on 8×H200

现在用 Roofline 分析 CH 6 推演过的 M3。

活跃参数(CH 2):~23B/ token。BF16 下 = 46 GB 权重读取。

FLOPs(CH 6):~215 GFLOPs/token。

KV Cache 读取($T=1\text{M}$):MSA 层只选 2048 个 token 的 KV($57 \times 4 \times 128 \times 2048 \times 2 \times 2 \approx 0.24$ GB),全 attention 层(3 层)需读全部 $T$($3 \times 4 \times 128 \times 1\text{M} \times 2 \times 2 \approx 6.4$ GB)。合计约 6.7 GB/token,占活跃权重读取(46 GB)的 ~15%。属于次要项,为简化先忽略。

算术强度

$$\text{AI} = \frac{215 \times 10^9}{46 \times 10^9} \approx 4.7 \text{ FLOPs/byte}$$

4.7 ≪ 206,仍然 memory-bound。

单卡 achievable TFLOPS:$4.7 \times 4.8 \times 10^{12} ≈ 22.4 \text{ TFLOPS}$。

但这里是多卡。 8×H200 共享权重的读取——专家分布在 8 张卡上(EP=8),每张卡只持有部分专家。对于单个 token,该 token 激活的 4 个专家可能分布在 4 张不同的卡上,每张卡读取的权重约为:

$$\text{Bytes}_{\text{per\_card}} \approx \frac{46}{4} \approx 11.5 \text{ GB}$$$$\text{单卡延迟} \approx \frac{11.5 \times 10^9}{4.8 \times 10^{12}} \approx 2.4 \text{ ms}$$

,EP 引入了 all-to-all 通信——卡之间需要 shuffle token 到持有对应专家的卡。这个通信开销(Gap 3 详述)可能使实际延迟翻倍。初步估计 decode 延迟在 5-15 ms 量级,与社区报告的 MoE 推理延迟一致。

关键是:如果 naive 地用 215G / (8 × 989T) 算,得到 0.027 ms,偏差 > 200×。 FLOPs 算对了,但没算"这些 FLOPs 在什么条件下执行"。

7.6 FP8/INT4 量化对延迟的影响

量化(FP8、INT4)减少的是每个参数的字节数,直接提升 AI。

精度bytes/paramDense AIM3 MoE AIBandwidth-bound time
BF1621.04.7baseline
FP812.09.32× 提升
INT40.54.018.74× 提升

但要注意:AI 提升只在 memory-bound 阶段有效。如果 AI 达到 ridge(对 H200 BF16 是 206),再降精度也不会提速——此时已进入 compute-bound。对 decode,即使 INT4 的 AI = 18.7 也远未到 206,所以量化对 decode 全程有效

这就是为什么 FP8 推理能让 decode 延迟接近减半:不是算得快了(算力没变),而是读得少了(每参数 1 byte vs 2 bytes),带宽负担减半。

7.7 Batch Size 对 Decode 延迟的影响

当 batch size $B > 1$ 时,权重读取被 $B$ 个样本共享(权重读完一次,可以给 $B$ 个 token 分别算):

$$\text{AI}(B) \approx \frac{B \times 2N_{\text{active}} + B \times \text{Attn\_FLOPs}}{N_{\text{active}} \times \text{bytes\_per\_param} + B \times \text{KV\_read\_per\_token}}$$
  • 分子:$B$ 个 token 的总 FLOPs(线性投影随 $B$ 线性增长)
  • 分母:权重只读一次,KV cache 每个 token 都要读

关键特性:权重读取不随 batch 增长(同一个权重矩阵用 $B$ 次),KV cache 读取随 batch 增长

当 $B$ 较小时($B=1-4$,推理常见场景),权重读取占主导,$B$ 增大带来显著的 AI 提升:

$$\text{B=1: AI ≈ 4.7, B=4: AI ≈ 4 × 4.7 = 18.8}$$

当 $B$ 足够大时,KV cache 读取成为新的瓶颈(因为它随 $B$ 线性增长)。但即使 $B=128$,对 M3 来说 AI ≈ 50-80,仍低于 H200 ridge = 206——仍在 memory-bound。

工程启示:在显存允许范围内,增大 batch size 能提升吞吐(tokens/s),但对单个 token 的首 token 延迟(TTFT)几乎无帮助——那是 prefill 的问题,而 prefill 通常已是 compute-bound。

7.8 三个模型 Decode 延迟对比

用 Roofline 方法估算几个代表性模型在 $T=1\text{M}$、BF16 下的 decode 延迟(不考虑通信开销的理论下界):

模型活跃参活跃权重(BF16)FLOPs/TAI理论延迟/卡主要限制
Llama-3 70B (Dense, 1×H200)70B140 GB140G1.0~29 ms纯带宽
Nemotron 550B (MoE+Mamba)55B110 GB~300G~2.7~23 ms带宽+EP通信
M3 (MoE+MSA)23B46 GB215G~4.7~5-15 ms带宽+EP通信

注意 Nemotron 活跃参(55B)比 M3(23B)大 2.4×,即使 Mamba-2 层的计算效率更高,其 decode 延迟仍受制于更大的权重读取量。这就是为什么活跃参数是推理延迟的第一性指标——它是 AI 公式分子的底层影响因素。

7.9 Roofline 视角下的架构设计启示

从 Roofline 分析出发,理解当前架构设计的选择逻辑:

MLA(K2.5 / DeepSeek V4):MLA 压缩 KV cache 的主要收益在存储(CH 4 详述),对 decode latency 的影响是间接的——KV cache 更小意味着同张卡可以装更大的 batch,间接提升吞吐。MLA 不直接改变每 token 的权重读取量,所以不直接降低单 token 延迟

MSA(M3):MSA 减少 attention 计算 FLOPs,但 decode 阶段 attention 计算本身不是瓶颈(它是 memory-bound,减 FLOPs 不改变延迟)。MSA 对 decode 延迟的收益是减少 KV cache 读取量——只读 2048 个 token 的 KV 而非全序列。在 $T=1\text{M}$ 时,这个优化把 KV 读取从 ~50 GB 降到 ~2 GB。

MoE:MoE 降低每 token 的活跃参数量 → 减少权重读取 → 降低延迟。这是 decode 延迟最直接的架构杠杆。

Mamba-2(Nemotron):用状态空间替代 Attention + KV cache。根本不需要 KV cache 读取 → 消除了 decode 中一个重要的带宽消耗源。结合 MoE 的稀疏化,进一步降低每 token 的有效工作量。

7.10 速查:Roofline 分析四步法

给定任意模型 + GPU,判断推理延迟:

  1. 算 AI:$AI = \frac{\text{FLOPs\_per\_token}}{\text{active\_weight\_bytes} + \text{KV\_read\_bytes}}$
  2. 判瓶颈:AI < AI_ridge → memory-bound;AI ≥ AI_ridge → compute-bound
  3. 求 achievable TFLOPS:$\min(\text{Peak}, \text{AI} \times \text{Bandwidth})$
  4. 得延迟:$T_{\text{token}} = \frac{\text{FLOPs\_per\_token}}{\text{achievable\_TFLOPS}}$

对绝大多数 LLM decode 场景,第 2 步的答案是 memory-bound。牢记这一点,就不会再犯 “FLOPs ÷ Peak” 的错误。


本章定位:Roofline 模型给出了单卡无通信场景下的延迟下限。实际多卡推理中,TP/PP/EP 的通信开销会在此基础上叠加——这是 communication-methodology.md 要解决的主题。本章的 “B=1, no comm” 延迟应理解为 理论下界,实际系统在此基础上 ×1.5–3×。


本章公式速查

计算目标公式说明
权重显存$M_w = N \times \text{bytes}$$N$ 为总参数量
GQA KV Cache (per layer)$2 \times H_{kv} \times D_h \times T \times \text{bytes}$K 和 V 两份
MLA KV Cache (per layer)$(d_{kv} + D_{rope}) \times T \times \text{bytes}$只存压缩向量
MSA Index KV (per layer)$1 \times D_{\text{idx}} \times T \times \text{bytes}$只有 K
总显存$M_w + B \times M_{kv}^{(1)} + M_{act}$Batch 乘 KV
MoE 激活参$\text{Non-MoE} + k \times \text{Params}_{\text{expert}}$$k$ 为 top-k
Full Attn decode QK FLOPs$2 \times H_q \times D_h \times T$$T$ = cached length
MSA Main QK FLOPs$2 \times H_q \times D_h \times K$$K$ = 2048 (16 blocks × 128)
最低卡数$\lceil M_w / \text{per\_card} \rceil$仅考虑权重
最大 Batch$\lfloor (M_{pool} - M_w) / (M_{kv}^{(1)} + M_{act}) \rfloor$考虑 KV Cache
算术强度 (AI)$\text{AI} = \frac{\text{Total FLOPs}}{\text{Bytes read from HBM}}$FLOPs/byte
Roofline Ridge$\text{AI}_{\text{ridge}} = \frac{\text{Peak TFLOPS}}{\text{Bandwidth}}$AI < ridge → memory-bound
Achievable TFLOPS$\min(\text{Peak}, \text{AI} \times \text{Bandwidth})$memory-bound 时取右边
Dense decode AI(近似)$\text{AI} \approx 2 / \text{bytes\_per\_param}$BF16 → 1, FP8 → 2, INT4 → 4
Decode 延迟下限$T_{\text{token}} \geq \frac{\text{Bytes}_{\text{HBM}}}{\text{Bandwidth}}$memory-bound 时成立
Prefill AI(大 T 近似)$\text{AI}_{\text{prefill}} \gg \text{AI}_{\text{decode}}$O(T²) FLOPs 提升 AI → compute-bound

本章常见计算错误

#错误正确做法
1用 $H_q$ 代替 $H_{kv}$ 算 KV CacheKV Cache 宽度由 KV 头数决定(GQA 下 $H_{kv} \ll H_q$),与 Q 头数无关
2MSA 的 KV Cache 忘记 Index KMSA 额外存储 1 个 Index K(每层 1 头 × $D_{idx}$),约占总 KV Cache 的 10%
3认为 MSA 减少了 KV CacheMSA 减少的是计算(FLOPs),不是存储(KV Cache)——两者解耦
4EP 只看总显存够不够EP 要求每张卡装得下其分配的专家子集 + 非 MoE 参数副本,不能只看平均数
5Batch 乘 KV Cache 时忘记 batch 效应权重跨 batch 共享,KV Cache 不共享——$B=100$ 就是 100× KV
6混淆 Attention 加速比和端到端加速比30× 是 per-layer Attention 算子加速;10× 是全模型 end-to-end 加速(含不变的线性投影和 FFN)
7激活值完全忽略虽然通常 < 权重的 5%,但在 tight memory budget 下 5% = 50 GiB(8 卡场景),可能就是 OOM 的原因
8用 FLOPs ÷ Peak TFLOPS 算 decode 延迟Decode 的 AI ≈ 1-5 ≪ Ridge(~200),是 memory-bound。延迟 = Bytes / BW,不是 FLOPs / Peak。偏差 50-500×
9认为 FP8 使 decode 算得更快FP8 加速 decode 不是算力翻倍(memory-bound 下用不到 Peak),而是权重字节数减半 → 读取时间减半
10认为 MoE 的 decode AI 比 Dense 高很多AI 公式中活跃 FLOPs 和活跃 Bytes 同比缩放(≈ 2 / bytes_per_param),MoE 降低的是绝对值而非 AI。例外:MoE router + dispatch 有额外开销
11忽略 KV cache 读取对带宽的消耗短上下文可忽略,但 $T=1\text{M}$ 时 KV 读取可达 GB/层量级。MSA/稀疏注意力通过减少读 KV 量来缓解
12认为增大 batch 能无限提升吞吐提升 AI 的边际递减——KV cache 读取随 B 增长,权重读取固定。超大 B 时 KV 读取成为新瓶颈

各模型 BF16 推理显存横评

模型总参权重 (GB)KV/样本 (GB)可用 (GB)Max Batch
Nemotron 3 Ultra550B1,10013281
MiniMax M3428B8561442721
DeepSeek V4 Flash~300B~600~72 (MLA)~528~7
Kimi K2.5~1T~2,000~72 (MLA)< 0 (OOM!)需 16 卡+

注:K2.5 BF16 推理即使 16 张 H200 (2,256 GiB) 也只能负载 ~2,000 GiB 权重 + 少量 KV。实际部署需要 FP8 或 INT4 量化。


系列导航:CH 1-2(预备知识 + 参数分解)→ CH 3(FLOPs 估算)→ CH 4(KV Cache)→ CH 5(推理显存)→ CH 6(M3 实战推演)→ CH 7(Roofline 与推理延迟)


附录

附录 A: 常见 config.json 字段速查表

哪些字段影响哪些计算:

config 字段影响的计算示例值
hidden_size所有投影矩阵参数 + QKV/O 的 FLOPs6144 (M3), 7168 (K2.5), 8192 (Nemotron)
num_hidden_layers总层数 → 乘到每层参数/FLOPs/KV cache60 (M3), 61 (K2.5), 108 blocks (Nemotron)
num_attention_headsQ 投影大小 + QK 点积 FLOPs64 (大多数 7B+ 模型)
num_key_value_headsK/V 投影大小 + KV cache 大小4 (M3 GQA), 2 (Nemotron), 64 (K2.5 MHA)
head_dimQK 点积维度 + KV cache 的 D128 (大多数)
intermediate_sizeFFN 参数(up/gate/down gate)12288 (M3 dense), 18432 (K2.5)
moe_intermediate_sizeMoE expert 参数2048 (M3), 5120 (Nemotron)
n_routed_expertsMoE 总专家数 → 总 MoE 参数128 (M3), 256 (GLM-5.1), 384 (K2.5), 512 (Nemotron)
num_experts_per_tok激活参数计算4 (M3), 8 (K2.5), 22 (Nemotron)
kv_lora_rankMLA KV 压缩维度 → KV cache 大小512 (K2.5, DeepSeek V3/V4)
q_lora_rankMLA Q 压缩维度 → Attention 参数1536 (K2.5)
qk_rope_head_dimMLA k_rope 维度 → KV cache 的 rope 分量64 (K2.5)
ssm_state_sizeMamba-2 state 维度 → 替代 KV cache 的状态大小128 (Nemotron)
max_position_embeddings最大上下文 → KV cache 最大 T + FLOPs 最大 T262144 (K2.5), 1048576 (M3/Nemotron)
vocab_sizeEmbedding 参数 + LM head 参数131072 (Nemotron), 200064 (M3)
dense_intermediate_sizeMoE 模型的 dense FFN 层参数12288 (M3)
shared_intermediate_size共享 expert 的 FFN 参数3072 (M3)
sparse_block_sizeMSA 的 block 大小 → FLOPs 计算128 (M3)
sparse_topk_blocksMSA 的 top-k blocks → FLOPs 计算16 (M3)
vision_config.hidden_sizeViT 参数 + FLOPs1280 (M3), 1152 (K2.5)
vision_config.num_hidden_layersViT 层数32 (M3), 27 (K2.5)
patch_size图像 token 数 → Vision encoder FLOPs14 (大多数)
rope_theta位置编码 theta → 上下文扩展策略判断50000 (K2.5), 5000000 (M3), 10000 (Nemotron)

附录 B: 符号与缩写表

符号含义常用值示例
$d$ / $d_{model}$隐藏维度 (hidden_size)6144, 7168, 8192
$H$Q(Query)头数 (num_attention_heads)64
$H_{kv}$K/V 头数 (num_key_value_heads)4 (GQA), 2 (GQA), 64 (MHA)
$D$每个 head 的维度 (head_dim)128
$d_{ff}$FFN 中间维度 (intermediate_size / moe_intermediate_size)2048-18432
$L$总层数60-108
$L_{attn}$使用 Attention 的层数(Mamba hybrid 中仅部分层)12 (Nemotron)
$T$序列长度(当前总 token 数)4K-1M
$T_{new}$新生成 token 数(decode 时为 1)1
$N_E$MoE 专家总数 (n_routed_experts)128-512
$k$每个 token 激活的专家数 (num_experts_per_tok)4-22
$B$Batch size1 (单样本推理)
$d_{kv}$MLA KV 压缩维度 (kv_lora_rank)512
$d_{rope}$MLA RoPE 维度 (qk_rope_head_dim)64
$D_{nope}$MLA 每头无位置编码维度 (qk_nope_head_dim)128 (K2.5), 192 (GLM-5)
$D_v$MLA 每头 V 维度 (v_head_dim)128 (K2.5), 256 (GLM-5)
$D_{qk}$MLA 每头 QK 有效维度($D_{nope} + D_{rope}$)192 (K2.5), 256 (GLM-5)
$d_{inner}$Mamba-2 内部维度($H_{mamba} \times D_{mamba}$)16384 (Nemotron)
$d_{conv}$Mamba-2 conv1d 通道数18432 (Nemotron)
$H_{mamba}$Mamba-2 SSD head 数256
$d_{state}$Mamba-2 状态空间维度128
$d_{latent}$LatentMoE 低秩维度2048 (Nemotron)
$C$Mamba-2 chunk 大小128
$B_{msa}$MSA block 大小128
$K_{msa}$MSA top-k blocks16
$N_{img}$每图像 token 数576
$V$词表大小 (vocab_size)131072, 200064
字节精度BF16=2, FP8=1, FP4=0.5, FP32=4

附录 C: 8 个已拆解模型的计算结果速览

模型总参激活参FLOPs (decode, T=1M)KV Cache (1M)推理显存 (BF16, 1 sample)
Nemotron 3 Ultra550B55B~1.2×10¹⁵12.0 GiB (仅12 Attn层)~1.13 TiB
MiniMax M3428B23B~2.2×10¹¹144 GiB~1,000 GiB
Kimi K2.51T32B~(未在1M下)~21.5 GiB (256K)— (256K context)
DeepSeek V4-Flash~300B37B~131 GiB (1M, MLA)
MiniMax M2.7~275B~17B— (Full Attn O(T²))
GLM-5.1744B32B
Qwen3.5-MoE~35B~3B
MiMo-V2-Flash~140B~7B

("—" = 该模型未在该上下文长度下做详细估算,或报告未公开该维度数据)


关于本文:本文档从 8 个开源 LLM 的深度架构拆解中提炼而成。每个公式、每个数字都在对应模型上验证通过。如果你发现错误或有改进建议,欢迎反馈。

系列导航(一)预备知识与参数分解(二)FLOPs 估算(三)KV Cache 与推理显存 ← 当前 → (五)训练显存估算(六)通信与掩盖分析