Repository navigation
How Expert Balance Works
A large MoE model has hundreds of routed experts per layer. On 4× 96 GB cards (384 GB total, effective ~90 GB per card after reserve) the expert weights of big models do not fit — and KV cache needs room too. Yet most traffic only touches a fraction of experts.
- Hot bank — experts that live in GPU memory. Zero transfer cost per token.
- Cold bank — the rest, pinned in host RAM, read over PCIe on demand (UVA: the GPU can access host memory directly, no explicit copy).
With PCIe 4.0 (≈ 25 GB/s effective per card on this host class) a cold hit is slower but the hot set covers the vast majority of routed tokens — so the average stays fast.
One shared planner (patches/hotsplit_plan.py, numpy-only, unit-tested) does the work:
-
Routing histogram — counts of how often each expert is routed (from
balance.shon sample traffic — shipped with the DeepSeek/GLM recipes; the MiMo recipe ships a referenceexpert_hist_mix.jsoninstead — re-rank it for your traffic withpatches/hotsplit_rerank.py). -
Greedy hot set — sort experts by routing share per byte (popularity ÷ size) and fill
the per-rank budget
HOTSPLIT_HOT_GIB. - Validation — NaN/negative/mismatched expert counts raise; budget overflow raises.
- Oracle check — for small cases a brute-force planner confirms greedy is optimal.
The same planner is byte-identical across all four recipes (enforced by tests).
-
Static (
HOTSPLIT_DYNAMIC=0) — hot set fixed at load time from the histogram. -
Dynamic (
HOTSPLIT_DYNAMIC=1, default) — the hot set adapts at runtime: everyHOTSPLIT_DYN_STEPSengine steps the live routing counters are evaluated and the weakest hot experts are swapped for the strongest cold ones (host→GPU copies on a dedicated CUDA stream, published via events so a decode-graph replay never sees a half-applied swap).
Dynamic updates are validated at startup (bad values like HOTSPLIT_DYN_STEPS=0 refuse to
start), repeated planner failures abort the run, and each update logs a hot/cold hit-rate
line — the number that proves the mode is earning its keep.
| Knob | Meaning | Default |
|---|---|---|
HOTSPLIT_HOT_GIB |
per-rank hot budget (GiB) | empty = stock GPU-resident expert bytes (NOT the full bank) |
HOTSPLIT_DYNAMIC |
runtime adaptation | 1 |
HOTSPLIT_DYN_STEPS |
steps between swaps | 2000 |
HOTSPLIT_DYN_MAX_SWAPS |
swaps per layer per update | 2 |
HOTSPLIT_DYN_MARGIN |
swap only if in > margin × out | 1.25 |
HOTSPLIT_VRAM_RESERVE_GIB |
headroom for CUDA graphs / KV cache | 2 |
HOTSPLIT_NUMA_POLICY |
preferred / bind / off | preferred |
This hardware: cards are PCIe Gen 5, but the host slots are PCIe 4.0 and the RAM is DDR4.
All recipes measure on the observed platform (nvidia-smi, numastat), not spec sheets.
English
Русский
中文