fix(plugin): gate dual-stream MoE by runtime graph mode - #1791
fix(plugin): gate dual-stream MoE by runtime graph mode#1791XiaobingSuper wants to merge 2 commits into
Conversation
Use the frontend's per-forward graph decision so FULL decode can retain overlap while PIECEWISE capture remains safely single-stream. Co-authored-by: Cursor <cursoragent@cursor.com>
🏷️ CI GuideRuns automatically on every eligible PR before approval:
Heavy model tests:
|
There was a problem hiding this comment.
Pull request overview
This PR fixes dual-stream MoE gating in vLLM plugin mode by switching from ATOM’s static compilation config to the per-forward runtime cudagraph mode selected by the active frontend (vLLM or native ATOM). This ensures decode forwards that vLLM runs under FULL capture are not incorrectly forced onto the single-stream MoE path when ATOM is configured with composite cudagraph modes (e.g., FULL_AND_PIECEWISE).
Changes:
- Add a frontend-aware helper (
get_current_cudagraph_runtime_mode) that resolves the concrete runtime graph mode by normalizing enum values by name (NONE/PIECEWISE/FULL), with safe fallback to native ATOM context and defaulting unknown/unavailable toNONE. - Update dual-stream MoE dispatch gating to disable dual-stream only for actual
PIECEWISEruntime forwards (allowing eager/NONE and whole-model FULL capture).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| atom/utils/forward_context.py | Adds normalization + runtime-mode resolution across vLLM/native forward contexts, defaulting to NONE when unavailable/unknown. |
| atom/model_ops/module_dispatch_ops.py | Switches dual-stream MoE safety gating from static compilation cudagraph config to concrete per-forward runtime mode (disables only for PIECEWISE). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Match the repository's Ruff import ordering rules. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (1)
atom/utils/forward_context.py:651
- New runtime-mode normalization + vLLM fallback logic is now gating dual-stream MoE behavior, but there’s no regression test covering the key cases (vLLM context present with NONE/PIECEWISE/FULL by name, context unavailable, and composite modes being rejected). This is easy to regress and would silently flip MoE dispatch decisions in plugin mode.
def get_current_cudagraph_runtime_mode() -> CUDAGraphMode:
"""Return the concrete graph mode for the active model forward.
In vLLM plugin mode graph capture/replay is owned by vLLM, so its forward
context is authoritative. Native ATOM records the same decision on its
own ForwardContext. An unavailable/unknown context is treated as NONE:
eager dual-stream execution is valid, and some vLLM runners expose NONE
while a whole-model FULL graph is being captured. Replay does not execute
this Python dispatcher.
"""
from atom.plugin import is_vllm
if is_vllm():
try:
from vllm.forward_context import (
get_forward_context as get_vllm_forward_context,
)
from vllm.forward_context import (
is_forward_context_available,
)
if is_forward_context_available():
mode = _normalize_cudagraph_runtime_mode(
get_vllm_forward_context().cudagraph_runtime_mode
)
if mode is not None:
return mode
except (ImportError, AttributeError, AssertionError):
pass
mode = _normalize_cudagraph_runtime_mode(
getattr(get_forward_context(), "cudagraph_runtime_mode", None)
)
return mode if mode is not None else CUDAGraphMode.NONE
Problem
In vLLM plugin mode, CUDA/HIP graph capture is owned by vLLM and the concrete runtime mode is selected per forward (
FULL,PIECEWISE, orNONE). ATOM's MoE dispatcher instead checks its static compilation config.For
FULL_AND_PIECEWISE, the plugin maps vLLM's compile mode to ATOM level 3, which initializes the ATOM-side static graph mode asPIECEWISE. As a result, decode forwards that vLLM actually dispatches asFULLare incorrectly forced onto the single-stream MoE path. This was observed while validating Kimi-K3 dual-stream shared/routed expert overlap in #1752.Solution
PIECEWISEforward; preserve it for eager/NONEand whole-modelFULLcapture.Validation
FULL_DECODE_ONLYandFULL_AND_PIECEWISE