← All tutorials

Mixture of Experts Designs

GPUs, memory and failures

On this page

1 Balancing with a bias instead of a loss 2 How the main designs differ 3 Experts across GPUs 4 Memory versus compute 5 Batch size and expert load 6 Fine-tuning an MoE model 7 Bias routing and logging in PyTorch 8 MoE routing and balancing settings 9 MoE failures, symptoms and fixes 10 References

One MoE layer, as built in Mixture of Experts (MoE), is the starting point. Real models add balancing without a loss, choices of how many experts and how big, and a way to spread the experts over many GPUs.

tokenrouter+ biasGPU 1E1E2E3E4GPU 2E5E6E7E8+output
Figure 1. 1 bias, 2 designs, 3 GPUs, 4 memory to fine-tuning, 5 failures.

1 Balancing with a bias instead of a loss

The balance loss pulls against the task loss: too small a weight leaves the load uneven, and too large a weight hurts quality (Wang et al. 2024, their Fig. 2). DeepSeek-V3 (DeepSeek-AI, 2024) instead keeps a per-expert offset that is used only for picking, so nothing pulls on the task loss. It also scores experts with a sigmoid instead of a softmax: the illustrative scores of Mixture of Experts, section 2 become 0.77, 0.73, 0.45 and 0.50 for “cat”.

Step 1: every bias 0E1thecathasE2E3E43loads 3, 0, 0, 1 against a mean of 1; MaxVio 2.0Step 2: biases after one updateE1−0.1theE2+0.1catE3+0.1hasE403loads 1, 1, 1, 1; MaxVio 0cat: 0.67 against 0.83, moves to E2has: 0.72 against 0.79, moves to E3
Figure 2. Illustrative: one bias update moves the two near-tie tokens to idle experts.

At step 1 every bias is 0. E1 takes 3 tokens and E2 and E3 none, so MaxVio, how far the busiest expert sits above the mean, is 2.0. One update with an illustrative step γ = 0.1 (DeepSeek-V3 uses 0.001) sets the biases to −0.1, +0.1, +0.1 and 0, and at step 2 every expert gets one token. Keep a small offset per expert that only changes who gets picked; after each step, lower it for busy experts and raise it for idle ones.

Sigmoid scores, a bias that only picks, and the bias update after each step.

si = 11 + e−zi
S = top-k indices of si + bi
gi = siΣj∈S sj
bi ← bi + γ sign(ℓ − ℓi)
MaxVio = maxi ℓi − ℓℓ
Line 1: zi is the router’s score for expert i, and si squashes it between 0 and 1 on its own, the sigmoid of Logistic Regression, section 2. The scores no longer add to 1, which is why line 3 divides by the chosen scores’ sum.
Line 2: S is the chosen set of k experts, and the bias bi enters only here. Line 3’s gates gi use s alone, so the output weights stay what the router learned. With k = 1 the gate is 1 whatever the bias, so the router gets no gradient from the output. DeepSeek-V3 uses k = 8; the example uses k = 1 only to show the picks.
Line 4: ℓi is how many tokens expert i got this step, and the mean ℓ is kT/N for T tokens and N experts. sign(…) is +1 for an idle expert, −1 for a busy one and 0 at the mean; γ is how far one step moves the bias, and ← means replace after each step.
Line 5: how far the busiest expert sits above the mean, as a fraction of the mean; 0 is perfect balance.
The balance pressure therefore no longer comes through gradients, and it does not pull against the task loss.
Source: DeepSeek-V3 eqs. 12 to 16, section 2.1.2; Wang et al. Algorithm 1 and eq. 4.

The toy runs this rule with 8 experts, top‑2, 512 tokens a step and a frozen router that prefers E1; a token counts once for each of its 2 experts, so an even share is 2·512/8 = 128 tokens per expert.

Figure 3. Illustrative toy: 1 MaxVio now, 2 busiest expert, if any.

Too small a step balances late, too large a step keeps swinging, and in between it settles; the bottom row shows each bias minus the average, since only the differences between biases change a pick. Each step moves a bias by only γ, so a run of tens of thousands of steps can afford a far smaller γ than this 60-step toy: Wang et al. tried 0.0001, 0.001 and 0.01 over 40k steps, saw the smallest balance late and the largest swing late, and chose 0.001 (their Fig. 4). DeepSeek-V3 runs this on 256 experts with γ = 0.001.

The bias is carried between steps and updated once per step, after the batch’s loads are counted. DeepSeek-V3 also keeps a tiny balance loss computed per sequence instead of per batch, with weight α = 0.0001, so no single sequence piles onto one expert.

2 How the main designs differ

Designs differ in how many experts run per token, how small they are, and whether some always run.

MoE layer at: every other FFN (Switch, GShard),every fourth (ST-MoE), every block (Mixtral),all but the first 3 (DeepSeek-V3)Switch 1 of NOne expert per token: least compute and traffic.GShard 2 of NA second expert, gates renormalized to add to 1.Mixtral 2 of 8 SwiGLU experts8 large experts: 13B of 47B used per token.DeepSeekMoE fine-grained plus sharedSmaller experts, same weights and compute.DeepSeek-V3 1 shared + 8 of 256Many tiny experts, balanced by a bias (section 1).chosenshared
Figure 4. Green: the experts one token uses; purple: shared, run for every token.

Switch (Fedus et al., 2021) sends each token to 1 expert, and GShard (Lepikhin et al., 2020) to 2 with renormalized gates; Figure 4 draws both with an illustrative 16 experts. Mixtral (Jiang et al., 2024) has 8 experts per layer and uses 2 per token. DeepSeekMoE (Dai et al., 2024) splits each expert into smaller ones and adds shared experts that every token uses. At the same weights and compute, 16 experts choosing 2 give 120 combinations, while 64 choosing 8 give 4,426,165,368. DeepSeek-V3 uses 1 shared and 8 of 256 routed experts, balanced by the bias of section 1. ST-MoE (Zoph et al., 2022) puts an MoE layer in every fourth block, the setting behind the fine-tuning results of section 6.

Each Mixtral expert is a SwiGLU FFN: three weight matrices instead of two. One branch passes through SiLU, a smooth curve shaped like ReLU, and multiplies a second branch element by element before the output matrix. One expert holds 176.2M weights, three matrices of 4,096 by 14,336.

DeepSeekMoE draws the shared experts in its own figure. It numbers experts 1 to 2N because it splits each of N experts in two, and its K = 3 is this page’s k.

From the DeepSeekMoE paper: an input hidden vector goes to a router over routed experts 2 to 2N and to one shared expert, expert 1, which always runs; the router keeps the top K = 3 routed experts, and their outputs and the shared expert's are added to the input to give the output hidden vector.
Figure 5. From the DeepSeekMoE paper (their Fig. 2): “…(c) demonstrates the integration of the shared expert isolation strategy…”

MMoE (Ma et al., 2018) uses the same gate idea for multitask learning rather than scale: shared experts with one gate per task. It is the hard-sharing setup of Introduction to Multitask Learning, section 3, with a learned mix per task.

3 Experts across GPUs

Big MoE models use expert parallelism: different experts sit on different GPUs, so tokens travel to their experts. In an all-to-all exchange, every GPU sends a different slice of its tokens to every other GPU. Each MoE layer needs two in the forward pass: dispatch and combine (Switch, section 5.4).

tokensexpertstokens backdispatchcombineGPU 1GPU 1E1E2GPU 1GPU 2GPU 2E3E4GPU 2GPU 3GPU 3E5E6GPU 3GPU 4GPU 4E7E8GPU 4two all-to-all exchanges per MoE layer
Figure 6. Dispatch sends tokens to their experts’ GPUs; combine sends outputs back.

A node is one machine holding several GPUs; DeepSeek-V3 has 8 per node. Its node-limited routing lets each token’s experts sit on at most M = 4 nodes, which cuts traffic between machines.

4 Memory versus compute

Mixtral weights in bfloat16in memory: about 94 GB (47B)used per token: about 26 GB (13B)
Figure 7. Every expert sits in memory; a token uses only its k experts.

Compute follows the experts a token uses; memory follows all of them. In bfloat16, a 16-bit number format (Mixture of Experts, section 5), Mixtral’s 47B weights take about 94 GB at 2 bytes each, while each token uses only 13B of them, about 26 GB. In Mixtral’s words, “The memory costs for serving Mixtral are proportional to its sparse parameter count”. Storing weights in fewer bits (Quantization, section 1) shrinks what has to sit in memory, and DeepSeek-V3 serves extra copies of its busiest experts.

5 Batch size and expert load

Each expert sees about kT/N tokens of a batch (Figure 8). Shazeer et al. (2017) call this the shrinking batch problem: with many experts, each one’s batch gets small and runs inefficiently. The fix is data parallelism: several GPUs each run a different slice of the batch through their own copy of the non-expert weights, and all send tokens to one shared copy of each expert.

Tokens per expert in a batch of 4,096Mixtral, 2 of 8: 1,024DeepSeek-V3, 8 of 256: 128Fix: 8 data-parallel copies of 4,096DeepSeek-V3 expert: 8 × 128 = 1,024each expert sees about kT/N; T counts all copies
Figure 8. Illustrative batch: each expert gets a slice; data-parallel copies add up.

6 Fine-tuning an MoE model

ST-MoE names two problems that held MoE back, “training instabilities and uncertain quality during fine-tuning”. The training one shows as loss spikes (section 9); the fine-tuning one is mostly overfitting.

ST-MoE fine-tunes its large model, ST-MoE-L, on SuperGLUE five ways. SuperGLUE is a harder successor to GLUE; both are sets of English understanding tasks such as question answering and entailment. Updating all weights, only the non-MoE weights, or only the dense FFNs scores about the same; updating only attention scores a little lower; updating only the MoE weights drops sharply.

Bar chart from the ST-MoE paper: SuperGLUE score by parameters updated. All about 86.1, Non MoE about 86.1, MoE about 82.7 with a wide error bar, Attention about 85.7, FFN about 86.4.
Figure 9. From the ST-MoE paper (their Fig. 5): “…fine-tuning only the MoE parameters results in a drastic quality reduction.”

Expert layers sit in only every fourth block, and a token sees at most two experts per layer, so updating only them changes few of the weights a token uses. MoE models also overfit small tasks (Switch, section 2.4). Expert dropout helps: fine-tuning Switch-Base on GLUE, dropout 0.1 elsewhere with 0.4 inside the experts scores 85.2, against 84.7 with 0.1 everywhere. Dropout (Regularization and Data Augmentation, section 1.1) is the chance of zeroing a unit. ST-MoE adds a smaller batch and a higher learning rate.

7 Bias routing and logging in PyTorch

Bias-balanced routing, then the bias update once per step.

import torch
def route_with_bias(z, b, k):         # z: (tokens, n), b: (n,)
    s = torch.sigmoid(z)
    _, idx = (s + b).topk(k, dim=-1)  # the bias only picks
    g = s.gather(-1, idx)
    g = g / g.sum(-1, keepdim=True)   # gates from s alone
    return g, idx
@torch.no_grad()
def update_bias(b, idx, n, gamma=1e-3):
    load = torch.bincount(idx.flatten(), minlength=n).float()
    b += gamma * torch.sign(load.mean() - load)
    return load
  1. 1The bias card, lines 1 and 2: sigmoid scores, with the bias only in the pick.
  2. 2Line 3: the gates use s, not s + b.
  3. 3Line 4, run once per step after the batch. b is a buffer (register_buffer), not a trained weight, so the update sits inside no_grad.
loss offloss ontoken countsper expertloss off: one expert takes all 512router entropy02.07ln 8 = 2.08 is even; ln k is collapseMaxVio7.00.23busiest expert over the meandropped, CF 1.2584%0%tokens past C = 80 skip the experts
Figure 10. Illustrative toy of the balance demo, step 40: collapse shows in every row.

Router entropy, dropped-token rate and MaxVio for every MoE layer.

def log_router(load, keep, z):
    max_vio = (load.max() - load.mean()) / load.mean()
    dropped = 1 - keep.float().mean()
    share = load / load.sum()
    router_entropy = -(share * share.clamp_min(1e-9).log()).sum()
    z_loss = torch.logsumexp(z, dim=-1).pow(2).mean()
    return dict(max_vio=max_vio.item(), dropped=dropped.item(),
                router_entropy=router_entropy.item(), z_loss=z_loss.item())
  1. 1max_vio is the bias card’s line 5.
  2. 2dropped is the share of token-to-expert assignments past capacity, from the keep mask of Mixture of Experts, section 6.3; a dropless layer, one with no capacity limit such as DeepSeek-V3’s, logs 0.
  3. 3router_entropy is the entropy of the load shares: ln N when even, ln k when collapsed (Figure 10).
  4. 4z_loss is the z-loss of Mixture of Experts, section 5 (code in 6.2).

8 MoE routing and balancing settings

14.8T training tokensfirst 14.3T: γ = 0.001last 500B: γ = 0all the way: sequence-wise α = 0.0001M = 4 nodes per token1 shared + 8 of 256 routed experts
Figure 11. DeepSeek-V3’s balancing settings over its 14.8T training tokens.
knobentersraise itlower itseen in
γbias card, line 4corrects faster, keeps swinging (Figure 3)balances slowly; 0 freezes the biasDeepSeek-V3: 0.001, then 0 for the last 500B tokens
sequence-wise αadded lossstronger guard per sequence, small pull on the task lossone sequence can crowd an expertDeepSeek-V3: 0.0001
expert dropoutinside the expertshelps small fine-tuning tasks (section 6)more overfittingSwitch: 0.4 in experts; 0.2 or 0.3 everywhere scored 84.4 and 83.9
Mroutingmore experts reachable, more trafficless traffic between machinesDeepSeek-V3: 4 nodes
k and Nbias card, line 2smaller experts, more combinationsfewer, larger expertsDeepSeek-V3: 8 of 256 plus 1 shared; Mixtral: 2 of 8

9 MoE failures, symptoms and fixes

The router runs for every generated token (Softmax, Temperature and Decoding, section 8.1), and Transformer Cost and Efficiency counts what the rest of the block costs.

10 References

  1. DeepSeek-AI (2024). DeepSeek-V3 Technical Report. arXiv:2412.19437.
  2. Wang, L., et al. (2024). Auxiliary-Loss-Free Load Balancing Strategy for Mixture-of-Experts. arXiv:2408.15664.
  3. Fedus, W., Zoph, B., Shazeer, N. (2021). Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity. JMLR 2022. arXiv:2101.03961.
  4. Lepikhin, D., et al. (2020). GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding. arXiv:2006.16668.
  5. Jiang, A. Q., et al. (2024). Mixtral of Experts. arXiv:2401.04088.
  6. Dai, D., et al. (2024). DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models. arXiv:2401.06066.
  7. Zoph, B., et al. (2022). ST-MoE: Designing Stable and Transferable Sparse Expert Models. arXiv:2202.08906.
  8. Ma, J., et al. (2018). Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Experts. KDD 2018. doi:10.1145/3219819.3220007.
  9. Shazeer, N., et al. (2017). Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer. arXiv:1701.06538.