- Authors

- Name
- Youngju Kim
- @fjvbn20031

概述
随着大语言模型的参数量扩展到万亿级别,每个 token 都要激活全部参数的 Dense 模型的局限性变得明显。训练与推理成本随参数量成比例增加。Mixture of Experts(MoE)已经确立为应对这一问题最有力的方案。MoE 只从全部参数中选择性地激活一部分专家(Expert),在保持庞大模型容量的同时,把实际运算量相对 Dense 模型大幅削减。
2022 年,Switch Transformer 用单专家路由打开了万亿级参数扩展的可能性,GShard 提出了 600B 参数模型的分布式训练流水线。ST-MoE 同时提升了训练稳定性与迁移学习质量,Mixtral 8x7B 证明了开源 MoE 模型的实用性。DeepSeek-MoE 与 DeepSeek-V3 则开辟了细粒度专家切分和无辅助损失负载均衡这一新方向。本文将分析各篇论文的核心贡献,并梳理路由机制、训练稳定性、推理优化等在实战中运营 MoE 所需的策略。
MoE 核心概念
稀疏激活(Sparse Activation)的原理
MoE 的核心思想是条件计算(Conditional Computation)。由于每个输入 token 只会激活全部专家中的一部分,模型的总参数量与实际参与运算的参数量被解耦。例如 Mixtral 8x7B 总共拥有 47B 参数,但每个 token 只使用 13B 参数。相比 Dense 47B 模型,运算量降低到约 1/3.6,而质量与之相近甚至更高。
Dense 与 Sparse MoE 对比
| 项目 | Dense 模型 | Sparse MoE |
|---|---|---|
| 活跃参数 | 全部参数 = 活跃参数 | 只激活全部的 10-30% |
| FLOPs 效率 | 与参数量成正比 | 与活跃参数量成正比 |
| 内存需求 | 等于参数体量 | 需要存储全部参数(内存更大) |
| 训练稳定性 | 相对稳定 | 路由不稳定,存在专家崩溃风险 |
| 可扩展性 | 线性成本增加 | 通过增加专家实现低成本扩展 |
| 推理延迟 | 可预测 | 路由开销、专家加载延迟 |
| 代表模型 | LLaMA、GPT-4(推测) | Mixtral、DeepSeek-V3、Switch Transformer |
基础 MoE 层实现
用 PyTorch 实现 MoE 层的基本结构如下。门控网络(Gating Network)针对输入 token 计算各专家的权重,选出 Top-K 专家后对输出求和。
import torch
import torch.nn as nn
import torch.nn.functional as F
class Expert(nn.Module):
"""单个专家 FFN 模块"""
def __init__(self, d_model: int, d_ff: int, dropout: float = 0.1):
super().__init__()
self.w1 = nn.Linear(d_model, d_ff)
self.w2 = nn.Linear(d_ff, d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.w2(self.dropout(F.gelu(self.w1(x))))
class MoELayer(nn.Module):
"""Mixture of Experts 层"""
def __init__(
self,
d_model: int,
d_ff: int,
num_experts: int,
top_k: int = 2,
dropout: float = 0.1,
):
super().__init__()
self.num_experts = num_experts
self.top_k = top_k
self.experts = nn.ModuleList([
Expert(d_model, d_ff, dropout) for _ in range(num_experts)
])
# 门控网络: 输入 -> 专家分数
self.gate = nn.Linear(d_model, num_experts, bias=False)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# x: (batch, seq_len, d_model)
batch_size, seq_len, d_model = x.shape
x_flat = x.view(-1, d_model) # (B*S, d_model)
# 计算门控分数
gate_logits = self.gate(x_flat) # (B*S, num_experts)
gate_probs = F.softmax(gate_logits, dim=-1)
# 选择 Top-K 专家
top_k_probs, top_k_indices = torch.topk(
gate_probs, self.top_k, dim=-1
) # (B*S, top_k)
# 对选中的专家权重重新归一化
top_k_probs = top_k_probs / top_k_probs.sum(dim=-1, keepdim=True)
# 汇总各专家输出
output = torch.zeros_like(x_flat)
for k in range(self.top_k):
expert_idx = top_k_indices[:, k] # (B*S,)
weight = top_k_probs[:, k].unsqueeze(-1) # (B*S, 1)
for i in range(self.num_experts):
mask = (expert_idx == i)
if mask.any():
expert_input = x_flat[mask]
expert_output = self.experts[i](expert_input)
output[mask] += weight[mask] * expert_output
return output.view(batch_size, seq_len, d_model)
这个实现是出于教学目的,实际生产环境中会使用 Megablocks、Tutel 这类优化库来高效地完成按专家分批处理与 All-to-All 通信。
主要论文分析
Switch Transformer(Fedus et al., 2022)
Switch Transformer 的核心贡献在于把 MoE 路由做到了极致的简化。以往的 MoE 会组合 Top-2 以上的专家,而 Switch Transformer 引入了 Switch Routing——每个 token 只分配给单一一个专家。这个决定看似违反直觉,但实验结果表明,单专家路由能把通信成本减半,同时也降低了路由运算本身的开销,从而支撑了这一设计。
在同等运算量下,基于 T5-Base 架构最高实现了 7 倍的预训练速度提升,并扩展到了万亿级参数模型。通过 bfloat16 混合精度训练也改善了内存效率,并同时应用专家丢弃(Expert Dropout)与辅助负载均衡损失,缓解了训练不稳定的问题。
Switch Transformer 引入的专家容量因子(Capacity Factor)决定了每个专家能处理的最大 token 数。超出容量的 token 会被丢弃,这会在训练中造成信息损失,但对于平衡运算负载而言是必要的。
GShard(Lepikhin et al., 2021)
GShard 是一篇聚焦于如何在大规模分布式环境中实用地训练 MoE 的系统设计论文。它用 2,048 个 TPU v3 加速器,在 4 天内训练出一个 600B 参数的多语言翻译模型。核心技术贡献有三点。
第一是专家并行(Expert Parallelism)。它确立了把专家分散部署到多个设备上,并将 token 路由到目标专家所在设备的 All-to-All 通信模式。第二是随机路由(Random Routing)。在确定性地选出 Top-1 专家之后,第二个专家按与门控权重成比例的概率随机选出。这种方式会促进训练中的探索(exploration)。第三,通过扩展 XLA 编译器,提供了一套轻量级 API,只需极少的代码改动就能表达多种并行化模式。
GShard 按组计算容量的公式 C = 2N / (G * E),会综合考虑组大小 G、专家数 E、token 数 N,动态决定各专家的处理容量。
ST-MoE(Zoph et al., 2022)
正如 ST-MoE 这个名字所暗示的,这篇论文的核心问题是「MoE 模型能否被稳定地(Stable)训练,并有效地迁移(Transferable)?」。研究者以相当于 32B Dense 模型的运算成本,训练出了一个 269B 参数的 Sparse 模型(ST-MoE-32B),并在 SuperGLUE、ARC、XSum 等多种基准测试上首次让 Sparse 模型取得了最佳性能。
为了训练稳定性,论文引入了 Router Z-Loss。这个损失函数通过控制路由器 logit 的大小,防止训练过程中的发散(divergence)。与既有的辅助损失(auxiliary loss)搭配使用时,训练稳定性会大幅改善。此外论文还系统整理了一系列实战设计建议:Top-2 路由、训练时容量因子取 1.25、每个核心最多部署 1 个专家等。
论文的实验结果表明,微调时提高专家丢弃比例、缩小批大小、并把学习率设置得更保守,有助于提升迁移学习的质量。
Mixtral 8x7B(Mistral AI, 2024)
Mixtral 8x7B 决定性地证明了开源 MoE 模型的实用性。它在与 Mistral 7B 相同的 Transformer 架构上,把每层的 FFN 替换为 8 个专家,并为每个 token 选出 Top-2 专家。由于总共 47B 参数中只有 13B 被激活,推理速度与 13B Dense 模型相近,而质量可与 LLaMA 2 70B 匹敌。
| 项目 | Mixtral 8x7B | LLaMA 2 70B | Mistral 7B |
|---|---|---|---|
| 总参数量 | 46.7B | 70B | 7.3B |
| 活跃参数量 | 12.9B | 70B | 7.3B |
| 推理 FLOPs | ~26B | ~140B | ~15B |
| MMLU | 70.6 | 69.8 | 60.1 |
| ARC-Challenge | 66.4 | 64.6 | 55.5 |
| 专家数量 | 8 | - | - |
| 活跃专家数 | 2 | - | - |
Mixtral 的专家特化分析结果显示,专家的特化倾向更多取决于句法模式而非领域。并非某个特定专家只对代码或数学作出反应,而是专家选择会随句子结构或 token 位置变化。
DeepSeek-MoE 与 DeepSeek-V3
DeepSeek-MoE 以「终极专家特化(Ultimate Expert Specialization)」为目标,提出了两项核心策略。
第一是细粒度专家切分(Fine-Grained Expert Segmentation)。把原有的 N 个专家细分为 mN 个,同时把每个专家 FFN 的中间维度缩小到 1/m,以维持总参数量不变。取而代之的是激活 mK 个专家,从而实现更灵活的专家组合。DeepSeek-MoE 16B 只用 40% 的运算量就达到了与 LLaMA 2 7B 相近的性能。
第二是共享专家(Shared Expert)隔离。把所有 token 共同使用的专家单独分离出来,防止路由专家之间出现重复的知识存储,从而提高各专家的特化程度。
DeepSeek-V3 把这一思路扩展到 671B 参数规模,并引入了创新的无辅助损失(Auxiliary-Loss-Free)负载均衡。它使用 256 个路由专家与 1 个共享专家,每个 token 激活 8 个专家。以往的辅助损失方案在负载均衡与模型性能之间存在权衡,而 DeepSeek-V3 为每个专家添加一个偏置项,并在训练过程中实时监控专家负载来动态调整偏置。通过这种方式,整个训练过程都能在不丢弃 token 的前提下维持均衡的负载。
MoE 模型对比综合
| 模型 | 总参数 | 活跃参数 | 专家数 | 活跃专家 | 路由方式 | 负载均衡 |
|---|---|---|---|---|---|---|
| Switch Transformer | 1.6T | ~1/E | 128 | 1 | Top-1 | 辅助损失 |
| GShard 600B | 600B | ~2/E | 2048 | 2 | Top-1 + Random | 容量限制 + 辅助损失 |
| ST-MoE-32B | 269B | 相当于 32B | 64 | 2 | Top-2 | Router Z-Loss + 辅助损失 |
| Mixtral 8x7B | 46.7B | 12.9B | 8 | 2 | Top-2 | 辅助损失 |
| DeepSeek-V3 | 671B | 37B | 256+1 | 8+1 | Top-8 | Auxiliary-Loss-Free |
路由机制深度解析
Top-K 路由实现
路由机制是 MoE 的核心。它接收输入 token 的隐藏状态,决定要激活哪些专家,而这一决策的质量直接左右模型的整体性能。下面来看几种路由策略的具体实现。
import torch
import torch.nn as nn
import torch.nn.functional as F
from typing import Tuple
class TopKRouter(nn.Module):
"""带噪声注入的 Top-K 路由"""
def __init__(
self,
d_model: int,
num_experts: int,
top_k: int = 2,
noise_std: float = 1.0,
):
super().__init__()
self.top_k = top_k
self.num_experts = num_experts
self.noise_std = noise_std
self.gate = nn.Linear(d_model, num_experts, bias=False)
def forward(
self, x: torch.Tensor
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
"""
Args:
x: (batch * seq_len, d_model)
Returns:
top_k_indices: (batch * seq_len, top_k)
top_k_weights: (batch * seq_len, top_k)
gate_logits: (batch * seq_len, num_experts)
"""
gate_logits = self.gate(x)
# 训练时注入噪声以促进探索
if self.training:
noise = torch.randn_like(gate_logits) * self.noise_std
gate_logits = gate_logits + noise
gate_probs = F.softmax(gate_logits, dim=-1)
top_k_probs, top_k_indices = torch.topk(
gate_probs, self.top_k, dim=-1
)
# 重新归一化
top_k_weights = top_k_probs / top_k_probs.sum(dim=-1, keepdim=True)
return top_k_indices, top_k_weights, gate_logits
路由策略对比
| 策略 | 论文 | 活跃专家 | 优点 | 缺点 |
|---|---|---|---|---|
| Top-1 | Switch Transformer | 1 | 通信成本最低,实现简单 | 专家崩溃风险高 |
| Top-2 | ST-MoE, Mixtral | 2 | 稳定,性能优秀 | 通信量是 Top-1 的 2 倍 |
| Top-1 + Random | GShard | 2 | 促进探索 | 推理结果非确定性 |
| Top-K (K >= 4) | DeepSeek-V3 | 8 | 充分利用细粒度专家 | 只有专家数量多时才有效 |
| Expert Choice | EC Routing | 可变 | 保证完全均衡 | 各 token 分到的专家数不均匀 |
Expert Choice Routing 把传统路由的视角颠倒了过来。不是由 token 去选择专家,而是每个专家去选择自己要处理的 token。这种方式能完全保证负载均衡,但存在特定 token 可能不会被任何专家选中的问题。
训练稳定性与负载均衡
负载均衡损失实现
MoE 训练中最常见的问题是专家崩溃(Expert Collapse)。当 token 集中流向特定专家时,只有那些专家会得到训练,其余专家则得不到利用,实际上沦为 Dead Expert。为防止这一问题,通常会使用辅助负载均衡损失。
def load_balancing_loss(
gate_logits: torch.Tensor,
top_k_indices: torch.Tensor,
num_experts: int,
top_k: int = 2,
) -> torch.Tensor:
"""
Switch Transformer 风格的负载均衡损失计算
最小化每个专家分配到的 token 比例(f_i)
与门控概率均值(p_i)的内积。
在均匀分布时取得最小值。
Args:
gate_logits: (num_tokens, num_experts)
top_k_indices: (num_tokens, top_k)
num_experts: 专家数
top_k: 活跃专家数
Returns:
标量负载均衡损失
"""
num_tokens = gate_logits.shape[0]
gate_probs = F.softmax(gate_logits, dim=-1)
# f_i: 每个专家分配到的 token 比例
# 用 one-hot 编码统计分配数
expert_mask = F.one_hot(
top_k_indices, num_classes=num_experts
).float() # (num_tokens, top_k, num_experts)
expert_mask = expert_mask.sum(dim=1) # (num_tokens, num_experts)
tokens_per_expert = expert_mask.sum(dim=0) # (num_experts,)
f = tokens_per_expert / (num_tokens * top_k)
# p_i: 每个专家的平均门控概率
p = gate_probs.mean(dim=0) # (num_experts,)
# 均衡损失: num_experts * sum(f_i * p_i)
balance_loss = num_experts * (f * p).sum()
return balance_loss
Router Z-Loss
ST-MoE 引入的 Router Z-Loss,通过控制路由器 logit 的大小来防止训练发散。当 logit 值过大时,softmax 的梯度会消失,导致训练不稳定,而 Z-Loss 能够抑制这一现象。
def router_z_loss(gate_logits: torch.Tensor) -> torch.Tensor:
"""
ST-MoE Router Z-Loss 实现
最小化路由器 logit 的 log-sum-exp 值的平方均值。
防止 logit 过度增大,从而确保训练稳定性。
Args:
gate_logits: (num_tokens, num_experts)
Returns:
标量 z-loss 值
"""
# log(sum(exp(x))) 的平方
log_z = torch.logsumexp(gate_logits, dim=-1) # (num_tokens,)
z_loss = (log_z ** 2).mean()
return z_loss
# 在训练循环中的整合
def compute_moe_loss(
task_loss: torch.Tensor,
gate_logits: torch.Tensor,
top_k_indices: torch.Tensor,
num_experts: int,
alpha_balance: float = 0.01,
alpha_z: float = 0.001,
) -> torch.Tensor:
"""
MoE 总损失 = 任务损失 + 均衡损失 + Z-Loss
"""
bal_loss = load_balancing_loss(
gate_logits, top_k_indices, num_experts
)
z_loss = router_z_loss(gate_logits)
total_loss = task_loss + alpha_balance * bal_loss + alpha_z * z_loss
return total_loss
alpha_balance 与 alpha_z 的设置很关键。辅助损失系数太大会拉低模型性能,太小则失去负载均衡效果,导致专家崩溃。ST-MoE 推荐 alpha_balance = 0.01、alpha_z = 0.001。
Auxiliary-Loss-Free 方法
DeepSeek-V3 引入的无辅助损失负载均衡,从根本上化解了这一权衡。它为每个专家添加一个可学习的偏置项,并在训练过程中实时监控各专家的负载来调整偏置。
class AuxLossFreeRouter(nn.Module):
"""DeepSeek-V3 风格的 Auxiliary-Loss-Free 路由器"""
def __init__(
self,
d_model: int,
num_experts: int,
top_k: int = 8,
bias_update_speed: float = 0.001,
):
super().__init__()
self.num_experts = num_experts
self.top_k = top_k
self.gamma = bias_update_speed
self.gate = nn.Linear(d_model, num_experts, bias=False)
# 偏置不通过梯度更新,而是基于规则调整
self.register_buffer(
"expert_bias", torch.zeros(num_experts)
)
self.register_buffer(
"target_load", torch.ones(num_experts) / num_experts
)
def forward(self, x: torch.Tensor):
gate_logits = self.gate(x)
# 加上偏置以影响路由决策
biased_logits = gate_logits + self.expert_bias.unsqueeze(0)
gate_probs = F.softmax(gate_logits, dim=-1)
# Top-K 选择使用带偏置的 logit
_, top_k_indices = torch.topk(
biased_logits, self.top_k, dim=-1
)
# 权重从原始门控概率中提取
top_k_probs = torch.gather(gate_probs, 1, top_k_indices)
top_k_weights = top_k_probs / top_k_probs.sum(dim=-1, keepdim=True)
# 训练时更新偏置(不需要梯度)
if self.training:
with torch.no_grad():
expert_load = F.one_hot(
top_k_indices.view(-1), self.num_experts
).float().sum(0)
expert_load = expert_load / expert_load.sum()
# 过载专家降低偏置,负载不足的专家提高偏置
self.expert_bias += self.gamma * (
self.target_load - expert_load
)
return top_k_indices, top_k_weights, gate_logits
这种方法的关键在于,偏置只影响路由决策(Top-K 选择),而专家输出的权重计算仍然使用原始门控概率。由于偏置不会干扰模型的梯度流,因此能够在不损失性能的前提下实现负载均衡。
推理优化
Expert Offloading 与 Capacity Budgeting
MoE 模型推理中最大的挑战是内存。当所有专家都常驻 GPU 内存不现实时,专家卸载(Expert Offloading)就变得不可或缺——把未被激活的专家转移到 CPU 内存或磁盘,只在需要时才加载到 GPU 上。
2025 年以来出现的研究,把投机解码(Speculative Decoding)与专家卸载结合起来,大幅改善了性能。SpecMoEOff 通过投机解码扩大专家的工作量,从而隐藏卸载延迟,实现了最高 2.5 倍的解码吞吐量提升。MoE-Spec 无需训练,只需固定各层的专家容量、丢弃不常用的专家,就带来了 10-30% 的吞吐量提升。
from dataclasses import dataclass
from typing import Dict, Optional
import torch
@dataclass
class ExpertCacheConfig:
"""专家缓存配置"""
gpu_cache_size: int = 4 # GPU 上常驻的专家数
prefetch_count: int = 2 # 预取的专家数
device: str = "cuda:0"
class ExpertOffloadManager:
"""
专家卸载管理器。
基于 LRU 管理 GPU 缓存,
并预取下一层需要用到的专家。
"""
def __init__(
self,
experts: Dict[int, torch.nn.Module],
config: ExpertCacheConfig,
):
self.experts = experts
self.config = config
self.gpu_cache: Dict[int, torch.nn.Module] = {}
self.access_order: list = []
def get_expert(self, expert_id: int) -> torch.nn.Module:
"""把专家加载到 GPU(LRU 缓存)"""
if expert_id in self.gpu_cache:
self.access_order.remove(expert_id)
self.access_order.append(expert_id)
return self.gpu_cache[expert_id]
# GPU 缓存已满时淘汰 LRU 专家
if len(self.gpu_cache) >= self.config.gpu_cache_size:
evict_id = self.access_order.pop(0)
self.gpu_cache[evict_id].cpu()
del self.gpu_cache[evict_id]
# 把专家移动到 GPU
expert = self.experts[expert_id].to(self.config.device)
self.gpu_cache[expert_id] = expert
self.access_order.append(expert_id)
return expert
def prefetch(self, predicted_expert_ids: list):
"""异步预取下一层将使用的专家"""
for eid in predicted_expert_ids[:self.config.prefetch_count]:
if eid not in self.gpu_cache:
self.get_expert(eid)
量化与 Expert Pruning
提升 MoE 模型推理效率的另一个方向是量化与专家剪枝。与其对所有专家采用相同比特位量化,不如采用自适应量化策略——常被激活的专家保持高精度,很少使用的专家则做更激进的量化,效果更好。Expert Pruning 在训练结束后彻底移除激活频率低的专家,以降低内存占用。已有实验结果表明,在 Mixtral 8x7B 上剪掉 2 个专家,性能下降微乎其微。
故障排查
下面整理 MoE 模型训练与推理中经常出现的问题及其解决办法。
专家崩溃(Expert Collapse)
症状:训练过程中只有少数专家被激活,其余专家的门控概率收敛到 0。在 TensorBoard 中监控各专家的 token 分配比例,可以看到 90% 以上的 token 集中在特定专家上。
原因大多是辅助损失系数过小,或者训练初期路由器权重初始化不均衡。解决办法是:把 alpha_balance 从 0.01 起步逐步调整,把路由器权重以较小的数值均匀初始化,并在训练初期的若干步内应用随机路由的预热(warmup)。
训练发散(Training Divergence)
症状:训练过程中 loss 突然剧增,或出现 NaN。这种情况在 MoE 模型使用 bfloat16 训练时尤为常见。
应用 Router Z-Loss,并为路由器 logit 单独保留 float32 运算,是有效的解决办法。把学习率设置为比 Dense 模型低 2-5 倍也是推荐做法。
All-to-All 通信瓶颈
症状:分布式训练中,专家并行的 All-to-All 通信占用了整体训练时间的 30% 以上。
把专家数设置为设备数的倍数,并降低容量因子以减少传输数据量。让通信与运算重叠的流水线调度也是有效手段。Megablocks 库通过块稀疏运算提供了一种规避 All-to-All 通信的方案。
推理时内存不足
症状:由于所有专家都无法装入 GPU 内存,出现 OOM。
应用 Expert Offloading,或者通过专家剪枝直接降低内存需求。把张量并行(Tensor Parallelism)与专家并行组合起来,分散到多张 GPU 上,也是一种办法。
失败案例
辅助损失系数设置过大
有一个团队在训练基于 Mixtral 架构的定制 MoE 模型时,为了防止专家崩溃,把 alpha_balance 设置成了偏高的 0.1。负载均衡确实做到了完美,但模型被训练成了不顾 token 含义、平均分配到各专家的方向,导致实际任务性能反而低于 Dense 模型。辅助损失压过了主损失,使路由器无法学到有意义的专家特化。直到把 alpha_balance 降到 0.005 并同时应用 Router Z-Loss 之后,性能才得到改善。
推理时切换到 Top-1 的陷阱
有一个案例,训练时使用 Top-2 路由的模型,为了降低推理成本而切换到 Top-1。运算量确实减半了,但基准测试分数下降了 8-12%。因为两个专家的输出在训练中是互补学习的,只用其中一个会导致表达能力大幅损失。如果目标是降低推理成本,应该从训练阶段起就按 Top-1 设计,或者改走量化与剪枝的路线。
缺少共享专家的细分化失败
有一个案例,在应用 DeepSeek-MoE 的细粒度专家切分时省略了共享专家(Shared Expert)。结果所有专家都重复学习了基础的语言模式(冠词、介词、标点符号等),每个专家的独有知识量因此减少,细分化本该带来的收益被抵消。只有共享专家吸收了通用知识,路由专家才能专注于各自独有的模式。
运维检查清单
下面整理了从训练到服务化运营 MoE 模型时需要确认的事项。
训练配置
- 路由器权重是否以较小的标准差(0.01 以下)初始化
- 辅助损失系数(alpha_balance)是否从 0.005-0.01 的区间开始设置
- 是否启用了 Router Z-Loss
- 学习率相对同规模 Dense 模型是否保守(低 2-5 倍)
- bfloat16 训练时路由器 logit 运算是否保持 float32
- 专家数是否为设备数的倍数
- 容量因子(Capacity Factor)是否设置在 1.0-1.5 区间
监控
- 是否实时追踪各专家的 token 分配比例
- 是否为 Dead Expert(分配比例低于 1%)数量设置了告警
- 是否追踪路由器 logit 的平均大小与方差
- 是否测量 All-to-All 通信时间与运算时间的比例
- 是否有针对训练 loss 剧烈波动(spike)的自动检测
推理服务
- 是否确定了专家卸载策略(全量 GPU / 部分卸载 / 磁盘)
- 是否按专家差异化应用量化级别(常用专家保持高精度)
- 是否用基准测试确认了专家剪枝后的性能下降幅度
- 是否测量了不同批大小下的路由开销
- 是否监控专家缓存命中率(Hit Rate)
- 应用投机解码时,是否确认了 Draft 模型与专家预测的准确率
微调
- 专家丢弃比例是否比预训练时更高(ST-MoE 推荐做法)
- 批大小是否比预训练时更小
- 是否试验过固定(freeze)路由器、只微调专家的方案
- 是否确认了微调后专家特化分布是否随任务发生了相应变化
参考资料
- Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity (Fedus et al., 2022)
- GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding (Lepikhin et al., 2021)
- ST-MoE: Designing Stable and Transferable Sparse Expert Models (Zoph et al., 2022)
- Mixtral of Experts (Mistral AI, 2024)
- DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models (2024)
- DeepSeek-V3 Technical Report (2024)
- Mixture-of-Experts with Expert Choice Routing (Zhou et al., 2022)
- A Review on the Evolvement of Load Balancing Strategy in MoE LLMs
- Applying Mixture of Experts in LLM Architectures - NVIDIA Technical Blog
小测验
Q1:《Mixture of Experts(MoE)架构论文综述与实战扩展 2026》主要讲的是什么主题?
Mixture of Experts(MoE)架构核心论文分析。涵盖 Switch Transformer、GShard、ST-MoE 直到 Mixtral 的路由机制、专家并行化、负载均衡策略,从实战角度加以梳理。
Q2:MoE 核心概念讲的是什么?
稀疏激活(Sparse Activation)的原理 MoE 的核心思想是条件计算(Conditional
Computation)。由于每个输入 token 只会激活全部专家中的一部分,模型的总参数量与实际参与运算的参数量被解耦。
Q3:请说明主要论文分析的核心概念。
Switch Transformer(Fedus et al., 2022) Switch Transformer
的核心贡献在于把 MoE 路由做到了极致的简化。以往的 MoE 会组合 Top-2 以上的专家,而 Switch
Transformer 引入了 Switch Routing——每个 token 只分配给单一一个专家。
Q4:路由机制深度解析涵盖哪些要点?
Top-K 路由实现 路由机制是 MoE 的核心。它接收输入 token
的隐藏状态,决定要激活哪些专家,而这一决策的质量直接左右模型的整体性能。
Q5:训练稳定性与负载均衡是如何运作的?
负载均衡损失实现 MoE 训练中最常见的问题是专家崩溃(Expert Collapse)。当 token
集中流向特定专家时,只有那些专家会得到训练,其余专家则得不到利用,实际上沦为 Dead Expert。