SGLang optimizations for NVIDIA Spark (GB10) — SM121 Grace Blackwell
12
stars
14,141
commits
Python
primary language
Sep 7, 2026
updated
Fork of SGLang with optimizations for the NVIDIA Spark (GB10) — Grace Blackwell SM 12.1.
These patches fix critical issues that prevent NVFP4-quantized models from running on SM121 and add performance optimizations specific to the GB10's unified memory architecture.
| Component | Spec |
|---|---|
| Platform | ASUS Ascent GX10 / NVIDIA Spark (GB10) |
| GPU | Grace Blackwell, SM 12.1 |
| Memory | 128 GB unified (CPU+GPU shared) |
| CUDA | 13.0, TORCH_CUDA_ARCH_LIST=12.1 |
| Model | Quantization | Decode Speed | MTP Accept Rate | MTP Accept Length |
|---|---|---|---|---|
| Qwen3.5-35B-A3B | NVFP4 + GDN post-quant | ~76 tok/s | ~97% | ~2.9 |
| Qwen3.5-122B-A10B | NVFP4 + FP8 post-quant | ~43-45 tok/s | ~90% | ~2.7 |
Problem: All CUTLASS FP4 GEMM operations produce corrupt output (zeros/NaN) on SM121.
Solution: Route all NVFP4 through the Marlin FP4 backend with a scale interleaving fix.
s_tb_groups by 2, causing adjacent K-groups (16 elements each) to share one scale. Fix: byte-interleave adjacent FP8 scale rows in 8-byte chunks before storing. Applied to both dense and MoE pathways.dequant_fp8_scales block and fixed missing moe_sum_reduce 3rd argument (routed_scaling_factor=1.0).Key files:
python/sglang/srt/layers/quantization/marlin_utils.py — nvfp4_marlin_interleave_scales(), scale processingpython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4.py — Marlin FP4 densepython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4_moe.py — Marlin MoEpython/sglang/jit_kernel/csrc/gemm/marlin_moe/marlin_template.h — MoE kernel templateFinding: CUTLASS FP8 (fp8_scaled_mm from sgl-kernel) is 2-3x faster than BF16 matmul at M=1 on SM121. In contrast, torch._scaled_mm dispatches to sm89_xmma and is not faster than BF16 on SM121.
in_proj_qkv, o_proj in linear attention blocks).LogitsProcessor._compute_lm_head() which bypassed FP8 for ParallelLMHead (checked hasattr(lm_head, "weight") → True → fell through to torch.matmul BF16 fallback). Now checks lm_head.weight.dtype == torch.float8_e4m3fn.Key files:
python/sglang/srt/layers/quantization/fp8_post_quant.py — FP8 post-quant implementationpython/sglang/srt/layers/logits_processor.py — lm_head FP8 routing fix| Model | Preset | Notes |
|---|---|---|
| Qwen3.5-122B-A10B-NVFP4 | ./sglang.sh Qwen3.5-NVFP4 | MTP speculative decoding, FP8 KV cache |
| Qwen3.5-35B-A3B-NVFP4 | ./sglang.sh Qwen3.5-35B-NVFP4 | MTP, GDN post-quant |
| Mistral-Small-4-119B NVFP4 | ./sglang.sh mistral-small-4 | Triton attention, EAGLE disabled by default |
| Nemotron-3-Super-120B-A12B-NVFP4 | ./sglang.sh nemotron | FP8 post-quant, Triton MoE |
| MiniMax M2.5 | ./sglang.sh minimax | NGRAM speculation |
| Qwen3-Coder-Next NVFP4 | ./sglang.sh Qwen3-Coder-Next-NVFP4 | |
| Qwen3-Coder-Next FP8 | ./sglang.sh Qwen3-Coder-Next-FP8 | Dense FP8 |
./sglang.sh build
This creates a .sglang/ venv with all dependencies compiled for SM 12.1. See ./sglang.sh --help for partial rebuild options (--skip-venv, --skip-torch, etc.).
# Qwen3.5-122B MoE NVFP4 with MTP speculative decoding
./sglang.sh Qwen3.5-NVFP4
# Qwen3.5-35B with MTP
./sglang.sh Qwen3.5-35B-NVFP4
# Override context length
CONTEXT_LENGTH=32768 ./sglang.sh Qwen3.5-NVFP4
# Disable speculative decoding
DISABLE_MTP=1 ./sglang.sh Qwen3.5-NVFP4
| Variable | Default | Description |
|---|---|---|
CONTEXT_LENGTH | 65536 | Context window size |
KV_CACHE_DTYPE | fp8_e4m3 | KV cache dtype (auto for BF16) |
DISABLE_MTP | 0 | Disable MTP speculative decoding |
DISABLE_NGRAM | 0 | Disable NGRAM speculation (minimax) |
Model paths can be overridden with QWEN35_MODEL, NEMOTRON_MODEL, MISTRAL_MODEL, etc.
torch._scaled_mm slow on SM121 — Dispatches to sm89_xmma kernel. Use fp8_scaled_mm (sgl-kernel CUTLASS FP8) instead.python/sglang/srt/layers/quantization/marlin_utils.py — NVFP4 scale processing + interleavingpython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4.py — Marlin FP4 dense GEMMpython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4_moe.py — Marlin FP4 MoEpython/sglang/srt/layers/quantization/fp8_post_quant.py — CUTLASS FP8 post-quantpython/sglang/srt/layers/logits_processor.py — lm_head FP8 routingpython/sglang/jit_kernel/csrc/gemm/marlin_moe/marlin_template.h — MoE dequant_fp8_scalespython/sglang/jit_kernel/csrc/gemm/nvfp4/nvfp4_quant.cuh — FP4 quantizationpython/sglang/jit_kernel/nvfp4.py — FP4 JIT kernelpython/sglang/srt/models/qwen3_5.py — SM121 GDN post-quant, FP8 post-quantpython/sglang/srt/models/mistral_small.py — Mistral-Small-4 NVFP4 supportpython/sglang/srt/models/jet_nemotron.py — Nemotron-H NVFP4 loadingpython/sglang/srt/server_args.py — SM121 detection, backend auto-selectionsglang.sh — Build script + model launch presetsBased on sgl-project/sglang main branch. This fork contains 227 commits of GB10-specific optimizations on top of upstream.
Apache 2.0 (same as upstream SGLang)
(top 30 of 452)
Python
76.6%
MDX
6.7%
Rust
6.5%
Cuda
4.1%
C++
2.4%
JavaScript
2.2%
SGLang optimizations for NVIDIA Spark (GB10) — SM121 Grace Blackwell
12
stars
14,141
commits
Python
primary language
Sep 7, 2026
updated
Fork of SGLang with optimizations for the NVIDIA Spark (GB10) — Grace Blackwell SM 12.1.
These patches fix critical issues that prevent NVFP4-quantized models from running on SM121 and add performance optimizations specific to the GB10's unified memory architecture.
| Component | Spec |
|---|---|
| Platform | ASUS Ascent GX10 / NVIDIA Spark (GB10) |
| GPU | Grace Blackwell, SM 12.1 |
| Memory | 128 GB unified (CPU+GPU shared) |
| CUDA | 13.0, TORCH_CUDA_ARCH_LIST=12.1 |
| Model | Quantization | Decode Speed | MTP Accept Rate | MTP Accept Length |
|---|---|---|---|---|
| Qwen3.5-35B-A3B | NVFP4 + GDN post-quant | ~76 tok/s | ~97% | ~2.9 |
| Qwen3.5-122B-A10B | NVFP4 + FP8 post-quant | ~43-45 tok/s | ~90% | ~2.7 |
Problem: All CUTLASS FP4 GEMM operations produce corrupt output (zeros/NaN) on SM121.
Solution: Route all NVFP4 through the Marlin FP4 backend with a scale interleaving fix.
s_tb_groups by 2, causing adjacent K-groups (16 elements each) to share one scale. Fix: byte-interleave adjacent FP8 scale rows in 8-byte chunks before storing. Applied to both dense and MoE pathways.dequant_fp8_scales block and fixed missing moe_sum_reduce 3rd argument (routed_scaling_factor=1.0).Key files:
python/sglang/srt/layers/quantization/marlin_utils.py — nvfp4_marlin_interleave_scales(), scale processingpython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4.py — Marlin FP4 densepython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4_moe.py — Marlin MoEpython/sglang/jit_kernel/csrc/gemm/marlin_moe/marlin_template.h — MoE kernel templateFinding: CUTLASS FP8 (fp8_scaled_mm from sgl-kernel) is 2-3x faster than BF16 matmul at M=1 on SM121. In contrast, torch._scaled_mm dispatches to sm89_xmma and is not faster than BF16 on SM121.
in_proj_qkv, o_proj in linear attention blocks).LogitsProcessor._compute_lm_head() which bypassed FP8 for ParallelLMHead (checked hasattr(lm_head, "weight") → True → fell through to torch.matmul BF16 fallback). Now checks lm_head.weight.dtype == torch.float8_e4m3fn.Key files:
python/sglang/srt/layers/quantization/fp8_post_quant.py — FP8 post-quant implementationpython/sglang/srt/layers/logits_processor.py — lm_head FP8 routing fix| Model | Preset | Notes |
|---|---|---|
| Qwen3.5-122B-A10B-NVFP4 | ./sglang.sh Qwen3.5-NVFP4 | MTP speculative decoding, FP8 KV cache |
| Qwen3.5-35B-A3B-NVFP4 | ./sglang.sh Qwen3.5-35B-NVFP4 | MTP, GDN post-quant |
| Mistral-Small-4-119B NVFP4 | ./sglang.sh mistral-small-4 | Triton attention, EAGLE disabled by default |
| Nemotron-3-Super-120B-A12B-NVFP4 | ./sglang.sh nemotron | FP8 post-quant, Triton MoE |
| MiniMax M2.5 | ./sglang.sh minimax | NGRAM speculation |
| Qwen3-Coder-Next NVFP4 | ./sglang.sh Qwen3-Coder-Next-NVFP4 | |
| Qwen3-Coder-Next FP8 | ./sglang.sh Qwen3-Coder-Next-FP8 | Dense FP8 |
./sglang.sh build
This creates a .sglang/ venv with all dependencies compiled for SM 12.1. See ./sglang.sh --help for partial rebuild options (--skip-venv, --skip-torch, etc.).
# Qwen3.5-122B MoE NVFP4 with MTP speculative decoding
./sglang.sh Qwen3.5-NVFP4
# Qwen3.5-35B with MTP
./sglang.sh Qwen3.5-35B-NVFP4
# Override context length
CONTEXT_LENGTH=32768 ./sglang.sh Qwen3.5-NVFP4
# Disable speculative decoding
DISABLE_MTP=1 ./sglang.sh Qwen3.5-NVFP4
| Variable | Default | Description |
|---|---|---|
CONTEXT_LENGTH | 65536 | Context window size |
KV_CACHE_DTYPE | fp8_e4m3 | KV cache dtype (auto for BF16) |
DISABLE_MTP | 0 | Disable MTP speculative decoding |
DISABLE_NGRAM | 0 | Disable NGRAM speculation (minimax) |
Model paths can be overridden with QWEN35_MODEL, NEMOTRON_MODEL, MISTRAL_MODEL, etc.
torch._scaled_mm slow on SM121 — Dispatches to sm89_xmma kernel. Use fp8_scaled_mm (sgl-kernel CUTLASS FP8) instead.python/sglang/srt/layers/quantization/marlin_utils.py — NVFP4 scale processing + interleavingpython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4.py — Marlin FP4 dense GEMMpython/sglang/srt/layers/quantization/compressed_tensors/schemes/compressed_tensors_w4a4_nvfp4_moe.py — Marlin FP4 MoEpython/sglang/srt/layers/quantization/fp8_post_quant.py — CUTLASS FP8 post-quantpython/sglang/srt/layers/logits_processor.py — lm_head FP8 routingpython/sglang/jit_kernel/csrc/gemm/marlin_moe/marlin_template.h — MoE dequant_fp8_scalespython/sglang/jit_kernel/csrc/gemm/nvfp4/nvfp4_quant.cuh — FP4 quantizationpython/sglang/jit_kernel/nvfp4.py — FP4 JIT kernelpython/sglang/srt/models/qwen3_5.py — SM121 GDN post-quant, FP8 post-quantpython/sglang/srt/models/mistral_small.py — Mistral-Small-4 NVFP4 supportpython/sglang/srt/models/jet_nemotron.py — Nemotron-H NVFP4 loadingpython/sglang/srt/server_args.py — SM121 detection, backend auto-selectionsglang.sh — Build script + model launch presetsBased on sgl-project/sglang main branch. This fork contains 227 commits of GB10-specific optimizations on top of upstream.
Apache 2.0 (same as upstream SGLang)
(top 30 of 452)
Python
76.6%
MDX
6.7%
Rust
6.5%
Cuda
4.1%
C++
2.4%
JavaScript
2.2%