DeepSeek EP 方案的抉择:Prefill 与 Decode 之间的 Insight

Nov 8, 2026

English version

部署 MoE 模型时,专家并行(EP)的规模要在 prefill 和 decode 两个阶段分别确定。DeepSeek 在 DeepInfer 中给两个阶段选择了相反的规模:prefill 在显存放得下的前提下取最小的 EP,通常是 EP2 到 EP8;decode 则开到 EP64 到 EP128。本文从“每个专家每步分到多少 token”出发,解释这一选择背后的原因。

本文依据 DeepInfer 的部署文档和 DeepSeek V4.1-Flash 的模型配置,只讨论 MoE 层:384 个路由专家,每个 token 选 6 个,另有 1 个共享专家,hidden 5120,专家中间维度 2304,专家权重为 FP4。硬件取 B200 的规格(FP8 稠密算力 4.5 PFLOPS,显存带宽 8 TB/s,NVLink 单向 900 GB/s),文中的时间都是按峰值估算的每层每卡耗时。

概要

一、从 DeepInfer 思考 EP 规模的选择

DeepInfer 的部署文档对并行方式的说明很简短:prefill 使用 EP2 到 EP8,在显存允许的范围内取最小值;decode 使用 EP64 到 EP128,在可用 GPU 允许的范围内取最大值。两个阶段运行的是同一个模型、同一组专家,选择却正好相反。

一种常见的解释是,decode 每步的计算量小,所以可以分到更多卡上;prefill 的通信量大,所以要少分几张。这个解释默认了一个前提:EP 越大,每张卡分到的计算越少。本文先指出这个前提并不成立,再把 EP 的影响分成两类来看:改变 EP 时保持不变的守恒量,以及随之改变的变化量。

二、EP 规模变化时的守恒量:每张卡的计算量

DeepInfer 的注意力采用数据并行,DP 与 EP 的大小相同,每张卡处理自己那部分请求,持有 TT 个 token,形状为 [T, 5120]。gate 为每个 token 从 384 个路由专家中选出 6 个。token 按目标卡发出,每张卡收下选中本卡专家的行,按专家分组做两次矩阵乘,再把结果送回来源卡,与共享专家的输出相加。

TT 由每张卡上的请求决定,加卡并不会让它变小,官方的性能曲线也是按每卡的请求数对齐比较的。在这个前提下,整个 EP 组每层产生 EP × T × 6 行,路由均匀时平均分到每张卡的是

EP×T×6EP=6T\frac{EP \times T \times 6}{EP} = 6T

行,再加上共享专家的 TT 行,共 7T7T 行。EP 在式中被约去:从 EP8 增加到 EP64,每张卡要做的有效计算保持不变。一行经过一个专家约需 70.8 MFLOP,decode 每卡 256 个 token 时每层约 28 µs,prefill 每卡 32,768 个 token 时约 3.6 ms。

这里守恒的是平均每卡的有效计算。路由不均匀时,最忙那张卡会多算一些,这正是下一节要讨论的专家负载不均;分组矩阵乘在专家行数很少时还要补零对齐,实际执行的运算会略多于有效计算,这在 decode 的小 EP 下更明显,但不改变本文的结论。

既然 EP 不能减少计算,它的作用就只能从它改变的那些量里找。

三、EP 规模变化时的变化量:行数、通信份数与专家负载不均

每个专家的行数:决定读权重的时间

EP 改变的是这 6T6T 行如何分到专家上。每张卡持有 384 / EP 个专家,每个专家每步分到的行数为

r=EP×T×6384r = \frac{EP \times T \times 6}{384}

以 decode 每卡 256 个 token 为例,EP8 时每张卡有 48 个专家,每个专家只有 32 行;EP64 时每张卡有 6 个专家,每个专家有 256 行。

rr 的意义在于,专家权重每一步都要从显存读取一次,rr 决定了读一次权重能被多少行复用。一个专家的参数量记为 PP,算 rr 行需要 2Pr2Pr 次运算,读取权重需要搬运 PbPb 字节,bb 是每个参数的字节数。令两者耗时相等,PP 被约去,得到权重复用阈值:

r∗=b2×算力显存带宽r^{*} = \frac{b}{2} \times \frac{\text{算力}}{\text{显存带宽}}

V4.1 的专家权重为 FP4,连同缩放因子约 0.53 字节每参数,代入 B200 的规格,r∗≈0.265×562.5≈150r^{*} \approx 0.265 \times 562.5 \approx 150 行。这里只计了权重,把每行激活的读写也算上,阈值约为 180 行,不影响下文的结论。rr 高于 r∗r^{*} 时,专家矩阵乘受算力限制;低于 r∗r^{*} 时,时间主要花在读权重上。r/r∗r / r^{*} 近似等于计算时间与读权重时间之比,加大 EP 的作用,就是把 rr 推过 r∗r^{*},让读权重的时间降到计算以下。

101001,00010,000248163264128EP每个专家每步的行数 rPrefill(每卡 32,768 个 token)Decode(每卡 256 个 token)r* ≈ 150(只计权重)≈ 180(计入激活)Prefill EP2:r = 1,024 行,r / r* = 6.85Prefill EP4:r = 2,048 行,r / r* = 13.71Prefill EP8:r = 4,096 行,r / r* = 27.41Prefill EP16:r = 8,192 行,r / r* = 54.83Prefill EP32:r = 16,384 行,r / r* = 109.66Prefill EP64:r = 32,768 行,r / r* = 219.31Prefill EP128:r = 65,536 行,r / r* = 438.62Decode EP2:r = 8 行,r / r* = 0.05Decode EP4:r = 16 行,r / r* = 0.11Decode EP8:r = 32 行,r / r* = 0.21Decode EP16:r = 64 行,r / r* = 0.43Decode EP32:r = 128 行,r / r* = 0.86Decode EP64:r = 256 行,r / r* = 1.71Decode EP128:r = 512 行,r / r* = 3.43Decode 在 EP ≈ 38 越过阈值官方 prefill:EP2–8官方 decode:EP64–128
图 1:每个专家每步的行数随 EP 的变化。prefill 每卡 32,768 个 token,decode 每卡 256 个 token;虚线为权重复用阈值。

图 1 中两条线的斜率相同,都随 EP 线性增长,但高度相差 128 倍。prefill 在 EP2 时就已远在阈值之上;decode 要到 EP 约为 38 时才越过阈值。

每个 token 的通信份数:决定通信时间

一个 token 的 6 个专家里,平均有 6×(EP−1)/EP6 \times (EP - 1) / EP 个在别的卡上。每个 token 要传几份,取决于实现是否按卡去重,两种做法都有实际的实现。不去重时,每个“token–专家”对各传一份,DeepEP 的 V1 低延迟模式和 Mega MoE 都是这样:

c不去重=6×(1−1EP)c_{\text{不去重}} = 6 \times \left(1 - \frac{1}{EP}\right)

按卡去重时,发往同一张卡的只传一份,到了再展开,DeepEP 的 V1 普通模式和 V2 direct 模式是这样:

c去重=(EP−1)×[1−(1−1EP)6]c_{\text{去重}} = (EP - 1) \times \left[1 - \left(1 - \frac{1}{EP}\right)^{6}\right]

每份数据在 dispatch 时约 5.4 KB(FP8),在 combine 时约 10.2 KB(BF16)。通信时间正比于 T×cT \times c,计算时间正比于 7T7T,两个式子里都没有 TT,所以无论是否去重,通信与计算之比都与 TT 无关,只取决于 EP 和链路带宽。

0123456248163264128EP每个 token 的通信份数 c不去重(Mega MoE、DeepEP V1 低延迟)按卡去重(DeepEP V1 普通、V2 direct)上限 6(每个 token 选 6 个专家)不去重 EP2:c = 3.00不去重 EP4:c = 4.50不去重 EP8:c = 5.25不去重 EP16:c = 5.62不去重 EP32:c = 5.81不去重 EP64:c = 5.91不去重 EP128:c = 5.95按卡去重 EP2:c = 0.98按卡去重 EP4:c = 2.47按卡去重 EP8:c = 3.86按卡去重 EP16:c = 4.82按卡去重 EP32:c = 5.38按卡去重 EP64:c = 5.68按卡去重 EP128:c = 5.84EP4:相差 1.82 倍EP64:相差 1.04 倍
图 2:每个 token 的通信份数随 EP 的变化。

两种做法的 cc 都随 EP 单调增加,并趋近 6;去重带来的节省却随 EP 增大而迅速消失,EP4 时能少传近一半(4.50 对 2.47),EP64 时只少 4%。所以去重在 prefill 的小 EP 下很有价值,到 decode 的大 EP 下几乎没有作用;反过来说,Mega MoE 不去重,在 decode 中几乎不吃亏,在 prefill 中则要多付一些通信。DeepInfer 在 NVLink 域内使用的是 Mega MoE,下文的数值按不去重计算。

专家负载不均:决定最忙的卡比平均慢多少

所有卡要在 combine 时汇合,一层的耗时由最忙的卡决定。设某个专家的负载是平均值的 hh 倍,它所在卡的负载与平均值之比为

lb=1+h−1384/EPlb = 1 + \frac{h - 1}{384 / EP}

每卡的专家越多,单个专家负载偏高的影响越容易被摊平。lblb 同样与 TT 无关,只取决于 EP。

阶段EPrrr/r∗r / r^{*}通信 / 计算lblb(h=10h = 10)
Prefill21,0246.80.471.05
Prefill42,04813.70.711.09
Prefill84,096270.831.19
Decode8320.210.831.19
Decode321280.860.921.75
Decode642561.70.932.5
Decode1285123.40.944

表 1:EP 改变的三个量。通信 / 计算按 Mega MoE 不去重、NVLink 计。prefill 每卡 T = 32,768,取 DeepInfer benchmark 的默认值;decode 每卡 T = 256,取官方曲线上每卡 64 个请求、每个请求每步验证 4 个 token 的配置。

表 1 中 EP8 的两行最能说明问题:两个阶段的通信与计算之比和 lblb 完全相同,r/r∗r / r^{*} 却相差两个数量级。通信和专家负载不均只随 EP 变化,每个专家的行数随 EP × T 变化。图 3 把这一点画了出来:通信与计算之比只有一条线,两个阶段共用;读权重与计算之比是两条线,彼此平行,相差 128 倍。

0.010.1110248163264128EP与计算时间之比读权重 ÷ 计算:prefill读权重 ÷ 计算:decode通信 ÷ 计算:两个阶段相同(不去重,NVLink)与计算相等读权重 ÷ 计算(prefill) EP2:0.126读权重 ÷ 计算(prefill) EP4:0.0638读权重 ÷ 计算(prefill) EP8:0.0325读权重 ÷ 计算(prefill) EP16:0.0169读权重 ÷ 计算(prefill) EP32:0.00904读权重 ÷ 计算(prefill) EP64:0.00514读权重 ÷ 计算(prefill) EP128:0.00318读权重 ÷ 计算(decode) EP2:16.2读权重 ÷ 计算(decode) EP4:8.16读权重 ÷ 计算(decode) EP8:4.16读权重 ÷ 计算(decode) EP16:2.16读权重 ÷ 计算(decode) EP32:1.16读权重 ÷ 计算(decode) EP64:0.657读权重 ÷ 计算(decode) EP128:0.407通信 ÷ 计算 EP2:0.473通信 ÷ 计算 EP4:0.709通信 ÷ 计算 EP8:0.827通信 ÷ 计算 EP16:0.886通信 ÷ 计算 EP32:0.916通信 ÷ 计算 EP64:0.931通信 ÷ 计算 EP128:0.938decode:EP32–64 之间降到 1 以下prefill:始终远低于 1只随 EP 变化,与 T 无关
图 3:读权重时间、通信时间与计算时间之比随 EP 的变化。

四、两个阶段的取舍

把读权重、通信和计算三项放在一起,就能看出每种组合下谁最慢。图 4 按每卡的 TT 和 EP,标出计算、读权重和通信三项中耗时最长的一项。左图在 NVLink 域内:prefill 的官方配置落在计算受限的区域,decode 的官方配置刚好越过读权重受限的区域。右图把链路换成每卡 100 GB/s 的网卡,几乎所有组合都变成通信最慢,这也是两个阶段都留在 NVLink 域内的原因。

计算最慢读权重最慢通信最慢NVLink 900 GB/s64KEP2,T = 65,536:计算 7,215.5 µs,读权重 455.6 µs,通信 3,411.4 µsEP4,T = 65,536:计算 7,215.5 µs,读权重 230.0 µs,通信 5,117.1 µsEP8,T = 65,536:计算 7,215.5 µs,读权重 117.2 µs,通信 5,969.9 µsEP16,T = 65,536:计算 7,215.5 µs,读权重 60.8 µs,通信 6,396.3 µsEP32,T = 65,536:计算 7,215.5 µs,读权重 32.6 µs,通信 6,609.5 µsEP64,T = 65,536:计算 7,215.5 µs,读权重 18.5 µs,通信 6,716.1 µsEP128,T = 65,536:计算 7,215.5 µs,读权重 11.5 µs,通信 6,769.4 µs32KEP2,T = 32,768:计算 3,607.8 µs,读权重 455.6 µs,通信 1,705.7 µsEP4,T = 32,768:计算 3,607.8 µs,读权重 230.0 µs,通信 2,558.5 µsEP8,T = 32,768:计算 3,607.8 µs,读权重 117.2 µs,通信 2,984.9 µsEP16,T = 32,768:计算 3,607.8 µs,读权重 60.8 µs,通信 3,198.2 µsEP32,T = 32,768:计算 3,607.8 µs,读权重 32.6 µs,通信 3,304.8 µsEP64,T = 32,768:计算 3,607.8 µs,读权重 18.5 µs,通信 3,358.1 µsEP128,T = 32,768:计算 3,607.8 µs,读权重 11.5 µs,通信 3,384.7 µs16KEP2,T = 16,384:计算 1,803.9 µs,读权重 455.6 µs,通信 852.8 µsEP4,T = 16,384:计算 1,803.9 µs,读权重 230.0 µs,通信 1,279.3 µsEP8,T = 16,384:计算 1,803.9 µs,读权重 117.2 µs,通信 1,492.5 µsEP16,T = 16,384:计算 1,803.9 µs,读权重 60.8 µs,通信 1,599.1 µsEP32,T = 16,384:计算 1,803.9 µs,读权重 32.6 µs,通信 1,652.4 µsEP64,T = 16,384:计算 1,803.9 µs,读权重 18.5 µs,通信 1,679.0 µsEP128,T = 16,384:计算 1,803.9 µs,读权重 11.5 µs,通信 1,692.4 µs8KEP2,T = 8,192:计算 901.9 µs,读权重 455.6 µs,通信 426.4 µsEP4,T = 8,192:计算 901.9 µs,读权重 230.0 µs,通信 639.6 µsEP8,T = 8,192:计算 901.9 µs,读权重 117.2 µs,通信 746.2 µsEP16,T = 8,192:计算 901.9 µs,读权重 60.8 µs,通信 799.5 µsEP32,T = 8,192:计算 901.9 µs,读权重 32.6 µs,通信 826.2 µsEP64,T = 8,192:计算 901.9 µs,读权重 18.5 µs,通信 839.5 µsEP128,T = 8,192:计算 901.9 µs,读权重 11.5 µs,通信 846.2 µs4KEP2,T = 4,096:计算 451.0 µs,读权重 455.6 µs,通信 213.2 µsEP4,T = 4,096:计算 451.0 µs,读权重 230.0 µs,通信 319.8 µsEP8,T = 4,096:计算 451.0 µs,读权重 117.2 µs,通信 373.1 µsEP16,T = 4,096:计算 451.0 µs,读权重 60.8 µs,通信 399.8 µsEP32,T = 4,096:计算 451.0 µs,读权重 32.6 µs,通信 413.1 µsEP64,T = 4,096:计算 451.0 µs,读权重 18.5 µs,通信 419.8 µsEP128,T = 4,096:计算 451.0 µs,读权重 11.5 µs,通信 423.1 µs2KEP2,T = 2,048:计算 225.5 µs,读权重 455.6 µs,通信 106.6 µsEP4,T = 2,048:计算 225.5 µs,读权重 230.0 µs,通信 159.9 µsEP8,T = 2,048:计算 225.5 µs,读权重 117.2 µs,通信 186.6 µsEP16,T = 2,048:计算 225.5 µs,读权重 60.8 µs,通信 199.9 µsEP32,T = 2,048:计算 225.5 µs,读权重 32.6 µs,通信 206.5 µsEP64,T = 2,048:计算 225.5 µs,读权重 18.5 µs,通信 209.9 µsEP128,T = 2,048:计算 225.5 µs,读权重 11.5 µs,通信 211.5 µs1KEP2,T = 1,024:计算 112.7 µs,读权重 455.6 µs,通信 53.3 µsEP4,T = 1,024:计算 112.7 µs,读权重 230.0 µs,通信 80.0 µsEP8,T = 1,024:计算 112.7 µs,读权重 117.2 µs,通信 93.3 µsEP16,T = 1,024:计算 112.7 µs,读权重 60.8 µs,通信 99.9 µsEP32,T = 1,024:计算 112.7 µs,读权重 32.6 µs,通信 103.3 µsEP64,T = 1,024:计算 112.7 µs,读权重 18.5 µs,通信 104.9 µsEP128,T = 1,024:计算 112.7 µs,读权重 11.5 µs,通信 105.8 µs512EP2,T = 512:计算 56.4 µs,读权重 455.6 µs,通信 26.7 µsEP4,T = 512:计算 56.4 µs,读权重 230.0 µs,通信 40.0 µsEP8,T = 512:计算 56.4 µs,读权重 117.2 µs,通信 46.6 µsEP16,T = 512:计算 56.4 µs,读权重 60.8 µs,通信 50.0 µsEP32,T = 512:计算 56.4 µs,读权重 32.6 µs,通信 51.6 µsEP64,T = 512:计算 56.4 µs,读权重 18.5 µs,通信 52.5 µsEP128,T = 512:计算 56.4 µs,读权重 11.5 µs,通信 52.9 µs256EP2,T = 256:计算 28.2 µs,读权重 455.6 µs,通信 13.3 µsEP4,T = 256:计算 28.2 µs,读权重 230.0 µs,通信 20.0 µsEP8,T = 256:计算 28.2 µs,读权重 117.2 µs,通信 23.3 µsEP16,T = 256:计算 28.2 µs,读权重 60.8 µs,通信 25.0 µsEP32,T = 256:计算 28.2 µs,读权重 32.6 µs,通信 25.8 µsEP64,T = 256:计算 28.2 µs,读权重 18.5 µs,通信 26.2 µsEP128,T = 256:计算 28.2 µs,读权重 11.5 µs,通信 26.4 µs128EP2,T = 128:计算 14.1 µs,读权重 455.6 µs,通信 6.7 µsEP4,T = 128:计算 14.1 µs,读权重 230.0 µs,通信 10.0 µsEP8,T = 128:计算 14.1 µs,读权重 117.2 µs,通信 11.7 µsEP16,T = 128:计算 14.1 µs,读权重 60.8 µs,通信 12.5 µsEP32,T = 128:计算 14.1 µs,读权重 32.6 µs,通信 12.9 µsEP64,T = 128:计算 14.1 µs,读权重 18.5 µs,通信 13.1 µsEP128,T = 128:计算 14.1 µs,读权重 11.5 µs,通信 13.2 µs64EP2,T = 64:计算 7.0 µs,读权重 455.6 µs,通信 3.3 µsEP4,T = 64:计算 7.0 µs,读权重 230.0 µs,通信 5.0 µsEP8,T = 64:计算 7.0 µs,读权重 117.2 µs,通信 5.8 µsEP16,T = 64:计算 7.0 µs,读权重 60.8 µs,通信 6.2 µsEP32,T = 64:计算 7.0 µs,读权重 32.6 µs,通信 6.5 µsEP64,T = 64:计算 7.0 µs,读权重 18.5 µs,通信 6.6 µsEP128,T = 64:计算 7.0 µs,读权重 11.5 µs,通信 6.6 µs32EP2,T = 32:计算 3.5 µs,读权重 455.6 µs,通信 1.7 µsEP4,T = 32:计算 3.5 µs,读权重 230.0 µs,通信 2.5 µsEP8,T = 32:计算 3.5 µs,读权重 117.2 µs,通信 2.9 µsEP16,T = 32:计算 3.5 µs,读权重 60.8 µs,通信 3.1 µsEP32,T = 32:计算 3.5 µs,读权重 32.6 µs,通信 3.2 µsEP64,T = 32:计算 3.5 µs,读权重 18.5 µs,通信 3.3 µsEP128,T = 32:计算 3.5 µs,读权重 11.5 µs,通信 3.3 µs248163264128EPPD跨节点,网卡 100 GB/sEP2,T = 65,536:计算 7,215.5 µs,读权重 455.6 µs,通信 30,702.3 µsEP4,T = 65,536:计算 7,215.5 µs,读权重 230.0 µs,通信 46,053.5 µsEP8,T = 65,536:计算 7,215.5 µs,读权重 117.2 µs,通信 53,729.0 µsEP16,T = 65,536:计算 7,215.5 µs,读权重 60.8 µs,通信 57,566.8 µsEP32,T = 65,536:计算 7,215.5 µs,读权重 32.6 µs,通信 59,485.7 µsEP64,T = 65,536:计算 7,215.5 µs,读权重 18.5 µs,通信 60,445.2 µsEP128,T = 65,536:计算 7,215.5 µs,读权重 11.5 µs,通信 60,924.9 µsEP2,T = 32,768:计算 3,607.8 µs,读权重 455.6 µs,通信 15,351.2 µsEP4,T = 32,768:计算 3,607.8 µs,读权重 230.0 µs,通信 23,026.7 µsEP8,T = 32,768:计算 3,607.8 µs,读权重 117.2 µs,通信 26,864.5 µsEP16,T = 32,768:计算 3,607.8 µs,读权重 60.8 µs,通信 28,783.4 µsEP32,T = 32,768:计算 3,607.8 µs,读权重 32.6 µs,通信 29,742.9 µsEP64,T = 32,768:计算 3,607.8 µs,读权重 18.5 µs,通信 30,222.6 µsEP128,T = 32,768:计算 3,607.8 µs,读权重 11.5 µs,通信 30,462.4 µsEP2,T = 16,384:计算 1,803.9 µs,读权重 455.6 µs,通信 7,675.6 µsEP4,T = 16,384:计算 1,803.9 µs,读权重 230.0 µs,通信 11,513.4 µsEP8,T = 16,384:计算 1,803.9 µs,读权重 117.2 µs,通信 13,432.3 µsEP16,T = 16,384:计算 1,803.9 µs,读权重 60.8 µs,通信 14,391.7 µsEP32,T = 16,384:计算 1,803.9 µs,读权重 32.6 µs,通信 14,871.4 µsEP64,T = 16,384:计算 1,803.9 µs,读权重 18.5 µs,通信 15,111.3 µsEP128,T = 16,384:计算 1,803.9 µs,读权重 11.5 µs,通信 15,231.2 µsEP2,T = 8,192:计算 901.9 µs,读权重 455.6 µs,通信 3,837.8 µsEP4,T = 8,192:计算 901.9 µs,读权重 230.0 µs,通信 5,756.7 µsEP8,T = 8,192:计算 901.9 µs,读权重 117.2 µs,通信 6,716.1 µsEP16,T = 8,192:计算 901.9 µs,读权重 60.8 µs,通信 7,195.9 µsEP32,T = 8,192:计算 901.9 µs,读权重 32.6 µs,通信 7,435.7 µsEP64,T = 8,192:计算 901.9 µs,读权重 18.5 µs,通信 7,555.6 µsEP128,T = 8,192:计算 901.9 µs,读权重 11.5 µs,通信 7,615.6 µsEP2,T = 4,096:计算 451.0 µs,读权重 455.6 µs,通信 1,918.9 µsEP4,T = 4,096:计算 451.0 µs,读权重 230.0 µs,通信 2,878.3 µsEP8,T = 4,096:计算 451.0 µs,读权重 117.2 µs,通信 3,358.1 µsEP16,T = 4,096:计算 451.0 µs,读权重 60.8 µs,通信 3,597.9 µsEP32,T = 4,096:计算 451.0 µs,读权重 32.6 µs,通信 3,717.9 µsEP64,T = 4,096:计算 451.0 µs,读权重 18.5 µs,通信 3,777.8 µsEP128,T = 4,096:计算 451.0 µs,读权重 11.5 µs,通信 3,807.8 µsEP2,T = 2,048:计算 225.5 µs,读权重 455.6 µs,通信 959.4 µsEP4,T = 2,048:计算 225.5 µs,读权重 230.0 µs,通信 1,439.2 µsEP8,T = 2,048:计算 225.5 µs,读权重 117.2 µs,通信 1,679.0 µsEP16,T = 2,048:计算 225.5 µs,读权重 60.8 µs,通信 1,799.0 µsEP32,T = 2,048:计算 225.5 µs,读权重 32.6 µs,通信 1,858.9 µsEP64,T = 2,048:计算 225.5 µs,读权重 18.5 µs,通信 1,888.9 µsEP128,T = 2,048:计算 225.5 µs,读权重 11.5 µs,通信 1,903.9 µsEP2,T = 1,024:计算 112.7 µs,读权重 455.6 µs,通信 479.7 µsEP4,T = 1,024:计算 112.7 µs,读权重 230.0 µs,通信 719.6 µsEP8,T = 1,024:计算 112.7 µs,读权重 117.2 µs,通信 839.5 µsEP16,T = 1,024:计算 112.7 µs,读权重 60.8 µs,通信 899.5 µsEP32,T = 1,024:计算 112.7 µs,读权重 32.6 µs,通信 929.5 µsEP64,T = 1,024:计算 112.7 µs,读权重 18.5 µs,通信 944.5 µsEP128,T = 1,024:计算 112.7 µs,读权重 11.5 µs,通信 952.0 µsEP2,T = 512:计算 56.4 µs,读权重 455.6 µs,通信 239.9 µsEP4,T = 512:计算 56.4 µs,读权重 230.0 µs,通信 359.8 µsEP8,T = 512:计算 56.4 µs,读权重 117.2 µs,通信 419.8 µsEP16,T = 512:计算 56.4 µs,读权重 60.8 µs,通信 449.7 µsEP32,T = 512:计算 56.4 µs,读权重 32.6 µs,通信 464.7 µsEP64,T = 512:计算 56.4 µs,读权重 18.5 µs,通信 472.2 µsEP128,T = 512:计算 56.4 µs,读权重 11.5 µs,通信 476.0 µsEP2,T = 256:计算 28.2 µs,读权重 455.6 µs,通信 119.9 µsEP4,T = 256:计算 28.2 µs,读权重 230.0 µs,通信 179.9 µsEP8,T = 256:计算 28.2 µs,读权重 117.2 µs,通信 209.9 µsEP16,T = 256:计算 28.2 µs,读权重 60.8 µs,通信 224.9 µsEP32,T = 256:计算 28.2 µs,读权重 32.6 µs,通信 232.4 µsEP64,T = 256:计算 28.2 µs,读权重 18.5 µs,通信 236.1 µsEP128,T = 256:计算 28.2 µs,读权重 11.5 µs,通信 238.0 µsEP2,T = 128:计算 14.1 µs,读权重 455.6 µs,通信 60.0 µsEP4,T = 128:计算 14.1 µs,读权重 230.0 µs,通信 89.9 µsEP8,T = 128:计算 14.1 µs,读权重 117.2 µs,通信 104.9 µsEP16,T = 128:计算 14.1 µs,读权重 60.8 µs,通信 112.4 µsEP32,T = 128:计算 14.1 µs,读权重 32.6 µs,通信 116.2 µsEP64,T = 128:计算 14.1 µs,读权重 18.5 µs,通信 118.1 µsEP128,T = 128:计算 14.1 µs,读权重 11.5 µs,通信 119.0 µsEP2,T = 64:计算 7.0 µs,读权重 455.6 µs,通信 30.0 µsEP4,T = 64:计算 7.0 µs,读权重 230.0 µs,通信 45.0 µsEP8,T = 64:计算 7.0 µs,读权重 117.2 µs,通信 52.5 µsEP16,T = 64:计算 7.0 µs,读权重 60.8 µs,通信 56.2 µsEP32,T = 64:计算 7.0 µs,读权重 32.6 µs,通信 58.1 µsEP64,T = 64:计算 7.0 µs,读权重 18.5 µs,通信 59.0 µsEP128,T = 64:计算 7.0 µs,读权重 11.5 µs,通信 59.5 µsEP2,T = 32:计算 3.5 µs,读权重 455.6 µs,通信 15.0 µsEP4,T = 32:计算 3.5 µs,读权重 230.0 µs,通信 22.5 µsEP8,T = 32:计算 3.5 µs,读权重 117.2 µs,通信 26.2 µsEP16,T = 32:计算 3.5 µs,读权重 60.8 µs,通信 28.1 µsEP32,T = 32:计算 3.5 µs,读权重 32.6 µs,通信 29.0 µsEP64,T = 32:计算 3.5 µs,读权重 18.5 µs,通信 29.5 µsEP128,T = 32:计算 3.5 µs,读权重 11.5 µs,通信 29.7 µs248163264128EPPD每卡 TP:官方 prefill 配置(EP4,T = 32,768) D:官方 decode 配置(EP64,T = 256)
图 4:每种 EP 与每卡 T 的组合下,三项中最慢的一项。左为 NVLink 900 GB/s,右为跨节点、网卡 100 GB/s;P、D 为官方的 prefill 和 decode 配置。

Prefill:读权重已不是瓶颈,取最小 EP

Prefill 每卡每步处理数万个 token,EP4 时 rr 已是阈值的十几倍,读权重的时间只有计算的十几分之一。继续加大 EP,能节省的读权重时间很有限,通信与计算之比却从 0.71 升到 0.83(按卡去重时也从 0.39 升到 0.61),专家负载不均的影响也在变大;官方实测的 prefill moe_lb 在 EP2 时为 1.045,EP4 时为 1.074。因此 prefill 在显存允许的范围内取最小的 EP,下限取决于每张卡能否放下 384 / EP 个专家的权重。

Decode:读权重是瓶颈,加大 EP 直到它降到计算以下

Decode 的 TT 由并发数和延迟要求决定,每卡只有 256 个 token。EP8 时 rr 只有 32 行,读权重约需 117 µs,计算只需 28 µs。TT 无法增大,能把 rr 推过阈值的只有 EP:EP 从 8 增到 64,读权重的时间降到约 19 µs,低于计算时间。部署文档对 Wide-EP 的解释也正是这一点:它大幅减少了 MoE 专家部分每步的显存流量。官方曲线也反映了这一点(图 5),每卡 64 个请求时,EP64 每卡约 15.7K tok/s,每个用户约 246 tok/s;EP8 分别约为 12.6K 和 198。

0K5K10K15K20K25K30K050100150200250300350每个用户的速度(tok/s)每卡吞吐(tok/s/GPU)EP64EP8EP64,每卡 8 个请求:每用户 325 tok/s,每卡 2,600 tok/sEP64,每卡 16 个请求:每用户 315 tok/s,每卡 5,050 tok/sEP64,每卡 32 个请求:每用户 297 tok/s,每卡 9,500 tok/sEP64,每卡 64 个请求:每用户 246 tok/s,每卡 15,700 tok/sEP64,每卡 128 个请求:每用户 178 tok/s,每卡 22,800 tok/sEP64,每卡 256 个请求:每用户 103 tok/s,每卡 26,300 tok/sEP8,每卡 8 个请求:每用户 238 tok/s,每卡 1,900 tok/sEP8,每卡 16 个请求:每用户 230 tok/s,每卡 3,700 tok/sEP8,每卡 32 个请求:每用户 220 tok/s,每卡 7,050 tok/sEP8,每卡 64 个请求:每用户 198 tok/s,每卡 12,650 tok/sEP8,每卡 128 个请求:每用户 150 tok/s,每卡 19,200 tok/sEP8,每卡 256 个请求:每用户 98 tok/s,每卡 24,900 tok/s64 个请求:15.7K,24664 个请求:12.6K,198数据从 DeepInfer README 的 decode 曲线读出,为近似值;context 131,072,nextn = 3。
图 5:DeepInfer 官方的 decode 曲线,从 README 的图中读出,为近似值。

rr 越过 r∗r^{*} 之后,读权重已降到计算以下,再加大 EP 也省不下时间:计算保持在 28 µs,通信和专家负载不均却继续加重。按本文的估算,这个交点在 EP32 与 EP64 之间,官方推荐的 EP64 到 EP128 正好在它之后不远。在这个范围内,通信与计算之比约为 0.93,每层还要与 63 张以上的卡同步,一个负载为平均值 10 倍的专家就能让 lblb 达到 2.5。因此 decode 需要放在 64 到 128 卡的 NVLink 域内,并依赖 EPLB 复制负载高的专家、定期重排,官方实测的 decode moe_lb 为 1.090。

EP
每卡 T
阈值 ≈ 150 行
计算
读权重
通信

图 6:每层每卡的三项时间(B200,NVLink 900 GB/s)。圆点是每个专家分到的行数,横轴按对数刻度。

在图 6 中可以自己验证这两种取舍:TT 取 32K 时,无论 EP 取多少,三项中都是计算最长;TT 取 256 时,随着 EP 从 8 增大,读权重的时间迅速下降,直到 rr 越过阈值,此后通信与计算接近,继续加大 EP 已省不下时间。

五、阈值随硬件和精度的变化

阈值 r∗r^{*} 只由权重精度和硬件的算力带宽比决定。图 7 列出了几种常见组合:FP4 权重的字节数是 FP8 的一半,阈值也减半,这是 V4.1 在 B200 上只需约 150 行的原因;如果激活也用 FP4,算力翻倍,阈值又回到约 300 行。H20 的算力相对显存带宽很低,阈值只有约 37 行。

权重复用阈值 r*(行)= 每参数字节 ÷ 2 × 稠密算力 ÷ 显存带宽0100200300H20,FP8 权重H20,FP8 权重:r* ≈ 37 行37B200,FP4 权重 × FP8 激活B200,FP4 权重 × FP8 激活:r* ≈ 149 行149H200,FP8 权重H200,FP8 权重:r* ≈ 206 行206B200,FP8 权重B200,FP8 权重:r* ≈ 281 行281H100,FP8 权重H100,FP8 权重:r* ≈ 295 行295B200,FP4 权重 × FP4 激活B200,FP4 权重 × FP4 激活:r* ≈ 299 行299蓝色为本文的配置。按公开的稠密峰值和显存带宽计算。
图 7:不同 GPU 与权重精度下的权重复用阈值,按公开的稠密峰值和显存带宽计算。

令 r=r∗r = r^{*},可以得到 decode 越过阈值所需的最小 EP:

EPmin⁡=r∗×3846×TEP_{\min} = \frac{r^{*} \times 384}{6 \times T}

每卡 256 个 token 时,B200 上的 FP4 专家约需 EP38,H100 上的 FP8 专家约需 EP74,H20 上约需 EP9。同样的模型和负载,在 H20 上把 EP 开到 8 到 16 就基本越过了阈值,继续加大 EP 能省下的时间很有限;在 H100 上则要开得比 B200 更大,而一台 H100 机器只有 8 张卡,EP74 必须跨节点,通信又会变成新的瓶颈,情形与图 4 右侧类似。换到别的模型时,把 384 和 6 换成它的路由专家数和每个 token 选择的专家数即可。

六、估算与实际情况的差距

前面的数字都按理想情况估算:算力和显存带宽取峰值,路由完全均匀,通信可以完全藏在计算后面,并且只看 MoE 层。实际系统在每一项上都会打折扣,但这些折扣大多改变数值,不改变比较的方向。

矩阵乘和显存读写都达不到峰值。阈值 r∗r^{*} 取决于两者之比,算力跑到峰值的七成、带宽跑到八成五时,阈值约为 120 行;计入每行激活的读写,又会把它抬高约两成。阈值在 120 到 180 行之间浮动,decode 越过它所需的 EP 在 30 到 45 之间:EP8 远远不够,EP64 足够,结论不变。

路由也不会完全均匀。专家负载不均让最忙的卡多算、多收,计算和通信按同样的倍数放大,两者之比不变;官方开启 EPLB 后实测的放大倍数在 1.045 到 1.090 之间,影响有限。

通信也不一定能完全藏在计算后面。每层的同步和启动都有一段固定开销,与要传多少数据无关。prefill 每层的计算约 3.6 ms,这段开销可以忽略;decode 每层的计算只有约 28 µs,它的占比就不小了,而且参与同步的卡越多越明显,这也是 decode 的 EP 停在 64 到 128、不再继续加大的原因之一。

最后,本文只看 MoE 层。官方曲线上,decode 每卡 64 个请求时一步约 13 ms,MoE 层只占其中一部分,其余是注意力和大量与批量无关的固定开销。所以本文的数字适合用来判断不同 EP 下谁是瓶颈、EP 该往哪个方向调,不能直接当作每步的实际耗时;官方 EP64 与 EP8 的实测差距,方向与本文的推导一致。注意力和这些固定开销如何影响 EP 的选择,留待后续分析。

小结

Prefill 与 decode 的 EP 选择看似相反,遵循的却是同一个规律:EP 不改变每张卡的计算量,只改变每个专家的行数、通信份数和专家负载不均。每个专家的行数随 EP × T 变化,决定读权重的时间;通信份数和专家负载不均只随 EP 变化。

这个判断并不只适用于 V4.1。DeepSeek 在 V3/R1 的推理系统中把 decode 的 EP 开到 144,给出的理由同样是让每个专家分到足够大的 batch;NVIDIA 在 GB200 NVL72 上推行 Wide-EP,MegaScale-Infer 把注意力和专家拆到不同的 GPU 上汇聚 token,出发点也相同。换到别的模型和硬件,用第五节的两个式子,就能大致判断 EP 该往哪个方向调。

参考

  1. DeepInfer, Inference deployment Q&A
  2. DeepInfer, README: Performance benchmarks
  3. DeepSeek, Day 6: DeepSeek-V3/R1 Inference System Overview
  4. NVIDIA, Scaling Large MoE Models with Wide Expert Parallelism on NVL72 Rack Scale Systems
  5. Zhu et al., MegaScale-Infer: Serving Mixture-of-Experts at Scale with Disaggregated Expert Parallelism