The idea: many FFNs, but each token uses only a few

In a transformer block, the feed-forward network (FFN) after attention holds most of the weights. A mixture-of-experts (MoE) layer replaces that one FFN by several smaller FFNs called experts, plus a tiny router that decides, for every token, which experts run. Only the chosen experts do any work, so the model can store many more parameters without spending more compute per token.

Left: a dense FFN where the token passes through one big FFN and every weight is used. Right: an MoE layer where the router gives probabilities 0.13, 0.62, 0.06 and 0.19 to experts E1 to E4 for the token The; only E2 and E4 run, and their outputs are added with gate weights 0.77 and 0.23.
A dense FFN uses all its weights for every token; an MoE layer keeps several experts but runs only the top-k the router picks.

The canvas follows 8 tokens, The cat sat on 3 + 4 =, through one MoE layer with 4 experts. Mixtral 8×7B, DeepSeek-V3 and (reportedly) GPT-4 are built this way. Where the layer sits inside a whole model is on How a Large Language Model Works; the attention layer that comes before it is on Self-Attention.

The router: a linear layer and a softmax

The router is a single weight matrix W_r with one column per expert. For a token vector x it computes the scores z = x · W_r and turns them into probabilities with softmax: p_i = e^z_i / Σ e^z. For cat the scores are [2.0, 0.3, −0.2, 1.0] and the probabilities [0.60, 0.11, 0.07, 0.22]. The router is trained with the rest of the model, so it learns which experts are good for which tokens. (Demo 1: one token through the router)

Top-k and the gate weights

Only the top-k experts by probability run. The layer's output is their weighted sum y = Σ g_i · E_i(x), added back to x by the residual connection.

  • k = 2 (GShard, Mixtral): the two probabilities are renormalized to add up to 1. cat keeps E1 (0.60) and E4 (0.22), so g = 0.73 and 0.27.
  • k = 1 (Switch Transformer): one expert, and the gate weight is the probability itself, g = p. Multiplying by p is what lets the gradient reach the router.

The experts that were not chosen are never computed for this token. That is the "sparse" in sparse MoE.

Capacity and overflow

In a large model each expert lives on its own GPU, and the hardware wants fixed-size buffers. So every expert gets a fixed number of slots per batch, its expert capacity:

C = ⌈capacity_factor · k · N / E⌉

k · N / E is the fair share (here 2 · 8 / 4 = 4 assignments per expert); the capacity factor adds headroom. Assignments are dispatched in order: first every token's first choice, then every second choice. When an expert is full, the next assignment overflows: the token is dropped for that expert and skips it. A token that loses all its experts passes through on the residual connection alone, unchanged by the layer.

Top-1 routing with capacity 2: E1 receives cat, sat and equals; the third does not fit in its 2 slots and is dropped. E3 receives 3, plus and 4; 4 is dropped. E2 holds The and on. E4 is idle with 0 tokens.
Top-1, capacity factor 1.0, so C = 2: E1 and E3 overflow while E4 stays idle.
SettingCLoads E1–E4Dropped
top-2, capacity factor 1.2554 3 4 5none
top-2, capacity factor 1.044 3 4 43 → E4
top-1, capacity factor 1.022 2 2 04 → E3, = → E1

A larger capacity factor drops fewer tokens but wastes memory and compute on empty slots; Switch Transformer used 1.0–1.25 in training. (Demo 2: a batch, top-2, capacity 1.25; Demo 3: top-1, capacity 1.0: overflow)

The load-balancing loss

Left alone, the router tends to collapse: a few experts get slightly better early on, get more tokens, get trained more and win even more often. The others sit idle, and the busy ones overflow. With the collapsed router on the canvas, E1 gets every token's first choice and drops +, 4 and =. (Demo 4: collapsed router, balancing loss)

Switch Transformer adds an auxiliary loss to the training loss:

L_aux = E · Σ_i f_i · P_i

Here f_i is the share of assignments that chose expert i and P_i is its mean router probability over the batch. When both are 1/E for every expert, L_aux = 1; it grows when the counts and the probabilities pile up on the same experts (the trained router scores 0.98). The collapsed router has f_1 = 0.50, P_1 = 0.69 and L_aux = 1.60. f is a count and has no gradient, but P does: ∂L/∂z_tj = (E/N) · p_tj · (f_j − Σ_i f_i p_ti), which pushes down the scores of experts with f above average. The real loss is multiplied by a small coefficient (α = 0.01); the canvas takes big steps so the effect shows in two: L_aux goes 1.60 → 1.37 → 1.03 and no token is dropped any more. (Demo 5: training with the aux loss)

Sparse vs dense compute

Join the 4 experts into one FFN with a 4× wider hidden layer and you get a dense layer with exactly the same parameters. It runs every weight for every token: 8 × 4 = 32 expert-sized passes for the batch. The top-2 MoE runs 16, half the work. With more experts the gap grows: total parameters scale with E, compute per token only with k. (Demo 6: sparse vs dense compute)

ModelExperts per layerkTotal paramsActive per token
This page424 FFNs2 FFNs
Switch Transformerup to 2,04811.6 Tabout one FFN
Mixtral 8×7B8247 B13 B
DeepSeek-V3256 routed + 1 shared8671 B37 B

The catch is memory: every expert must be loaded, so an MoE needs the memory of its total size while running at the speed of its active size. Moving tokens between GPUs (all-to-all communication) also costs time. See also LoRA and Quantization for shrinking that memory, and Softmax & Cross-Entropy for the softmax the router uses.

What the page leaves out

The token vectors and the experts' own math (each expert is an ordinary FFN, see Neural Network Forward Pass). Real experts do not specialize in neat topics like "numbers"; their split is learned and hard to read. Also left out: noisy top-k gating, the router z-loss, expert-choice routing (experts pick tokens, so nothing overflows), DeepSeek's shared expert and bias-based balancing without an auxiliary loss, dropless kernels such as MegaBlocks, expert parallelism across GPUs, and the gradient flowing into W_r rather than straight into the scores.