AI Grimoire
Sheet
statuspromising
difficultyintermediate
timeO(k·d²)
described2022
revisedtoday

Expert-Choice Routing

Load imbalance is an artefact of letting tokens choose. Turn the assignment around — every expert takes exactly its capacity, most valuable tokens first — and balance stops being something to enforce.

Standing

PromisingPromising and actively moving. The results are real but narrow — one lab, one model family, or one benchmark suite — and the picture may look different in a year.

Perfect balance by construction and unusable for autoregressive decoding, because the choice depends on future tokens. Encoders and vision models can use it; decoders cannot.

judged as of 2026-09 · what the labels mean

Theory

Standard routing computes an affinity matrix SRT×ES \in \mathbb{R}^{T \times E} and takes the top-kk along the expert axis: each token picks its experts. Every problem with capacity follows from that, because nothing constrains how many tokens pick the same one.

Take the top-kk along the other axis instead.

token choice: topk(St,:)expert choice: topC(S:,e)\text{token choice: } \mathrm{top}_k\bigl(S_{t,:}\bigr) \qquad \text{expert choice: } \mathrm{top}_C\bigl(S_{:,e}\bigr)
eq. 1 — same matrix, transposed argmax

Expert ee takes the CC tokens that score highest for it. Every expert takes exactly CC — no more, by construction, and no fewer as long as TCT \ge C. There is no capacity factor, no auxiliary loss, no controller, and no dropping.

Variable compute per token

The interesting consequence is not the balance but its dual. Under token choice, every token gets exactly kk experts. Under expert choice, a token may be chosen by many experts, one, or none.

The flip side is that a token chosen by nobody passes through unchanged. This is the same event as a dropped token, arrived at by a different route, and it is untroubling for the same reason — a shared expert or the residual path means the layer is never wholly absent.

Why decoders cannot use it

topC(S:,e)\mathrm{top}_C(S_{:,e}) ranks all TT tokens against each other. Whether token 5 is selected depends on how tokens 6 through TT scored — so the computation at position 5 depends on the future, which is exactly what causal masking exists to prevent.

The damage is not subtle. During training the model sees a routing that used future information; during autoregressive generation that routing cannot be reproduced, because the future does not exist yet. Train/inference mismatch of this kind does not degrade gracefully.

Zhou et al. evaluated on encoder-style and fine-tuning workloads where the whole sequence is present, which is where the method is sound. For decoder pre-training it is not repairable — a causal variant would have to rank each token against only its predecessors, and then the expert’s top-CC changes at every position.

Implementation

python · torch
import torch
from torch import Tensor, nn


class ExpertChoiceRouter(nn.Module):
    """Non-causal. Encoders, vision, and fine-tuning on full sequences only."""

    def __init__(self, dim: int, n_experts: int, capacity_factor: float = 2.0):
        super().__init__()
        self.gate = nn.Linear(dim, n_experts, bias=False)
        self.f, self.n_experts = capacity_factor, n_experts

    def forward(self, x: Tensor) -> tuple[Tensor, Tensor]:    # [T, D]
        t = x.size(0)
        capacity = int(self.f * t / self.n_experts)

        scores = self.gate(x).softmax(-1)                     # [T, E]

        # top-k down the token axis: each expert takes its best `capacity`.
        weight, tokens = scores.t().topk(capacity, dim=-1)    # [E, C]
        return tokens, weight

One line differs from token-choice routing — the .t() — and it changes what the layer is. Worth noting how cheap the balance is once the assignment runs this way: the entire apparatus of capacity factors, auxiliary losses and bias controllers exists to approximate, under token choice, what a transpose gives exactly.

The soft alternative

Soft MoE takes the same insight further and drops discreteness altogether: each expert processes a weighted average of all tokens, with the weights from the same affinity matrix. Perfectly balanced, fully differentiable, no dropping — and non-causal for the same reason, since the average is over the whole sequence. Both methods are the same trade: give up autoregression, get balance for free.

Tokens dropped
none
Balance
exact by construction
Causal decoding
not possible
Zhou et al., 2022

Related

References

[1]Zhou et al. — Mixture-of-Experts with Expert Choice Routing (2022)arXiv:2202.09368
[2]Fedus et al. — Switch Transformers (2021)arXiv:2101.03961
[3]Puigcerver et al. — From Sparse to Soft Mixtures of Experts (2023)arXiv:2308.00951