Repository navigation
Conversation
With the FlashInfer SSU backend and Mamba cache stochastic rounding, FlashInferSSUBackend draws a seed with torch.randint(0, 2**32, (1,)) right before every SSU kernel, a small non-overlapped kernel on the critical path of every Mamba-2 layer. Add VLLM_MAMBA_SR_SEED_PREFETCH (default off). When set, the first SSU call of a forward pass forks a dedicated side stream with a CUDA event and issues the same num_layers randint calls there, recording one event per seed; the k-th SSU call of the forward waits on event k and uses seed k. The generator state advances on the host in the same call order, so the seed values are identical to stock. Forward passes are told apart by ForwardContext; calls beyond num_layers, outside a forward context or under DBO draw inline. Disabled for ReplaySSM, Mamba-1 models and non-CUDA platforms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks. It doesn't change the randomness: the seeds are the same Reworked locally as you suggested: the Mamba-2 metadata builder draws them once per step into a persistent buffer (stable address for graph replay), on the current stream, with no side stream and no events. The metadata carries per-layer views that the FlashInfer, Triton and ReplaySSM paths take as |
|
Dropping this one: after moving the draws into the metadata build (no events), the remaining gain is within noise (about -0.7 % per verify iteration), so it isn't worth the added complexity. Thanks for the review. |
Overview
Opt-in
VLLM_MAMBA_SR_SEED_PREFETCH=1(default off): with the FlashInfer Mamba SSU backend and--enable-mamba-cache-stochastic-rounding, draw a forward pass's per-layer stochastic-rounding seeds up front on a side CUDA stream; each SSU call waits on an event for its seed. Seed values are identical to stock.Claims
torch.randint, ~2.5 µs, non-PDL) per Mamba-2 layer from the critical path of every decode step, between conv1d and the SSU kernel.Validation
Validated on this commit: the
vllm/vllm-openai:cu129-nightly-ac9126e58...image with this branch'svllm/files overlaid read-only. The image's installed files for every touched path were first verified byte-identical toac9126e58. Earlier validation on v0.30.0 is in pst2154#2. The port ontoac9126e58only needed a textual conflict resolution next to the new ReplaySSM commit helper; the non-ReplaySSM SSU call path (FlashInferSSUBackend.__call__, one call per Mamba-2 layer per decode forward) is unchanged.pytest -v tests/kernels/mamba/test_sr_seed_prefetch.py(1x B200): 4 passed. In serving, the one-time linePrefetching Mamba stochastic-rounding seeds for 40 layers per forward on a side stream.appeared.End to end on this commit, all five related drafts (#59726, #59727, #59728, #59729, #59730) enabled together vs stock. Nemotron-H (hybrid Mamba-2 / latent-MoE, NVFP4) with MTP (7 draft tokens), TP4 on 4x B200, FP8 KV cache, MRV2, async scheduling, prefix caching, FlashInfer Mamba backend with stochastic rounding. Streaming chat at concurrency 1, 10 requests with ~10k-token prompts, temperature 1, top_p 0.95. Each arm used a fresh server, with arms interleaved on one node. Both arms set
CUDA_SELECTIVE_DEVICE_CODE_RECOMPILE=FORCED, because without it the installed driver runtime-patches the image's Blackwell kernels and skews timings. Time per verify iteration = sum(request latency - TTFT) / sum(streamed chunks), one chunk per verify iteration, so it does not depend on acceptance.--speculative_config.moe_backend flashinfer_trtllm--speculative_config.moe_backend flashinfer_trtllmAL comes from the server's spec-decode metrics over the measured window. At temperature 1 it varies by several percent between runs, and tok/s/user and ITL x AL inherit that noise, so read the per-iteration time. The drafter MoE flag is not part of these PRs; it changes draft numerics, and AL was lower with it in these runs. The changes were not measured one at a time on this commit.
Server command
Stock:
vllm serve <Nemotron-H NVFP4 checkpoint with MTP head, FP8 KV in its config> --tensor-parallel-size 4 --moe-backend auto --max-num-seqs 512 --max-model-len 262144 --max-num-batched-tokens 10240 --enable-prefix-caching --async-scheduling --speculative_config.method mtp --speculative_config.num_speculative_tokens 7 --speculative_config.moe_backend flashinfer_cutlass --mamba-backend flashinfer --mamba-ssm-cache-dtype float16 --enable-mamba-cache-stochastic-rounding --mamba-cache-philox-rounds 5 --mamba-cache-mode align. The PR arms addVLLM_NEMOTRON_H_MOE_ROUTER_OVERLAP=1 VLLM_MAMBA_SR_SEED_PREFETCH=1 VLLM_CUSTOM_ALL_GATHER_SMALL=1 VLLM_MAMBA_FUSED_STATE_INDEX=1and--speculative_config.use_local_argmax_reduction true.Earlier, on v0.30.0 (1x B200):
Eager (with and without extra calls beyond N), CUDA-graph capture + 3 replays (identical to stock, fresh values per replay), fallback outside a forward context. In serving, the one-time log line
Prefetching Mamba stochastic-rounding seeds for 40 layers per forward on a side stream.appeared (40 = the model's Mamba-2 layers).No model eval: seeds, and therefore outputs, are unchanged.
Details
StochasticRoundingSeedPrefetcherinssu_dispatch.py. The first SSU call of a forward records_fork_eventon the current stream, makes a dedicated side stream wait on it and issues the samenum_layersrandintcalls (same shape, dtype, device, order) there, recording_events[k]after the k-th. The k-th SSU call waits on_events[k]and uses seed k. The CUDA generator's (seed, offset) advances on the host in call order, so seed k equals the stock k-th draw. Forwards are told apart byForwardContextidentity.num_layers= Mamba-2 layers in the KV cache config._fork_eventrecorded once all consumers of the previous seeds were enqueued.ForwardContextidentity vs an explicit per-forward reset hook from the model runner.gh pr list --repo vllm-project/vllm --state open --search "stochastic rounding seed"-> [Mamba] Support quantized FlashInfer ReplaySSM state cache #52962, INT16/FP8/INT8 + SR SSM Cache Support #40012, [Spec Decode] Verify in head dtype and drop the FP32 chunk workaround #53630, [Feature][Mamba] Support batch-invariant Mamba2 prefill and recovery #54993, [Kernel] ReplaySSM: cache SSM inputs for faster Gated DeltaNet standard decode #48792, [Kernel] ReplaySSM: cache SSM inputs for faster Gated DeltaNet speculative decode #49887, [Bugfix] Bound accepted-token state lookups in GDN/KDA spec decode #50021 (SSM cache quantization / ReplaySSM / batch-invariance work; none moves the seed draw);--search "mamba stochastic rounding"-> the same set plus [Mamba] Unify FI ReplaySSM STP/MTP/Prefix Caching Lifecycle #55688, [Kernel] ReplaySSM: cache SSM inputs for faster Mamba2 speculative decode #49847, Gdn ucache backend #50380, [Perf][MoE] Eliminate staging from NCCL symmetric reduce-scatter #49194 (unrelated to the seed draw);--search "ssu seed prefetch"-> no results. No open PR implements this change.AI assistance: Claude Code was used to port this change, write the tests, run the validation and draft this description. The human submitter reviews every changed line before this leaves draft.
Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.
🤖 Generated with Claude Code