Repository navigation
[Perf] mamba: write the deduplicated conv verify window as one tile - #46184
Merged
Merged
Conversation
Co-authored-by: Zihan Zhang <tiancaizhangdaxian@sjtu.edu.cn>
jianc99
requested review from
BBuf,
DarkSharpness,
HaiShaw,
HydraQYH,
Ying1123,
alphabetc1,
celve,
hanming-lu,
hnyls2002,
huangtingwei9988,
hzh0425,
ispobock,
merrymercy,
xiezhq-hermann,
yizhang2077 and
yuan-luo
as code owners
October 24, 2026 00:14
This was referenced Oct 24, 2026
Qiaolin-Yu
approved these changes
Oct 26, 2026
Qiaolin-Yu
enabled auto-merge (squash)
October 29, 2026 21:14
Qiaolin-Yu
disabled auto-merge
October 29, 2026 21:14
Yuxingwang-intel
pushed a commit
to Yuxingwang-intel/sglang
that referenced
this pull request
Nov 6, 2026
…gl-project#46184) Co-authored-by: Jian Chen <jic188@ucsd.edu> Co-authored-by: Zihan Zhang <tiancaizhangdaxian@sjtu.edu.cn>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is component 1 of the DFlash adaptive-verification series. Original implementation and component-only review: jianc99#1. Integration and full-system results: #46182.
Updated onto upstream
main(6a319e7). All applicable pre-commit checks passed on this branch. The GPU tests and benchmark results below were run previously on the original source branch; they have not been rerun after this upstream update. Submission preparation used AI assistance.Motivation
On hybrid models, linear-chain speculative verify (EAGLE chain, MTP, DFLASH, DSPARK, standalone) calls
causal_conv1d_updatewith an intermediate conv window. The window lets the conv state of the accepted prefix be restored after verify.On CUDA and ROCm,
MambaPoolstores this window deduplicated. Each slot holds one[dim, T + K - 2]row, exposed as an overlapping[T, dim, K - 1]view whose step stride equals its window stride.The kernel still writes the window per token, with three lane-strided element stores per draft token. Each column is therefore written up to three times by narrow scattered stores. On GB300 (dim 10240, bf16, T = 8, bs 128), the verify conv takes 106 us with the deduplicated window, against 39 us with a dense window.
Modifications
_causal_conv1d_update_kernel: adds aDEDUP_CONV_WINDOWpath.[state[1], state[2], x_0, ..., x_{T-1}].[BLOCK_N, next_pow2(T + 2)]tile before the token loop, and skips the per-token window stores.tl.static_asserts keep the branch from being compiled for a conv width other than 4 or together with a tree mask, so the kernel is safe without relying on its caller.causal_conv1d_update: takes the tile path only when all three hold:With step stride == window stride == s, the per-token stores write column t + w of the row at (t + w) * s, and the tile writes column c at c * s: the same addresses and the same values, for any layout with those strides. MambaPool's deduplicated view is one such layout. There are no new arguments, and callers are unchanged. Kernels that do not take the tile get
NP2_WINDOW_COLS=1, so no extra variants are compiled.Test:
test_causal_conv1d_update_dedup_window_matches_per_token.num_accept_tokensstate offset, MambaPool's axis-0 window layout seen transposed, fp32 and bf16, a dim that leaves a partial channel block, with and without padded rows.A comment in
MambaPoolis updated to describe the new write.Scope
This path is used by every chain verify (topk <= 1) whose conv window uses
MambaPool's deduplicated layout. Examples are GDN models (Qwen3.5/3.8) and Mamba2, on CUDA and ROCm.These are unchanged and keep the per-token stores:
UnifiedMambaPool, KDA / Kimi-Linear, tree verify;Accuracy Tests
num_accept_tokensfails exactly the accept-offset cases, and forcing the tile together with a tree mask fails at compile time on the new assert.NP2_WINDOW_COLS=1for launches without the tile. The extra 72-case check below, which covers accepted-token offsets, transposed views and odd T, is also memcheck-clean.Benchmarking and Profiling
Kernel time per call in microseconds (GB300, dim 10240, K 4, bf16, CUDA graph):
End-to-end setup:
--max-running-requests 128;Decode tok/s = per-request decode rate (output tokens after the first / time after the first token), times concurrency; c1 is the single-request decode rate.
Acceptance length is 3.59-3.63 in all six runs.
At c128 the running cap equals the concurrency, so about one request waits in the queue. #46182 shows that this setup reads 7-15% higher at that level than a larger cap, on both sides, so compare c128 only within this table.
Single runs at lower concurrency: c8 2031 -> 2104 (+3.6%), c32 4723 -> 4973 (+5.3%). At c1 the change is within noise: 332 -> 321, with acceptance length 3.70 vs 3.60 from sampling; per accepted token the rate differs by under 0.5%. Greedy (single runs): c1 357.0 -> 357.1 with identical acceptance length and output tokens, c64 6746 -> 7145 (+5.9%).
The end-to-end runs used the first commit; the two later commits add compile-time asserts, comments and tests, and pass
NP2_WINDOW_COLS=1to kernels that skip the tile, with no runtime change on the tile path.Related upstream work
causal_conv1d_update_varlen, to the same file. It writes the intermediate window per token with three stores per step, the pattern this PR replaces. There is no textual conflict (it is a new function), but if both land, packed verify through that kernel does not get the tile store. [Feat] gdn: run target verify on packed ragged tokens (ReplaySSM) #46189 takes the other route: it adds packed rows to this kernel, so the tile store covers them too.Notes
MambaPoolcomment), 8eb01f2 (tree-mask assert, stride-based wrapper comment,NP2_WINDOW_COLS=1when the tile is off, more test layouts). Squash them when merging upstream.CI States
Latest PR Test (Base): ✅ Run #40568730789
Latest PR Test (Extra): ❌ Run #40568730891
Latest PR Test (AMD ROCm 10): ❌ Run #40568730701