Skip to content

[Core][Hardware][NVIDIA] Add custom all-reduce suspend hooks#47806

Draft
galletas1712 wants to merge 1 commit into
vllm-project:mainfrom
galletas1712:schwinns/custom-allreduce-suspend-resume
Draft

[Core][Hardware][NVIDIA] Add custom all-reduce suspend hooks#47806
galletas1712 wants to merge 1 commit into
vllm-project:mainfrom
galletas1712:schwinns/custom-allreduce-suspend-resume

Conversation

@galletas1712

@galletas1712 galletas1712 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Purpose

Add backend-owned suspend/resume hooks to CustomAllreduce for checkpoint lifecycle support (part of #46877 / #47500; FlashInfer counterparts: flashinfer-ai/flashinfer#3727, flashinfer-ai/flashinfer#3745):

  • prepare_for_suspend() collectively quiesces the TP group and closes all imported CUDA IPC peer mappings (wrapper-owned metadata/eager-staging mappings and native captured-graph mappings).
  • reinit_after_resume() exchanges fresh IPC handles, reopens peer mappings, and rewrites the stable device-side RankSignals/RankData tables so previously captured CUDA graphs remain valid.

Why indirection instead of stable-address remap: peer signal pointers were previously baked into captured kernel launches by value, and legacy cudaIpcOpenMemHandle cannot remap at a requested address after resume. Kernels therefore now read peer signals through a device-side table that resume rewrites — the same pattern the existing RankData table already uses for graph-captured peer activations. A VA-stable cuMemMap-based design was considered and deferred: it requires FD-exchange infrastructure and cannot cover torch-allocated graph buffers, which force legacy IPC in any zero-copy design.

Lifecycle semantics (modeled on flashinfer-ai/flashinfer#3727): fail-fast — a failed transition leaves the communicator in a terminal failed state and any use raises (no NCCL degradation during the suspend window); repeated successful calls are idempotent no-ops. No rollback or cross-rank voting.

Not a duplicate: no open PR implements custom-all-reduce IPC teardown/rebuild; #45611 only disables custom all-reduce under the cumem allocator and does not preserve mappings or captured graphs.

Test Plan

  • pytest tests/distributed/test_custom_all_reduce.py on ≥2 CUDA GPUs (covers eager + captured-graph suspend/resume, idempotency, detached-use errors, close); 4 GPUs for the pp=2 parametrization.
  • Native CUDA build (uv pip install -e .) and ROCm compile check (suspend/resume itself is CUDA-only and raises on ROCm).
  • benchmarks/kernels/benchmark_device_communicators.py before/after, to bound the cost of the signal-table indirection in the reduce kernels.

Test Result

TODO — pre-commit hooks (ruff, clang-format, mypy, typos) pass; GPU runs and benchmark numbers pending. Post-resume validation is intentionally limited to cheap invariants (metadata counts, local signal/eager-buffer identity) with robust validation left as a TODO in reinit_after_resume — layout comparison alone cannot prove mapping integrity.


This PR was created with AI assistance. The submitting human must review every changed line and complete the GPU validation above before marking it ready.

Allow custom all-reduce to close all imported peer mappings before a
process suspend and rebuild them from fresh IPC handles after resume.
Captured CUDA graphs stay valid because kernels read peer pointers
through stable device-side RankSignals/RankData tables that resume
rewrites in place. Lifecycle failures are terminal (fail-fast, no
rollback or cross-rank voting); repeated successful transitions are
no-ops.

Assisted-by: OpenAI Codex
Assisted-by: Claude
Signed-off-by: Schwinn Saereesitthipitak <schwinns@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant