[Bugfix] DeepEP-V2: expert_tokens_meta must be None on the decode/cudagraph path (empty recv_expert_num_tokens) (#52632)
Signed-off-by: Anton Alexander <dmvevents@gmail.com> Signed-off-by: Roger Wang <hey@rogerw.io> Co-authored-by: Roger Wang <hey@rogerw.io>
Anton A committed
Aug 20, 2026 at 04:11 UTC
14617c2b6c1257ac0d6c7b5e05b195ca30013827
1 file changed
+13
-4
vllm/model_executor/layers/fused_moe/prepare_finalize/deepep_v2.py
+13
-4
@@ -210,14 +210,23 @@ class DeepEPV2PrepareAndFinalize(mk.FusedMoEPrepareAndFinalizeModular):
210
else:
211
expert_x, expert_x_scale = recv_x, None
212
213
- expert_tokens_meta = mk.ExpertTokensMetadata.make_from_list(
214
- recv_expert_num_tokens,
215
- device=expert_x.device,
216
- )
213
+ if recv_expert_num_tokens:
214
+ expert_tokens_meta = mk.ExpertTokensMetadata.make_from_list(
215
+ recv_expert_num_tokens,
216
+ device=expert_x.device,
217
+ )
218
+ else:
219
+ # Decode/cudagraph path (do_cpu_sync=False) skips the CPU sync and
220
+ # leaves recv_expert_num_tokens empty. A present-but-empty
221
+ # ExpertTokensMetadata violates the decode-mode contract above
222
+ # (expert_tokens_meta must be None) and crashes DeepEP combine
223
+ # during profile_run when CUDA graphs are enabled.
224
+ expert_tokens_meta = None
225
226
if recv_topk_idx is None:
227
# do_expand=True (prefill mode): build topk_ids from
228
# per-expert token counts.
229
+ assert expert_tokens_meta is not None
230
total_tokens = sum(recv_expert_num_tokens)
231
if total_tokens > 0:
232
recv_topk_idx = torch.repeat_interleave(