Mixture-of-Experts

Imagine a company that hires a thousand specialists. Each incoming task goes to only two or three of them. The payroll (total parameters) can grow enormous. Yet the work done per task (compute per token) stays small. This is precisely the bargain that Mixture-of-Experts (MoE) architectures strike inside large language models. A dense transformer forces every token through every parameter of every feed-forward layer. An MoE transformer instead routes each token to a small, learned subset of "expert" subnetworks. The rest of the parameters stay untouched for that token. This distinction matters enormously in practice. Scaling laws tell us that larger models trained on more data perform better. But dense scaling multiplies both parameter count and compute (FLOPs) together. Training and serving costs explode in lockstep. MoE breaks this coupling: it decouples total parameters (model capacity, memory footprint) from active parameters (compute per forward pass). Models like GShard, Switch Transformer, GLaM, Mixtral, and DeepSeek-MoE exploit this idea. So does the widely rumored architecture behind GPT-4-class systems. All reach trillion-parameter capacity while keeping inference cost close to that of a much smaller dense model. The big picture is a routing problem wrapped around ordinary transformer blocks. Each MoE layer replaces a single feed-forward network (FFN) with many parallel FFNs ("experts"). A lightweight router (or "gate") decides, per token, which experts should process it. Only the chosen experts do work; everyone else stays idle for that token. Training this sparsely-gated system requires care. Naive gradient descent tends to collapse onto a few favorite experts. This wastes capacity and starves the rest of training signal. So auxiliary balancing losses and careful capacity constraints become essential engineering. This article builds the routing mechanism from first principles. It covers the gating function, the top-k selection, and the load-balancing losses that keep training stable. It then examines the systems-level consequences: memory layout, all-to-all communication, and the accuracy/efficiency tradeoffs. These tradeoffs make MoE the workhorse for scaling to the largest deployed language models. It builds on the standard Transformer architecture. It connects directly to the Emergent Abilities & Scaling Laws literature that motivates ever-larger capacity.

Key takeaways
  • MoE replaces a dense FFN layer with many expert FFNs plus a router that picks a sparse subset (usually top-1 or top-2) per token.
  • Total parameters can be huge (capacity) while active/compute-per-token stays small — decoupling scale from FLOPs.
  • A learned softmax gate scores experts; only the top-k are activated and their outputs are combined by gate weight.
  • Load-balancing (auxiliary) losses are essential — without them routing collapses onto a handful of "popular" experts.
  • Training and inference need extra machinery: expert capacity limits, token dropping, and all-to-all communication across devices.
  • MoE is a stepping stone to broader efficiency techniques like Quantization, LoRA & Distillation, which shrink compute from a different angle.
The core insight

Mixture-of-Experts scales a model's parameter capacity almost for free by activating only a small, learned subset of expert subnetworks per token, rather than all of them.

The idea

A standard transformer block applies the same dense feed-forward network (FFN) to every token: an d→4d→dd \to 4d \to d MLP with a nonlinearity in between, using the same weights for all tokens in all sequences. An MoE layer replaces this single FFN with NN parallel FFNs, called experts (E1,…,ENE_1, \dots, E_N), each with independent weights. A router (or gating network) GG, typically a single learned linear layer followed by a softmax, computes a distribution over experts for each token's hidden representation xx:

G(x)=softmax(xWg)G(x) = \mathrm{softmax}(x W_g)

where Wg∈Rd×NW_g \in \mathbb{R}^{d \times N}. Instead of using this full distribution to form a weighted average over all NN experts (which would cost the same as a dense layer, just relabeled), the router selects only the top-kk experts by gate score, typically k=1k=1 (Switch Transformer) or k=2k=2 (GShard, Mixtral, GLaM). The token's output is the weighted sum of just those kk expert outputs, re-normalized over the selected subset:

y=∑i∈TopK(G(x),k)G(x)i∑j∈TopKG(x)j Ei(x)y = \sum_{i \in \mathrm{TopK}(G(x), k)} \frac{G(x)_i}{\sum_{j \in \mathrm{TopK}} G(x)_j} \, E_i(x)

This is conditional computation: the computational graph executed for a given token depends on the token's own content. The crucial efficiency claim is that if NN experts each have the same size as a dense FFN, total parameters scale as O(N)O(N), but active compute per token stays O(k)O(k) — independent of NN. A model can therefore have, say, 8 or 64 or 256 experts per MoE layer while each token only ever touches 1 or 2 of them. The key terminology to fix: sparse activation (only a subset of parameters fire per input), expert capacity (the maximum number of tokens a single expert can process per batch, a hard systems constraint), load balancing (encouraging roughly-even utilization of experts so none is starved or overloaded), and token dropping (what happens when an expert's capacity is exceeded — excess tokens either skip that expert via a residual pass-through, or are computed with reduced batching efficiency). MoE layers are typically interleaved with ordinary dense transformer blocks — replacing, say, every other FFN — rather than replacing every layer, both to control the routing overhead and to preserve stable gradient flow through the attention sublayers.

How it works

An MoE transformer layer processes a batch of tokens through three logical stages: routing (decide which experts each token goes to), dispatch and compute (send tokens to their chosen experts and run the expert FFNs), and combine (weight and sum the expert outputs back into the token's residual stream). In a multi-device setting, experts are typically sharded across accelerators — expert ii lives entirely on device ii — so dispatch and combine require an all-to-all communication step that physically moves tokens (or their hidden states) to the device holding their assigned expert and back.

Step-by-step mechanism for one MoE layer: 1. For each token xx in the batch, compute router logits xWg∈RNx W_g \in \mathbb{R}^N and a softmax over the NN experts. 2. Select the top-kk expert indices by softmax score for that token. 3. Re-normalize the top-kk scores so they sum to 1 (these become the combine weights). 4. Enforce expert capacity: each expert may only accept up to CC tokens in this batch (a fixed buffer size, computed as a capacity factor times the average tokens-per-expert). If more tokens are routed to an expert than CC allows, the lowest-scoring overflow tokens are dropped for that expert (they either bypass the layer via the residual connection or fall back to being unprocessed by that expert). 5. Dispatch: physically gather each expert's assigned tokens into a per-expert batch (in a distributed setting, this is the "dispatch" all-to-all). 6. Compute: run each expert's FFN on its batch of tokens, in parallel across experts/devices. 7. Combine: scatter the expert outputs back to their original token positions, multiply by the combine weight from step 3, and sum contributions from a token's kk chosen experts. 8. Add an auxiliary load-balancing loss to the training objective (computed from the router's soft probabilities and the actual hard dispatch fractions), so gradient signal discourages routing collapse. ``` function MoE_Layer(X, experts[1..N], W_g, k, capacity C):

# X: batch of T token vectors, each in R^d logits = X @ W_g # T x N probs = softmax(logits, axis=-1) # T x N, router probabilities topk_idx = [] # for each token, list of k expert ids topk_weight = [] # matching gate weights (renormalized) for t in 1..T: idx = indices of the k largest entries of probs[t] w = probs[t][idx] w = w / sum(w) # renormalize over the top-k subset topk_idx[t] = idx topk_weight[t] = w

# --- capacity-constrained dispatch --- expert_buffer = [ [] for e in 1..N ] # tokens routed to each expert dropped = set() for t in 1..T: for (e, w) in zip(topk_idx[t], topk_weight[t]): if size(expert_buffer[e]) < C: expert_buffer[e].append( (t, w) ) else: dropped.add( (t, e) ) # overflow: this (token, expert) pair is skipped

# --- expert compute (parallel across e) --- Y = zeros_like(X) for e in 1..N: if expert_buffer[e] is empty: continue tokens_e = gather(X, [t for (t, w) in expert_buffer[e]]) out_e = experts[e].forward(tokens_e) # standard FFN: d -> 4d -> d for (t, w), o in zip(expert_buffer[e], out_e): Y[t] += w * o # weighted combine

# tokens with all top-k experts dropped keep their residual (identity) path for t in 1..T: if all((t, e) in dropped for e in topk_idx[t]): Y[t] = X[t] # graceful fallback return Y, probs, expert_buffer # probs used for balancing loss ```

The load-balancing auxiliary loss. Left unconstrained, the router tends to converge to a self-reinforcing loop: an expert that is (by chance, early in training) slightly better on some tokens receives more gradient updates on those tokens, becomes even better on them, and is routed to even more — a rich-get-richer collapse. To counter this, Switch Transformer and GShard add an auxiliary loss that penalizes uneven distribution of the fraction of tokens dispatched to each expert (fef_e) multiplied by the average router probability mass assigned to it (PeP_e):

Laux=N⋅∑e=1Nfe⋅Pe,fe=1T∑t=1T1[ e∈TopK(t) ],Pe=1T∑t=1Tprobs[t,e]L_{\text{aux}} = N \cdot \sum_{e=1}^{N} f_e \cdot P_e, \qquad f_e = \frac{1}{T}\sum_{t=1}^T \mathbb{1}[\,e \in \mathrm{TopK}(t)\,], \qquad P_e = \frac{1}{T}\sum_{t=1}^T \mathrm{probs}[t, e]

This loss is minimized when all experts receive an equal share (fe=Pe=1/Nf_e = P_e = 1/N for all ee, giving Laux=N⋅N⋅(1/N)2=1L_{\text{aux}} = N \cdot N \cdot (1/N)^2 = 1, its theoretical minimum given the ∑fe=∑Pe=1\sum f_e = \sum P_e = 1 constraints), and is added to the main cross-entropy loss with a small coefficient (commonly α≈0.01\alpha \approx 0.01). Using fef_e (a hard, non-differentiable count) multiplied against PeP_e (a soft, differentiable probability) is the trick that lets gradients flow: fef_e acts as a fixed importance weight in the backward pass while PeP_e carries the gradient.

Figure
One MoE transformer block: routing, capacity-limited dispatch, expert compute, and weighted combine
Input tokens (after attention) x1 x2 x3 x4 Router G softmax(x·Wg), top-k dispatch (capacity C=2/expert) Expert 1 buf: x1, x3 FFN d→4d→d Expert 2 buf: x2, x4 FFN d→4d→d Expert 3 buf: (over capacity) x5 dropped → residual Weighted combine y = Σ gate_weight · Expert(x) output tokens y

Complexity & correctness

Compute (FLOPs) per token. A dense FFN of hidden width dd and expansion factor 44 costs O(8d2)O(8d^2) multiply-adds per token (two matrix multiplies of size d×4dd \times 4d and 4d×d4d \times d). An MoE layer with NN experts of the same shape and top-kk routing costs the router's negligible O(dN)O(dN) (a single small linear layer) plus kk expert FFN evaluations, i.e. O(k⋅8d2)O(k \cdot 8d^2). Since k≪Nk \ll N (commonly k∈{1,2}k \in \{1,2\} while NN ranges from 8 to hundreds), compute per token is independent of NN and matches a dense model with roughly kk times the FFN width, not NN times. This is the central efficiency claim, and it is exact at the level of FLOP counting — it's a direct consequence of top-kk sparse selection, not an approximation.

Parameters. Total parameter count of the MoE layer is O(N⋅8d2)O(N \cdot 8d^2) — every expert's weights are stored and must be addressable (e.g., in accelerator memory or across a cluster), even though only kk of them are touched per token. This is why MoE models are described by two separate numbers: total parameters (e.g., Mixtral 8x7B has ~47B total parameters) and active parameters per token (Mixtral activates ~13B per token, roughly 22 of 88 experts' worth plus shared attention layers). The capacity/compute decoupling is real, but it shifts the bottleneck to memory bandwidth and interconnect: all expert weights must reside somewhere accessible, and tokens must physically travel (via all-to-all communication in distributed training/inference) to whichever device holds their assigned expert.

Communication cost in distributed settings. If experts are sharded one-per-device across NN devices, each all-to-all dispatch/combine step moves O(T⋅d)O(T \cdot d) data (each of TT tokens sends a dd-dimensional vector to its expert's device), and the shape of this exchange is irregular — it depends on the token-to-expert routing decided at runtime, which is why fixed expert capacity CC is enforced: it upper-bounds the communication and compute per expert to a static, schedulable size, at the cost of dropping overflow tokens. Typically CC is set as a capacity factor γ\gamma times the ideal even split, C=γ⋅kTNC = \gamma \cdot \frac{k T}{N}, with γ\gamma slightly above 11 (e.g., 1.251.25) to absorb natural imbalance while bounding worst-case cost.

Correctness / why the routing signal is trainable at all. The top-kk selection is a discontinuous, non-differentiable operation — a naive view suggests gradients can't flow to the router. The resolution is that the router does receive gradient signal, but only through the combine weights of the tokens it actually routes: ∂y/∂(gate score of a selected expert)\partial y / \partial (\text{gate score of a selected expert}) is well-defined via the softmax renormalization in step 3 of the algorithm, so the router learns to increase the weight (and thus future likelihood of selecting) experts that reduce loss, and decrease it for experts that don't, exactly analogous to how attention weights are learned. What the router does not get is gradient information about experts it didn't pick — this is the fundamental credit-assignment gap in sparse routing, and is why load-balancing losses (which use all NN router probabilities, not just the selected ones) are needed as an auxiliary signal encouraging exploration of underused experts. Without this term, experts that start out slightly ahead are the only ones ever selected, gradient never flows to the rest, and their weights never leave initialization — a degenerate local optimum that empirically occurs within the first few hundred training steps if LauxL_\text{aux} is omitted.

Honest tradeoffs. MoE is not a free lunch:

  • Memory: total parameters must be stored (VRAM or across a cluster), so MoE trades compute-efficiency for memory-footprint, unlike dense models where the two scale together.
  • Training instability: the discrete routing decision plus capacity dropping introduces noisy, discontinuous gradients; MoE training typically needs auxiliary losses, careful learning-rate schedules, and sometimes explicit "z-loss" terms to stabilize router logits from growing unboundedly large.
  • Batch-size sensitivity: at small batch sizes, expert buffers are underfilled, hardware utilization drops, and the capacity-based token-dropping becomes a larger fraction of tokens — MoE benefits are much stronger at large batch/throughput regimes (training, or high-QPS serving) than at single-token, low-latency inference.
  • Fine-tuning generalization: sparse experts can overfit narrow specializations seen in pretraining and can be harder to fine-tune on small, distribution-shifted downstream datasets than dense models of equal active-parameter size.

Worked example

Consider one MoE layer with N=4N = 4 experts, top-k=2k = 2, and T=5T = 5 tokens in the batch, with capacity C=2C = 2 per expert (so total slots =8≥k⋅T=10= 8 \ge k \cdot T = 10 is not satisfied — this intentionally forces an overflow to illustrate dropping). Suppose the router produces the following softmax scores (rows = tokens, columns = experts):

tokenE1E2E3E4top-2 picksrenormalized weights
x10.100.550.250.10E2, E3E2: 0.688, E3: 0.312
x20.050.600.050.30E2, E4E2: 0.667, E4: 0.333
x30.400.100.050.45E4, E1E4: 0.529, E1: 0.471
x40.150.500.200.15E2, E3E2: 0.714, E3: 0.286
x50.200.050.600.15E3, E1E3: 0.750, E1: 0.250

Tallying raw dispatch requests per expert: E1 gets {x3, x5} (2 requests), E2 gets {x1, x2, x4} (3 requests), E3 gets {x1, x4, x5} (3 requests), E4 gets {x2, x3} (2 requests). With capacity C=2C=2, E1 and E4 fit their requests exactly. E2 and E3 each receive 3 requests but can only serve 2 — the lowest-scoring request at each overloaded expert is dropped:

  • E2's requests are (x1: 0.688, x2: 0.667, x4: 0.714); the lowest score is x2 (0.667), so x2's E2 assignment is dropped.
  • E3's requests are (x1: 0.312, x4: 0.286, x5: 0.750); the lowest score is x4 (0.286), so x4's E3 assignment is dropped.

Final dispatch:

experttokens processed
E1x3, x5
E2x1, x4
E3x1, x5
E4x2, x3

Now check each token's final combine: x1 gets both its picks (E2 + E3) → fully served, normal weighted combine. x4 gets only E2 (its E3 pick was dropped) — practical implementations either renormalize over the surviving expert alone (weight 1.01.0 on E2's output) or simply scale by the original weight and accept a partial combine; Switch/GShard-style systems use the former, so x4's output is just E2(x4)E2(x4), with no contribution from E3. x2 lost its E2 assignment entirely but kept E4, so x2's output is just E4(x2)E4(x2). No token loses both of its assignments in this example, so nobody falls back to the pure residual (identity) path — but the mechanism from the pseudocode's fallback step exists precisely for the case where that happens. This trace shows three real phenomena at once: uneven expert popularity (E2 and E3 are hot, E1 and E4 are comparatively cold — exactly what LauxL_\text{aux} penalizes over many batches), capacity-triggered token dropping (a systems-level approximation, not a bug), and the resulting effective kk for some tokens silently dropping from 2 to 1 mid-training — a subtlety often missed when reasoning about MoE purely in terms of the idealized top-kk formula.

Common pitfalls & traps

PitfallWhy it happensConsequence / fix
Omitting the load-balancing auxiliary lossAssuming top-k routing alone is enough to spread loadRouting collapses onto a few experts within hundreds of steps; add LauxL_\text{aux} with coefficient ~0.01
Setting capacity factor too tight (γ≈1\gamma \approx 1)Trying to minimize wasted compute/memoryExcess token dropping early in training when routing is still noisy, hurting quality; use γ≈1.25\gamma \approx 1.25–22 during training, tighter at inference
Confusing total parameters with active parametersMarketing numbers report total (e.g. "47B model")Misjudging inference cost/latency, which tracks active params and memory bandwidth, not total params
Ignoring communication cost in distributed trainingTreating expert compute as if it were localAll-to-all dispatch/combine can dominate wall-clock time if experts are spread across many nodes with slow interconnect
Assuming MoE always improves downstream fine-tuningExtrapolating from pretraining loss gainsSparse experts can overfit/underfit narrowly on small fine-tuning sets; dense models of matched active-param count sometimes generalize better with limited data
Treating router softmax scores as calibrated confidenceSoftmax output looks like a probabilityRouter logits can grow unboundedly without a stabilizing "z-loss," making scores overconfident and unstable, not meaningful uncertainty

Pioneers & history

The Mixture-of-Experts idea predates the transformer era by decades, originating in classical neural network ensembling research before being re-engineered for sparse, trillion-parameter-scale conditional computation.

Origins · 1 minGeoffrey E. Hinton and how this was discovered
GE
Geoffrey E. Hinton
1947–present · Co-authored the original 1991 Adaptive Mixtures of Local Experts paper introducing gated combination of specialized subnetworks, decades before this idea was revived for sparse LLM scaling

History
1991
— Jacobs, Jordan, Nowlan, and Hinton introduce Adaptive Mixtures of Local Experts, the original gated multi-network architecture.
2017
— Shazeer et al. introduce the sparsely-gated Mixture-of-Experts layer for LSTMs, scaling to 137B parameters with top-k routing and a load-balancing loss.
2020
— GShard (Lepikhin et al.) demonstrates MoE transformers at massive scale with automatic sharding across TPU pods.
2021
— Switch Transformer (Fedus et al.) simplifies routing to top-1 and shows trillion-parameter models trainable with improved stability tricks.
2023–2024
— Mixtral 8x7B and DeepSeek-MoE popularize open-weight sparse MoE transformers, and reporting suggests GPT-4-class systems use MoE architectures internally.

Where this matters

MoE architectures underlie some of the largest deployed language models today. Mixtral 8x7B and Mixtral 8x22B (Mistral AI) use 8 experts per MoE layer with top-2 routing, achieving performance competitive with much larger dense models while activating only a fraction of total parameters per token. DeepSeek-MoE and DeepSeek-V2/V3 push this further with fine-grained experts (many small experts rather than few large ones) and shared always-active experts alongside routed ones, improving load balance and specialization simultaneously. Google's GShard and GLaM demonstrated multi-hundred-billion to trillion-parameter MoE translation and language models years before MoE became mainstream in open-source LLMs. Industry reporting has widely suggested that GPT-4 and similar frontier proprietary systems use MoE-style architectures to manage the tension between capacity and inference cost at scale. Beyond raw language modeling, MoE routing ideas appear in multi-modal models (routing different modalities to specialized experts), in multilingual translation systems (language-specific expert specialization emerges naturally from routing), and in efficient serving infrastructure, where expert-parallelism becomes a first-class dimension of model parallelism alongside tensor and pipeline parallelism. Understanding MoE is a natural bridge to the broader efficiency toolkit — techniques like Quantization, LoRA & Distillation attack the same cost-versus-capability tradeoff from the angle of compressing a fixed model rather than sparsely activating a large one, and both approaches are frequently combined in production systems. MoE routing decisions can themselves be seen as an extreme, hard form of the soft weighting performed by Attention Mechanism over tokens, applied instead over subnetworks, and both rely on the representational groundwork laid by the standard Transformer architecture.

Ask the tutor: How would you design the expert capacity factor and load-balancing coefficient differently for training versus low-latency production inference?

What is the difference between MoE's "total parameters" and "active parameters"?

Total parameters count every weight stored in the model, including all experts across all MoE layers, even the ones a given token never touches. Active parameters count only the weights actually used to process a specific token — the shared attention and embedding layers plus the top-k experts selected in each MoE layer. A model like Mixtral 8x7B has roughly 47B total parameters but only about 13B active per token, since each token uses 2 of 8 experts per MoE layer. Active parameters roughly determine inference FLOPs and latency, while total parameters determine memory footprint. Marketing figures often cite total parameters, which can be misleading if you're trying to estimate serving cost, so both numbers matter for different purposes.

Does MoE always make a model faster to train and serve?

Not unconditionally. Compute per token is lower than an equally-capacious dense model, but MoE introduces new costs: routing overhead, capacity-related token dropping, and — critically — all-to-all communication when experts are sharded across devices. At small batch sizes or with slow interconnects, communication and underfilled expert buffers can erase the FLOP savings. MoE's efficiency advantage is strongest at large-batch training and high-throughput serving, where expert buffers fill efficiently and communication overhead amortizes over many tokens. For single-request, low-latency inference, the benefits are smaller and sometimes outweighed by memory-bandwidth costs of loading many experts' weights.

How many experts should a top-k router select — why not just k=1?

Switch Transformer showed that top-1 ("switch") routing works and is the cheapest option, simplifying dispatch and reducing communication. However, top-2 (used in GShard, Mixtral, GLaM) tends to give better quality for the same total parameter budget because a token gets to combine two specialized viewpoints, and it provides some robustness — if one expert is a poor match, the second can compensate. The tradeoff is roughly linear: top-k costs about k times the FLOPs of top-1 for the same expert count. In practice, k=1 or k=2 dominates deployed systems, since higher k erodes the sparsity benefit that makes MoE attractive in the first place.

What is expert capacity and why is it a fixed number rather than dynamic?

Expert capacity CC is the maximum number of tokens a single expert can process in one batch/step, typically set as a capacity factor (e.g., 1.25) times the ideal even split kT/NkT/N. It exists because distributed training needs statically-shaped tensors and communication patterns to schedule efficiently on accelerators — a dynamically-sized buffer per expert would prevent ahead-of-time compilation and predictable all-to-all communication volume. The cost of this fixed cap is token dropping: if routing happens to send more tokens to one expert than CC allows, the lowest-scoring excess tokens are skipped for that expert, typically falling back to a residual (identity) connection.

Is Mixture-of-Experts related to ensembling multiple independent models?

They look superficially similar — multiple subnetworks contributing to a prediction — but the mechanism differs fundamentally. An ensemble runs every member model on every input and averages their independent full predictions; cost scales linearly with ensemble size. MoE instead partitions the input space across experts via routing, so each token engages only a sparse subset, and experts specialize on different token types rather than each modeling the full distribution independently. MoE's goal is scaling capacity at fixed compute; ensembling's goal is typically variance reduction and calibration at proportionally increased compute.

Why do MoE experts tend to specialize, and on what?

Specialization emerges from the interaction between gradient descent and the router's selection: once an expert becomes even slightly better on some subset of tokens, the router's gradient pushes toward routing more similar tokens to it, reinforcing the pattern (this is the same dynamic that load-balancing losses must counteract to prevent collapse). Empirically, in multilingual and code-mixed models, experts often specialize by language, by syntactic pattern, or by topic/domain, though the specialization is rarely as clean or human-interpretable as one might hope — many experts appear to split along less intuitive statistical regularities in token co-occurrence rather than clean semantic categories.

How does MoE interact with fine-tuning and downstream adaptation techniques like LoRA?

Sparse MoE models can be trickier to fine-tune than dense models of equivalent active-parameter size, because routing decisions learned during large-scale pretraining may not transfer cleanly to a narrow downstream distribution, and small fine-tuning datasets can fail to exercise (and thus properly update) most experts. In practice, LoRA-style adapters are often applied per-expert or only to the router and shared layers, to avoid destabilizing the learned routing while still adapting the model efficiently. This connects MoE directly to the broader efficiency landscape covered by Quantization, LoRA & Distillation, where parameter-efficient fine-tuning and sparse activation are complementary, not competing, strategies.

Before this

Where this leads