feat(deepep-efa): vLLM DeepEP-V2 MoE all-to-all over EFA via NCCL-GIN GDAKI (GPU-initiated) - #1231
feat(deepep-efa): vLLM DeepEP-V2 MoE all-to-all over EFA via NCCL-GIN GDAKI (GPU-initiated)#1231dmvevents wants to merge 9 commits into
Conversation
… GDAKI (GPU-initiated)
GDAKI (NCCL_GIN_TYPE=3, GPU-initiated / kernel-posted WQE) counterpart to the
CPU-proxy sample 3.test_cases/pytorch/vllm/deepep-v2-efa. Same base, torch/NCCL/
NVSHMEM/vLLM/DeepEP pins; the deltas are the GDAKI transport stack, all built from
public source and pinned by immutable SHA:
- rdma-core @ master post-PR#1701 (EFA completion-counter verbs)
- libfabric @ main post-PR#12591 (prov/efa comp-cntr caps), built against it
- aws-ofi-nccl @ a3d2680 --enable-gdaki + PR#1351 forced-PCIe cherry-pick
(a3d2680 carries PR#1311 hw-counter tristate + the GIN seq-space fix)
- DeepEP b306af06 + PR#612 + a dlsym-guarded V13 host-UC shim (inert on upstream)
NGC-from-scratch (FROM nvcr.io/nvidia/cuda). Measured 2026-08-14 on 2x/4x
p5en.48xlarge (H200), Qwen3-30B-A3B-FP8, DP16/EP16 and DP32/EP32, eager + non-eager
(3-commit fix stack), every sweep 121/121 HTTP 200. Same-node-set, same-image
transport A/B (env-flip only): GDAKI >= CPU-proxy in all 10 paired comparisons across
the EP16+EP32 2x2, +0.2-3.2% aggregate tok/s. Numbers, provenance, and honest caveats
(single-sweep variance; functional wire-proof on efa.ko 3.0.x nodes, not a byte tally)
in benchmarks/README.md.
Mirrors the proxy sibling's layout (Dockerfile at root, COPY'd setup_deepep_v2_gdaki_efa.sh,
recipe/, setup/, kubernetes/, benchmarks/). The setup script is first-party for the
GDAKI path and intentionally outside .github/workflows/deepep-vendor-sync.yml.
Signed-off-by: Anton Alexander <dmvevents@gmail.com>
KeitaW
left a comment
There was a problem hiding this comment.
Let's incorporate necessary changes into upstream instead of patches.
…o-patch eager only Same re-scope as the proxy twin: remove recipe/apply-noneager-fix-stack.sh and its boot hook in the deploy YAML (no-patches rule). Eager is the shipped + supported path; default compilation documented as pending the upstream empty-ExpertTokensMetadata guard (vLLM PR <PENDING-PR>) — pin bump enables it, no recipe change. Non-eager numbers in benchmarks/ relabeled historical. Signed-off-by: Anton Alexander <dmvevents@gmail.com>
Signed-off-by: Anton Alexander <dmvevents@gmail.com>
|
Re-scoped per the repo's no-patches rule — thank you for stating it plainly rather than letting it surface in review. What changed (this push):
This keeps the case alive across pin bumps by construction: nothing in the build rewrites upstream source. |
…config -p output format Same fix as the sibling vLLM DeepEP-V2 case: ldconfig -p prints 'libnccl.so.2 (libc6,x86-64) => /path', so the literal 'libnccl.so.2 => $NCCL_ROOT/lib' pattern cannot match and the build failed 100% at this step. Assert the first resolver line points at the pinned pip NCCL (2.28.x lacks the GIN/LSA symbols the GIN plugin needs). Signed-off-by: Anton Alexander <dmvevents@gmail.com>
|
One follow-up commit ( |
|
@KeitaW the changes-requested items are addressed on this branch (patch machinery deleted, zero-patch eager path is the shipped recipe — details in the two comments above), and the sibling #1230 eager path is live-verified E2E from its branch. Ready for another look whenever convenient. (Noting it here since fork authors can't use the re-request-review button on this repo.) |
|
Thanks @KeitaW — agreed, upstream-first is the right call, and it's the direction this stack is already built on. Here's exactly where each modification lives today (every status re-verified against the source repos): Already merged upstream — the Dockerfile pins the post-merge SHA, so these are incorporated upstream, not carried as patches:
Filed upstream, open: DeepEP deepseek-ai/DeepEP#612 (cap auto-QP at 2 on EFA). I'll pin the merge SHA once it lands and drop the local reference. The two genuine local artifacts — and how I'll retire them:
Net: this folder reduces to post-merge upstream SHA pins + one open upstream DeepEP PR, with zero local source patches. I'll push that reduction, re-run the |
…EP ref, zero local patches Follows through on the review commitment for PR awslabs#1231: this folder now reduces to post-merge upstream SHA pins plus one open upstream DeepEP PR, with zero local source patches. Three reductions: 1. Drop the aws-ofi-nccl PR#1351 forced-PCIe cherry-pick. The maintainer closed #1351 in favour of requiring GDRCopy 2.5+ on the node, so we follow that guidance rather than carry the patch. aws-ofi-nccl is now a plain SHA pin at a3d2680 (--enable-gdaki), which already carries the merged PR#1311 hw-counter tristate and the GIN seq-space fix. GDRCopy 2.5+ is documented as a NODE PRECONDITION (README Prerequisites, Dockerfile Layer 3, K8s manifest header) and enforced fail-loud in recipe/verify-image.sh (parses /sys/module/gdrdrv/version, requires >= 2.5). Removed OFI_NCCL_GDRCOPY_FORCED_PCIE_COPY=1 from the image ENV, the K8s env list, serve.sh and run-kernel-test.sh. 2. Remove the v13-host-uc-shim.patch from the build. It was dlsym-guarded and inert on the pinned plugin a3d2680 (which does not export the host-UC register hook), so behaviour is unchanged. Dropped the COPY, the setup-script apply/commit/grep block, and the verify marker check. 3. DeepEP PR#612 (deepseek-ai/DeepEP, "cap auto-QP at 2 on EFA") is OPEN upstream, so it stays as the ONE upstream reference, merged by its immutable head SHA, labelled "filed upstream, open" with a documented re-pin path for when it merges. The already-merged-upstream substrate fixes (rdma-core #1701, libfabric #12591, aws-ofi-nccl #1311 carried by the a3d2680 pin) remain plain post-merge SHA pins and are no longer described as "patches" anywhere. Signed-off-by: Anton Alexander <dmvevents@gmail.com>
…erence (reorg awslabs#1119) Reorg awslabs#1119 removed the numbered 3.test_cases/ tree and moved every test case under examples/. This branch predated that reorg, so its files landed on the now-deleted 3.test_cases/pytorch/vllm/deepep-v2-GDAKI-efa/ path, leaving the PR mergeable_state=dirty against main. Migrate via `git mv` (history preserved, R100 pure renames) to the new home: 3.test_cases/pytorch/vllm/deepep-v2-GDAKI-efa -> examples/inference/vllm/deepep-v2-gdaki-efa Also lowercase the directory to deepep-v2-gdaki-efa: the reorg's dir convention is lowercase-kebab (the sibling is examples/inference/vllm/deepep-v2-efa), and this folder's own artifacts already use lowercase `gdaki` (setup script, k8s manifest, image tag). GDAKI stays uppercase in prose/READMEs (it is an acronym). Only one in-tree self-reference needed updating (Dockerfile echo label). Index rows added so the case is discoverable from the reorg's new indexes: examples/inference/README.md (framework-level index) examples/inference/vllm/README.md (case-level pointer, repointed lowercase) Known forward-reference: examples/inference/vllm/deepep-v2-gdaki-efa/README.md cross-links `../deepep-v2-efa` (the CPU-proxy DeepEP-V2 sibling, PR awslabs#1230). That directory only lands on main once awslabs#1230 merges; the link resolves then. This is the same cross-sibling reference awslabs#1230's own README carries and is intentional, not a broken link. Signed-off-by: Anton Alexander <dmvevents@gmail.com>
Run the repo's documented markdown gate (`npx markdownlint-cli2`, root .markdownlint.jsonc) against the migrated folder. The files were already failing that gate before this branch touched them: - blanks-around headings/fences/lists (MD022/MD031/MD032) throughout the README and benchmarks/README — auto-fixed (27 fixes), same class as the repo-wide sweep in awslabs#1245. - README.md: an inline "libfabric #12591" issue-ref had wrapped so `#12591` started a line, which GitHub renders as an H1 mid-paragraph (MD025 multiple H1 + MD022 + MD026 trailing punctuation + MD001 heading-increment). Reflowed the wrap so the ref stays inline (matching the sibling `#1701`/`#1311` refs); fixes the render and clears all four rules. No content change beyond the reflow; `npx markdownlint-cli2` now exits clean. Signed-off-by: Anton Alexander <dmvevents@gmail.com>
…ibuting fork; drop superseded awslabs#612 Repoint the DeepEP source from deepseek-ai/DeepEP + a refs/pull/612/head fetch-merge to the amazon-contributing/DeepEP fork, pinned at an immutable SHA (97d8f9bcc1). This matches the house V2/NCCL-Gin canonical micro-benchmarks/expert-parallelism/deepep-v2-benchmark/setup_deepep_gin.sh, which already clones the same fork. The fork carries the EFA delta in-code, including both halves of the draft deepseek-ai/DeepEP#612 that this sample previously fetch-merged: - the get_rdma_gbs() sysfs link-rate fast path (deep_ep/utils/envs.py) - the auto-QP overflow clamp (deep_ep/buffers/elastic.py) So awslabs#612 is superseded: pinning the fork HEAD is strictly ahead of the old base+PR-merge, and it addresses the review note that pinning stock upstream at the pre-fix fork point forfeits exactly those AWS fixes. - setup_deepep_v2_gdaki_efa.sh: DEEPEP_REPO -> amazon-contributing/DeepEP, DEEPEP_SHA -> fork HEAD; drop the refs/pull/612/head fetch+merge; add fail-loud asserts that both awslabs#612 fix-halves are present in the clone. - Dockerfile: rewrite the Layer-5 provenance header to name the fork; drop the DEEPEP_PR / DEEPEP_PR_SHA ARGs and their pass-through. - README.md: rewrite the source-pin paragraph + Net summary to the fork, naming both superseded awslabs#612 halves. No local source patches; the pin is override-able via DEEPEP_SHA. Test Results: docs-and-packaging change (source-repoint + provenance). An end-to-end GDAKI all-to-all rebuild+serve verification on 2x p5en is tracked separately as the GPU-verify half of this change. Signed-off-by: Anton Alexander <dmvevents@gmail.com>
Reduction pushed + re-review requested — head is now
|
What
Adds a vLLM + DeepEP-V2 MoE all-to-all test case that routes the expert-parallel dispatch/combine over AWS EFA using the NCCL-GIN GDAKI transport (
NCCL_GIN_TYPE=3,OFI_NCCL_GIN_GDAKI=1) — the GPU-initiated path where the GPU kernel posts the RDMA work requests itself, instead of handing them to a CPU proxy thread.Placement:
3.test_cases/pytorch/vllm/deepep-v2-GDAKI-efa, parallel to the CPU-proxy sample3.test_cases/pytorch/vllm/deepep-v2-efa(PR #1230). It mirrors that sibling's layout, README section order, and voice; the only functional deltas are the GDAKI transport stack. (The proxy sibling is not onmainyet — #1230 is open — so this PR branches frommainand adds the GDAKI sample as a peer; both touch only3.test_cases/pytorch/vllm/README.md's index table.)Why GDAKI needs a different substrate
DeepEP's default transport is NVSHMEM/IBGDA, which EFA does not provide. The proxy sibling runs V2's
ElasticBufferover the GIN CPU-proxy. This sample uses GDAKI (kernel-posted WQEs), which on EFA needs a newer transport substrate, all built from public source and pinned by immutable SHA:prov/efaconsumes the comp-cntr caps; built against the rdma-core above.a3d2680--enable-gdaki+ a PR#1351 cherry-pick (forced-PCIe gdrcopy override).a3d2680carries PR#1311 (the per-platform EFA hw-counter tristateOFI_NCCL_GDAKI_EFA_HW_COUNTER) and the GIN seq-space aliasing fix.b306af06+ PR#612 (same base+PR as the proxy sample) + adlsym-guarded V13 host-UC shim that is inert (logs a fallback and no-ops) unless the plugin exports a hook upstream does not — carried as evidence lineage, not a live code path.Everything else —
EP_REUSE_NCCL_COMM=0(or serve init segfaults under vLLM's lazy NCCL comm), the vLLM wheel-pin, and the eager/non-eager fix stack — is identical to the proxy sample.Measured evidence (2026-08-14, 2×/4× p5en.48xlarge H200,
Qwen/Qwen3-30B-A3B-FP8)Full tables + provenance + honest caveats in
benchmarks/README.md.GDAKI-CQE … status 9(the known upstream failure signature) through every phase./syshw-counter tally — that needs efa.ko ≥ 3.3.0 (documented in the node preconditions).Build / reproducibility
FROM nvcr.io/nvidia/cuda:13.0.0-devel-ubuntu22.04; every layer from a public source (EFA installer, rdma-core, libfabric, gdrcopy, torch cu130, aws-ofi-nccl, DeepEP, vLLM wheel). A tester with docker + NGC + GitHub/PyPI reproduces the image with zero private access.setup/env_vars.exampleuses the standard placeholder; the manifest usesREPLACE_WITH_YOUR_REGISTRY.setup_deepep_v2_gdaki_efa.shis COPY'd (in-tree, reviewable), not curled, and is first-party for the GDAKI path — deliberately outside.github/workflows/deepep-vendor-sync.yml(that CI gates the NVSHMEMsetup_deepep_efa.shvendored copy, a different script). The V13 shim patch was dry-run-verified to apply cleanly (patch -p0, exit 0) against upstream DeepEPb306af06.Layout
Opened as draft — pending maintainer review of placement/scope alongside #1230.
DCO signed off.