大模型架构正在向MoE(混合专家模型)加速迁移。从GPT-4到爆火的DeepSeek-V3,MoE凭借“大容量、低算力消耗”的稀疏激活特性成为主流。本文带你拆解其底层逻辑与极简代码实现方案。

在过去几年里,大语言模型(LLM)的迭代速度令人咋舌。但无论上层能力如何演进,其底层骨架——仅包含解码器的标准 Decoder-only Transformer——几乎长期保持不变。
这一格局最近被彻底打破。顶尖研究机构正集体转向一种更具扩展性的架构:混合专家模型(Mixture-of-Experts,简称 MoE)。
传闻中的 GPT-4 采用了 MoE 架构,而开源社区里引爆行业海啸的 DeepSeek-V3 和 DeepSeek-R1,更是将 MoE 的性价比推向了极致:
“为了进一步拓展开源模型能力边界,我们推出了 DeepSeek-V3。这是一个总参数量 6710 亿(671B)的大型 MoE 模型,但在处理每个 Token 时,仅激活其中的 370 亿(37B)参数。”
为什么 MoE 能成为训练超大规模模型的高效利器?它的底层代码又是如何运转的?
传统的标准 Transformer 是“稠密模型”(Dense Model)。这意味着每输入一个词(Token),神经网络中的所有参数都要参与前向计算和反向传播。当参数量上升到数百亿、数千亿时,每次推理和训练的浮点计算量(FLOPs)呈线性爆炸。
MoE 做的事情很简单:将参数容量与计算成本解耦。
在 MoE 结构中,原先标准 Transformer 层中的前馈神经网络(FFN)被替换为一组并行的“专家网络”(Experts),并引入一个“门控路由网络”(Gating / Router Network)。
每个 Token 进入层内时:
以 DeepSeek-V3 为例,虽然总参数量高达 671B,但计算量只相当于一个 37B 的稠密模型。这不仅大幅压低了单次推理的计算成本,还让模型拥有了容纳更多世界知识的潜力和容量。
要彻底理解 MoE,从零写一个极简实现(nanoMoE)是最直观的方式。MoE 的最小实现由三个关键部分构成:专家层、门控路由、以及负载均衡机制。
专家本质上就是普通的 FFN(多层感知机)。在 PyTorch 中,我们可以将多个专家打包为一个模块列表:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Expert(nn.Module):
def __init__(self, embed_dim, hidden_dim):
super().__init__()
self.net = nn.Sequential(
nn.Linear(embed_dim, hidden_dim),
nn.GELU(),
nn.Linear(hidden_dim, embed_dim)
)
def forward(self, x):
return self.net(x)
路由器的任务是输出一个概率分布,指示每个 Token 应该派发给哪位专家。通常通过一个线性映射后做 Softmax,再取 Top-K:
class TopKRouter(nn.Module):
def __init__(self, embed_dim, num_experts, top_k=2):
super().__init__()
self.top_k = top_k
self.gate = nn.Linear(embed_dim, num_experts, bias=False)
def forward(self, x):
# x 形状: (batch_size, seq_len, embed_dim)
logits = self.gate(x) # (batch_size, seq_len, num_experts)
weights, indices = torch.topk(logits, self.top_k, dim=-1)
weights = F.softmax(weights, dim=-1)
return weights, indices
在具体前向传播中,Token 被分发到各自对应的专家中计算,然后按路由权重加权汇总:
class MoELayer(nn.Module):
def __init__(self, embed_dim, hidden_dim, num_experts=8, top_k=2):
super().__init__()
self.num_experts = num_experts
self.top_k = top_k
self.router = TopKRouter(embed_dim, num_experts, top_k)
self.experts = nn.ModuleList([
Expert(embed_dim, hidden_dim) for _ in range(num_experts)
])
def forward(self, x):
batch_size, seq_len, embed_dim = x.shape
weights, indices = self.router(x)
# 展平输入以方便路由计算
flat_x = x.view(-1, embed_dim)
flat_weights = weights.view(-1, self.top_k)
flat_indices = indices.view(-1, self.top_k)
out = torch.zeros_like(flat_x)
# 遍历每个专家,批量处理分配给它的 Token
for expert_id, expert in enumerate(self.experts):
mask = (flat_indices == expert_id)
if not mask.any():
continue
token_idx, top_pos = torch.where(mask)
selected_x = flat_x[token_idx]
expert_out = expert(selected_x)
weight = flat_weights[token_idx, top_pos].unsqueeze(-1)
out.index_add_(0, token_idx, expert_out * weight)
return out.view(batch_size, seq_len, embed_dim)
上述代码展示了 MoE 的核心算法逻辑,但在工业级集群训练与推理时,MoE 带来了一系列新的工程挑战:
从大模型结构演进的轨迹来看,MoE 已经完成了从学术验证到工业落地的主流替代。对于任何希望洞察现代大模型系统架构的工程师而言,搞懂稀疏激活与路由策略,是绕不开的必修课。
免费获取企业 AI 成熟度诊断报告,发现转型机会
关注公众号

扫码关注,获取最新 AI 资讯
3 步完成企业诊断,获取专属转型建议
已有 200+ 企业完成诊断