feat(prefetch): async expert prefetcher v4 -- 94.3% cache hit rate, 2.8x speedup, zero RAM overhead#362
Conversation
β¦ng, adaptive cache, RMSNorm scaling, and routing EMA
β¦ds by 3x and accelerate prefetching
β¦ion to break 90% hit rate barrier
β¦0 EMA update to reach 90.9% hit rate and 3.25 tok/s
β¦loop to break 94% hit rate barrier
- Fix ENV VARS header: document PILOT=0-3, SMOOTH, CONF_LIMIT; remove stale REBAL entry - Fix per-layer EMA: apply routing momentum to all layers (not just layer 0) with correct offset - Fix in-flight slot race in expert_get: LRU eviction now skips slots with eid==-1 (being loaded) - Fix in-flight slot race in pilot_realload: same fix, prevents concurrent writes into active slot - Fix idx[] buffer overflow: clamp max_cand to 128 before E in pilot_prefetch
- Fix LRU fallback: when all evictable slots are in-flight, find oldest non-in-flight slot (pinned ok) before falling back to slot 0 - Fix pin_hot_experts: guard enqueue behind g_pilot>0, call ensure_pilot_worker_started(), and set is_queued flag to prevent duplicate in-flight loads from pilot_prefetch() - Fix token counting: increment token_count/freq_token_count by S (batch size) instead of 1 so prefill tokens are counted accurately and warmup threshold triggers at the right time
- Fix queue flush race: clear is_queued under mutex only; never move pilot_w backwards (would break r<=w ring-buffer invariant). Worker skips stale entries via new is_queued guard at start of pilot_realload - Add early-exit in pilot_realload when is_queued==0 (entry flushed between enqueue and worker pickup), preventing unnecessary loads - Fix misleading EMA struct comment: momentum_logits is used only by the PILOT prefetcher, not blended into actual MoE routing decisions - Fix Slot pinned comment: 'never evicted' was too strong; clarify that pinned slots may be displaced under extreme all-pinned cache pressure - Use st_read_f32() for scale tensor (.qs) instead of st_read_raw() to handle potential future BF16/F16 dtype changes robustly
|
First: thank you β and not as a formality. This PR gets right, on its own, several things this repo learned the hard way over the past week:
Housekeeping: I've retargeted the PR to The ask: would you run the same protocol on GLM-5.2?Here's the honest reason, explained calmly rather than as an objection. Your OLMoE numbers are credible in OLMoE's regime: with
None of that says your design won't help GLM β multi-layer lookahead and the EMA predictor are exactly the kind of thing that pays on a latency-bound queue, and If you take the GLM run, the protocol that will make it land without a second round:
And if OLMoE-only is the scope you want for this PR, that's completely fine too β say so and we'll review it as an OLMoE improvement on its own merits, with the oracle you already provided. Either way: genuinely good work, and welcome. |
|
Merged into One framing note for future readers: this lands in the OLMoE testbed ( |
β¦d onto #391 split) Re-derivation of e7/disk-class-instr @ de6dd6d (base caa49f7) onto origin/dev @ 61004dc, after PR #391 split c/glm.c into c/colibri.c plus quant.h/sample.h/kv_persist.h/telemetry.h/grammar.h. Semantic equivalence, not a copy: same events, same accounting, re-sited onto the new tree. Placement: colibri.c, unchanged from before the split. telemetry.h (#391) is the dashboard/stats module (HWINFO/TIERS/EMAP/HITS protocol lines + usage persistence) β prof_report(), expert_load_impl(), moe(), g_prof_io and g_edisk_ns all stayed in colibri.c, so DISK-CLASS's aggregation and printing follow them there. No relocation needed, no DEVIATION. Read path: #362 (prefetcher-v3, 22509fc) turned out to be testbed-only scope per its own merge message ("glm.c untouched") β confirmed zero c/glm.c changes in that merge's diff. The seven expert_load() call sites this patch touches (pipe_worker, expert_host_ensure, moe()'s OMP miss loop, pilot_realload, repin_pass_limit, pin_load x2) are structurally identical to the pre-split tree; the demand flag re-attaches at the same sites with the same semantics (1 only at moe()'s own PIPE/OMP miss path, 0 everywhere else), so DISK-CLASS still counts demand loads only. One real drift, unrelated to #362: #417 (cfcc742) fixed the exact "Metal pre-routed FASE A never bumps the real elast/eaccess_clock" defect this feature's comments described as a documented, deliberately-unfixed upstream issue β the real clock now ticks in FASE A too. The private elast_dc/eaccess_clock_dc clock is kept anyway: its job was never only to route around that freeze, it also snapshots pre-bump state so a call's own routing bump can't contaminate its own classification, and keeping DISK-CLASS's bookkeeping fully separate from stock elast state is what makes "byte-identical with PROF=0" provable by construction instead of by argument. Code comments referencing the old defect are updated to reflect the fix (historical note + #417/cfcc742 pointer) rather than describing a bug that no longer exists. Gates: make glm METAL=0 and METAL=1 both clean, zero warnings (matches stock 61004dc, also built clean with zero warnings for comparison). make test-c: 0 failures. make test-python: 77 tests, OK. Authored by Fable 5 in Claude Code, analysis in partnership with @monotophic. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
This PR implements an asynchronous expert prefetcher (
PILOTmodes 0β3) forolmoe.c, significantly accelerating streaming inference directly from SSD storage.By combining multi-layer lookahead prediction, stale request pruning, consolidated expert I/O, routing EMA (momentum logits), and persistent pre-warmed expert pinning, this achieves a 94.3% overall cache hit rate (up from 62.4% baseline) and a 2.8Γ speedup (1.26 β 3.54 tok/s), with zero additional RAM overhead (Peak RSS stays at 4.80 GB).
All code has been reviewed and hardened for thread safety, numerical stability, and memory safety before submission.
Benchmark Results (OLMoE-1B-7B merged model, cache=32 experts/layer, bits=8)
The hit rate during the decode phase alone reaches 95.2% under the final configuration.
Core Enhancements
Consolidated Expert I/O
gate_proj,up_proj, anddown_projweights into a single contiguous file (merged_weight) plus a.qsscale file per expert.Stale Request Pruning & Queue De-duplication
pilot_q) decouples prediction from loading.Routing Momentum (EMA Logits)
SMOOTHenv var, default 0.3).Persistent Hot Pinning & Pre-warmup
hot_pinned.binin the snapshot folder after the warmup phase.Multi-layer Lookahead (PILOT=2/3)
i+2(after MoE residual is available).i+3speculative pass to hide even deeper I/O latency.Cross-platform Test Suite & Tooling
Implementation Quality
is_queuedand the prefetch queue are guarded byg_pilot_mx. The worker thread is detached (pthread_detach) immediately after creation; thread creation failures exit cleanly.max_logitbeforeexpf()to prevent overflow toINFin the softmax-style scoring loop.mallocreturn value is checked inslot_ensure_allocated;hot_eidsarray bounds are clamped to 256 to prevent stack overflow.max_candis now correctly derived fromtopk * g_wideso theWIDEenv var has the intended effect.rebalance_cache()function, and its associatedREBALenv var have been removed entirely.Verification
-O2 -march=native -fopenmp).Matching tokens: 12/12vs HF oracle).c/tools/test_olmoe_real.py.