MoE 架构全景
在标准 Transformer 中,每个 token 都经过同一个 MLP 层。Mixture of Experts(MoE) 的核心思想是:用多个独立的 expert MLP 替换单一 MLP,每个 token 只被路由到其中 top-k 个 expert 进行计算。这样模型参数量可以大幅增加(例如 256 个 expert),但每个 token 的实际计算量只等价于 k 个 expert,实现了参数量与计算量的解耦。
Megatron-LM 的 MoE 实现位于 megatron/core/transformer/moe/ 目录,核心文件包括:
moe_layer.py— MoELayer 主类,编排整个前向流程router.py— TopKRouter,决定 token 到 expert 的路由token_dispatcher.py— AlltoAll / AllGather / Flex 三种 token 分发策略experts.py— GroupedMLP / TEGroupedMLP / SequentialMLP 三种 expert 实现shared_experts.py— SharedExpertMLP,所有 token 共享的"常驻 expert"moe_utils.py— 辅助函数(aux loss、sinkhorn、permute/unpermute 等)
MoELayer 的前向流程由五个阶段组成,定义在 MoELayer.forward() 的 custom_forward 内部函数中:
shared_experts_compute(hidden_states)
Shared expert 使用原始 hidden_states(路由之前)进行前向计算。这一步在 route 之前执行,确保 shared expert 看到的是未经修改的输入。
route(hidden_states) → probs, routing_map
Router 计算每个 token 到各 expert 的路由概率。输出 probs(权重)和 routing_map(bool 掩码,标记哪些 expert 被选中)。
preprocess → dispatch → routed_experts_compute
preprocess:Token Dispatcher 的预处理(排列 token、计算 split 元信息)。dispatch:通过 All-to-All 通信将 token 发送到对应 EP rank。routed_experts_compute:各 rank 上的 local expert 处理接收到的 token。
combine(output, shared_expert_output)
通过反向 All-to-All 收集 expert 输出,unpermute 恢复原始 token 顺序,最后加上 shared expert 的输出。
def forward(self, hidden_states: torch.Tensor):
def custom_forward(hidden_states):
# ① Shared expert 先于路由执行(使用原始 hidden_states)
shared_expert_output = self.shared_experts_compute(hidden_states)
# ② Route:计算路由概率与选择掩码
probs, routing_map = self.route(hidden_states)
# ③ Preprocess:token dropping / padding 等前处理
hidden_states, probs, residual = self.preprocess(
hidden_states, probs, routing_map
)
# ④ Dispatch:All-to-All 分发 token 到对应 EP rank
dispatched_input, probs = self.dispatch(hidden_states, probs)
# ⑤ Compute:本 rank 上的 local experts 计算
output, mlp_bias = self.routed_experts_compute(
dispatched_input, probs, residual
)
# ⑥ Combine:All-to-All 收集 + 加权合并 + 叠加 shared expert
output = self.combine(output, shared_expert_output)
return output, mlp_bias
if self.moe_layer_recompute:
outputs = tensor_parallel.checkpoint(custom_forward, False, hidden_states)
else:
outputs = custom_forward(hidden_states)
return outputs
TransformerLayerSubmodules.mlp 的 spec 从普通 MLP 替换为 MoELayer 来启用。MoE 层在 TransformerLayer 中的位置与 MLP 完全相同:位于第二个 LayerNorm 之后,接收 [S/TP, B, H] 的输入,输出相同形状的张量。
class MoELayer(BaseMoELayer):
def __init__(self, config, submodules, layer_number, pg_collection):
super().__init__(config=config, ...)
# ---- 1. Router ----
self.router = TopKRouter(config=self.config, pg_collection=pg_collection)
# ---- 2. Token Dispatcher ----
if config.moe_token_dispatcher_type == "alltoall":
self.token_dispatcher = MoEAlltoAllTokenDispatcher(...)
elif config.moe_token_dispatcher_type == "allgather":
self.token_dispatcher = MoEAllGatherTokenDispatcher(...)
elif config.moe_token_dispatcher_type == "flex":
self.token_dispatcher = MoEFlexTokenDispatcher(...)
# ---- 3. Routed Experts ----
self.experts = build_module(submodules.experts, self.num_local_experts, ...)
# ---- 4. Shared Experts (可选) ----
if self.use_shared_expert:
self.shared_experts = build_module(submodules.shared_experts, ...)
if self.shared_expert_overlap:
self.token_dispatcher.set_shared_experts(self.shared_experts)
Expert Parallelism
Expert Parallelism(EP) 是 MoE 模型特有的并行策略:将 expert 分配到不同 GPU 上,每个 GPU 只持有总 expert 数的一个子集。例如 64 个 expert 分到 8 个 EP rank 上,每个 rank 持有 8 个 local expert。
与 TP/PP/DP 不同,EP 不切分单个 expert 的参数,而是将不同的 expert 放到不同 rank。由于每个 token 只被路由到 top-k 个 expert,而这些 expert 可能分布在不同 rank 上,因此需要 All-to-All 通信来跨 rank 交换 token。
| EP Rank 0 | EP Rank 1 | EP Rank 2 | EP Rank 3 |
|---|---|---|---|
|
E0 E1 E2 E3 num_local_experts = 4 |
E4 E5 E6 E7 num_local_experts = 4 |
E8 E9 E10 E11 num_local_experts = 4 |
E12 E13 E14 E15 num_local_experts = 4 |
Megatron 的 MoE 并行涉及三个独立的通信组:
| 通信组 | 配置 | 用途 |
|---|---|---|
| EP group | expert_model_parallel_size |
expert 分布的维度,All-to-All token 交换发生在此组内 |
| Expert TP group | expert_tensor_parallel_size |
对单个 expert 的 MLP 做 TP 切分(当 expert FFN 太大时使用),与 Attention 的 TP 组独立 |
| Expert DP group | 自动计算 | Expert 级别的数据并行,持有相同 expert 副本的 rank 组成此组,用于梯度同步 |
class BaseMoELayer(MegatronModule, ABC):
def __init__(self, config, layer_number, pg_collection):
super().__init__(config)
self.ep_group = pg_collection.ep
ep_size = utils.get_pg_size(self.ep_group)
ep_rank = utils.get_pg_rank(self.ep_group)
# 每个 EP rank 持有的 local expert 数量
assert self.config.num_moe_experts % ep_size == 0
self.num_local_experts = self.config.num_moe_experts // ep_size
# 本 rank 负责的 expert 索引范围
local_expert_indices_offset = ep_rank * self.num_local_experts
self.local_expert_indices = [
local_expert_indices_offset + i
for i in range(self.num_local_experts)
]
| EP Rank 0 | EP Rank 1 | EP Rank 2 | EP Rank 3 | |
|---|---|---|---|---|
| Expert TP=0 | GPU 0 | GPU 2 | GPU 4 | GPU 6 |
| Expert TP=1 | GPU 1 | GPU 3 | GPU 5 | GPU 7 |
| Experts | E0 E1TP=2 切分 | E2 E3TP=2 切分 | E4 E5TP=2 切分 | E6 E7TP=2 切分 |
Expert TP group: {GPU0, GPU1}, {GPU2, GPU3}, {GPU4, GPU5}, {GPU6, GPU7}
TopKRouter 路由机制
TopKRouter 是 Megatron MoE 唯一的 Router 实现,负责将每个 token 路由到 top-k 个 expert。Router 的核心是一个线性门控网络(gating network):一个形状为 [E, H] 的权重矩阵,将 hidden_states [num_tokens, H] 投影到 [num_tokens, E] 的 logits 空间,其中 E 为 expert 总数。
Router 的完整前向流程如下:
① Input Jitter(可选)
为输入添加均匀噪声 input * U(1-eps, 1+eps),增强训练稳定性(参考 ST-MoE)。通过 moe_input_jitter_eps 控制。
② Gating(线性投影)
logits = hidden_states @ W_gate.T,输出形状 [num_tokens, num_experts]。Gate 权重默认使用 FP32 精度(self.weight.fp32 = True)。
③ Z-Loss(可选)
鼓励 logits 保持较小值以增强训练稳定性:\(\text{z\_loss} = \text{coeff} \cdot \text{mean}(\text{logsumexp}(\text{logits})^2)\)。来自 ST-MoE 论文。
④ Top-K 选择 + Score Function
通过 topk_routing_with_score_function() 计算路由。支持两种 score function:softmax(传统方式)和 sigmoid(DeepSeek-V3 风格)。sigmoid 模式下,expert_bias 作为参数传入,在 top-k 选择时加到 logits 上。输出 probs [num_tokens, E] 和 routing_map [num_tokens, E](bool 掩码)。
⑤ _apply_expert_bias(更新 token 计数 buffer)
统计本步各专家收到的 token 数,写入 local_tokens_per_expert buffer,用于下一步更新 expert_bias(不影响当前步路由)。仅在 moe_router_enable_expert_bias=True 且 torch.is_grad_enabled() 时执行。
def topk_routing_with_score_function(
logits, topk, use_pre_softmax=False, num_groups=None,
group_topk=None, scaling_factor=None, score_function="softmax",
expert_bias=None, fused=False,
):
if score_function == "sigmoid":
scores = torch.sigmoid(logits.float()).type_as(logits)
if expert_bias is not None:
# expert_bias 在 top-k 选择时加到 scores 上
scores_for_routing = scores + expert_bias
_, top_indices = compute_topk(scores_for_routing, topk, ...)
# 但 probs 仍然使用原始 scores(不含 bias)
scores = torch.gather(scores, dim=1, index=top_indices)
else:
scores, top_indices = compute_topk(scores, topk, ...)
if topk > 1:
probs = scores / (scores.sum(dim=-1, keepdim=True) + 1e-20)
else:
probs = scores
routing_probs = torch.zeros_like(logits).scatter(1, top_indices, probs)
routing_map = torch.zeros_like(logits).int().scatter(1, top_indices, 1).bool()
return routing_probs, routing_map
pre_softmax(先 softmax 再 top-k)和 post_softmax(先 top-k 再 softmax)两种模式。Sigmoid(DeepSeek-V3 风格):每个 expert 独立计算分数,不受其他 expert 约束。当 top-k > 1 时,对选中的 expert 做归一化(scores / sum)。sigmoid 模式支持 expert_bias 来动态调整路由偏好。
Group TopK:当配置了 moe_router_num_groups 和 moe_router_group_topk 时,expert 被分成若干组,先在组间选 top-k_group 个组,再在选中的组内选 top-k 个 expert。这是 DeepSeek-V3 使用的分组路由策略。
负载均衡策略
MoE 训练的核心挑战之一是负载不均衡:如果 router 总是把 token 发给少数几个 expert,其余 expert 的参数就浪费了。Megatron 提供了多种负载均衡策略,通过 moe_router_load_balancing_type 配置。
| 策略 | 核心思想 | 配置 |
|---|---|---|
| Aux Loss | Switch Transformer 的辅助损失,在 micro-batch 级别鼓励 token 均匀分配。loss = E * Σ f_i * P_i,其中 f_i 是 expert i 的 token 占比,P_i 是平均路由概率。 |
moe_router_load_balancing_type="aux_loss"moe_aux_loss_coeff=0.01 |
| Seq Aux Loss | 序列级别辅助损失:将 batch 维度 reshape 到 expert 维度,对每个序列独立计算 aux loss 后取平均。粒度更细。 | moe_router_load_balancing_type="seq_aux_loss" |
| Global Aux Loss | 全局级别辅助损失:跨所有 DP rank 累积 token 分布(使用滑动平均),在全局维度上鼓励均衡。参考 DeepSeek-V3 论文。 | moe_router_load_balancing_type="global_aux_loss" |
| Sinkhorn | 使用 Sinkhorn 迭代(双随机矩阵归一化)使 token-expert 分配矩阵接近均匀,无需额外损失项。 | moe_router_load_balancing_type="sinkhorn" |
| Expert Bias | 为每个 expert 维护一个可训练的 bias(DeepSeek-V3 风格),在 top-k 选择时加到 logits 上引导路由。bias 根据 token 分布的不均衡程度动态更新。 | moe_router_enable_expert_bias=True |
| None | 不使用任何负载均衡(仅用于测试/基准)。 | moe_router_load_balancing_type="none" |
多策略组合:moe_router_load_balancing_type 可以接受列表,同时启用多种策略。例如 ["aux_loss", "global_aux_loss"] 会在同一个前向中依次应用两种 aux loss。对应的 moe_aux_loss_coeff 也需要是列表。
def _apply_aux_loss(self, probs, scores_for_aux_loss, routing_map):
tokens_per_expert = routing_map.sum(dim=0) # [num_experts]
# EP > 1: 跨 tp_ep 组 reduce,获取完整 EP 组的 token 分布
# EP = 1: 跨 tp_cp 组 reduce
if self.ep_group.size() > 1:
reduce_group = self.tp_ep_group # expert_tp x EP
else:
reduce_group = self.tp_cp_group # TP x CP
tokens_per_expert = reduce_from_tensor_model_parallel_region(
tokens_per_expert, reduce_group
)
aux_loss = switch_load_balancing_loss_func(
probs=scores_for_aux_loss,
tokens_per_expert=tokens_per_expert,
total_num_tokens=num_tokens * reduce_group.size(),
topk=self.topk,
num_experts=self.config.num_moe_experts,
moe_aux_loss_coeff=aux_loss_coeff,
)
# 通过 MoEAuxLossAutoScaler 将 aux loss 附加到 probs 的梯度图上
probs = MoEAuxLossAutoScaler.apply(probs, aux_loss)
return probs
MoEAuxLossAutoScaler(一个自定义 autograd.Function)将 aux loss 的梯度注入到 probs 张量上。前向时 probs 不变,反向时 aux loss 的梯度会流经 probs 传播到 router 的 gate 权重上,从而实现对 router 的正则化。
Token Dispatcher
Token Dispatcher 负责将 token 从"按 rank 组织"转换为"按 expert 组织",以及反向操作。这是 MoE 层最复杂的部分,因为它需要协调跨设备的通信和本地的 permute/unpermute 操作。
Megatron 提供三种 Token Dispatcher 实现:
| Dispatcher | 通信方式 | 适用场景 | 配置 |
|---|---|---|---|
| MoEAlltoAllTokenDispatcher | EP 维度 All-to-All + TP 维度 AllGather/ReduceScatter | EP > 1 的标准场景,通信量最优 | moe_token_dispatcher_type="alltoall" |
| MoEAllGatherTokenDispatcher | TP*EP 维度 AllGather + ReduceScatter | EP == 1 或小规模场景,实现简单 | moe_token_dispatcher_type="allgather" |
| MoEFlexTokenDispatcher | DeepEP / HybridEP 融合 kernel | 高性能场景,permute + All-to-All 融合为一步 | moe_token_dispatcher_type="flex" |
Token Dispatcher 的接口被拆分为六个阶段,将通信操作(可能在专用 stream 上异步执行)和本地计算操作分离,以实现最大化的通信-计算 overlap:
AlltoAll Dispatcher 详解
MoEAlltoAllTokenDispatcher 是最常用的实现。它的核心思路是:
- Permute 1:将 token 按照 routing_map 重排,使发往同一 EP rank 的 token 排列在一起(为 All-to-All 准备)
- All-to-All (EP):各 EP rank 交换 token。Rank i 发送
input_splits[j]个 token 给 Rank j,接收output_splits[j]个 token - AllGather (TP):如果使用了 Expert TP,需要在 TP 组内 AllGather 以获取完整的 token
- Sort by Expert:将接收到的 token 按 local expert 排序(expert 0 的 token 排在前面,expert 1 的排在后面...),生成
tokens_per_expert告知 GroupedGEMM 每个 expert 处理多少 token
def token_dispatch(self, permutated_local_input_tokens, permuted_probs):
"""All-to-All 通信:在 EP group 内交换 token"""
# input_splits: [ep_size] 本 rank 发给各 EP rank 的 token 数
# output_splits: [ep_size] 本 rank 从各 EP rank 接收的 token 数
global_input_tokens = all_to_all(
self.ep_group,
permutated_local_input_tokens,
self.output_splits, # 接收 split
self.input_splits # 发送 split
)
global_probs = all_to_all(
self.ep_group,
permuted_probs,
self.output_splits,
self.input_splits
)
return global_input_tokens, global_probs
| EP Rank 0 | EP Rank 1 | |
|---|---|---|
|
初始 tokens + 路由
[A,B,C,D] A→E0 B→E2 C→E1 D→E0 |
初始 tokens + 路由
[E,F,G,H] E→E1 F→E0 G→E3 H→E2 |
| EP Rank 0 | EP Rank 1 | |
|---|---|---|
| →EP0 | →EP1 [A,D | B,C] | →EP0 | →EP1 [F | E,G,H] |
| EP Rank 0 | EP Rank 1 | |
|---|---|---|
| 收到 (→ E0, E1) [A,D] + [F] = [A,D,F] | ⇄ | 收到 (→ E2, E3) [B,C] + [E,G,H] = [B,C,E,G,H] |
| EP Rank 0 | EP Rank 1 | |
|---|---|---|
| E0=[A,D,F] E1=[] tokens_per_expert=[3, 0] | E2=[B,H] E3=[G] tokens_per_expert=[2, 1] |
input_splits 和 output_splits 等元信息需要从 GPU 拷贝到 CPU(因为 NCCL All-to-All API 需要 CPU 上的 split sizes),但这个 DtoH 拷贝会触发 GPU-CPU 同步。Dispatcher 通过 cuda_dtoh_point 和 cuda_sync_point 机制,将 DtoH 操作放到独立的 CUDA stream 上执行,并尽可能延迟同步点,以最大化 GPU 利用率。
Expert 计算
Expert 计算是 MoE 层中实际处理 token 的部分。每个 expert 本质上是一个标准 MLP(fc1 + activation + fc2),但由于单个 rank 上有多个 local expert,如何高效地执行它们是一个关键问题。
Megatron 提供三种 expert 实现:
| 实现 | 计算方式 | 优势 | 限制 |
|---|---|---|---|
| GroupedMLP | 使用 grouped_gemm 库,将所有 local expert 的矩阵乘法打包成一个调用 |
GPU 利用率最高,减少 kernel launch 开销 | 不支持 bias;需要安装 grouped_gemm 库 |
| TEGroupedMLP | 使用 TransformerEngine 的 GroupedLinear |
支持 FP8/FP4 训练、融合 kernel、bias | 需要 TransformerEngine ≥ 2.x |
| SequentialMLP | 创建 num_local_experts 个独立 MLP 实例,顺序执行 |
实现简单,兼容性好 | GPU 利用率低(多次小 kernel 调用) |
三种实现的输入输出接口完全相同:
- 输入:
permuted_local_hidden_states [total_tokens, H](所有 local expert 的 token 拼接在一起),tokens_per_expert [num_local_experts](每个 expert 分到的 token 数),permuted_probs [total_tokens](路由权重) - 输出:
fc2_output [total_tokens, H](expert 计算结果,已乘以路由权重)
GroupedGEMM 原理
GroupedMLP 的核心是 Grouped GEMM(Grouped General Matrix Multiplication)。传统方式下,N 个 expert 需要 N 次独立的矩阵乘法调用,每次处理不同数量的 token。Grouped GEMM 将这 N 个矩阵乘法打包成一次 GPU kernel 调用,极大提升了 GPU 的 SM 利用率。
| Expert 0[t0,t1,t2] @ W0 | kernel |
| Expert 1[t3] @ W1 | kernel |
| Expert 2[t4,t5] @ W2 | kernel |
| Expert 3[t6,t7,t8] @ W3 | kernel |
|
gmm 单次调用
gmm([t0..t8], [W0,W1,W2,W3], tpe=[3,1,2,3]) | kernel |
CUTLASS grouped GEMM 实现
def forward(self, permuted_local_hidden_states, tokens_per_expert, permuted_probs):
# 将权重 reshape 为 [num_local_experts, H, ffn_hidden]
w1 = self.weight1.view(self.num_local_experts, self.config.hidden_size, -1)
w2 = self.weight2.view(self.num_local_experts, -1, self.config.hidden_size)
# GroupedGEMM: fc1
# input: [total_tokens, H], w1: [num_experts, H, ffn_hidden*2]
fc1_output = gg.ops.gmm(
permuted_local_hidden_states, w1, tokens_per_expert, trans_b=False
)
# SwiGLU activation + 路由权重
intermediate = self.activation_func_with_probs(
fc1_output, permuted_probs.unsqueeze(-1)
)
# GroupedGEMM: fc2
# input: [total_tokens, ffn_hidden], w2: [num_experts, ffn_hidden, H]
fc2_output = gg.ops.gmm(
intermediate, w2, tokens_per_expert, trans_b=False
)
return fc2_output, None
GroupedMLP 将所有 local expert 的权重存储在两个大矩阵中:weight1 [H, num_local_experts * ffn_hidden * 2](fc1,包含 SwiGLU 的 gate 和 value)和 weight2 [num_local_experts * ffn_hidden, H](fc2)。在前向时通过 view 操作将其 reshape 为 [num_local_experts, ...] 的形状供 Grouped GEMM 使用。这种紧凑存储避免了为每个 expert 创建独立 Parameter 的开销。
Shared Experts
Shared Expert 是一种所有 token 都会经过的"常驻 expert",与 routed expert(只处理被路由到的 token)互补。Shared expert 的输出直接加到 routed expert 的输出上,确保每个 token 至少获得一些"通用知识"的处理。这一设计来自 DeepSeek-MoE / DeepSeek-V3 架构。
SharedExpertMLP 继承自标准 MLP,额外支持:
- Gate Mechanism:可选的 sigmoid 门控,学习一个标量系数来调节 shared expert 的输出贡献。
gate_score = sigmoid(hidden_states @ gate_weight.T),然后output = output * gate_score。 - 独立的 FFN 大小:通过
moe_shared_expert_intermediate_size控制,通常比 routed expert 的 FFN 更大。 - Overlap 模式:可与 Token Dispatcher 的通信操作重叠执行(详见下节)。
class SharedExpertMLP(MLP):
def forward(self, hidden_states):
# 标准 MLP 前向:fc1 -> activation -> fc2
if self.activation_recompute:
output, _ = self._forward_with_activation_recompute(hidden_states)
else:
output, _ = super().forward(hidden_states)
# 可选:sigmoid gate 调节输出
if self.use_shared_expert_gate:
logits = F.linear(hidden_states, self.gate_weight)
gate_score = torch.sigmoid(logits)
output = output * gate_score
return output
pg_collection.tp),而非 Expert TP 组。这是因为 shared expert 处理所有 token,其并行方式与普通 MLP 相同。Routed expert 则使用 Expert TP 组(pg_collection.expt_tp),后者可以与 Attention TP 有不同的大小。
通信-计算 Overlap
MoE 层的主要性能瓶颈是 All-to-All 通信。当 EP 较大时,跨节点的 All-to-All 延迟可能显著影响训练吞吐。Megatron 通过将 Shared Expert 计算与 Token Dispatcher 通信重叠来隐藏通信延迟。
当 moe_shared_expert_overlap=True 时,SharedExpertMLP 的前向被拆分为多个细粒度函数,穿插在 AlltoAll Dispatcher 的各阶段之间,在独立的 CUDA stream 上执行:
关键实现细节:
- Shared expert 的
linear_fc1和linear_fc2的 TP 通信(AllGather/ReduceScatter)被拆出来由pre_forward_comm和post_forward_comm显式执行。Linear 模块内部的 TP 通信被禁用(linear.parallel_mode = None)。 - 所有 shared expert 操作都在
SharedExpertMLP.stream(一个独立的 CUDA stream)上执行。最终通过torch.cuda.current_stream().wait_stream(self.stream)同步。 - 使用
_set_sequence_nr()控制反向传播的调度顺序,确保 shared expert 的反向在正确的时机执行。
配置参数速查表
基础配置
| 参数 | 默认值 | 说明 |
|---|---|---|
num_moe_experts | - | Expert 总数(如 64、128、256) |
moe_router_topk | - | 每个 token 路由到的 expert 数量(如 1、2、8) |
moe_ffn_hidden_size | =ffn_hidden_size | 每个 routed expert 的 FFN 隐藏层维度 |
expert_model_parallel_size | 1 | Expert Parallelism 大小(EP size),num_moe_experts 必须能被整除 |
expert_tensor_parallel_size | 1 | Expert 内部的 Tensor Parallelism 大小 |
路由配置
| 参数 | 默认值 | 说明 |
|---|---|---|
moe_router_load_balancing_type | "aux_loss" | 负载均衡策略:aux_loss / seq_aux_loss / global_aux_loss / sinkhorn / none,可用列表组合多种 |
moe_aux_loss_coeff | 0.0 | Aux loss 系数,配合 load_balancing_type 使用 |
moe_z_loss_coeff | None | Z-loss 系数,鼓励 logits 保持小值 |
moe_router_score_function | "softmax" | 打分函数:softmax 或 sigmoid |
moe_router_pre_softmax | False | 是否在 top-k 之前做 softmax(仅 softmax 模式) |
moe_router_enable_expert_bias | False | 启用 expert bias(DeepSeek-V3 风格动态负载均衡) |
moe_router_num_groups | None | 分组路由的组数(DeepSeek-V3 风格) |
moe_router_group_topk | None | 分组路由中每个 token 选择的组数 |
moe_router_topk_scaling_factor | None | 路由概率的缩放因子 |
moe_input_jitter_eps | None | 输入 jitter 噪声幅度 |
moe_router_dtype | None | 路由计算的精度:fp32 / fp64 |
Token Dispatcher 配置
| 参数 | 默认值 | 说明 |
|---|---|---|
moe_token_dispatcher_type | "allgather" | Dispatcher 类型:alltoall / allgather / flex |
moe_expert_capacity_factor | None | Expert 容量因子,设置后启用 token dropping |
moe_pad_expert_input_to_capacity | False | 是否 pad 输入到固定容量(drop and pad 模式) |
moe_token_drop_policy | "probs" | Token dropping 策略:probs(丢低概率)或 position"(丢后面的) |
moe_permute_fusion | False | 使用融合 permute kernel |
moe_flex_dispatcher_backend | - | Flex dispatcher 后端:deepep / hybridep |
Expert 与 Shared Expert 配置
| 参数 | 默认值 | 说明 |
|---|---|---|
moe_grouped_gemm | False | 使用 GroupedMLP(grouped_gemm 库)替代 SequentialMLP |
moe_apply_probs_on_input | False | 将路由权重乘到输入(而非输出),仅 topk=1 时可用 |
moe_shared_expert_intermediate_size | None | Shared expert 的 FFN 隐藏层维度,设置后启用 shared expert |
moe_shared_expert_gate | False | 是否为 shared expert 添加 sigmoid gate |
moe_shared_expert_overlap | False | 将 shared expert 计算与 dispatcher 通信重叠 |
- GPT 模型架构 — TransformerLayer 与 MLP 的位置关系
- Rank 与并行组 — EP/TP/DP 组的划分方式
- 集合通信操作 — All-to-All 通信原理
- Tensor Parallelism — ColumnParallelLinear / RowParallelLinear 切分