Repository navigation
[CUDA] Optimize Qwen3.8-Flash-Next DSA, Indexer, HC, and QMoE kernels for SM12x and 256K context - #33802
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical issues can discard valid top-k candidates, admit stale workspace data, and break builds targeting pre-SM70 GPUs and tests on SM90.
5 open issues
Update GEMV launch-configuration expectations and test table · New Initialize the full suffix for noncompact top-k mode · New Round up active chunk boundary to prevent sentinel/live-key overlap · New Guard __match_any_sync for targets below SM70 · New Use runtime tensor capacity when validating reuse · New
What changed in this PR
This PR builds on #33786 to optimize ONNX Runtime’s CUDA kernels for Qwen3.8-Flash-Next, targeting SM12x GPUs and contexts up to 256K tokens.
Changes:
- Enables INT8 tensor-core sparse attention by default and adds a lower-shared-memory pipeline.
- Optimizes sparse-indexer scoring and top-k selection, while allowing runtime-sized caches.
- Tunes HyperConnection and quantized MoE kernel dispatch, buffering, and prefetching.
| File | Description |
|---|---|
onnxruntime/contrib_ops/cuda/sparse/packed_sparse_attention_indexer.cc |
Allows runtime cache capacities in QSA and CSA refresh paths. |
onnxruntime/contrib_ops/cuda/sparse/packed_sparse_attention_indexer_impl.cu |
Tiles query scoring and optimizes top-k initialization, histograms, and merging. |
onnxruntime/contrib_ops/cuda/moe/qmoe_kernels.cu |
Makes scalar fallback launch-grid conversions explicit. |
onnxruntime/contrib_ops/cuda/moe/qmoe_int3_tc.cuh |
Enables FC2 remainder prefetch and adjusts kernel configurations. |
onnxruntime/contrib_ops/cuda/llm/moe_gemm/moe_gemv_tc.cuh |
Specializes small-route discovery and widens eligible INT2 FC2 tiles. |
onnxruntime/contrib_ops/cuda/llm/fpA_intB_gemv/int8_tc_gemv.cuh |
Simplifies load addressing and retunes INT8 GEMV dispatch. |
onnxruntime/contrib_ops/cuda/bert/hyper_connection_low_rank_mix_impl.cu |
Reduces shared-memory weight slots on selected architectures. |
onnxruntime/contrib_ops/cuda/bert/dynamic_sparse_attention.cc |
Enables INT8 tensor-core prefill and decode by default. |
onnxruntime/contrib_ops/cuda/bert/dynamic_sparse_attention_prefill_int8.cuh |
Adds a two-buffer shared-memory attention pipeline. |
onnxruntime/contrib_ops/cuda/bert/dynamic_sparse_attention_impl.cu |
Selects and launches attention variants based on shared-memory capacity. |
onnxruntime/contrib_ops/cpu/bert/dynamic_sparse_attention_helper.h |
Clamps total sequence length to the bound past-cache capacity. |
Review effort: Balanced
…g and top-k - Tile 8 query tokens per CTA in QsaRaggedPrefillScoreKernel<T, TState, true> (4 in registers + 4 in shared memory) with a bit-exact 19-shuffle 16-head butterfly reduction, cutting present_key_state DRAM traffic by 2x and speeding up 128K prefill scoring by 1.96x (11.67s -> 5.94s on RTX Spark SM121). - Avoid zero-filling inactive 2048-key chunks in QsaScoreTileTopKKernel beyond element-0 sentinels, eliminating the 256K state_capacity padding overhead on short/medium chunks. - Use warp-level __match_any_sync aggregation for radix histogram updates in QsaPartialTopKKernel and extend single-launch QsaFinalMergeAndEmitKernel up to 64 chunks (256K context). - Allow runtime past_key_state / past_key capacities configured via dynamic_batching / runtime_profiles to differ from static node attributes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tianlei Wu (tianleiwu)
force-pushed
the
tlwu/qfn_rtx_spark_opt
branch
from
November 2, 2026 23:08
39b1a55 to
6985510
Compare
- Put the non-WarpHeads token loop in the else branch of QsaRaggedPrefillScoreKernel (fixes "loop is not reachable" nvcc error that broke the CUDA CI builds). - Round up the first inactive 2048-key chunk so sentinels never overwrite live keys. - Initialize the whole key suffix when ORT_PACKED_SPARSE_INDEXER_COMPACT_TOPK=0. - Guard __match_any_sync for SM70+ and fall back to per-thread atomicAdd. - Use the runtime past_key_state capacity in ComputeReuse. - Update INT8 tensor-core GEMV launch-configuration tests and comments for the new dispatch branches; drop the always-false waves(7) < waves(8) check. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Akshay Sonawane (apsonawane)
approved these changes
Nov 3, 2026
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.


Summary
Stacked on #33786 ( lwu/20261031/qmoe-cuda-int2-tc).
This PR optimizes CUDA prefill and decode kernels for Qwen3.8-Flash-Next (RC5) on Blackwell SM 12.x (100 KB shared memory/SM, RTX Spark N1X) from short/medium contexts (2K–32K) up to 256K (262,144) context length:
untime_profiles.
untime_profiles.
Validation