Skip to content

perf(sm120): skip split-K when the reduction is slower than the single-token GEMM - #77

Open
ormandj wants to merge 1 commit into
sgl-project:devfrom
ormandj:fix/sm120-splitk-tiny-m
Open

perf(sm120): skip split-K when the reduction is slower than the single-token GEMM#77
ormandj wants to merge 1 commit into
sgl-project:devfrom
ormandj:fix/sm120-splitk-tiny-m

Conversation

@ormandj

@ormandj ormandj commented Aug 14, 2026

Copy link
Copy Markdown

Description

The SM120 split-K heuristic partitions K when the number of MN blocks is below half the SM count. For single-token decode shapes where M is much smaller than BLOCK_M, the separate reduction kernel costs more than the work saved by splitting the GEMM.

This change returns split_k = 1 when:

expected_m * 4 <= block_m

Larger decode and prefill shapes continue through the existing split-K heuristic.

Profiled result

Measured on an RTX PRO 6000 Blackwell SM120 using a DeepSeek-V4-Flash single-user decode projection:

Dimension Value
M after padding 4
N 8,192
K 1,024
BLOCK_M 32
Path GPU duration
Split GEMM plus sm120_split_k_reduce_impl approximately 22.4 µs
Same projection with split_k = 1 approximately 13.2 µs
Difference approximately -9.2 µs

This projection appears in 43 model layers, corresponding to approximately 0.4 ms removed from the decode graph.

The profile comparison uses the same projection shape and changes only the split-K selection.

Numerical and serving validation

The source-equivalent serving stack containing the change:

  • built and installed the SM120 DeepGEMM wheel;
  • initialized DeepSeek-V4-Flash-0731 on two SM120 GPUs at TP2;
  • captured and replayed CUDA graphs;
  • completed a deterministic 40-request replay without the previously observed residual-shape compilation pause;
  • completed five measured repetitions at every concurrency from C1 through C32;
  • completed five cold-prefill requests at 8K, 32K, 64K, and 128K;
  • completed all 1,319 GSM8K requests with zero request errors; and
  • completed 8/8 long-output structural validations.

The complete candidate produced these forward-pass medians:

Concurrency Forward passes/s
C1 63.864
C2 47.737
C4 34.322
C8 22.968
C16 17.304
C32 12.722

The complete release stack also contained the separately reviewed SM120 compiled-dimension correction. These end-to-end results therefore establish integration and regression coverage; the isolated split-K performance attribution is the matched 22.4 µs versus 13.2 µs projection profile above.

Scope

The change is limited to the SM120 heuristic. It does not modify the kernels, reduction implementation, other architectures, or larger-M split-K behavior.

Prepared with AI assistance.

The SM120 split-K heuristic fills idle SMs by partitioning K whenever the
MN block count is below half the SM count. At decode-sized M this trades a
cheap GEMM for an expensive reduction: the reduce pass reads
split_k * M * N floats to produce M * N, so its cost is dominated by launch
and write-back rather than by the arithmetic it parallelises.

Measured on SM120 (RTX PRO 6000, DeepSeek-V4-Flash single-user decode,
M = 4 after padding, N = 8192, K = 1024, BLOCK_M = 32): the split GEMM plus
sm120_split_k_reduce_impl costs about 22.4 us per projection, against about
13.2 us for the same projection with split_k = 1. Across 43 layers this is
roughly 0.4 ms per decode graph.

Skip split-K when M is at least 4x smaller than BLOCK_M, which leaves
prefill and larger-batch decode shapes unchanged.

Signed-off-by: David Orman <ormandj@corenode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant