From 425349b799f14f4921363c4b8ff7c39b7fc2c739 Mon Sep 17 00:00:00 2001 From: zky Date: Fri, 31 Jul 2026 11:25:59 +0800 Subject: [PATCH] [Perf][DSA] Pass topk_length to flash_mla_sparse_fwd in the sparse attention path (#31128) --- .../sglang/srt/layers/attention/dsa_backend.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/sglang/srt/layers/attention/dsa_backend.py b/python/sglang/srt/layers/attention/dsa_backend.py index df3a0ed61..3fe440859 100644 --- a/python/sglang/srt/layers/attention/dsa_backend.py +++ b/python/sglang/srt/layers/attention/dsa_backend.py @@ -2205,6 +2205,7 @@ class DeepseekSparseAttnBackend( page_table_1=page_table_1, sm_scale=layer.scaling, v_head_dim=layer.v_head_dim, + topk_length=metadata.dsa_cache_seqlens_int32, ) elif dsa_impl == "flashinfer_sparse_mla": if q_rope is not None: @@ -2361,6 +2362,7 @@ class DeepseekSparseAttnBackend( page_table_1=page_table_1, sm_scale=layer.scaling, v_head_dim=layer.v_head_dim, + topk_length=metadata.dsa_cache_seqlens_int32, ) elif self.dsa_decode_impl == "flashinfer_sparse_mla": if q_all is None: @@ -2475,6 +2477,7 @@ class DeepseekSparseAttnBackend( v_head_dim: int, page_table_1: torch.Tensor, sm_scale: float, + topk_length: Optional[torch.Tensor] = None, ) -> torch.Tensor: from sgl_kernel.flash_mla import flash_mla_sparse_fwd @@ -2503,12 +2506,25 @@ class DeepseekSparseAttnBackend( # indices shape must be (s_q, h_kv=1, topk), keep h_kv=1 unchanged indices_input = page_table_1.unsqueeze(1) + # topk_length is the per-row count of valid indices + # (`dsa_cache_seqlens_int32` = seqlens clipped to `index_topk`). Rows + # whose context is shorter than `index_topk` have their indices + # tail-padded with -1; passing the valid length lets the kernel skip + # the padded tail instead of scanning the full topk width. The output + # is unchanged: the kernel masks -1 indices either way. + if topk_length is not None and topk_length.shape[0] != num_tokens: + # Metadata rows are expected to match q rows (the DP/CP padding + # helpers keep them aligned); fall back to full-width compute if + # they ever diverge. + topk_length = None + o, _, _ = flash_mla_sparse_fwd( q=q_input, kv=kv_cache, indices=indices_input, sm_scale=sm_scale, d_v=v_head_dim, + topk_length=topk_length, ) # Trim output back to original num_heads if we padded