Skip to content

[DeepSeek-V4.1] DeepSelect cluster top-k for long rows and bf16 index logits - #44051

Merged
BBuf merged 2 commits into
sgl-project:mainfrom
DarkSharpness:deepselect-cluster-select
Oct 15, 2026
Merged

BBuf merged 2 commits into
sgl-project:mainfrom
DarkSharpness:deepselect-cluster-select

Conversation

@DarkSharpness

@DarkSharpness DarkSharpness commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

(auto generated by Claude)

Speeds up DeepSelect top-k for small-batch, long-context decode (the DeepSeek-V4.1 indexer case) and lets the V4.1 index layers run on bf16 scores.

DeepSelect cluster kernel (bf16, topk <= 1024)

  • Rewritten cluster kernel: each CTA takes a contiguous slice of the row; a slice of up to 32K stays in registers, a longer one streams through a bulk-copy ring behind a cluster-wide pivot taken from a window (three pseudo-random stages plus the slice's tail). The cluster agrees on the final pivot by pushing 256-bin histograms to every CTA, then writes its output directly (DSMEM atomics for unsorted, a bitmap prefix for sorted_index).
  • Dispatch keys only on the row count, never on the (CUDA-graph padded) width: cluster sizes 16/8/4/3/2 are tiered by an occupancy probe of how many clusters fit in one wave; the per-row end decides everything else inside the kernel.
  • All modules of a call signature are compiled in parallel (parallel_compile in the JIT utils).
  • Without abort, a NaN row now selects index 0 in every slot instead of writing a 0x3F3F3F3F sentinel to slot 0; return_value and abort_when_nan_found default to False.

DeepSeek-V4.1 indexer

  • SGLANG_OPT_DSV41_BF16_INDEX_LOGITS (default off): the DeepGEMM fp4 MQA logits are emitted in bf16 (the reference ranks bf16 scores), their top-k goes through DeepSelect, and amax8_varlen reads bf16 scores (now templated on input/output dtype).

Kernel latency (B200, cold L2, width 1M, topk 1024, us at end 128K / 1M). Before, the cluster kernel only ran for rows <= 6 at width >= 512K; every other case took one CTA per row.

rows one CTA per row cluster (this PR)
1 19.0 / 81.8 6.1 / 13.0
8 19.3 / 82.7 6.5 / 15.5
32 19.5 / 82.8 8.6 / 22.3
66 19.8 / 83.2 13.2 / 40.9

Validation

  • B200 and H200: test_deep_select.py, plus randomized checks of every cluster size against torch.topk (ties, constants, -inf, +-0, NaN, ascending/descending rows, ragged end, offsets, int64, page transform, values, sorted_index).
  • B200: DeepSeek-V4.1 indexer kernel tests pass with the flag off; with it on, only tests whose references use fp32 logits differ (bf16 rounding and ties at the selection floor).
  • 2x GB300, DeepSeek-V4.1-Flash end to end, flag on vs off: no crash, GSM8K within run-to-run noise (0.893 vs 0.913 / 0.897 on a rerun), passkey correct at 125K and 209K; decode top-k in the index layers 51.1 -> 27.6 us per step at 128K.

🤖 Generated with Claude Code


CI States

Latest PR Test (Base): 🚫 Run #38555200909
Latest PR Test (Extra): ❌ Run #38555200886
Latest PR Test (AMD ROCm 10): ❌ Run #38555200764

… logits

DeepSelect cluster kernel (bf16, max_topk 1024):
- Rewrite the cluster kernel: contiguous per-CTA slices streamed through a bulk-copy ring, a cluster-wide two-pass radix pivot over pushed histograms, and output placement by DSMEM atomics (unsorted) or a per-CTA bitmap prefix (sorted_index). Rows up to 32K per CTA stay in registers.
- Cluster sizes 16/8/4/3/2 picked per row count from an occupancy probe; modules for a call signature are compiled in parallel (new jit utils parallel_compile).
- A NaN row without abort now selects index 0 in every slot instead of a 0x3F3F3F3F sentinel; return_value / abort_when_nan_found default to False.

DeepSeek-V4.1 indexer:
- SGLANG_OPT_DSV41_BF16_INDEX_LOGITS (default off): DeepGEMM fp4 MQA logits in bf16, top-k through DeepSelect, amax8_varlen on bf16 scores (templated on input/output dtype).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@DarkSharpness
DarkSharpness force-pushed the deepselect-cluster-select branch 2 times, most recently from 0060230 to 362978e Compare October 13, 2026 12:07
@DarkSharpness DarkSharpness added the run-ci CI: run the baseline test suite on this PR label Oct 13, 2026
@DarkSharpness DarkSharpness mentioned this pull request Oct 13, 2026
17 of 56 tasks
@BBuf
BBuf merged commit 9d68ecc into sgl-project:main Oct 15, 2026
244 of 267 checks passed
yuyu5333 pushed a commit to yuyu5333/sglang-bytedance that referenced this pull request Oct 15, 2026
… logits (sgl-project#44051)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Co-authored-by: Xiaoyu Zhang <1182563586@qq.com>
@DarkSharpness
DarkSharpness deleted the deepselect-cluster-select branch October 15, 2026 13:47
zcnrex added a commit to zcnrex/sglang that referenced this pull request Oct 23, 2026
Resolve conflicts with bf16 V4.1 index logits (sgl-project#44051, sgl-project#45880), grouped
verify rows (sgl-project#45251), the two-level-only prefill graph (sgl-project#45783) and KV-shard
index-K writes (sgl-project#44280): the adapter takes a logits_dtype and maps
[batch, next_n] paged queries and schedules to grouped varlen rows on SM100.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zou3519 added a commit to sgl-project/sglang-torchtpu that referenced this pull request Oct 29, 2026
Cherry-picks the python/sglang/kernels/jit/utils part of upstream
sgl-project/sglang#44051 (9d68ecc) ahead of the next upstream sync,
so callers can import parallel_compile from sglang.kernels.jit.utils.
zou3519 added a commit to sgl-project/sglang-torchtpu that referenced this pull request Oct 29, 2026
Cherry-picks the python/sglang/kernels/jit/utils part of upstream
sgl-project/sglang#44051 (9d68ecc) ahead of the next upstream sync,
so callers can import parallel_compile from sglang.kernels.jit.utils.
ShivanshuPurohit pushed a commit to latent-to/sglang that referenced this pull request Nov 1, 2026
…1 (upstream sgl-project#47748 @ b411cc3, production files)

SGLANG_ENABLE_DETERMINISTIC_SPARSE_TOPK (default False) keeps DeepSelect on its
single-CTA kernel (the cluster kernels merge CTA picks in arrival order, so a
row's order and, on bf16 ties, its set vary between runs) and routes the DSv4
sparse top-k entry points in dsv4/topk.py through it or an exact torch
selection. Nothing changes unless the variable is set.

This covers the bf16 index-logit path the arena takes on SM103
(SGLANG_OPT_DSV41_BF16_INDEX_LOGITS=1 sends the indexer's paged and ragged
top-k to DeepSelect since upstream sgl-project#44051), which the arena's own top-k pin
(topk_v2 / topk_bf16_small) does not touch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmhYp5Hj8PzMk8jC4Myhjz
@yiakwy-xpu-ml-framework-team

Copy link
Copy Markdown
Contributor

@DarkSharpness we are supporting epic long context with our brand new sparse attention , where top 2048 is very useful !

Let me explain, we will 2048 chunks, with partials scores each chunk corresponding to 64~128 elements, where we can select total 1 billion context efficiently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jit-kernel run-ci CI: run the baseline test suite on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants