mirror of
https://github.com/deepseek-ai/DeepEP.git
synced 2026-11-05 00:47:32 +00:00
[PR #762] Fix hybrid combine top-k weight gradients with single reduction #764
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#764
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/762
Author: @Gstdioh
Created: 9/23/2026
Status: 🔄 Open
Base:
main← Head:codex/fix-hybrid-combine-score-grad📝 Commits (6)
2de61edFix hybrid combine top-k weight source selection299bcbfAdd regression for receiver-local top-k weight gradients612bf08Apply repository formatting to combine reduce epilogue6d7a1e4Complete top-k weight gradient regression463065cKeep score-gradient fix minimal without reformatting655d77eReport failing ranks in score-gradient regression📊 Changes
2 files changed (+115 additions, -1 deletions)
View changed files
📝
deep_ep/include/deep_ep/impls/combine_reduce_epilogue.cuh(+9 -1)➕
tests/elastic/test_combine_topk_weights.py(+106 -0)📄 Description
With hybrid combine,
do_expand=Falseandallow_multiple_reduction=False, the sender forwards a separate top-k weight row for each destination GPU. The reduce epilogue currently selects the master slot by scale-out rank, so routes on different GPUs in the same scale-out domain can read the wrong row.For example, receiver-local score-gradient rows
[11, 0]and[0, 22]should produce[11, 22], but selecting one domain-wide row produces[0, 22]. This affectscombine(..., topk_weights=...), including its use for dispatch backward. A plain dispatch/combine weight roundtrip can hide the bug because the dispatched weights are duplicated.This change selects the score source master slot by global GPU rank for this mode, matching the forwarded row layout. The existing selection is preserved for other modes, with a compile-time assertion for slot layout. The original header formatting is preserved; the production change is limited to this one block (+9/-1 lines).
A standalone distributed regression uses synthetic receiver-local gradients and covers same-GPU, same-domain/different-GPU, and cross-domain routes, including invalid top-k slots. It supports
--allow-multiple-reduction=1as a control.Validation: Python syntax, Ruff 0.6.5, YAPF 0.40.2, and
git diff --checkpass. The header already differs from clang-format on the base branch; whole-file formatting is intentionally excluded to keep this fix focused. Real multi-node GPU validation completed for commit655d77e6bfcdcf46b065a4596104f6f2d4338503: two nodes with 8 NVIDIA H200 GPUs each (16 ranks), with fresh processes and separate JIT caches for--allow-multiple-reduction=0and=1. All three cases passed for all ranks in both modes, and both node launchers exited with code 0 for each run. No test or production-code changes were needed. This run used PyTorch 2.9.0 (CUDA 12.4) and nvcc 12.8.61; it does not validate the README's PyTorch >=2.10 baseline or add distributed CI coverage. See the GPU validation results.Run on each node (replace the rendezvous placeholders):
The test asserts at least two logical scale-out domains and at least two GPUs per domain. Repeat with
--allow-multiple-reduction=1to exercise the control path.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.