EXPERT_BUDGET=N: miss-aware cap on distinct experts/layer (+75% decode tok/s, 6x prefill on low-RAM hosts)#254
Merged
Conversation
β¦faster decode Add EXPERT_BUDGET env var that caps the number of distinct experts loaded per layer across the batch-union. When the union exceeds the budget, keeps only the highest-aggregate-gate-weight experts and drops the rest from idxs[] so they're never loaded from disk. Complementary to TOPP (per-position) β this trims the cross-position union that multiplies under MTP/prefill. Based on MoE-Spec (arXiv 2602.16052): 'top 32 of 64 experts capture 93% of routing weight.' Measurements (GLM-5.2 744B, 24GB RAM, cap=2, MTP=0, 32 tokens): Baseline (budget=0): 0.18 tok/s, 9.3% hit, 176s decode, 39s prefill EXPERT_BUDGET=12: 0.19 tok/s, 14.0% hit, 171s decode, 12s prefill EXPERT_BUDGET=6: 0.26 tok/s, 21.0% hit, 123s decode, 7s prefill EXPERT_BUDGET=4: 0.33 tok/s, 16.4% hit, 97s decode, 9s prefill Budget=4 nearly doubles decode speed (+83%) and 4x's prefill speed by halving disk reads per layer. Default OFF (EXPERT_BUDGET=0).
β¦ misses
The original budget dropped experts blindly β even cached ones that cost
zero disk I/O. The miss-aware version pre-scans pin/ecache residency
before applying the budget:
- ALL cache hits are kept (free to compute, no disk I/O)
- Only misses compete for the remaining budget slots
- Miss budget = EXPERT_BUDGET - nhits (min 0)
Results (budget=4, same prompt/config as before):
Original Miss-aware
tok/s 0.33 0.36 (+9%)
hit rate 16.4% 38.2% (2.3x)
prefill 8.9s 5.6s (1.6x faster)
decode 97.4s 88.9s (9% faster)
The hit rate doubling is the key quality signal: the model now gets the
full contribution from all resident experts plus the top-4 new loads,
instead of losing some hits to the budget.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
EXPERT_BUDGET=Nenv var that caps the number of distinct experts loaded per layer across the batch-union. When the union exceeds the budget, keeps cache hits + the highest-aggregate-gate-weight misses, drops the rest β they're never loaded from disk. Targets the low-RAM design corner (cap=1-2, nearly every routed expert is a disk miss).Closes #220.
The problem
Every expert miss costs ~19 MB of disk I/O. On low-RAM hosts where the LRU cache cap is tiny (e.g.
cap=2on 24 GB RAM), nearly every routed expert is a miss. Withtopk=8and 75 sparse layers, a single-token decode reads ~8.5 GB of experts from disk. Under MTP the batch-union produces 20-32 distinct experts per layer β almost all misses.TOPPtrims experts within a single position's top-K. It cannot reduce the cross-position union β the deduplication across batch positions (prefill, MTP verification) that multiplies disk loads.The fix
In
moe(), after the batch-unionuniq[]is built but before the cache-resolve/load loop:Dropped experts are removed from
idxs[]entirely β never resolved, never loaded, never computed. The downstream code already tolerateskeff[s] < K(theTOPPpath produces the same state).Miss-aware design: cache hits are always kept regardless of budget. Only misses compete for the remaining budget slots. This means on a warm cache, budget has no effect β it only constrains cold-cache disk reads.
Code change
c/glm.cβ 68 lines added, single file:g_expert_budgetglobal +g_budget_droppedcounterEXPERT_BUDGET=N(default 0 = off)moe()batch-unionEXPERT_BUDGET=N (dropped X experts, ~Y GB I/O saved)A/B measurements
Setup: GLM-5.2 744B per-row int4, 24 GB RAM (cache
cap=2), Core Ultra 9 185H (AVX-VNNI), same prompt: "Explain the concept of recursion in programming. Provide a simple example.", 32 tokens, greedy (temp=0).MTP off β speed
MTP on β speed + acceptance rate
MTP interaction β the honest finding
The maintainer's concern (#220 comment) was exactly right: dropped experts on draft positions force MTP rejects. At budget=8 + MTP, acceptance drops from 38% β 21%. The draft tokens route to experts that were budgeted away, so verification rejects them.
Despite the lower acceptance, tok/s still improves (0.12 β 0.23, +92%) because the per-forward cost drops dramatically (fewer experts loaded). The net win is positive but the acceptance hit is real.
Recommendation: use a higher budget with MTP (e.g.
EXPERT_BUDGET=16-24) so the draft's experts survive. Without MTP, budget=4-6 is the sweet spot.Token agreement β the confound
Greedy-token agreement between budgeted and unbudgeted runs is 0% at every budget level on this model. But this is not meaningful: the per-row int4 model is already incoherent at baseline (output: "Hire Some To Take Object-Oriented Programming Assignment"), so all outputs are garbled differently. A proper token-agreement test requires the grouped-int4 model (#242, merged) on a warm cache where the baseline produces coherent text. That A/B is the next step once the grouped conversion completes.
Safety
EXPERT_BUDGET=0) β zero behavior change unless explicitly setTOPPTOPP)Prior art
MoE-Spec (arXiv 2602.16052) β "Expert Budgeting for Efficient Speculative Decoding": "top 32 of 64 experts capture 93% of routing weight." Our approach applies the same principle at the batch-union level, making it effective for prefill and single-token decode too.