Skip to content

[DeepSeek-V4] Fix nvcc 13 crash building the topk_v2 kernel - #32910

Merged
BBuf merged 3 commits into
sgl-project:mainfrom
guptaishaan:fix-32830
Aug 3, 2026
Merged

BBuf merged 3 commits into
sgl-project:mainfrom
guptaishaan:fix-32830

Conversation

@guptaishaan

@guptaishaan guptaishaan commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #32830

topk_small_batch_kernel put a cluster-mapped DSMEM address
(cluster.map_shared_rank(topk_indices, worker_rank)) into problem.out, and the
problem_transform epilogue then loads through that same pointer. On CUDA 13.x, cicc
segfaults on that merge, so the whole dpsk_v4_topk_v2 JIT module fails to build and every
DeepSeek-V4 server on a Hopper or Blackwell host with CUDA 13 dies during CUDA graph capture
with ninja exited with status 139.

The mapped alias now lives in a copy that is only passed to Cluster::forward, which takes
TopKProblem by value anyway. The elected rank (blockIdx.y == worker_rank) reads the same
bytes back through its own topk_indices, exactly like the Register4 and Streaming branches
next to it, so there is no behaviour change.

Verified:

  • Reproduced the crash outside sglang with the reporter's toolchain (nvcc 13.2.86, gcc 13.4)
    on the exact translation unit load_jit() generates, targeting sm_90a: same two nvcc
    warnings, same Segmentation fault (core dumped), exit 139. Bisected it to the DSMEM
    pointer plus the later load: removing either one alone also stops the crash, and
    -Xcicc -O1 compiles the unpatched file, so it is a cicc optimizer crash, not a source
    error.
  • After the patch, the same file compiles with nvcc 13.2.86 and still compiles with nvcc 12.6.
  • New test_topk_v2_compiles_for_sm90a in test/registered/kernels/ops/attention/test_topk_v2.py
    runs nvcc -ptx -arch=sm_90a on that translation unit. It fails with exit 139 on the
    pre-fix source and passes on the fixed source. It needs a toolkit, not a cluster-capable
    GPU, and skips when nvcc is not on PATH or under CUDA_HOME.

Not verified: nothing ran on a GPU. The hardware available for this fix was A40 (sm_86),
where topk_v2.cuh does not compile at all (__cluster_dims__ is not supported for this GPU architecture), so the 244 existing correctness cases in test_topk_v2.py could not be run
before or after. Please run them on Hopper or Blackwell. I also did not compile the rest of
the JIT tree against CUDA 13.2, so there may be further cicc crashes later in startup; no
other JIT kernel uses map_shared_rank, so none has this specific trigger.

Thanks to @ramon-garcia for the report and the full startup log, which pinned the failure to
the topk_v2 JIT build.


CI States

Latest PR Test (Base): 🚫 Run #30772568799
Latest PR Test (Extra): 🚫 Run #30772573006

topk_small_batch_kernel assigned a cluster-mapped DSMEM address to
problem.out, and the problem_transform epilogue loads through that same
pointer. cicc segfaults on that merge on CUDA 13.x, so the whole
dpsk_v4_topk_v2 JIT module fails to build and a DeepSeek-V4 server on a
Hopper or Blackwell host dies at CUDA graph capture with "ninja exited
with status 139".

Keep the mapped alias in a copy that is only handed to Cluster::forward,
which takes TopKProblem by value anyway. The elected rank reads the same
bytes back through its own topk_indices, like the Register4 and
Streaming branches beside it, so behaviour is unchanged.

Adds test_topk_v2_compiles_for_sm90a, which runs nvcc -ptx -arch=sm_90a
on the translation unit load_jit() generates. It exits 139 on the
pre-fix source and passes on the fixed one, needs a toolkit rather than
a cluster-capable GPU, and skips when nvcc is unavailable.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@lucashaha

lucashaha commented Jul 30, 2026

Copy link
Copy Markdown

CUDA 13.2,sglang version above 0.5.14 can not work, #32830, not only DEEPSEEK-V4, glm5.2 has same problm, this fix,can solve it?

@guptaishaan

Copy link
Copy Markdown
Contributor Author

Probably yes, if your GLM-5.2 failure is the same nvcc segfault. The kernel this patch fixes
is not DeepSeek-V4-only: topk_v2.cuh is the shared DSA top-k transform, and the DSA backend
routes decode work for GLM DSA models to it too
(python/sglang/srt/layers/attention/dsa/dsa_topk_backend.py, "Shared by DeepSeek-V3.2 and
GLM DSA"), on by default via SGLANG_OPT_USE_TOPK_V2. So a GLM-5.2 run on H100/B200 with
CUDA 13 builds the same translation unit that cicc crashes on.

Can you confirm your log shows that same failure? The signature is a Segmentation fault
from cicc and ninja: build stopped / ninja exited with status 139 while building
dpsk_v4_topk_v2, during CUDA graph capture at startup. "Cannot work on CUDA 13.2" could
also be a different problem, and I only checked this one kernel, not the whole JIT tree
against 13.2.

A quick way to tell without building the patch: run with SGLANG_OPT_USE_TOPK_V2=0. That
skips this JIT module entirely (sglang already forces it off for SM120 and ROCm) at some
decode performance cost. If your run still fails that way, your problem is elsewhere and a
separate issue with the log would help. I have not run that on GLM-5.2 myself.

Fair warning on this PR: I verified the crash and the fix at compile level with nvcc 13.2.86
targeting sm_90a. I had no Hopper or Blackwell GPU, so nothing was run at runtime for either
model.

Comment on lines +309 to +346
def test_topk_v2_compiles_for_sm90a(tmp_path) -> None:
"""The kernel must compile for Hopper, whatever the local GPU is.

cicc crashes on CUDA 13.x if the fused small-batch kernel lets a
shared::cluster (DSMEM) address reach the pointer its epilogue loads, so the
whole module fails to build on a Hopper/Blackwell host (issue #32830). Only a
toolkit is needed to catch that, not a cluster-capable GPU.
"""
from tvm_ffi.libinfo import find_dlpack_include_path, find_include_path

from sglang.kernels.jit.utils.compile import DEFAULT_INCLUDE, KERNEL_PATH

nvcc = _nvcc_path()
if nvcc is None:
pytest.skip("nvcc not found")

# Same translation unit load_jit() feeds to nvcc for the topk_v2 module.
source = tmp_path / "topk_v2.cu"
source.write_text(
f'#include "{KERNEL_PATH / "csrc" / "deepseek_v4" / "topk_v2.cuh"}"\n'
"TVM_FFI_DLL_EXPORT_TYPED_FUNC(topk_transform, (TopKKernel::transform));\n"
"TVM_FFI_DLL_EXPORT_TYPED_FUNC(topk_plan, (TopKKernel::plan));\n"
)
includes = [*DEFAULT_INCLUDE, find_include_path(), find_dlpack_include_path()]
result = subprocess.run(
# Device-only (-ptx) keeps this to a few seconds; the flags mirror
# get_default_target_flags() for a 9.0a target.
[nvcc, "-ptx", "-arch=sm_90a", "-DSGL_CUDA_ARCH=900"]
+ ["-std=c++20", "-O3", "--expt-relaxed-constexpr"]
+ [f"-I{path}" for path in includes]
+ [str(source), "-o", str(tmp_path / "topk_v2.ptx")],
capture_output=True,
text=True,
)
assert (
result.returncode == 0
), f"nvcc exited with {result.returncode}\n{result.stderr}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should include this test for this extremely corner case. What do you think @BBuf @zcnrex

@DarkSharpness DarkSharpness left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. nvcc crash is really sick 😅

@lucashaha

Copy link
Copy Markdown

I test it,SGLANG_OPT_USE_TOPK_V2=0 can solve this glm5.2 nvcc problem

Per review, the nvcc-13 cicc segfault is too much of a corner case to keep a
dedicated regression test for. test_topk_v2.py goes back to its pre-PR
contents; the topk_v2.cuh fix is unchanged.
@guptaishaan

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Dropped test_topk_v2_compiles_for_sm90a, so test_topk_v2.py is back to its pre-PR contents and the only change left is the topk_v2.cuh fix. Happy to restore it if @BBuf or @zcnrex would rather keep a guard on it.

@lucashaha thanks for confirming SGLANG_OPT_USE_TOPK_V2=0 fixes your GLM-5.2 startup. That is the same kernel this PR patches, so the build should work with the fix and without the env var, though I have not run GLM-5.2 myself. Please reopen #32830 or ping here if it still fails once this lands.

@DarkSharpness

Copy link
Copy Markdown
Collaborator

/rerun-test test_topk_v2.py

@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Results for /rerun-test test_topk_v2.py:

🚀 1-gpu-h100 (1 test): ✅ View workflow run

cd test/ && python3 registered/kernels/ops/attention/test_topk_v2.py

@guptaishaan

Copy link
Copy Markdown
Contributor Author

The red CI on this head is infrastructure, not the diff. Could someone kick off a rerun?

Only one job failed on its own, base-b-test-4-gpu-b200 (0). It died in environment setup,
before any sglang code ran:

uv pip install sglang-kernel==0.4.5 --index-url https://docs.sglang.ai/whl/cu130/ ...
  x Failed to download `sglang-kernel==0.4.5+cu130`
  |-> HTTP status server error (503 Service Unavailable) for url
      (https://github.com/sgl-project/whl/releases/download/v0.4.5/sglang_kernel-0.4.5+cu130-cp310-abi3-manylinux2014_x86_64.whl)

That same job also got a 503 from codeload.github.com pulling actions/checkout two minutes
earlier, so it looks like a GitHub blip in that window.

Everything else is the cascade. The 11 other red jobs (base-b-test-1-gpu-small 3 to 9,
base-b-test-1-gpu-large 4 to 8, and pr-test-finish) log Fast-fail: skipping with root
cause wait-for-base-b, base-b-test-4-gpu-b200 (0), so none of them ran a test.

The two PR Test Extra failures are the run-ci-extra label gate, not test results.

No change on my side, the diff is still just the topk_v2.cuh fix. For what it is worth,
/rerun-test test_topk_v2.py on this same commit came back green on 1-gpu-h100
(run 30613389220).

@BBuf
BBuf merged commit 28a2472 into sgl-project:main Aug 3, 2026
156 of 216 checks passed
DarkSharpness pushed a commit to DarkSharpness/sglang that referenced this pull request Aug 9, 2026
…3.1+

`TopKCluster::forward` selected its phase-3 scatter destination up front:

    const auto cur_out = is_primary ? problem.out : smem->tmp_out;

`problem.out` can be a `shared::cluster` (DSMEM) alias of the elected rank's
buffer, while `tmp_out` is `shared::cta`. Merging both into one pointer variable
makes cicc 13.1+ mis-lower the block-local arm for sm_90a and silently drop
every non-primary rank's staged output: `tmp_out` stays zero, and phase 3.5 then
faithfully copies zeros to perfectly correct DSMEM addresses.

The result is a top-k row where only the primary's slots and the `handle_tie`
tail hold valid indices. Slot-diffing one row against a CUDA 12.9 build shows
exactly one contiguous bad run -- [61, 443] -- with slots 0-60 (the primary's own
scatter) and 444-511 (handle_tie) correct. Downstream sparse attention then
dereferences the garbage slots, which is the illegal memory access reported in
sgl-project#33835.

Fix: keep the two destinations in separate code paths so neither pointer ever
carries two address spaces, and note it so nobody merges them back.

Scope: affects any fused small-batch cluster shape (`batch <= 30` and
`seq_len > cluster_floor`), not just rows near the 32K small-batch floor -- the
floor only makes the path reachable at `batch <= 15`. The persistent-pool path
was never affected because it stages output in global memory.

Toolchain matrix (H200, sm_90a, 157-row suite over the report's shapes plus a
boundary sweep and register/streaming/persistent controls):

    nvcc     before        after
    12.9     0 bad         0 bad
    13.0     0 bad         0 bad
    13.1     157 bad       0 bad
    13.2     157 bad       0 bad
    13.3     157 bad       0 bad

CI builds cu130, which is a clean cell -- that is why this stayed hidden and why
the report came from a CUDA 13.1 deployment.

Also drops the `peer_problem` copy from sgl-project#32910 and states the
block-local pointer at the read-back site instead. That `__builtin_assume` is
load-bearing: removing it reproduces the sgl-project#32830 cicc segfault on 13.1/13.2/13.3.

Validation: 0 bad rows on 12.9/13.0/13.1/13.2/13.3; 1500-iteration randomized
stress and 500 CUDA-graph replays clean; builds for sm_90a and sm_100a on every
toolchain. No performance regression -- worst case +0.1% (noise), and the fused
cluster shapes get 1.3-2.9% faster. sm_100a is compile-verified only; no
Blackwell was available to run on.
saturn-acc pushed a commit to saturn-acc/sglang that referenced this pull request Aug 16, 2026
…ect#32910)

Co-authored-by: guptaishaan <guptaishaan@users.noreply.github.com>
Co-authored-by: Xiaoyu Zhang <1182563586@qq.com>
Atituiset pushed a commit to Atituiset/sglang that referenced this pull request Sep 10, 2026
…ect#32910)

Co-authored-by: guptaishaan <guptaishaan@users.noreply.github.com>
Co-authored-by: Xiaoyu Zhang <1182563586@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Nvidia compiler crashes with segmentation fault when trying to serve DeepkSeek v4

4 participants