Skip to content

Add lossless PCIe serving calibration probe - #81

Merged
lukealonso merged 4 commits into
masterfrom
feat/pcie-calibration-probe-20260726
Jul 29, 2026
Merged

Add lossless PCIe serving calibration probe#81
lukealonso merged 4 commits into
masterfrom
feat/pcie-calibration-probe-20260726

Conversation

@voipmonitor

@voipmonitor voipmonitor commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Add a standalone multi-process probe that measures the communication decisions used by the GLM DCP prefill stack on the exact selected GPU order:

  • lossless BF16 SparkInfer DMA versus NCCL crossover
  • CKV gather/prefetch overlap benefit
  • full-query versus query-split crossover
  • exact owner-merge result validation
  • cacheable machine-readable output for launcher integration

Design constraints

  • all correctness comparisons are exact/lossless
  • compressed FP8, INT8, and MXFP8 wire modes are outside automatic selection
  • GPU order, TP/DCP geometry, CPU/NUMA affinity, relevant NCCL/SparkInfer environment, and probe revision participate in the cache fingerprint
  • probe failure is reportable and does not require model loading

Validation

  • 13 passed in tests/comm/test_pcie_overlap_probe.py
  • Ruff passes for implementation and tests
  • git diff --check master...HEAD
  • E2E probe runs exercised TP8/DCP1 and TP8/DCP4 on adjacent and cross-root GPU orders; the cross-root run correctly disabled CKV prefetch

Measured values are deployment data, not hard-coded policy in this PR.

Summary by CodeRabbit

  • New Features
    • Added a PCIe calibration probe that measures communication/overlap, selects optimal TP communication backend, and determines whether to enable query splitting and CKV prefetch overlap.
    • Produces machine-readable policy output with timing summaries, correctness validation results, and a safe recommended prefetch depth.
    • Includes CLI support for distributed calibration runs with configurable workload and measurement parameters.
  • Documentation
    • Added a detailed calibration guide describing criteria, output format, and reproducible run examples.
  • Tests
    • Added automated coverage for geometry/config validation, decision logic, crossover detection, and correctness/error paths.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 236334e1-2e1e-4d78-83f0-e957f2c7c191

📥 Commits

Reviewing files that changed from the base of the PR and between 4288322 and f049ccd.

📒 Files selected for processing (5)
  • docs/evidence/pcie_calibration/20260726-adjacent-tp8-dcp4.json
  • docs/evidence/pcie_calibration/20260726-interleaved-tp8-dcp4.json
  • docs/pcie_calibration_probe.md
  • sparkinfer/comm/pcie/overlap_probe.py
  • tests/comm/test_pcie_overlap_probe.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/pcie_calibration_probe.md
  • sparkinfer/comm/pcie/overlap_probe.py

📝 Walkthrough

Walkthrough

Adds a distributed PCIe calibration probe for TP backend selection, CKV overlap, query splitting, and prefetch recommendations. It includes policy generation, correctness checks, CLI execution, documentation, calibration evidence, and unit tests.

Changes

PCIe calibration probe

Layer / File(s) Summary
Probe configuration and policy decisions
sparkinfer/comm/pcie/overlap_probe.py
Defines calibration geometry, structured timing results, backend/overlap/query-split decisions, crossover detection, and prefetch recommendations.
Distributed probe setup and workload execution
sparkinfer/comm/pcie/overlap_probe.py
Initializes process groups, CUDA resources, DMA, CKV buffers, and query-split indexer state, then executes collective and candidate merge operations.
Measurement, validation, and result aggregation
sparkinfer/comm/pcie/overlap_probe.py
Runs calibration measurements, validates collective equivalence, aggregates distributed timings, and generates the policy result.
CLI, documentation, evidence, and unit validation
sparkinfer/comm/pcie/overlap_probe.py, tests/comm/test_pcie_overlap_probe.py, docs/pcie_calibration_probe.md, docs/evidence/pcie_calibration/*
Adds torchrun argument handling, console and JSON output, probe documentation, recorded calibration results, and unit tests for configuration and policy logic.

Estimated code review effort: 5 (Critical) | ~90+ minutes

Sequence Diagram(s)

sequenceDiagram
  participant Torchrun
  participant Probe
  participant NCCL
  participant DMA
  participant QueryIndexer
  participant Rank0
  Torchrun->>Probe: initialize distributed calibration
  Probe->>NCCL: measure TP and CKV collectives
  Probe->>DMA: measure TP DMA all-reduce
  Probe->>QueryIndexer: measure full and split indexing
  Probe-->>Probe: validate outputs and aggregate timings
  Probe->>Rank0: emit policy and calibration results
Loading

Possibly related issues

  • local-inference-lab/vllm#182 — The probe measures the same query-split, DCP owner-merge, CKV gather, and DMA paths described by the issue.
  • local-inference-lab/rtx6kpro#35 — The calibration decisions cover the owner-merge, query-split, CKV prefetch, and candidate-transport paths described by the issue.
  • local-inference-lab/rtx6kpro#15 — The probe benchmarks NCCL and SparkInfer collectives relevant to the reported NCCL and P2P transport behavior.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a lossless PCIe serving calibration probe.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pcie-calibration-probe-20260726

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (6)
tests/comm/test_pcie_overlap_probe.py (1)

178-188: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Resolve Ruff RUF005.

Line 185 can use iterable unpacking instead of list concatenation:

Proposed fix
-    late_loss = points + [(16384, _backend("nccl"))]
+    late_loss = [*points, (16384, _backend("nccl"))]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/comm/test_pcie_overlap_probe.py` around lines 178 - 188, Update the
late_loss construction in test_dma_crossover_requires_winning_tail to use
iterable unpacking instead of list concatenation, while preserving the existing
points followed by the final nccl entry.

Source: Linters/SAST tools

sparkinfer/comm/pcie/overlap_probe.py (5)

1232-1266: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Nineteen defaults are duplicated between ProbeConfig and the parser.

Every default here restates a ProbeConfig field default. They currently agree, but nothing enforces that, and a drift means the CLI and the programmatic API calibrate differently. Deriving them from the dataclass removes the class of bug entirely.

♻️ Derive parser defaults from the dataclass
 def _build_parser() -> argparse.ArgumentParser:
+    defaults = ProbeConfig()
     parser = argparse.ArgumentParser(description=__doc__)
-    parser.add_argument("--tp-size", type=int, default=8)
-    parser.add_argument("--dcp-size", type=int, default=4)
-    parser.add_argument("--hidden-size", type=int, default=6144)
-    parser.add_argument("--tp-rows", type=int, default=8192)
+    parser.add_argument("--tp-size", type=int, default=defaults.tp_size)
+    parser.add_argument("--dcp-size", type=int, default=defaults.dcp_size)
+    parser.add_argument("--hidden-size", type=int, default=defaults.hidden_size)
+    parser.add_argument("--tp-rows", type=int, default=defaults.tp_rows)
     parser.add_argument(
         "--allreduce-rows",
         type=_parse_positive_ints,
-        default=(1, 8, 32, 128, 512, 2048, 8192),
+        default=defaults.allreduce_rows,
     )

Apply the same pattern to the remaining options.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sparkinfer/comm/pcie/overlap_probe.py` around lines 1232 - 1266, Update
_build_parser to derive every CLI option default from the corresponding
ProbeConfig dataclass field instead of duplicating literal defaults. Apply this
consistently to all options currently mirroring ProbeConfig, while preserving
parser types, names, and existing CLI behavior.

1330-1352: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Config validation errors surface as a traceback instead of a CLI error.

ProbeConfig.validate() only runs inside CollectiveOverlapProbe.__init__, i.e. after dist.init_process_group. A bad --dma-wire-mode or --dcp-size therefore aborts mid-rendezvous on every rank with a raw ValueError. Calling config.validate() right after construction lets the process exit cleanly with a usage message before any distributed setup — which matters given the PR goal that "failures are reportable without loading a model."

♻️ Validate before distributed init
         dma_wire_mode=args.dma_wire_mode,
     )
+    try:
+        config.validate()
+    except ValueError as exc:
+        print(f"invalid probe configuration: {exc}", file=sys.stderr)
+        return 2
     result = run_probe(config)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sparkinfer/comm/pcie/overlap_probe.py` around lines 1330 - 1352, Call
config.validate() immediately after constructing the ProbeConfig in the CLI
flow, before run_probe(config) can initialize distributed state. Preserve the
existing CollectiveOverlapProbe validation while ensuring invalid options such
as dma_wire_mode or dcp_size produce the CLI’s normal usage error instead of a
raw traceback.

683-685: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Every context binding shares one pair of scratch buffers.

full_plan/full_scratch and split_plan/split_scratch are allocated once and reused across all context_tokens bindings. That is correct for the current sequential measurement loop, but it is an implicit invariant: no two bindings may be in flight at once. measure_overlap already runs work on side_stream concurrently with main_stream, so if the indexer phase is ever folded into the overlap path this becomes a silent data race on shared scratch.

A short comment stating the "one binding active at a time" contract would make the constraint explicit.

Also applies to: 719-722

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sparkinfer/comm/pcie/overlap_probe.py` around lines 683 - 685, Add a concise
comment near the shared full_plan/full_scratch and split_plan/split_scratch
allocations documenting that all context bindings reuse these buffers and only
one binding may be active at a time; preserve the current sequential measurement
behavior and apply the same contract to the corresponding later allocation.

1047-1047: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

samples is re-annotated with a conflicting type in the same scope.

Line 1047 declares dict[str, list[float]], Line 1075 redeclares the same name as dict[str, list[tuple[float, ...]]]. Type checkers reject the second annotation as a redefinition. Rename one (e.g. backend_samples / overlap_samples).

Also applies to: 1075-1075

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sparkinfer/comm/pcie/overlap_probe.py` at line 1047, Rename one of the
conflicting annotations for samples in the surrounding probe logic, such as
using backend_samples for the dict[str, list[float]] collection and
overlap_samples for the dict[str, list[tuple[float, ...]]] collection, then
update all references so each variable retains its intended data and the type
checker sees no same-scope redefinition.

699-722: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

B023 hints here are benign, but the closure is fragile.

Ruff flags base_page_table/local_tokens as unbound loop variables at Lines 700 and 702; in practice make_binding is invoked immediately at Lines 719-722, so late binding never triggers. Binding them as default arguments silences the lint and protects against someone later deferring the call.

♻️ Bind loop variables explicitly
-            def make_binding(plan, scratch, rows: int):
-                page_table = base_page_table.expand(rows, -1)
+            def make_binding(
+                plan,
+                scratch,
+                rows: int,
+                base_page_table: torch.Tensor = base_page_table,
+                local_tokens: int = local_tokens,
+            ):
+                page_table = base_page_table.expand(rows, -1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sparkinfer/comm/pcie/overlap_probe.py` around lines 699 - 722, Update the
nested make_binding function to capture the loop-scoped base_page_table and
local_tokens values through default arguments, then use those captured
parameters when expanding the page table and creating seqlens. Preserve the
existing immediate binding calls and all other binding behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/pcie_calibration_probe.md`:
- Around line 63-76: Expand the “Validation snapshot” evidence around the
documented benchmark claims to include the exact command, commit and worktree
identity, GPU mode, correctness result, and raw timings used to derive the
percentages and crossover; alternatively, link a generated JSON artifact
containing all of that information. Ensure the evidence covers both adjacent and
interleaved topologies and clearly records ratio direction so the results are
reproducible and auditable.

In `@sparkinfer/comm/pcie/overlap_probe.py`:
- Around line 944-962: Update the overlap probe around first() and second() to
synchronize their launch with a shared CUDA start event: record the event after
setup, make both collective streams wait on it, then enqueue the two launches.
Preserve the existing completion synchronization and elapsed-time calculations
using the appropriate stream events.
- Around line 1092-1108: Update the overlap decision call around decide_overlap
to use the pessimistic tp_first measurements alongside the existing side_first
values, selecting the worst-case ordering for concurrent throughput, collective,
and wall medians. Keep both orderings in the result payload and ensure the
decision no longer relies solely on side_first.
- Around line 87-88: Update validate() to enforce all divisibility requirements
used by the owner-merge path: require tp_rows to divide evenly by tp_size, and
require query_split_rows to divide evenly by indexer_shards before computing
owner_rows. Raise clear ValueError messages for each invalid condition while
preserving the existing query_split_size validation.
- Around line 1185-1194: Update the calculation of maximum_safe_context_tokens
near recommend_prefetch_depth to report the largest contiguous enabled prefix,
rather than max(enabled). Sort or otherwise traverse the context-token decisions
in ascending order and stop at the first rejected entry, preserving 0 when no
prefix is enabled.
- Around line 980-984: Strengthen the CKV correctness gate in the validation
block around ckv_ok to verify the entire gathered ckv_output buffer, not just
one byte at each rank-chunk offset. Compare all elements against the expected
rank-chunk pattern using an efficient device-side O(bytes) check, while
preserving the existing ckv_ok boolean contract before timings are interpreted.
- Around line 77-92: Extend the configuration validation around indexer_topk so
it cannot exceed the smallest per-shard local index pool derived from
context_tokens and the configured sharding. Reject invalid values with a clear
ValueError before probe execution, ensuring paged top-k and run_row_topk never
receive a top-k larger than available local candidates.

---

Nitpick comments:
In `@sparkinfer/comm/pcie/overlap_probe.py`:
- Around line 1232-1266: Update _build_parser to derive every CLI option default
from the corresponding ProbeConfig dataclass field instead of duplicating
literal defaults. Apply this consistently to all options currently mirroring
ProbeConfig, while preserving parser types, names, and existing CLI behavior.
- Around line 1330-1352: Call config.validate() immediately after constructing
the ProbeConfig in the CLI flow, before run_probe(config) can initialize
distributed state. Preserve the existing CollectiveOverlapProbe validation while
ensuring invalid options such as dma_wire_mode or dcp_size produce the CLI’s
normal usage error instead of a raw traceback.
- Around line 683-685: Add a concise comment near the shared
full_plan/full_scratch and split_plan/split_scratch allocations documenting that
all context bindings reuse these buffers and only one binding may be active at a
time; preserve the current sequential measurement behavior and apply the same
contract to the corresponding later allocation.
- Line 1047: Rename one of the conflicting annotations for samples in the
surrounding probe logic, such as using backend_samples for the dict[str,
list[float]] collection and overlap_samples for the dict[str, list[tuple[float,
...]]] collection, then update all references so each variable retains its
intended data and the type checker sees no same-scope redefinition.
- Around line 699-722: Update the nested make_binding function to capture the
loop-scoped base_page_table and local_tokens values through default arguments,
then use those captured parameters when expanding the page table and creating
seqlens. Preserve the existing immediate binding calls and all other binding
behavior.

In `@tests/comm/test_pcie_overlap_probe.py`:
- Around line 178-188: Update the late_loss construction in
test_dma_crossover_requires_winning_tail to use iterable unpacking instead of
list concatenation, while preserving the existing points followed by the final
nccl entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a23e4df-4f30-4403-997f-8cb46f8d88b4

📥 Commits

Reviewing files that changed from the base of the PR and between c39b806 and 4288322.

📒 Files selected for processing (3)
  • docs/pcie_calibration_probe.md
  • sparkinfer/comm/pcie/overlap_probe.py
  • tests/comm/test_pcie_overlap_probe.py

Comment thread docs/pcie_calibration_probe.md Outdated
Comment thread sparkinfer/comm/pcie/overlap_probe.py
Comment thread sparkinfer/comm/pcie/overlap_probe.py
Comment thread sparkinfer/comm/pcie/overlap_probe.py
Comment thread sparkinfer/comm/pcie/overlap_probe.py Outdated
Comment thread sparkinfer/comm/pcie/overlap_probe.py Outdated
Comment thread sparkinfer/comm/pcie/overlap_probe.py Outdated
voipmonitor added a commit that referenced this pull request Jul 26, 2026
@voipmonitor

Copy link
Copy Markdown
Contributor Author

Final release-candidate integration validation passed.

Image: voipmonitor/vllm:gilded-gnosis-v20-vllm0c79e41-sie603f74-fi801d57a-cu132-20260726

The image contains SparkInfer integration e603f74bb67d0fce547336f1fb73c3c23e8f1887 with this PR at f049ccdfeafd80b1424e09983bfb75ce629246f1. CodeRabbit reports no remaining actionable comments; CPU tests are 16/16, Ruff/format checks pass, and adjacent/interleaved TP8/DCP4 GPU calibration evidence is committed.

E2E gates using the generated policy:

  • TP8/DCP1/A16/MTP0 CC1: 87.50 tok/s aggregate
  • TP8/DCP4/A16/MTP0 64k prefill: 5,835 tok/s
  • TP4/DCP4/NF3/MTP0 CC1: 57.3 tok/s

The DCP4 calibration selected query split from 8k, CKV prefetch depth 1, and a 24 MiB lossless DMA crossover. Compressed DMA remained explicit-only.

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.

2 participants