From 3f9d184833a4626e06d72bf099cc00a8c4258886 Mon Sep 17 00:00:00 2001 From: Xiaoyu Zhang <1182563586@qq.com> Date: Wed, 12 Aug 2026 10:41:54 +0800 Subject: [PATCH] [Diffusion] Tune QK head LayerNorm for SM120 (#34349) --- .../ops/diffusion/triton/layernorm_modulate.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/python/sglang/kernels/ops/diffusion/triton/layernorm_modulate.py b/python/sglang/kernels/ops/diffusion/triton/layernorm_modulate.py index 976925960..1ddbcface 100644 --- a/python/sglang/kernels/ops/diffusion/triton/layernorm_modulate.py +++ b/python/sglang/kernels/ops/diffusion/triton/layernorm_modulate.py @@ -46,6 +46,7 @@ import torch import triton # type: ignore import triton.language as tl # type: ignore +from sglang.kernels.jit.utils import get_jit_cuda_arch from sglang.kernels.ops.diffusion.triton.numerics import ( cuda_rsqrtf, div_rn_f32, @@ -340,6 +341,11 @@ def _is_bf16_cuda(t: torch.Tensor) -> bool: return t.is_cuda and t.dtype is torch.bfloat16 +def _is_sm120_or_newer() -> bool: + arch = get_jit_cuda_arch() + return arch.major * 10 + arch.minor >= 120 + + def _mod_row_stride(t: torch.Tensor, batch: int, hidden: int) -> int | None: # (batch, hidden) modulation rows, possibly strided views of a chunked # adaLN projection; the last dim must be packed. @@ -454,7 +460,12 @@ def fused_qk_head_layernorm( launch, bit-exact vs the eager aten kernel.""" head_dim = q.shape[-1] n_rows = q.numel() // head_dim - rows = 64 + # SM120 has a smaller register file per SM than H200. Grouping 64 exact + # Welford rows in one program depresses occupancy on RTX 5090; an exhaustive + # production-shape sweep selects 8 rows / 4 warps there (about 10% faster). + # Preserve the independently tuned SM90 launch byte-for-byte. + is_sm120 = _is_sm120_or_newer() + rows = 8 if is_sm120 else 64 q_out = torch.empty_like(q) k_out = torch.empty_like(k) with torch.cuda.device(q.device): @@ -470,6 +481,6 @@ def fused_qk_head_layernorm( ROWS=rows, # H200-tuned: 62us at (1, 4360, 32, 128) vs the 301us of the two # aten launches (one 128-thread block per head_dim-element row). - num_warps=2, + num_warps=4 if is_sm120 else 2, ) return q_out, k_out