Skip to content

WIP: PD-DFlash Phase A — measure-first runner (Task 2/3) - #157

Merged
drunkcoding merged 6 commits into
devfrom
feat/pd-dflash-phaseA-runner
Aug 15, 2026
Merged

WIP: PD-DFlash Phase A — measure-first runner (Task 2/3)#157
drunkcoding merged 6 commits into
devfrom
feat/pd-dflash-phaseA-runner

Conversation

@drunkcoding

Copy link
Copy Markdown
Contributor

WIP: PD-DFlash Phase A — measure-first runner (Task 2/3)

Draft. Do not merge. Prepares the Phase-A "measure-first" benchmark harness
so a human can run the go/no-go §8 matrix on the RTX PRO 6000 box. No hardware
was run by this change; all GPU work is gated/opt-in.

Plan: docs/superpowers/plans/2026-08-14-pd-dflash-serving-scheduler.md
(Task 2 + the CPU-safe parts of Task 3). Branched off origin/dev;
reuses the Task-1 contract commit (benchmarks/dflash/report.py).

What's here

  • Byte-accurate route-ahead accounting (feat(dflash)…): RouteAheadStats
    now records exact stored FP4/FP8 expert payload bytes
    (predicted/kept/wasted_bytes, wasted_prefetch_bytes in as_dict), sourced
    from a new registration-time ExpertPrefetcher.expert_nbytes_map populated in
    model_offload from live params (before offload placeholders erase shape) and
    forwarded through the executor route-ahead seam. Strictly additive,
    None-safe, off by default
    ; MagicMock/resident paths stay None via an
    isinstance(dict) guard, so no offload-path default behavior changes.
  • Opt-in B0–B3 runner benchmarks/dflash/pd_dflash_serving.py (+ private
    _serving_measure.py): import-safe CLI (torch/moe imported only on the GPU
    path), emits one JSON row per (model,baseline,B,concurrency,repeat) matching
    report.REQUIRED_METRICS, validates RTX PRO 6000 (12,0), refuses resident
    B0/B1/B2, wraps the five NVTX ranges the BM4 parser keys on, and blocks B2 as
    BLOCKED_UNTIL_2D_SCHEDULER until the 2-D scheduler (Task 6) lands.
  • CPU-safe Task-3 reporting: BM1 summarise_row (pass iff
    t_router < t_verify) plus a pure aggregation CLI
    (python -m benchmarks.dflash.report) that groups raw rows into §8 matrices,
    permits blocked B2 via --allow-blocked, and writes
    result_matrix.json/CSV/Markdown for validate_result_matrix.
  • One-command launcher benchmarks/dflash/run_phase_a.sh: runs the full
    matrix for both required targets with the documented env
    (HF_HOME=/mnt/raid0nvme0/public/huggingface, MOE_ENABLE_SM120=1,
    device-memory-ratio<0.9 to force offload) and aggregates the result matrix.
    All inputs are documented env vars in the script header.

Tests / verification (CPU)

  • test_route_ahead_metrics.py (18, incl. 5 new byte tests) — TDD RED→GREEN.
  • test_pd_dflash_report.py (16, incl. BM1 + aggregation).
  • test_pd_dflash_serving_contract.py (11, pure runner logic).
  • test_pd_dflash_serving_gpu.py1 skipped ungated (side-effect-free
    collection), asserts the §8 contract when MOE_DFLASH_SERVING_GPU=1.
  • Full focused set: 124 passed, 1 skipped. ruff check + ruff format
    clean; lsp diagnostics clean on all changed files.

Explicitly NOT in scope

No hardware benchmarks run; no offload-path default behavior changed; no
Phase B/C scheduler or C++ work; no GLM / feat/dflash-spec-decode changes.
B2 rows and the full go/no-go coverage/waste gate are completed on-device in
Task 3 / Task 6.

Runner notes for the operator (Task 3)

  • Pass --measured-h2d-gbps from a real bandwidth probe (never a theoretical
    PCIe number) for the hide inequality.
  • _serving_measure uses MoE.generate(..., speculative_draft=…); note the
    repo's MoE.generate deprecation in favor of MoE.serve() — confirm the
    preferred serving entry on-box.
  • Metrics without a native accessor (hit-rate/occupancy) fall back to 0.0 and
    are flagged per-row in a warnings field; wire native accessors as needed.

drunkcoding added 5 commits August 14, 2026 22:22
Record exact stored FP4/FP8 expert payload bytes through the route-ahead
observer so the measure-first gate can report wasted_prefetch_bytes as bytes,
not an expert count. RouteAheadStats.observe_layer gains an optional
expert_nbytes map and RouteAheadStepSummary/as_dict expose predicted/kept/
wasted byte fields (None when unavailable -- never a fabricated average).
ExpertPrefetcher.expert_nbytes_map is populated at registration time in
model_offload from live params (before offload placeholders erase shape);
the executor seam forwards it None-safely (isinstance-dict guard keeps mocks
and resident runs at None). Strictly additive and off by default.
Opt-in RTX PRO 6000 B0-B3 route-ahead serving runner. The CLI module is
import-safe (torch/moe_infinity imported only inside the GPU path), emits one
JSON row per (model,baseline,B,concurrency,repeat) matching REQUIRED_METRICS,
validates the device is an RTX PRO 6000 (12,0), refuses resident B0/B1/B2, and
blocks B2 as BLOCKED_UNTIL_2D_SCHEDULER until the 2-D scheduler lands. Wraps
draft/router/issue/verify/H2D in the frozen NVTX ranges the BM4 parser keys on.
GPU test is gated on MOE_DFLASH_SERVING_GPU (1 skipped, side-effect free
collection); CPU contract test locks the pure matrix/schema/writer logic.
Add BM1 summarise_row (pass iff t_router < t_verify, ratio + raw terms
retained) and a CPU-safe aggregation CLI: group raw rows into §8 matrices
keyed by (model,block,concurrency), permit blocked B2 via --allow-blocked,
attach BM1, and emit result_matrix.json/CSV/Markdown for validate_result_matrix.
Refactors the per-baseline metric check out of validate_result_matrix
(behavior-preserving).
run_phase_a.sh drives the full §8 matrix for both required MoE targets on one
RTX PRO 6000 with the documented env (HF_HOME, MOE_ENABLE_SM120, device-memory-
ratio<0.9 to force offload) and aggregates into result_matrix.json. All inputs
are documented env vars in the script header.
…runner

# Conflicts:
#	benchmarks/dflash/report.py
#	tests/python/dflash/test_pd_dflash_report.py
@drunkcoding
drunkcoding marked this pull request as ready for review August 15, 2026 18:14
@drunkcoding
drunkcoding merged commit 45e8b04 into dev Aug 15, 2026
9 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