Expand description
The global expert slot cache: which experts are resident on the GPU right now, and what one decode step has to move.
§One id space, one pool
Experts are addressed by a flat id, layer * num_experts + expert, and all layers compete for one pool of cache_size slots.
That is the “global” in global LRU, and it is the point: expert
activation is not uniform across layers, so a per-layer cache of
cache_size / num_layers slots wastes residency on layers whose
routing is flat and starves the layers where a few experts take most
of the traffic.
§What a step produces
ExpertCache::ensure takes the experts a layer routed to and
returns, for each, the slot it will be read from – plus a
CopyPlan: the (slot, host row) pairs the caller must copy before
the multiply. Nothing here moves bytes; the plan is the whole
output.
§Two rules that must not drift
- Victims are chosen by
(usage, slot)ascending, and a slot touched by this very step is not a victim. Without the second rule a step that misses more experts than it hits can evict an expert it is about to read. - Duplicate routes collapse. A batch routing twice to the same expert counts one miss, issues one copy, and shares one slot.
The hybrid entry point adds the crate::qstar split on top: only
the first fetch misses get slots, and the rest come back as
None, meaning “compute this one on the CPU”. Every route is
assigned exactly once, to exactly one device.
§Reading the cache back
ExpertCache::stats answers “is the cache big enough?” for the
model as a whole. ExpertCache::layer_stats answers it per MoE
layer, which is the only form that can tell one layer thrashing
from every layer uniformly a little over budget: both show the
same global miss rate and they have opposite fixes – rebalance
versus grow. ExpertCache::routing_skew goes one level below the
cache and reports what the routing distribution itself allows; a
layer whose oracle_hit_at_slots is already low cannot be helped by
any cache size, because no policy could do better on that traffic.
§The prefill double buffers
A prefill chunk walks the layers in order, so it can stage layer
L + 1‘s experts while layer L computes. The two staging buffers
borrow slots [0, 2 * num_experts) of this very cache and
rotate by layer % 2. Borrowed is not owned: the bytes in those
slots are rewritten every other layer within a chunk, so a slot at
or below 2 * num_experts can never be read as residency, and the
buffers’ contents are never registered in the residency map.
ExpertCache::prefetch_prefill_layer is the whole portable half
of that – which expert rows are already on the device, which have
to cross the link, and what the borrowed slots do to the LRU. No
streams, no events and no copies live here.
Ported 1:1 from FreeToken’s moe/offload_cache.py and
moe/offload_kernels.py, whose LRU is the lru_ensure kernel from
flashlib (both Apache-2.0); see docs/THIRD_PARTY_NOTICES.md.
Structs§
- Bank
Entry - One host-to-device transfer entry:
rowsconsecutive expert rows of one bank. - Copy
Plan - The copies a step needs before it can multiply.
- Ensure
Plan - What one
ensuredecided. - Expert
Cache - The GPU expert cache’s residency map.
- Expert
Cache Stats - Running counters, for
/metricsand for deciding whether the cache is sized right. - Expert
Id - A cached expert’s address in the flat id space.
- Gather
Plan - Device-to-device rows: what the prefill buffer can take from the cache instead of from the host.
- Layer
Routing Skew - One MoE layer’s routing concentration over the observed decode histogram.
- MissRun
- A contiguous run of expert ids,
[start, start + len). - Prefill
Plan - What staging one layer into a prefill double buffer costs.
- Rebuild
Rejected - A slot resize the cache refused, having changed nothing.
- Routing
Skew Report - The routing-skew report: per layer, plus the means over the layers that were actually routed to.
Enums§
- Fetch
Order - Which miss gets the scarce fetch slots when the split caps them.
Constants§
- SMALL_
BANK_ FEAT_ BYTES - Per-expert row size below which a host bank ships its whole layer as one transfer entry.