想象你住在一个小县城,县医院有 50 位各科室的医生。以前,无论谁来就诊,医院都让所有医生集合会诊——哪怕只是感冒,骨科、眼科医生也得陪着坐一上午。这就是“密集模型”:参数量巨大,而且每一次推理都要激活全部参数。后来医院改革了:大厅新增了一个分诊台,护士根据你的症状,只把最对口的 2 位专科医生的号,其余 48 位医生继续休息。医院还是那家医院,但每次接诊的成本骤降。这就是稀疏激活 MoE(Mixture of Experts,专家混合)的核心思想:模型可以很大,但每次干活的人很少。

岗位关联

掌握稀疏激活 MoE,你就能在有限算力下部署更大参数量的模型,直接降低推理成本——这是大模型架构师和推理优化工程师的核心竞争力。

目录
  1. 可视化演示
  2. MoE初体验:从密集到稀疏
  3. 门控分诊台:路由机制
  4. 稀疏激活精要:Top-K机制
  5. 负载均衡策略:别让一个专家累垮
  6. 参数效率与成本:大而省的秘密
  7. 业界稀疏实践:Mixtral 与 DeepSeek 的选择
  8. 落地调优:从实验到生产的最后一公里
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示混合专家模型的稀疏激活机制:门控网络为每个token选择Top-K专家,仅激活部分参数实现计算解耦与参数效率提升。

本节配有交互动效(进入视口后自动加载,约 3KB)。

MoE稀疏激活架构 将MLP层替换为多个并行专家网络,每个token仅激活Top-K个专家 总参数量大但推理计算量仅取决于激活的专家数 FLOPs ≈ K/N × Total 以更少计算获得更强性能

MoE初体验:从密集到稀疏

县医院的老规矩是“全员会诊”:无论患者是感冒还是骨折,50 位医生统统到场。这种做法的好处是绝不漏诊,代价是每一次接诊都在烧钱——对应到深度学习里,就是 Dense Model(密集模型)。GPT-3 有 1750 亿参数,哪怕你只输入一句“你好”,也要把这 1750 亿个参数从头到尾算一遍。推理成本高,就是因为这种“全员出诊”的机制。

后来医院改革了:把 50 位医生按专科划分,新增一个分诊台,每次只通知最相关的 2-3 位医生出诊。这就是 MoE(Mixture of Experts)的核心思想——把一个大模型拆成若干“专家网络”,外面套一个门控路由器,让每个输入只走少数几个专家。

从计算量上看,这个改革的效果可以用一个公式拆解。假设模型有 $E$ 个专家,每个 token 激活 $K$ 个专家,共享层(Attention、Embedding 等)是每个 token 必经的“挂号大厅”,那么:

所以,稀疏激活的真正价值不是“模型变小了”,而是“模型仍然很大,但每次推理只付一小部分钱”。医院还是那家医院,但感冒患者不再需要骨科医生陪着加班了。

FLOPsMoE≈FLOPs共享层+KE×FLOPs专家层\displaystyle FLOPs_{\text{MoE}} \approx FLOPs_{\text{共享层}} + \frac{K}{E} \times FLOPs_{\text{专家层}}
这个公式说明:MoE 的总计算量 = 共享层(所有人都要过) + 按激活比例缩小的专家层。如果 $E=8$、$K=2$,专家层只用算原来的四分之一。
  1. 共享层计算量Attention 和 Embedding 等结构对所有 token 都要计算,相当于医院挂号大厅,人人都得排队。
    FLOPs共享层FLOPs_{\text{共享层}}
  2. 激活比例 $K/E$$E$ 是专家总数,$K$ 是每次激活的专家数,比例越小越“稀疏”。
    KE\frac{K}{E}
  3. 专家层总计算量如果 50 位医生全部出动时的总工作量。MoE 不需要为每个 token 都付这笔钱。
    FLOPs专家层FLOPs_{\text{专家层}}
  4. 相加关系共享层加上按比例缩小的专家层,就是稀疏激活后的实际总成本。
    FLOPs共享层+KE×FLOPs专家层FLOPs_{\text{共享层}} + \frac{K}{E} \times FLOPs_{\text{专家层}}

门控分诊台:路由机制

改革后的医院,最关键的岗位就是分诊台护士。她得在患者进门的三分钟内,判断病情属于哪个科室,然后写好转诊单。这个岗位在 MoE 中叫门控路由器(Gate),它决定了每个 token 到底该找哪位“专科医生”。

门控路由器的实体是一个线性层加上 Softmax。输入 token 的向量 $x$ 先和门控权重矩阵 $W_g$ 相乘,得到 8 个“科室匹配分”,再用 Softmax 变成和为 1 的概率分布。公式如下:

分诊台护士的经验从哪来?从训练中来。模型看到大量文本,反复使用“这个 token 该请谁”的反馈,逐渐把门控权重调准。这也解释了为什么门控层不能一开始就学得很好——它和专家们是一起“上岗实习”的。

gi(x)=Softmax(Wg×x)i=exp⁡(Wg(i)×x)∑j=1Eexp⁡(Wg(j)×x)\displaystyle g_i(x) = \text{Softmax}(W_g \times x)_i = \frac{\exp(W_g^{(i)} \times x)}{\sum_{j=1}^{E} \exp(W_g^{(j)} \times x)}
$g_i(x)$ 表示第 $i$ 个专家在这个 token 上被选中的概率。这个概率不是拍脑袋定的,而是模型在训练中跟“该请哪些医生”的标签一起学出来的。
  1. 门控权重矩阵 $W_g$这是分诊台护士的“经验手册”,是路由器自己学出来的参数,决定了每个专家擅长哪种语义。
    Wg∈RE×dW_g \in \mathbb{R}^{E \times d}
  2. 原始打分token 向量与 $W_g$ 第 $i$ 行做点积,得到“这个 token 有多像专家 $i$ 的病人”。
    logiti=Wg(i)×x\text{logit}_i = W_g^{(i)} \times x
  3. 指数放大用 $\exp$ 把分数变成正数,同时让高分和低分的差距拉开。
    exp⁡(logiti)\exp(\text{logit}_i)
  4. 归一化除以所有专家指数的总和,使 8 个分数相加为 1,得到一个概率分布。
    gi(x)=exp⁡(logiti)∑j=1Eexp⁡(logitj)g_i(x) = \frac{\exp(\text{logit}_i)}{\sum_{j=1}^{E}\exp(\text{logit}_j)}

稀疏激活精要:Top-K机制

分诊台护士开转诊单时,不会把 8 个科室全勾上,而是只勾最对口的 $K$ 个。这个操作在数学上叫 Top-K 选择。$K$ 通常取 1 或 2,比如 Mixtral 8x7B 中 $K=2$。

被选中的专家才真正参与计算,没被选中的专家直接赋权重 0。最终输出是这 $K$ 个专家输出的加权和:

Top-K 的 $K$ 值本身就是个调试旋钮:$K=1$ 时计算量最小,但“只让一个医生看,误诊风险高”;$K=2$ 或更大时,多个专家可以形成互补意见,效果更好,但计算量也上升。稀疏度定义为 $K/E$,比如 8 个专家选 2 个,稀疏度就是 25%。

y=∑i=1Egi(x)×Ei(x),gi(x)={g^i(x),i∈TopK(g(x),K)0,i∉TopK(g(x),K)\displaystyle y = \sum_{i=1}^{E} g_i(x) \times E_i(x), \quad g_i(x) =\begin{cases}\hat{g}_i(x), & i \in \text{TopK}(g(x), K) \\0, & i \notin \text{TopK}(g(x), K)\end{cases}
稀疏激活的精髓就在这个“置零”操作:只用概率最高的 $K$ 个专家,其余专家的计算量被完全省掉,之后也不需要计算它们的输出。
  1. 专家输出 $E_i(x)$第 $i$ 个专家网络对输入 $x$ 做变换后的结果,相当于某专科医生给出的诊断建议。
    Ei(x)E_i(x)
  2. TopK 选择取概率最大的 $K$ 个专家的下标集合。
    TopK(g(x),K)\text{TopK}(g(x), K)
  3. 权重置零不在集合中的专家权重直接为 0,它们不需要出诊。
    gi(x)=0,i∉TopK(g(x),K)g_i(x) = 0, \quad i \notin \text{TopK}(g(x), K)
  4. 加权求和最终输出是选中专家输出的加权和,权重就是归一化后的路由概率。
    y=∑i∈TopKgi(x)×Ei(x)y = \sum_{i \in \text{TopK}} g_i(x) \times E_i(x)

负载均衡策略:别让一个专家累垮

如果分诊台护士总是把病人往口碑最好的科室送,那位医生过劳,其他医生却闲着。这对应 MoE 的负载失衡问题:少数热门专家承接了绝大多数 token,冷门专家长期得不到训练,模型容量被浪费。

解决的第一个手段是辅助损失函数。它像医院的分诊考核指标:既要看护士实际分给每个科室的病人比例,也要看她打分时给每个科室的平均概率,两者都接近均匀分布才算合格:

第二个手段是专家容量(Expert Capacity)。每个专家在一批数据里最多处理 $\lceil \text{CF} \times T / E \rceil$ 个 token,超出上限的 token 会被丢弃或绕过该专家直接走残差连接。这就好比给热门科室限号:挂满 50 号就停止接诊,逼着患者去其他科室。容量因子(Capacity Factor,默认 1.25)留出了一点缓冲,但调得太大又会让热门专家重新过载。

Laux=α×E×∑i=1Efi×Pi,fi=1T∑x∈B1{arg⁡max⁡g(x)=i},Pi=1T∑x∈Bgi(x)\displaystyle \mathcal{L}_{\text{aux}} = \alpha \times E \times \sum_{i=1}^{E} f_i \times P_i, \quad f_i = \frac{1}{T}\sum_{x \in \mathcal{B}} \mathbb{1}\{\arg\max g(x) = i\}, \quad P_i = \frac{1}{T} \sum_{x \in \mathcal{B}} g_i(x)
负载均衡损失 $\mathcal{L}_{\text{aux}}$ 越小,说明每个专家分到的 token 数量越均匀。它作为辅助惩罚项加到主损失上,引导门控网络“雨露均沾”。
  1. 实际分派比例 $f_i$一批数据里,最终被 argmax 路由到专家 $i$ 的 token 占多大比例。
    fi=1T∑x∈B1{arg⁡max⁡g(x)=i}f_i = \frac{1}{T}\sum_{x \in \mathcal{B}} \mathbb{1}\{\arg\max g(x) = i\}
  2. 平均路由概率 $P_i$门控网络给专家 $i$ 的平均 Softmax 分数,是“意愿”层面的统计。
    Pi=1T∑x∈Bgi(x)P_i = \frac{1}{T} \sum_{x \in \mathcal{B}} g_i(x)
  3. 乘积求和$f_i \times P_i$ 只有在两者都接近 $1/E$ 时才最小;如果某个专家两头都高,损失就会变大。
    ∑i=1Efi×Pi\sum_{i=1}^{E} f_i \times P_i
  4. 缩放系数 $\alpha \times E$$\alpha$ 控制惩罚力度(如 0.01),乘上 $E$ 让损失量级与专家数量无关。
    α×E\alpha \times E

参数效率与成本:大而省的秘密

这家医院虽然每次只开 2 间诊室,但大楼里仍然存放着 50 位医生的全部病历和设备。对应到 MoE:总参数量决定显存占用,激活参数量决定计算量。两者被稀疏激活解耦了:

值得注意的是,MoE 的痛点在于:虽然计算量降了,但显存并没有变小。更隐蔽的问题是内存带宽——每次推理都得把全部专家的权重从显存搬到计算单元,哪怕你只用了其中 2 个。在小 batch 场景(尤其是流式对话生成)下,权重搬运时间甚至会超过计算时间,这就是为什么 “MoE 省钱” 是有条件的:它主要省的是计算(FLOPs),而不是内存。

从性价比看,ST-MoE 等研究已经验证:用相同的 FLOPs 预算,MoE 模型的最终效果显著优于同等算力的 Dense 模型。换句话说,稀疏激活让每一分算力都花在了刀刃上。

Pactive=Pshared+K×Pexpert,Ptotal=Pshared+E×Pexpert\displaystyle P_{\text{active}} = P_{\text{shared}} + K \times P_{\text{expert}}, \qquad P_{\text{total}} = P_{\text{shared}} + E \times P_{\text{expert}}
总参数 $P_{\text{total}}$ 是所有专家参数之和,必须全部放进显存;激活参数 $P_{\text{active}}$ 只有 $K$ 个专家的参数,决定了每次推理的 FLOPs。
  1. 单个专家参数量 $P_{\text{expert}}$每个专科医生的“知识量”,即每个专家网络的权重数量。
    PexpertP_{\text{expert}}
  2. 共享参数量 $P_{\text{shared}}$Attention、Embedding 等所有 token 都要用的部分,相当于挂号大厅和走廊。
    PsharedP_{\text{shared}}
  3. 总参数量共享层加全部 $E$ 个专家,这是加载模型时占显存的量。
    Ptotal=Pshared+E×PexpertP_{\text{total}} = P_{\text{shared}} + E \times P_{\text{expert}}
  4. 激活参数量共享层加 $K$ 个专家,这是每次推理实际参与计算的量。
    Pactive=Pshared+K×PexpertP_{\text{active}} = P_{\text{shared}} + K \times P_{\text{expert}}

业界稀疏实践:Mixtral 与 DeepSeek 的选择

不同医院改革时会采取不同的排班方案。Mistral AI 的 Mixtral 8x7B 选择了最经典的方案:8 个专家,每 token 激活 Top-2。它的实际总参数量约 47B(因为 Attention 等共享层只有一个),而激活参数量约 13B——也就是说,它的推理成本和一个 13B 的 Dense 模型差不多,但效果却超过了当时许多 70B 级别的模型。

DeepSeek 则提供了更精细的方案。它把专家拆得更小(细粒度专家分割),每次激活更多小专家,让“组合方案”更灵活;同时引入共享专家(Shared Expert)——一位随叫随到的全科医生,所有 token 都会经过它处理通用知识,而路由专家则负责差异化的专业判断。这种“全科 + 专科”的搭配,让大模型的稠密通用能力和稀疏专业能力各司其职,进一步提升了参数利用效率。开源的实践说明:稀疏激活不是只有一种打开方式,关键是根据算力和数据规模找到最合适的“排班表”。

Mixtral 激活率=KE=28=25%\displaystyle \text{Mixtral 激活率} = \frac{K}{E} = \frac{2}{8} = 25\%
Mixtral 用四分之一的专家层计算量,换来了接近 70B Dense 模型的生成质量。这就是“稀疏激活性价比”最直观的行业验证。
  1. 专家总数 $E=8$Mixtral 在每个 Transformer 层放了 8 个 FFN 专家。
    E=8E = 8
  2. 激活专家数 $K=2$每个 token 只选 2 个专家,门控路由输出 Top-2。
    K=2K = 2
  3. 激活率$K$ 除以 $E$,得到专家层的实际计算比例。
    KE=28=25%\frac{K}{E} = \frac{2}{8} = 25\%

落地调优:从实验到生产的最后一公里

医院改革要真正省钱,还得定期调整分诊规则:专家数量、出诊上限、值班表,每一项都需要精细调优。MoE 从论文走到生产环境,同样面对四个核心问题。

第一个是专家数量权衡。$E$ 太大,总参数量和显存开销线性上涨,但每个专家分到的训练数据变少,容易欠拟合;$E$ 太小,稀疏激活的优势不明显。业界经验是 $E$ 取 8 到 128 之间,根据数据规模实验决定。第二个是容量因子。它的公式非常简单:

第三个是部署策略。与大 batch 的预填充阶段相比,MoE 在流式生成(小 batch)场景下容易被内存带宽卡脖子,因此生产中通常需要配合专家并行(Expert Parallelism),把不同专家放到不同 GPU 上,共同分摊带宽压力。第四个是监控体系:路由分布的熵、每个专家的利用率、token 丢弃率,都应该像医院的门诊统计一样被实时盯住——一旦某个专家长期超负荷或另一位长期闲置,就该回头调负载均衡权重和容量因子了。

稀疏激活的落地没有银弹,但它给了工程师一个宝贵的自由:把有限的算力花在最相关的参数上。掌握 Top-K、负载均衡和容量调优这三板斧,你就能在真实场景里把“医院”运营得既大又省。

Ci=⌈CF×TE⌉\displaystyle C_i = \left\lceil \text{CF} \times \frac{T}{E} \right\rceil
容量因子 $\text{CF}$ 决定了每个专家在这批数据里最多处理多少个 token。默认 1.25 是计算效率和 token 丢弃率之间的常见折中。
  1. 批次 token 数 $T$当前 batch 里的总 token 数量,相当于一天挂出去的总号源。
    TT
  2. 平均分配 $\frac{T}{E}$如果绝对均匀,每个专家应该分到多少 token。
    TE\frac{T}{E}
  3. 容量因子 $\text{CF}$预留的缓冲系数,允许热门专家多接一点病人。
    CF\text{CF}
  4. 向上取整容量必须是整数,多出来的号源按整数取整。
    Ci=⌈CF×TE⌉C_i = \left\lceil \text{CF} \times \frac{T}{E} \right\rceil

AI 应用场景

推荐系统 CTR 预估的实时推理优化

阶段:模型推理优化

解决的问题:传统推荐模型所有特征都要经过全量参数,广告点击率预估对延迟极其敏感,高峰期 QPS 常常压垮 GPU。用 MoE 把用户行为特征路由到不同专家(如“短期兴趣专家”、“长期偏好专家”、“价格敏感专家”),每次推理只激活 Top-2 专家,FLOPs 大幅下降。

具体案例:某电商推荐平台将 CTR 模型改造为 8 专家 + Top-2 路由结构。用户请求到达后,门控路由器快速判断当前会话属于“大促扫货”还是“日常闲逛”,分别路由到对应的兴趣专家。实测推理 QPS 提升约 3 倍,AUC 基本持平。

大模型 API 服务的推理降本

阶段:大模型服务部署与成本控制

解决的问题:MoE 大模型参数量大,但 API 服务按 token 计费更关心每次请求的计算量。通过 Top-K 稀疏激活,每个请求只计算少数专家,再配合 Expert Parallelism 把专家分散到多卡,可以在不牺牲生成质量的前提下大幅降低单卡负载。

具体案例:某云厂商部署 Mixtral 8x7B 作为对话 API 后端,相比同等效果的 70B Dense 模型,推理成本降低约 60%。在流式输出场景,团队通过增大 batch 提升带宽利用率,进一步摊薄了专家权重的搬运开销。

多语言代码生成模型的专家架构设计

阶段:模型架构设计

解决的问题:代码生成中 Python、Java、C++ 的语法差异巨大,单一 Dense 模型的知识容量被稀释。MoE 让不同语言各自“认领”专属专家,路由自动把 Python 的 token 分给 Python 专家、C++ 的 token 分给 C++ 专家,共享专家负责通用的代码结构知识。

具体案例:某代码助手团队在 CodeLlama 基础上增加 6 个领域专家(Python/Java/C++/Go/JS/SQL),Top-2 路由选择。HumanEval 多语言评测平均准确率提升 9 个百分点,单 token 推理计算量比同等参数量 Dense 模型减少 55%。

Python 演示

python62 行
import numpy as np  class Expert:    """单个专家网络 - 一层线性映射(简化版FFN)"""     def __init__(self, in_dim, out_dim, seed):        rng = np.random.default_rng(seed)        self.weight = rng.normal(0, 0.1, (in_dim, out_dim))        self.bias = np.zeros(out_dim)     def forward(self, x):        return x @ self.weight + self.bias  class SparseMoE:    """稀疏激活MoE - 门控路由 + Top-K专家"""     def __init__(self, in_dim, out_dim, n_experts=8, top_k=2, seed=42):        self.n_experts = n_experts        self.top_k = top_k        rng = np.random.default_rng(seed)        self.gate_weight = rng.normal(0, 0.1, (in_dim, n_experts))        self.experts = [Expert(in_dim, out_dim, seed + i)                        for i in range(n_experts)]     def route(self, x):        logits = x @ self.gate_weight        probs = np.exp(logits - logits.max(axis=-1, keepdims=True))        probs /= probs.sum(axis=-1, keepdims=True)        top_idx = np.argsort(-probs, axis=-1)[:, :self.top_k]        return probs, top_idx     def forward(self, x):        probs, top_idx = self.route(x)        out_dim = self.experts[0].bias.shape[0]        out = np.zeros((x.shape[0], out_dim))        for row in range(x.shape[0]):            for idx in top_idx[row]:                weight = probs[row, idx]                out[row] += weight * self.experts[idx].forward(x[row:row + 1])        return out  def main():    rng = np.random.default_rng(0)    x = rng.normal(0, 1, (64, 16))    moe = SparseMoE(in_dim=16, out_dim=4, n_experts=8, top_k=2)    y = moe.forward(x)    total_params = (moe.gate_weight.size +                    sum(e.weight.size + e.bias.size for e in moe.experts))    active_params = (moe.gate_weight.size +                     moe.top_k * (moe.experts[0].weight.size +                                  moe.experts[0].bias.size))    print(f"输入: {x.shape}, 输出: {y.shape}")    print(f"专家总数: {moe.n_experts}, 每token激活: {moe.top_k}")    print(f"激活比例: {moe.top_k / moe.n_experts * 100:.0f}%")    print(f"总参数量: {total_params}, 激活参与计算: {active_params}")  if __name__ == "__main__":    main()
目的:用 NumPy 从零实现一个简化版稀疏 MoE,演示门控路由、Softmax 打分、Top-K 选择和稀疏加权输出,并统计总参数与激活参数的差距。
  1. self.gate_weight = rng.normal(0, 0.1, (in_dim, n_experts))门控路由器的权重,相当于分诊台护士的经验手册,随机初始化后靠训练学习。
  2. probs = np.exp(logits - logits.max(axis=-1, keepdims=True))减去最大值做数值稳定处理,再用指数把分数变为正数。
  3. probs /= probs.sum(axis=-1, keepdims=True)Softmax 归一化,让 8 个专家的概率和为 1。
  4. top_idx = np.argsort(-probs, axis=-1)[:, :self.top_k]对概率降序排列,取前 K 个专家的下标,对应 Top-K 选择。
  5. out[row] += weight * self.experts[idx].forward(...)只对被选中的专家做前向计算,并按路由概率加权累加,其他专家完全跳过。
  6. active_params = ... + moe.top_k * (...)统计激活参数量,可以看到它只包含门控层和 K 个专家,远小于总参数量。

常见误区

误区MoE 的参数量是 Dense 模型的 8 倍,那不管怎么稀疏,推理肯定更耗时吧?

正解MoE 虽然总参数量大,但每次推理只激活 Top-K 个专家。Mixtral 8x7B 推理 FLOPs 接近 13B Dense 模型而非 47B。真正决定计算量的是激活参数量,不是总参数量。但显存占用确实跟着总参数量走,这一点没有魔法。

为何常见:人们习惯用“参数量大 = 计算量大”的直觉,忽略了稀疏路由“只让少数专家出诊”的机制。

误区推理时选 Top-2 很直观,训练时梯度回传到这几个专家就行了吧?

正解Top-K 的离散选择本身不可导,Switch Transformer 采用把路由概率乘到专家输出上的方式近似传递梯度。更重要的是,如果负载不均衡,冷门专家长期收不到梯度,所以还需要辅助损失和专家容量来保障每个专家都被训练到。

为何常见:从推理视角看 Top-K 只有“选与不选”,容易忽略训练视角下的梯度近似和负载问题。

误区MoE 计算量只有 Dense 的 1/4,那每次推理都更省钱,请求少的时候也划算。

正解MoE 的全部专家权重必须驻留显存,每次推理都要把它们从头到尾读一遍。batch 很小时,内存带宽成为瓶颈,FLOPs 的节省被权重搬运时间抵消,甚至可能更慢。实践中需要靠预填充阶段的大 batch 和专家并行来缓解。

为何常见:只看 FLOPs 下降,没考虑现代 GPU 推理中“搬权重”也是要花时间的。

误区都是让一部分神经元不工作,稀疏激活和 Dropout 差不多吧?

正解Dropout 是训练时随机正则化,推理时关闭;而 MoE 的稀疏激活是“条件计算”,由门控网络根据输入内容动态决定激活哪些专家,训练和推理都保持稀疏。前者是随机的、无条件的,后者是学习的、有条件的。

为何常见:两者都表现为“部分神经元不参与计算”,初学者容易把机制混淆。

误区把专家数从 8 加到 64,反正每次只激活 2 个,计算量不变,效果应该更好。

正解专家数增加,总参数量和显存线性增长,同时每个专家分到的训练样本变少,容易出现“专家欠拟合”。路由也更容易过拟合到少数热门专家,需要更强的负载均衡和容量控制。专家数必须根据数据规模和算力预算综合权衡。

为何常见:只看稀疏度 $K/E$ 变小,忽略了数据总量对专家学习质量的硬约束。

面试题

Q1. MoE 中“稀疏激活”的核心含义是什么?

单选题 · easy

  • A.只激活与输入相关的少数专家← 正确答案
  • B.一次性激活全部专家网络
  • C.随机忽略一半神经网络层
  • D.只更新模型中的部分权重

答案:A。稀疏激活的本质是“条件计算”——门控路由器为每个 token 动态挑选少数专家,好比分诊台只让感冒患者挂呼吸科。选项 B 是密集激活,C 是随机丢弃,D 是参数稀疏更新的概念,与稀疏激活无关。

Q2. 在 MoE 中,负责决定“token 去哪个专家”的组件是?

单选题 · easy

  • A.注意力模块
  • B.门控路由器← 正确答案
  • C.归一化层
  • D.残差连接

答案:B。门控路由器(Gate)是 MoE 的“分诊台”,它对每个 token 输出所有专家的概率分布,决定后续 Top-K 选择谁。注意力模块负责 token 间交互,归一化和残差是通用结构组件,不承担路由职责。

Q3. Mixtral 8x7B 模型中,每个 token 实际激活几个专家?

单选题 · easy

  • A.1 个
  • B.2 个← 正确答案
  • C.8 个
  • D.4 个

答案:B。Mixtral 采用 Top-2 路由,每个 token 只激活 8 个专家中的 2 个,专家层激活率 $K/E = 2/8 = 25\%$,这是稀疏激活在工业模型中最直接的应用。

Q4. 在 Top-K 路由中,被选中专家的组合权重通常来自哪里?

单选题 · mid

  • A.一个固定的常数权重
  • B.专家自身的可学习参数
  • C.门控网络输出的权重← 正确答案
  • D.所有专家的平均权重

答案:C。门控网络先通过 Softmax 产生每个专家的概率,Top-K 选择后,被选中专家按其概率加权组合输出。A 忽略了输入差异,B 是专家内部变换的参数而非路由权重,D 把所有专家混在一起,都不是路由机制的本意。

Q5. 负载均衡辅助损失的优化目标是什么?

单选题 · mid

  • A.增加模型收敛速度
  • B.让各专家负载变均匀← 正确答案
  • C.惩罚路由概率分布
  • D.随机打散输入顺序

答案:B。辅助损失统计实际分派比例 $f_i$ 与平均路由概率 $P_i$,二者都接近均匀分布时损失最小。它像医院给分诊台设 KPI,防止病人全涌向热门科室。A、D 与负载均衡无关,C 表述过于模糊。

Q6. 小 batch 场景下,MoE 推理的主要瓶颈往往是什么?

单选题 · hard

  • A.显存带宽不足← 正确答案
  • B.GPU 算力不足
  • C.路由器计算过慢
  • D.专家数量不足

答案:A。流式生成时每个 token 都要从显存读取全部专家权重。虽然 FLOPs 只有四分之一,但权重搬运量和 Dense 模型相当,GPU 带宽有限,搬运时间反而主导延迟。这解释了为什么 MoE 省计算、但未必省每次请求的延迟。

Q7. 以下哪些是改善 MoE 负载均衡的常用手段?

多选题 · mid

  • A.辅助损失惩罚不均衡← 正确答案
  • B.限制专家容量上限← 正确答案
  • C.丢弃超载的 token← 正确答案
  • D.增加专家数量到更大

答案:ABC。辅助损失在训练时约束路由分布,专家容量限制每个专家最多处理的 token 数,超载 token 会被丢弃或残差回退。增加专家数量并不能改善均衡,反而可能因热门专家更集中而加剧失衡。

Q8. MoE 相对 Dense 模型的优势体现在哪些方面?

多选题 · hard

  • A.推理计算量更小← 正确答案
  • B.同算力下性能更强← 正确答案
  • C.显存占用必然更小
  • D.训练速度必然更快

答案:AB。MoE 用稀疏激活在同样参数量下降低 FLOPs;或在同等 FLOPs 预算下用更多参数换取更强效果,ST-MoE 已验证这一点。但总参数更多,显存占用通常更大,训练也有负载均衡开销,不一定更快,因此 C、D 错误。

Q9. 容量因子(Capacity Factor)的作用是?

单选题 · mid

  • A.控制专家处理上限← 正确答案
  • B.控制路由器学习率
  • C.决定门控网络层数
  • D.决定专家网络宽度

答案:A。容量因子乘上平均分配的 $T/E$,得到每个专家最多处理的 token 数。默认 1.25 是计算效率和 token 丢弃率之间的折中,调大减少丢弃但增加计算量,调小则相反。

Q10. 关于 DeepSeek-MoE 的设计,正确的有哪些?

多选题 · extreme

  • A.采用细粒度专家分割← 正确答案
  • B.引入共享专家机制← 正确答案
  • C.共享专家处理通用知识← 正确答案
  • D.用共享专家代替路由

答案:ABC。DeepSeek 把专家拆成更细粒度,使每次激活的组合更灵活;共享专家承担所有 token 共用的通用知识,路由专家专注差异知识。共享专家是“全科医生”,是路由机制的补充而不是替代品,D 错误。