Repository navigation
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…FromProb FlashInfer 0.7.3 (flashinfer-ai/flashinfer#5352) added an int& last_valid_index parameter to flashinfer::sampling::DeviceSamplingFromProb, so the JIT tree speculative sampling kernel no longer compiled and EAGLE verify crashed the scheduler. Keep the per-thread candidate across the scan, as FlashInfer's own chain speculative sampling kernel now does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
|
Hi @leejnau , could you rename the backend name to |
|
Thanks @bobboli. I'd like to keep this PR to the FlashInfer 0.7.3 bump and the changes 0.7.3 requires, so that it stays easy to review and revert. As @trevor-m noted on #46885, renaming the backend everywhere touches 40+ files. A smaller way to get the name you suggested: accept |
Yes, that's the best way. Feel free to do it in the follow up PR. Thanks! |
nvpohanh
left a comment
There was a problem hiding this comment.
[by Claude Code] This review is done by agents. Please feel free to disagree if they do not make sense.
| # FlashInfer's host-side workspace metadata must stay on the CPU even | ||
| # when layers are built under a CUDA default-device context. | ||
| with torch.device("cpu"): | ||
| return create_communication(bootstrap, params, backend=a2a_config) |
There was a problem hiding this comment.
[by Claude Code] Severity: functional | Confidence: High
Issue
test/manual/ep/test_flashinfer_dispatcher.py still uses the removed MoeAlltoAll API, and this migration breaks it. Instances built here share one workspace when their geometry matches, and FlashInfer 0.7.3's check_round_owner rejects a dispatch while another instance on that workspace has not called combine. Each manual test calls dispatcher.dispatch() but never combine(). Its cleanup helpers import flashinfer.comm.trtllm_moe_alltoall, catch the ImportError, and do nothing.
Example
With torchrun --nproc_per_node=4 test_flashinfer_dispatcher.py, test_dispatch_basic leaves its round open, so test_dispatch_with_empty_tokens raises "another NVLinkOneSidedAlltoAll sharing this workspace has a dispatch awaiting its combine".
Fix
End each test with dispatcher.combine(...) or dispatcher.moe_a2a.destroy(), and port _zero_moe_a2a_dispatch_payloads and tearDownClass to the new API.
There was a problem hiding this comment.
Thanks. This is right, and it's tracked in #48506 along with a second problem in the same test. Its global_num_tokens layout doesn't match the dispatcher's sizing rules for its plain TP4 setup.
This PR doesn't make the test worse than main. On main with 0.7.2, all 5 tests already error while the dispatcher is built (num_fused_shared_experts=None in the fallback MoeRunnerConfig, which #46885's commit here fixes). On this PR test_dispatch_basic passes and the other 4 fail as you describe.
It's a manual test that CI doesn't run, and fixing it means porting the cleanup helpers to moe_ep and adding combine() or destroy() to each test. So I'd rather keep it out of the FlashInfer bump and fix it in a follow-up under #48506.
There was a problem hiding this comment.
I think it will be OK if we are not moving the affected test to CI test
…shInfer 0.7.3 FlashInfer 0.7.3 appends a fixed_uniform_q_len argument to the FA2 paged prefill planner, so fast_prefill_plan's 20-argument call fails with "Expected 21 but got 20 arguments" on the first EAGLE verify or draft-extend CUDA graph replay. Also clear _eagle_verify_fp8kv_sm90_state, as 0.7.3's plan() does on every call, so run() never launches the SM90 fp8-KV verify kernel with state from an earlier plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lashInfer 0.7.3 does flashinfer-ai/flashinfer#6996 (in 0.7.3) changed nvfp4_kv_quantize to guard the rounded E4M3 scale instead of the block amax, so a block whose scale underflows to zero now stores an all-zero payload instead of a saturated one. The fused MiniMax-M3.1 KV store reproduces that quantizer bit for bit, so make the same change; test_fused_store_matches_separate_stores failed on its _tiny case. Dequantized values are unchanged: a zero scale reads back as zero either way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ic mode FlashInfer 0.7.2.post1 and 0.7.3 added a small-batch MoE finalize kernel that adds the top-k expert outputs in a different order from the large-batch kernel (flashinfer-ai/flashinfer#8831). A token's output then depends on its batch size, so prefill and decode logprobs no longer match. Under --enable-deterministic-inference, the pre-routed NVFP4 path now asks FlashInfer for the unsummed outputs and sums them with moe_finalize_fuse_shared, which adds them in the same order at every batch size. It writes into the usual output buffer through a new out= argument. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…shed Kernel tests such as test_minimax_m31_nvfp4_trtllm_moe.py call the trtllm NVFP4 MoE runner without publishing the server's runtime config, so get_exec() raised. Check that the exec namespace exists first, as vision.py does, and treat a missing config as deterministic mode off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Motivation
This PR bumps FlashInfer to 0.7.3. It also brings in @trevor-m's migration of the NVLink one-sided all-to-all to
flashinfer.moe_epfrom #46885, because neither change can land without the other:flashinfer.comm.MoeAlltoAllandmoe_a2a_get_workspace_size_per_rank, which the currentFlashinferDispatcheruses (feat(moe_ep)!: sync NVLinkOneSidedAlltoAll with TensorRT-LLM's kernels; remove the deprecated MoeAlltoAll/MnnvlMoe flashinfer-ai/flashinfer#6047, [Feature] support add custom middlewares #6621).runtime_max_tokens_per_ranktoflashinfer.moe_ep, and that argument only exists from 0.7.3. In 0.7.2 it ismax_tokens_per_rank.#46926 (0.7.2.post1) stays open for now as a fallback.
Depends on
deepseek_v4_trtllm_backend.pypatchesflashinfer.mla._core._get_trtllm_gen_multi_ctas_kv_counter_buffer. 0.7.3 no longer has that name, so--dsv4-attn-backend trtllmfails at init. [Fix] [NVIDIA] deepseek-v4: Pass a caller-owned multi-CTA counter buffer to the trtllm sparse MLA kernel #48467 works on 0.7.2 and 0.7.3, so it can merge first.Modifications
NVLinkOneSidedAllToAllto theflashinfer.moe_epAPI.runtime_max_tokens_per_rankin dispatch.last_valid_indexargument toflashinfer::sampling::DeviceSamplingFromProbin SGLang's JIT tree speculative-sampling kernel (sgl_kernel/speculative/sampling.cuh). perf(sampling): defer last-valid-index reduction until fallback flashinfer-ai/flashinfer#5352 (in 0.7.3) added that parameter. Without this change the kernel fails to compile, and the first EAGLE verify step crashes the scheduler. The change mirrors FlashInfer's own chain speculative-sampling kernel, and it only compiles against 0.7.3 headers, so it has to land with the bump.fixed_uniform_q_lenargument in the FlashInfer backend'sfast_prefill_plan. FlashInfer 0.7.3's FA2 paged-prefillplan()takes 21 arguments instead of 20. The fast plan also clears_eagle_verify_fp8kv_sm90_state, as FlashInfer's ownplan()now does on every call.amax != 0tosf != 0).--enable-deterministic-inference, the pre-routed NVFP4 trtllm MoE path now calls FlashInfer withdo_finalize=Falseand sums the outputs with SGLang'smoe_finalize_fuse_shared, which uses one order at every batch size.moe_finalize_fuse_sharedgains anout=argument so the sum lands in the usual output buffer. Nothing changes outside deterministic mode. Remove this once [Bugfix] Fixing the bug when max_new_tokens is None. #8831 is fixed in a FlashInfer release.docker/Dockerfile,docker/Dockerfile.cu134,python/pyproject.tomland theengine.pyversion check.0.7.3 requires
nvidia-cutlass-dsl[cu13]>=4.8.0, and SGLang already pins 4.8.0.Tests
CI. The first run is expected to hit the cold SGLang JIT cache in the jit-kernel suite, as on earlier FlashInfer bumps.
On GB200, [Fix] [NVIDIA] deepseek-v4: Pass a caller-owned multi-CTA counter buffer to the trtllm sparse MLA kernel #48467's DeepSeek-V4 trtllm prefill test passes on 0.7.3 with the fix, and fails without it.
On GB200 with FlashInfer 0.7.3,
test/registered/kernels/ops/speculative/test_speculative_sampling.pypasses (11 passed).TestInklingSmallNvfp4DsparkDeterministic.test_input_output_logprobs_match(KL threshold 1e-9) on GB200, with the test's--tpchanged from 4 to 2 (GB200 at TP=4 fails even on main with 0.7.2):@trevor-m validated the
moe_epmigration on 0.7.3 on 4×GB200 (see [Chore] flashinfer: Use flashinfer moe-ep API instead of deprecated NVLinkOneSidedAllToAll API #46885): GSM8K 96%, andtest_flashinfer_a2a_wide_ep.py,test_flashinfer_dispatcher.pyandtest_muse_spark_runner_dispatch.pypassed.End-to-end on one 4×GB200 node: DeepSeek-V4-Flash with the cookbook's verified GB200 low-latency recipe (TP=4,
flashinfer_mxfp4MoE, EAGLE with 3 steps and 4 draft tokens) plus--dsv4-attn-backend trtllm, imagelmsysorg/sglang:dev(arm64). Full GSM8K (1319 questions) through sgl-eval 0.1.3 at temperature 1.0 and top_p 1.0, the cookbook's recommended sampling:Before the speculative-sampling fix, the 0.7.3 run scored 0%, because every request failed when the scheduler crashed on the JIT build error.
🤖 Generated with Claude Code
CI States
Latest PR Test (Base): ⏳ Run #42122889789
Latest PR Test (Extra): ⏳ Run #42122889726
Latest PR Test (AMD ROCm 10): ⏳ Run #42122889643
Tip
Base CI only covers the core cases, and its workload may not exercise your change. Use
/rerun-testto run the tests your change touches, or copy this prompt for an agent: