mirror of
https://github.com/deepseek-ai/DeepEP.git
synced 2026-11-05 00:47:32 +00:00
[PR #780] Document and test ordinary sync-free receive tensor lifetimes #776
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
deepseek-ai/DeepEP#776
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/deepseek-ai/DeepEP/pull/780
Author: @yuweih205
Created: 10/15/2026
Status: 🔄 Open
Base:
main← Head:codex/syncfree-recv-lifetime-1015📝 Commits (1)
97fa6d1Document and test sync-free receive tensor lifetimes📊 Changes
2 files changed (+168 additions, -0 deletions)
View changed files
📝
README.md(+2 -0)➕
tests/ep/test_recv_lifetime.py(+166 -0)📄 Description
Summary
Document and exercise the lifetime contract of ordinary independently allocated receive outputs from compact
dispatch(do_cpu_sync=False).record_streamhandoff, and why a prefix view retains the full capacity allocation.No production Python/C++/CUDA implementation, default, or API changes. The internal dispatch copy epilogue still runs. This is not borrowed communication-buffer storage or a zero-copy dispatch implementation.
Regression coverage
The new
tests/ep/test_recv_lifetime.pyuses the independent NCCL dispatch reference and requires bitwise equality of payloads, local expert indices, routing weights, source-token metadata, and the saved-activation weight gradient.Each process run covers:
ctx.save_for_backward, followed by three additional dispatches through the same buffer before backward.Scheduling can miss the pressure window. All ranks agree on numerical correctness and window validity, then retry in collective lockstep with a longer delay (at most three attempts). Actual corruption fails immediately; an inconclusive window is never silently reported as coverage.
The consumer handoff uses a CUDA event captured after the first dispatch-event wait, including its deterministic-sort hook. It does not depend on repeated waits on the original
EventOverlap; that is separate from this lifetime coverage.Validation
Current polished revision
Head:
97fa6d18ff717df99acbdbb862325bda3d4a0d46, based on public mainb5a33eefda39485f438dc764695b71ba7b9249b6.The current 166-line test passed on H200 with PyTorch
2.13.0+cu132, CUDA 13.2 and NCCL 2.32.3. Each native lifetime policy was run once with eight ranks: 24 distributed saved-prefix/backward cases in total, with 24 valid delayed-consumer allocator-pressure windows. This is positive coverage of the current reorganized test; the historical negative and scheduling controls below were not rerun against this revision.Historical validation of the earlier test version
Tested commit:
01c31d0d75f155ca00ba933a6b9ab7a01459169e, based on upstream93eb6eb238127e96c6d7a4a625a6dad158348509. The results in this subsection belong to that earlier test version, not to a rerun of the current 166-line test.One node, eight NVIDIA H200 GPUs in a single NVLink domain; PyTorch
2.13.0+cu132, CUDA runtime 13.2, loaded NCCL 2.32.3. The unchanged upstream native extension and the tested source archive/test-file hashes were verified. No borrowed-view implementation or event-wrapper patch was included.Both native lifetime policies were run in fresh processes, three repeats each, using the same two command lines above.
Validation controls:
EP_DISABLE_GIN=1,EP_REUSE_NCCL_COMM=0,EP_BUFFER_DEBUG=0,NCCL_NET_PLUGIN=none,CUBLAS_WORKSPACE_CONFIG=:4096:8. Seed 42; deterministic PyTorch algorithms enabled with uninitialized-memory filling disabled.EP_AVOID_RECORD_STREAM=0EP_AVOID_RECORD_STREAM=1Two additional controls were run outside the PR using that exact earlier public test source, without changing DeepEP's implementation:
prefix.record_stream(reader)expression fromcross_stream_pressure. For balanced nonempty receives, run both deterministic modes and both allocation streams. All 24 distributed cases were rejected by the specificCROSS_STREAM_RECEIVE_MISMATCHassertion; actual local data corruption was observed in all 192 rank/cases. Other assertions or an ineffective window do not count as detection.pending_beforequery. All ranks must retry attempt 0 together and pass on a later effective attempt. All 24 distributed cases / 192 rank/cases passed.An earlier draft's post-copy-event stress missed the deleted-record mutation. That draft is not the sensitivity evidence above; the pre-read/completed-pressure ordering and destination preallocation were added before rerunning all historical arms.
All eighteen historical fresh launches exited successfully. Source/input hashes, exact per-rank coverage, control mutation identities and completion/exit sentinels were audited from downloaded logs. Archive SHA256:
834a31fa761e439678244ae49cdaf98491ead5fb23b4724500ba038366eac777.Local checks for that earlier revision: Python compilation, Ruff 0.6.5, YAPF 0.40.2 (no diff), and
git diff --checkpassed.Scope
This establishes component lifetime/gradient correctness for ordinary compact BF16 receives in one physical NVLink domain. It does not establish full-model convergence, training throughput gains, borrowed-storage safety, FP8/expanded layouts, or multi-node hybrid routing. Capacity-retention assertions deliberately distinguish logical tensor bytes from retained storage bytes.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.