跳到主要内容

生产环境中的 MoE 模型:稠密模型基准测试所掩盖的服务特性

· 阅读需 13 分钟
Tian Pan
Software Engineer

基准测试告诉过你,运行 Mixtral 8x7B 的成本只有 46B 稠密模型的一半。但它们没告诉你的是,它需要的 GPU 显存大约是同等稠密模型的 8.6 倍,其响应延迟会因令牌命中哪个专家而产生剧烈波动,并且在中等批处理大小下会以难以诊断的方式崩溃。专家混合(MoE)架构已成为几乎所有前沿模型——DeepSeek-V3、Llama 4、Gemini 1.5、Grok、Mistral Large——的中流抵柱,但适用于稠密模型的推理假设在 MoE 上会以微妙且昂贵的方式失效。

如果你打算私有化部署或将流量路由到这些模型,以下是稠密模型直觉可能出错的地方。

内存悖论:为什么“高效”的 MoE 模型反而消耗更多显存

MoE 的核心承诺是计算效率:在推理时,每个令牌仅激活模型参数的一小部分。Mixtral 8x7B 总共有 46.7B 参数,但每个令牌仅激活约 12.9B。DeepSeek-V3 总共有 671B 参数,但每次前向传播仅激活约 37B。这听起来很划算。

问题在于,GPU 显存并不关心哪些专家是激活的。所有的专家权重都必须保留在显存中,以便路由网络可以将任何令牌发送给任何专家,而不会因为加载权重而产生延迟峰值。你需要在显存中支付全部参数量的成本,而计算上只需支付一小部分。在实践中测算,MoE 模型所需的 GPU 显存大约是具有同等计算需求的稠密模型的 8.6 倍。

对于 DeepSeek-V3 来说,这意味着在为激活或 KV 缓存分配任何空间之前,你面临的是大约 671B × 2 字节 (BF16) ≈ 1.34TB 的权重存储。这就是为什么在许多生产配置中,推理一个 37B 激活参数的模型仍然需要 32 路 H100 GPU 集群。营销材料中的“激活参数”数量并不是决定你硬件预算的数字——总参数量才是。

路由器网络本身也会增加容易被忽视的开销。在每个 Transformer 层,门控网络都会对所有专家运行线性投影和 softmax,以计算路由概率。对于像 DeepSeek-V3 这样拥有 256 个专家的模型,这种路由计算是不容忽视的,与同等的稠密前向传播相比,每个令牌大约增加 5-8% 的延迟。

延迟波动:稠密基准测试忽略的行为

稠密模型的延迟是可预测的。对于给定的序列长度和批处理大小,计算图是固定的。但 MoE 的延迟则不然,因为每个请求激活的专家集合是输入令牌分布的函数,而不是批处理配置的函数。

在 32 个请求的批处理中,每个请求都可能激活不同的专家子集。某些请求会触发负载较重的专家;另一些请求则可能被路由到使用较少的专家。这种离散的路由决策会导致同一批次中不同请求的计算时间产生真实差异,并且在深度 MoE 堆栈中,这种差异会层层累加。等待批次中最慢专家的请求会成为你的尾部延迟。

这产生了一种在离线基准测试中不会出现的故障模式:即使在负载稳定的情况下,你的 P99 延迟也明显差于平均值,而且它与序列长度的相关性也不像稠密模型延迟那样清晰。除非你正在跟踪延迟分布而非仅仅是平均值,否则为稠密模型调优的生产监控将完全忽略这一点。

具体到 Mixtral 8x7B,测得的单请求延迟约为 6.45ms/token,在单个并发请求时的首字延迟为 643ms。这对于交互式使用来说处于合理范围内,但分布情况比平均值更重要。

批处理大小敏感度:反转的优化曲线

对于稠密模型,批处理(Batching)几乎总是有益的。批次中的每个额外请求都会分摊加载模型权重的固定成本。标准的运维经验是:在显存允许的范围内运行最大的批次。

MoE 模型以一种特定的方式反转了这一点。小批次(1-16 个请求)才是 MoE 真正兑现其计算效率承诺的地方。当批次较小时,批次中的请求很可能会路由到重叠的专家子集,因此你实际上是在重复使用完整模型的一小部分。这种稀疏激活是名副其实的稀疏。

随着批处理大小增长,不同的请求会激活不同的专家。如果有 8 个专家和 32 个请求,整个批次的组合激活模式开始覆盖大部分专家池。当你达到大批处理大小时,你实际上已经加载了几乎整个模型——重现了稠密模型的内存访问模式——但还增加了路由计算和专家分发的额外开销。计算效率优势消失了,而内存效率低下的问题依然存在。

这意味着 MoE 的最佳批处理策略与稠密模型不同。像 vLLM 这样的框架建议为 MoE 工作负载设置更高的最大批次令牌数(MoE 为 32,768,稠密为 16,384),但批处理大小与吞吐量之间的关系是非单调的,你必须根据你的流量模式进行经验性测量。成本效益的批处理大小平衡点通常比你根据稠密模型经验预期的要低。

专家负载不均衡:沉默的 GPU 杀手

训练时的负载均衡和生产环境中的负载均衡是不同的问题。在训练过程中,辅助损失(auxiliary losses)会防止 token 路由坍缩到单个专家。但在生产环境中,实际的流量分布会产生持续的“热点专家”——这些专家由于专注于你工作负载领域中频繁出现的模式,从而接收了不成比例的 token。

当专家并行将专家分散到不同的 GPU 上时,热点专家会导致托管它们的节点出现 GPU 资源超限。这些 GPU 在峰值负载下会运行过热并导致显存溢出。而其他 GPU 上的冷门专家则处于空闲状态,等待热点专家所在的 GPU 完成计算。由于在前向传播完成之前,每个 GPU 都必须完成其专家计算,因此同步停顿(synchronization stall)会传播到整个 batch。

这种失效模式的扩展性极差。更大规模的专家并行配置会让更多的 GPU 暴露在这种不均衡中。特定领域(如客户支持、代码生成、医疗问答)的生产工作负载比通用基准测试更加倾斜,这意味着基于基准测试得出的推理配置会低估专用部署中的峰值显存需求。

缓解方案确实存在,但增加了操作复杂度:

  • 静态专家放置 (EPLB): 预先计算哪些专家在历史上是热点,然后将热点专家和冷门专家放置在同一个 GPU 上,使每个节点处理均衡的组合。
  • 在线 EPLB: 根据运行时监控持续将专家重新分配到 GPU,以适应流量模式的变化。
加载中…
References:Let's stay in touch and Follow me for more thoughts and updates