Skip to content

[JAX] EP Dispatch with overflow detection option - #3277

Merged
phu0ngng merged 3 commits into
NVIDIA:mainfrom
phu0ngng:ep-jax-overflow
Aug 4, 2026
Merged

[JAX] EP Dispatch with overflow detection option#3277
phu0ngng merged 3 commits into
NVIDIA:mainfrom
phu0ngng:ep-jax-overflow

Conversation

@phu0ngng

Copy link
Copy Markdown
Collaborator

Description

Adds a way to size EP recv buffers below the worst case and still stay correct. ep_prepare / ep_dispatch now expose total_recv_tokens, the per-rank pre-drop recv-slot demand, so callers can tell exactly when a step's routing exceeds recv_capacity_per_rank; no need to conservatively provision every rank for the theoretical maximum.

Bootstrap also gains an opt-indrop_on_overflow policy so an occasional overflowing step is handled gracefully and keeps running (the default behavior is unchanged).

Together these let users pick a tighter, cheaper recv capacity and monitor total_recv_tokens to confirm it holds or to drive their own capacity policy.

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

  • Bootstrap:ep_bootstrap gains a drop_on_overflow flag, plumbed through set_ep_bootstrap_params (pybind) and NVTEEpGroupConfig.drop_on_overflow.
    • New output:ep_prepare now returns (token_counts, total_recv_tokens, handle_mem); ep_dispatch's
      custom_vjp primal correspondingly returns total_recv_tokens as a non-differentiable output.
    • MoE:moe() and the Flax _MoEBlock now return(output, aux_loss, total_recv_tokens); the extra output is non-differentiable
    • Teardown: adds ep_finalize() (and reset_ep_config) to tear down the EP
      communicator so a process can re-ep_bootstrap with a different config.

Checklist:

  • I have read and followed the contributing guidelines
  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Signed-off-by: Phuong Nguyen <phuonguyen@nvidia.com>
recv_tokens, recv_topk_weights = tex.ep_dispatch_fwd(
cfg, handle_mem, topk_idx, tokens, topk_weights, recv_capacity_per_rank
)
out_leading = tuple(tokens.shape[:-1])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1Positional return contracts break

Existing callers that unpack the documented two-value ep_prepare, four-value ep_dispatch, or two-value MoE results now receive an additional positional value unconditionally, causing ValueError: too many values to unpack even when overflow dropping is disabled.

Knowledge Base Used:JAX Fused Layers: Functions and Flax Modules

@greptile-apps

greptile-appsBot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds optional expert-parallel overflow dropping and exposes each rank’s pre-drop receive demand.

  • Plumbs drop_on_overflow through JAX bootstrap, pybind, and the native EP configuration.
  • Adds total_recv_tokens outputs to EP prepare/dispatch and fused MoE interfaces.
  • Adds EP communicator finalization and re-bootstrap support.
  • Extends distributed tests and examples for overflow handling and the new metadata.

Confidence Score: 4/5

The PR is not yet safe to merge because its public EP and MoE functions still unconditionally change positional return arities and break existing unpacking callers.

Existing callers written against the previous ep_prepare, ep_dispatch, moe, or Flax MoE tuple contracts receive additional values even when overflow dropping is disabled, producing runtime unpacking failures; the previously reported compatibility issue remains in the current code.

Files Needing Attention: transformer_engine/jax/ep.py, transformer_engine/jax/moe.py, transformer_engine/jax/flax/moe.py

Important Files Changed

FilenameOverview
transformer_engine/jax/ep.pyAdds overflow policy plumbing, receive-demand reporting, and explicit EP teardown.
transformer_engine/jax/cpp_extensions/ep.pyExtends the EP prepare primitive with a sharded total_recv_tokens result and adds cached-config reset support.
transformer_engine/jax/csrc/extensions/ep.cppPasses the overflow policy into native initialization and returns pre-drop receive totals through the FFI handler.
transformer_engine/jax/moe.pyPropagates total_recv_tokens through the fused MoE custom-VJP forward result while discarding its cotangent.
transformer_engine/jax/flax/moe.pyExposes the receive-demand metadata through the Flax MoE block.
tests/jax/test_multi_process_ep.pyAdds multi-process coverage for overflow dropping, demand reporting, finalization, and re-bootstrap.

Sequence Diagram

sequenceDiagram
participant User
participant JAX as JAX EP/MoE API
participant FFI as JAX FFI
participant EP as Native EP communicator
User->>JAX: ep_bootstrap(drop_on_overflow)
JAX->>FFI: set bootstrap parameters
FFI->>EP: initialize communicator and buffers
User->>JAX: ep_prepare / ep_dispatch
JAX->>FFI: routing metadata and tensors
FFI->>EP: prepare and dispatch
EP-->>FFI: routed tensors and pre-drop demand
FFI-->>JAX: total_recv_tokens
JAX-->>User: outputs plus overflow signal
User->>JAX: ep_finalize()
JAX->>EP: release resources
Loading

Reviews (3): Last reviewed commit: "Merge branch 'main' into ep-jax-overflow" | Re-trigger Greptile

@phu0ngngphu0ngng changed the title [JAX] EP with overflow detection option[JAX] EP Dispatch with overflow detection optionJul 29, 2026
"""Exchange routing metadata for ``cfg``; return ``(token_counts, handle_mem)``."""
"""Exchange routing metadata for ``cfg``; return
``(token_counts, total_recv_tokens, handle_mem)``. ``total_recv_tokens`` is
the per-rank pre-drop recv-slot total (includes tokens dropped on overflow)."""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When drop-on-overflow aka overflow-detection is disabled, this will now return a "trt" tensor that has an uninitialized value, right? Can we instead update this so ep_prepare will return (token_counts, None, handle_mem) instead when drop-on-overflow=False?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it actually has the total_recv_tokens value i.e., the sum of token_counts.

The only difference here is that when drop-on-overflow=False (which is the default), as soon as there is an overflow, the kernel will trap and the program will crash.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, then the current implementation looks good. The PR LGTM once CI passes

@phu0ngng

Copy link
Copy Markdown
CollaboratorAuthor

/te-ci L1 JAX

@phu0ngng
phu0ngng merged commit 72f4e23 into NVIDIA:mainAug 4, 2026
9 of 14 checks passed
@phu0ngng
phu0ngng deleted the ep-jax-overflow branch August 4, 2026 01:00
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@phu0ngng@jberchtold-nvidia