Specialist tier · about 10 hours, optional · 7 parts
Part 4 of 7 · 3 min read
Grouped-query attention and mixture of experts
Two tricks that make big models cheaper to run: share keys and values across heads, and only use a few expert networks per token.
Grouped-query attention (GQA)
Module 2 computed that the key-value cache for 4,096 tokens takes 2 GiB in a 32-layer model with 32 heads. At 32,768 tokens that is 16 GiB per conversation, which limits how many users one GPU can serve. The observation behind GQA: the query heads need to be many, but the key and value heads can be shared by groups of query heads.
Multi-head, multi-query and grouped-query attention
Multi-head: every query head has its own key head and value head. Multi-query: all query heads share one key-value head. Grouped-query: query heads are split into groups, and each group shares one key-value head. It sits between the other two.
Cache for a 32,768-token conversation by number of key-value heads.
The code gives both effects (real output; model width 4,096 and 32 query heads):
Key-value heads
Attention parameters
Cache for 32,768 tokens
32 (multi-head)
67.1 M
16.0 GiB
8 (grouped)
41.9 M
4.0 GiB
4
37.7 M
2.0 GiB
1 (multi-query)
34.6 M
0.5 GiB
A 4x smaller cache means roughly 4x more simultaneous long conversations per GPU, which feeds directly into your price per token (module 6). In published comparisons the quality cost is small, which is why many recent models use grouped-query attention. (I did not measure quality here; the code has random weights.)
Mixture of experts (MoE)
A dense model uses all its parameters for every token. A mixture of experts replaces the MLP in a block with many parallel MLPs (the experts) and a small router that picks a few of them for each token.
defmoe_layer(x,router_w,experts,top_k=2):probs=softmax(x@router_w)# how much each expert suits each tokenchosen=np.argsort(-probs,axis=1)[:,:top_k]# keep the best top_k# mix the chosen experts' outputs by their renormalised router weights
Consequences, each tested:
Each token goes to exactly top_k distinct experts, and the mixing weights sum to 1.
With identical experts, the layer equals a single expert, which shows the mixing is correct.
Total parameters are large (all experts), but active parameters per token are small (top_k of them). With 2 of 8 experts active, a quarter of the expert parameters are used per token. You get the capacity of a big model at closer to the speed of a small one.
Load balance matters. If the router sends most tokens to a few experts, the rest are wasted and those few become a bottleneck. The demo prints each expert's share of tokens (real output with random weights and 8 experts): [0.1, 0.12, 0.18, 0.18, 0.1, 0.09, 0.09, 0.15]. A perfectly even split would be 0.125 each. Real training adds a penalty that pushes the router towards even use.
Memory is still the full parameter count: you must hold all the experts even if each token uses two.
Check yourself
Why is the cache 4 times smaller with 8 key-value heads than with 32?
With 16 experts and 2 active per token, what fraction of expert parameters does a token use?