Skip to content

WIP: PD-DFlash — native offloaded-expert stat accessors (unblock §8 B0–B2) - #164

Merged
drunkcoding merged 4 commits into
devfrom
feat/pd-dflash-native-stats
Aug 16, 2026
Merged

WIP: PD-DFlash — native offloaded-expert stat accessors (unblock §8 B0–B2)#164
drunkcoding merged 4 commits into
devfrom
feat/pd-dflash-native-stats

Conversation

@drunkcoding

Copy link
Copy Markdown
Contributor

WIP / DRAFT — do not merge

Wires the native offloaded-expert statistics accessors so the PD-DFlash Phase A §8 matrix's B0–B2 (offloaded) rows emit REAL metrics instead of 0.0 fallbacks — the last blocker to computing the hardware go/no-go. All accessors are read-only, additive, opt-in; no default/hot-path behavior changes.

Root cause of the prior blocker (measured on origin/dev)

The gpt-oss offloaded baselines were unmeasurable because _count_offloaded_experts(engine) returned 0 (gpt-oss's packed experts leave expert_prefetcher.expert_nbytes_map empty), so require_offloaded(B0|B1|B2, 0) raised. gpt-oss experts flow through the native ExpertDispatcher (FP4), whose hit/occupancy accounting was never surfaced to Python — hence expert_cache_hit_rate/expert_occupancy_bytes/wasted_prefetch_bytes all fell back to 0.0.

Counters exposed (C++ → pybind → Python)

Metric Native source (read-only) pybind Python surface
expert_cache_hit_rate ExpertDispatcher passive hit/access counters (gpt-oss); NodeBody hit/visit aggregate (others) expert_dispatcher.get_cache_hit_rate / prefetch_handle.get_hit_rate ExpertPrefetcher.get_hit_rate(), engine.expert_cache_hit_rate
expert_occupancy_bytes Σ byte_size over cached_experts_ (dispatcher) + on-CUDA node byte_size (handle) get_cache_occupancy_bytes / get_expert_occupancy_bytes ExpertPrefetcher.expert_occupancy_bytes(), engine.expert_occupancy_bytes
wasted_prefetch_bytes Σ byte_size × unused_count (topology) get_wasted_prefetch_bytes ExpertPrefetcher.wasted_prefetch_bytes(); runner native fallback
num_offloaded_experts is_tensor_offloaded over expert_tensor_map (populated for gpt-oss) (existing is_tensor_offloaded) ExpertPrefetcher.num_offloaded_experts, engine.num_offloaded_experts
measured_h2d_bytes_per_second opt-in on-device H2D probe --probe-h2d flag (flag --measured-h2d-gbps already accepted)
kv_occupancy_bytes engine KV-cache manager when present engine.kv_occupancy_bytes (see note)

The dispatcher hit/access counters are two std::atomic increments at the existing exec-arg emit sites (same instrumentation class as gpu_hit_cnt++/incache_visit_count++), reset by ClearExpertCacheCounts(); they change no routing/dispatch behavior.

Qwen 404 fix

Qwen/Qwen3-Coder-30B-A3B (harness default) returns HTTP 404 / never existed (verified via HF API). Replaced with the real, ungated Qwen/Qwen3-Coder-30B-A3B-Instruct (qwen3_moe, per-expert tensors) in the frozen §8 contract + tests + docstring. Draft z-lab/Qwen3-Coder-30B-A3B-DFlash unchanged (verified present).

RE-RUN §8 slice (SM120, gpt-oss-20b, --device-memory-ratio 0.30, --probe-h2d)

report.py --allow-blocked B2exit 0. B0/B1 now RUN (no require_offloaded RuntimeError); B2 remains the runner's pre-existing BLOCKED_UNTIL_2D_SCHEDULER.

baseline expert_cache_hit_rate expert_occupancy_bytes wasted_prefetch_bytes measured_h2d B/s tok/s
B0 0.978 19.97 GB 0.0 (real) 57.6 GB/s 18.51
B1 0.894 18.86 GB 0.0 (real) 57.6 GB/s 62.07
B3 0.890 18.45 GB 0.0 57.6 GB/s 84.56

Before: B0–B2 could not run at all; B3 alone reported hit_rate/occupancy/kv = 0.0 fallbacks. 4 of the 5 named gaps now emit real values.

Note on kv_occupancy_bytes: still 0.0 in this run — honestly, not fabricated. The MoE.generate() path uses HF's own KV cache (no MoE-Infinity KV manager), so the engine has nothing resident to report. The accessor is wired to report real KV occupancy when a KV-cache manager is present (continuous-batching/serving path).

Verification

  • New CPU tests tests/python/dflash/test_native_stat_accessors.py (14) — accessor surface with _store fakes.
  • Full dflash CPU suite: 371 passed, 7 GPU-gated skips.
  • No-regression tests/test_gpt_oss_offload_topology.py (+policy): 10 passed.
  • ruff + LSP clean on all changed files. _store rebuilt for sm_120, new symbols import cleanly.

Guardrails

Read-only accessors only; no GLM / feat/dflash-spec-decode / #119 touched; not on dev/main; DRAFT — do not merge.

drunkcoding added 4 commits August 15, 2026 19:00
Add native, behavior-inert getters so the PD-DFlash §8 runner can read real
offloaded-expert metrics instead of 0.0 fallbacks:

- ExpertDispatcher (gpt-oss/FP4 path): GetCacheOccupancyBytes() sums stored
  byte_size over the resident cached_experts_ set; GetCacheHitRate() divides
  two passive hit/access counters incremented at the existing exec-arg emit
  sites and reset by ClearExpertCacheCounts(). No routing/dispatch change.
- ArcherPrefetchHandle (topology path): GetExpertOccupancyBytes() and
  GetWastedPrefetchBytes() from a read-only GetResidentAndWastedBytes().
- pybind: get_cache_occupancy_bytes, get_cache_hit_rate,
  get_expert_occupancy_bytes, get_wasted_prefetch_bytes.
ExpertPrefetcher gains read-only helpers the §8 runner probes: get_hit_rate()
(dispatcher counter, else topology visit-count aggregate), expert_occupancy_bytes()
(dispatcher + handle), wasted_prefetch_bytes(), and a num_offloaded_experts
property that counts expert_tensor_map ids the store reports offloaded -- this
is populated for gpt-oss packed experts, so require_offloaded() no longer wrongly
refuses B0/B1/B2. OffloadEngine wires the dispatcher into the prefetcher and
exposes num_offloaded_experts / expert_cache_hit_rate / expert_occupancy_bytes /
kv_occupancy_bytes (kv from a kv-cache manager when present, else None).
…ix Qwen 404

_serving_measure now falls back to the native prefetcher wasted_prefetch_bytes
when RouteAheadStats has no per-expert byte payload (gpt-oss), and adds an opt-in
--probe-h2d device host->device bandwidth probe so the §7 hide inequality uses a
measured BW instead of the 'not supplied' warning. Also replaces the 404
Qwen/Qwen3-Coder-30B-A3B target (never existed) with the real ungated
Qwen/Qwen3-Coder-30B-A3B-Instruct repo in the frozen §8 contract.
Add CPU tests for the ExpertPrefetcher/runner accessor wiring (num_offloaded_experts,
hit-rate dispatcher/topology fallback, occupancy sum, native wasted fallback, h2d
probe) with fakes for the native _store engine, and point the contract/GPU tests at
Qwen/Qwen3-Coder-30B-A3B-Instruct.
@drunkcoding
drunkcoding marked this pull request as ready for review August 16, 2026 00:09
@drunkcoding
drunkcoding merged commit 7a77b9c into dev Aug 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant