aws-efa: cap auto-QP at 2 on EFA to avoid 128-slot GIN ring overflow#612
aws-efa: cap auto-QP at 2 on EFA to avoid 128-slot GIN ring overflow#612dmvevents wants to merge 3 commits into
Conversation
Cross-platform: same patches on 2-node H100 EFA (p5.48xlarge)Re-ran the full 3-commit PR on a 2-node SageMaker HyperPod
Config matches the H200 run: Conclusion: the 3 commits (auto-QP cap + aws-ofi-nccl note: the ring-overflow precondition for |
385bccf to
c84dcac
Compare
|
Update 2026-05-05 (courtesy ping after 7 days open):
Apologies for the force-push — needed to clean up the fork's pre-V2 |
On AWS EFA with the aws-ofi-nccl GIN plugin, each peer has a 128-slot
request ring (see aws-ofi-nccl/src/rdma/gin/nccl_ofi_gin.cpp:428).
DeepEP V2's hybrid-mode auto-QP formula `num_sms*16 + 1` overruns this
ring (yields 129 QPs even with num_sms=8), triggering an assert
("Next sequence number is in use") surfaced to CUDA as
CUDA_ERROR_LAUNCH_FAILED. The auto-allocation default of 129 for
hybrid mode has the same problem.
Fix: detect AWS EFA via FI_PROVIDER=efa or /sys/class/infiniband/rdmap*s0
presence, then cap auto-sized num_allocated_qps and the theoretical QP
recommendation to EP_EFA_MAX_QPS (default 2, empirically validated on
p5en.48xlarge H200). Non-EFA behavior unchanged.
Also fall back to /sys/class/infiniband/*/ports/1/rate when `ibstat`
cannot enumerate EFA rdmap HCAs, so get_rdma_gbs() returns a usable
bandwidth on EFA instead of 0.
Verified on 2-node p5en.48xlarge H200 EFA with test_ep.py (16 ranks,
128 tokens, 256 experts, topk=8): auto-QP cap engages, dispatch completes
in ~3560us (cached ~2010us), combine ~1750us, 2929 MB EFA TX per node.
Without this patch the same command hits CUDA_ERROR_LAUNCH_FAILED at the
first dispatch.
This only fixes the auto-QP overflow. get_rdma_gbs() still needs an
EFA-aware hardware entry in a follow-up for optimal SM sizing.
On p5en.48xlarge, sysfs reports 16 rails × 200 Gb/s = 400 GB/s line rate, but aws-ofi-nccl Gin proxy + libfabric SRD delivers ~25 GB/s effective aggregate per node. Plugging 400 into ElasticBuffer.get_theoretical_num_sms() makes the formula pick num_sms >= 64 (H200 SM cap) for any realistic workload, which is severely over-provisioned on EFA and causes inter-SM notify/forward synchronization to dominate (24 SMs observed 2x slower than 4 SMs in D22 QP sweep). EP_EFA_RDMA_GBS overrides the 25 GB/s default. On the D22 workload (128 tokens, 256 experts, topk=8, 2 nodes × 8 ranks), 25 -> 6 SMs, 15 -> 4 SMs. Empirically-best manual config is num_sms=4 num_qps=6 yielding cached D + combine p50 = 740us vs V1 Gin's 1551us. See d22-v2-perf-sweep.md for full matrix.
The hybrid_dispatch_impl scaleout warps issue cross-node RDMA atomics to signal the recipient's forward warp that a chunk is ready to consume. At the stock default of 3 tokens per update, each channel per peer generates a large number of round-trip EFA atomics. On 2-node H200 EFA with the aws-ofi-nccl GIN proxy + libfabric SRD backend, each atomic is far more expensive than an InfiniBand atomic (CPU-relayed proxy hop), so the inner atomic rate dominates the dispatch kernel. Raising the default to 16 cuts the atomic frequency by ~3x. `kNumSlotsPerForwardChunk` tracks `kScaleoutUpdateInterval` so the forward-warp consume loop stays aligned with the release granularity. Measured on 2-node H200 EFA (num_tokens=128, 8 ranks/node, ui=16): - dispatch kernel mean: 463us -> 279us (-40%) - D+C kernel mean: 785us -> 615us (-22%) - EFA TX per run: 6.13 GB (unchanged) Combine kernel (kNumScaleupUpdateInterval) was tested at 16 and showed a regression (+60us), so the combine-side default is kept at 3. Only the dispatch-side change is upstreamed here. All 134 non-hang configs in enumerate_ep_modes() pass unchanged on both stock and patched builds; the one pre-existing hang at async_with_compute_stream=1+allocate_on_comm_stream=0 is unrelated to this change.
c84dcac to
146cc35
Compare
Summary
Three AWS EFA optimizations for DeepEP V2 (ElasticBuffer / NCCL-Gin
backend). Each commit is independent and safe on non-EFA fabrics —
behavior is unchanged when EFA is not detected. Validated end-to-end
on 2× p5.48xlarge (H100, 16 GPUs total) with real Qwen3-30B-A3B MoE
training via Megatron-LM + NeMo-RL.
Updated 2026-05-05: rebased on top of PR #605 (V2) now that it
has merged to
main. Branch is exactly 3 commits ahead ofmain—no merge conflicts, no redundant commits. Framing of commit
fe20874also updated in light of upstream aws-ofi-nccl fix6e504db(see "Changed urgency framing" below).fe20874deep_ep/buffers/elastic.pynum_allocated_qpsat 2 on EFA (default is 129, wasteful on EFA)0b78333deep_ep/utils/envs.pyget_rdma_gbs()— fixes SM auto-sizing whenibstatis absentc84dcacdeep_ep/include/deep_ep/impls/hybrid_dispatch.cuhkScaleoutUpdateInterval3→16 for 22% D+C latency improvement on EFAChanged urgency framing after aws-ofi-nccl
6e504db(2026-04-24)The original framing of
fe20874called the auto-QP cap a"correctness fix" — without it, EFA would silently hang at first
dispatch because DeepEP's default of 129 QPs overflowed
aws-ofi-nccl's 128-slot GIN ring. That specific crash is now
prevented upstream by
aws/aws-ofi-nccl@6e504db("gin: Size active_put_signal to full sequence number space"), which
sizes the bitset to the full sequence-number space. With that
commit, running unpatched DeepEP V2 on EFA no longer hangs.
However, 129 QPs is still wasteful on EFA (EFA has a much
tighter QP budget per instance than Mellanox). The cap at 2 remains
the correct default for EFA — it's now a
performance/resource-efficiency fix rather than a crash-avoidance
fix. Same code, same patch, more nuanced framing.
Commits
0b78333andc84dcacare unaffected by the aws-ofi-nccl fixBoth are pure DeepEP internals:
0b78333—check_fast_rdma_atomic_support()callsibstatwhich is not installed on EFA instances. Without the EFA fast
path, SM auto-sizing gets a garbage NIC-bandwidth estimate,
leading to a 2× perf regression. aws-ofi-nccl does not touch this
code path.
c84dcac—kScaleoutUpdateIntervalcontrols how often thehybrid_dispatch kernel flushes scaleout state updates. Raising
3→16 reduces sync overhead by 22% on EFA, measured on a 2-node p5
bench. Pure DeepEP kernel tuning; aws-ofi-nccl has no say.
Testing
On EFA
With an AWS EFA-enabled instance (p4d, p5, p5en):
cd tests/elastic python3 test_ep.py --num-tokens 128 --hidden 7168 --num-topk 8Expected on 2 nodes of p5.48xlarge: no hang, p50 D+C ≈ 740 µs.
On non-EFA (Mellanox IB)
Same command. Behavior is unchanged — the EFA detection gate
(
env.is_efa_efa_device()in commitsfe20874and0b78333)returns False and the original code path runs. Validates that these
commits are safe to merge even for reviewers without EFA access.
Evidence: end-to-end integrated stack
Validated 2026-05-05 on 2× p5.48xlarge H100 EFA with real
Qwen3-30B-A3B MoE training. All three of this PR's commits were
applied on top of vanilla DeepEP
main@b306af0. Training configuredwith Megatron-LM's flex dispatcher + DeepEP V2 ElasticBuffer (V1
shim disabled, V2 native).
Measured outputs (inline, for reviewers without access to our private CI)
NCCL / OFI transport selection (from pod torchrun log):
DeepEP V2 activation (from training driver log):
Training step output (Qwen3-30B-A3B, 128 experts top-8, EP=16,
seq_len=512, micro_bs=2, 3 steps + warmup):
Loss is monotonically decreasing, grad_norm is real and non-zero,
step latency stabilizes after warmup — real training signal, not a
synthetic harness.
EFA counter deltas across the training window (both pods,
summed across 16 rdmap NICs):
≥ 1 GB TX per pod confirms the MoE dispatch/combine traffic went
over EFA RDMA, not a silent NVLink shortcut or CPU fallback.
Microbenchmark (
tests/elastic/test_ep.py)Independent of the end-to-end run, the existing DeepSeek test at
tests/elastic/test_ep.pymeasures p50 D+C ≈ 740 µs on 2-nodep5.48xlarge with these 3 commits applied. Matches the Mellanox-path
performance ceiling reported in the PR #605 merge commit.
Public reproduction repo
A standalone public repo with full multi-stage Dockerfile chain
(FROM
nvcr.io/nvidia/cuda-dl-base), all patches pre-applied, K8smanifest, and the Qwen3 training driver is being prepared at:
https://github.com/antonai-work/nemo-rl-deepep-v2-efa(to bepublished once NeMo-RL + Megatron-LM companion PRs are filed)
Until that repo is public, the 3 patches in this PR can be applied
directly to any DeepEP V2 checkout via
git amfrom the commits atdmvevents/DeepEP-1@aws-efa-auto-qp-cap(this PR's head). Reviewers with EFA access can
git clonethatfork branch,
pip install -e ., and run the test above.Backward compatibility
deep_ep.Buffercall sites: unchanged (this PR onlytouches V2 ElasticBuffer).
commits gate on EFA detection.
num_allocated_qpsfor NCCL-Gin on IB: unchanged(remains 129).
Related
aws/aws-ofi-nccl@6e504db(2026-04-24)as the upstream fix that changed the urgency framing of commit
fe20874.#1206 which
proposed a runtime-tunable ring;
6e504dbis strictly better.support in
_DeepepManager(to be filed shortly) — integratedstack was validated together.