[DSv32] Move deep_gemm.get_paged_mqa_logits_metadata to init time as metadata (#15040)
This commit is contained in:
@@ -300,10 +300,13 @@ class Indexer(CustomOp):
|
|||||||
seqlens_32 = metadata.get_seqlens_expanded()
|
seqlens_32 = metadata.get_seqlens_expanded()
|
||||||
else:
|
else:
|
||||||
seqlens_32 = metadata.get_seqlens_int32()
|
seqlens_32 = metadata.get_seqlens_int32()
|
||||||
# NOTE(dark): 132 is SM count on H200/B200, not magic number
|
# Reuse pre-computed schedule metadata if available (from init_forward_metadata),
|
||||||
schedule_metadata = deep_gemm.get_paged_mqa_logits_metadata(
|
# otherwise fall back to computing it here.
|
||||||
seqlens_32, blocksize, self.sm_count
|
schedule_metadata = getattr(metadata, "paged_mqa_schedule_metadata", None)
|
||||||
)
|
if schedule_metadata is None:
|
||||||
|
schedule_metadata = deep_gemm.get_paged_mqa_logits_metadata(
|
||||||
|
seqlens_32, blocksize, self.sm_count
|
||||||
|
)
|
||||||
|
|
||||||
assert len(q_fp8.shape) == 3
|
assert len(q_fp8.shape) == 3
|
||||||
q_fp8 = q_fp8.unsqueeze(1) # the next_n dim is 1 now
|
q_fp8 = q_fp8.unsqueeze(1) # the next_n dim is 1 now
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ from sglang.srt.layers.attention.nsa.utils import (
|
|||||||
from sglang.srt.layers.attention.trtllm_mla_backend import _concat_mla_absorb_q_general
|
from sglang.srt.layers.attention.trtllm_mla_backend import _concat_mla_absorb_q_general
|
||||||
from sglang.srt.layers.dp_attention import get_attention_tp_size
|
from sglang.srt.layers.dp_attention import get_attention_tp_size
|
||||||
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, ForwardMode
|
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, ForwardMode
|
||||||
from sglang.srt.utils import is_hip
|
from sglang.srt.utils import is_cuda, is_hip
|
||||||
|
|
||||||
# from sgl_kernel.flash_attn import flash_attn_varlen_func, flash_attn_with_kvcache
|
# from sgl_kernel.flash_attn import flash_attn_varlen_func, flash_attn_with_kvcache
|
||||||
|
|
||||||
@@ -113,6 +113,9 @@ class NSAMetadata:
|
|||||||
nsa_max_seqlen_q: Literal[1] = 1 # always 1 for decode, variable for extend
|
nsa_max_seqlen_q: Literal[1] = 1 # always 1 for decode, variable for extend
|
||||||
|
|
||||||
flashmla_metadata: Optional[NSAFlashMLAMetadata] = None
|
flashmla_metadata: Optional[NSAFlashMLAMetadata] = None
|
||||||
|
# DeepGEMM schedule metadata for paged MQA logits (decode/target_verify/draft_extend only).
|
||||||
|
# Precomputed once per forward batch and reused across layers.
|
||||||
|
paged_mqa_schedule_metadata: Optional[torch.Tensor] = None
|
||||||
# The sum of sequence lengths for key, prefill only
|
# The sum of sequence lengths for key, prefill only
|
||||||
seq_lens_sum: Optional[int] = None
|
seq_lens_sum: Optional[int] = None
|
||||||
# The flattened 1D page table with shape (seq_lens_sum,), prefill only
|
# The flattened 1D page table with shape (seq_lens_sum,), prefill only
|
||||||
@@ -155,6 +158,7 @@ def _cat(tensors: list[torch.Tensor], dim: int = -1) -> torch.Tensor:
|
|||||||
class NSAIndexerMetadata(BaseIndexerMetadata):
|
class NSAIndexerMetadata(BaseIndexerMetadata):
|
||||||
attn_metadata: NSAMetadata
|
attn_metadata: NSAMetadata
|
||||||
topk_transform_method: TopkTransformMethod
|
topk_transform_method: TopkTransformMethod
|
||||||
|
paged_mqa_schedule_metadata: Optional[torch.Tensor] = None
|
||||||
|
|
||||||
def get_seqlens_int32(self) -> torch.Tensor:
|
def get_seqlens_int32(self) -> torch.Tensor:
|
||||||
return self.attn_metadata.cache_seqlens_int32
|
return self.attn_metadata.cache_seqlens_int32
|
||||||
@@ -529,6 +533,32 @@ class NativeSparseAttnBackend(
|
|||||||
nsa_cu_seqlens_k = compute_cu_seqlens(nsa_cache_seqlens_int32)
|
nsa_cu_seqlens_k = compute_cu_seqlens(nsa_cache_seqlens_int32)
|
||||||
nsa_cu_seqlens_q = self.get_device_int32_arange(len(nsa_cu_seqlens_k))
|
nsa_cu_seqlens_q = self.get_device_int32_arange(len(nsa_cu_seqlens_k))
|
||||||
|
|
||||||
|
paged_mqa_schedule_metadata = None
|
||||||
|
# DeepGEMM paged MQA logits path needs a schedule metadata tensor.
|
||||||
|
# Compute it once per forward batch and reuse it across layers.
|
||||||
|
if is_cuda() and (
|
||||||
|
forward_batch.forward_mode.is_decode_or_idle()
|
||||||
|
or forward_batch.forward_mode.is_target_verify()
|
||||||
|
or forward_batch.forward_mode.is_draft_extend()
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
import deep_gemm
|
||||||
|
|
||||||
|
# NOTE: DeepGEMM paged path uses block_size=64.
|
||||||
|
seqlens_32 = (
|
||||||
|
seqlens_expanded
|
||||||
|
if (
|
||||||
|
forward_batch.forward_mode.is_target_verify()
|
||||||
|
or forward_batch.forward_mode.is_draft_extend()
|
||||||
|
)
|
||||||
|
else cache_seqlens_int32
|
||||||
|
)
|
||||||
|
paged_mqa_schedule_metadata = deep_gemm.get_paged_mqa_logits_metadata(
|
||||||
|
seqlens_32, 64, deep_gemm.get_num_sms()
|
||||||
|
)
|
||||||
|
except (ImportError, ModuleNotFoundError):
|
||||||
|
paged_mqa_schedule_metadata = None
|
||||||
|
|
||||||
metadata = NSAMetadata(
|
metadata = NSAMetadata(
|
||||||
page_size=self.real_page_size,
|
page_size=self.real_page_size,
|
||||||
cache_seqlens_int32=cache_seqlens_int32,
|
cache_seqlens_int32=cache_seqlens_int32,
|
||||||
@@ -547,6 +577,7 @@ class NativeSparseAttnBackend(
|
|||||||
if self.nsa_decode_impl == "flashmla_kv"
|
if self.nsa_decode_impl == "flashmla_kv"
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
|
paged_mqa_schedule_metadata=paged_mqa_schedule_metadata,
|
||||||
nsa_cache_seqlens_int32=nsa_cache_seqlens_int32,
|
nsa_cache_seqlens_int32=nsa_cache_seqlens_int32,
|
||||||
nsa_cu_seqlens_q=nsa_cu_seqlens_q,
|
nsa_cu_seqlens_q=nsa_cu_seqlens_q,
|
||||||
nsa_cu_seqlens_k=nsa_cu_seqlens_k,
|
nsa_cu_seqlens_k=nsa_cu_seqlens_k,
|
||||||
@@ -709,6 +740,29 @@ class NativeSparseAttnBackend(
|
|||||||
nsa_cu_seqlens_q = self.get_device_int32_arange(len(nsa_cu_seqlens_k))
|
nsa_cu_seqlens_q = self.get_device_int32_arange(len(nsa_cu_seqlens_k))
|
||||||
real_page_table = self._transform_table_1_to_real(page_table_1)
|
real_page_table = self._transform_table_1_to_real(page_table_1)
|
||||||
|
|
||||||
|
paged_mqa_schedule_metadata = None
|
||||||
|
if is_cuda() and (
|
||||||
|
forward_mode.is_decode_or_idle()
|
||||||
|
or forward_mode.is_target_verify()
|
||||||
|
or forward_mode.is_draft_extend()
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
import deep_gemm
|
||||||
|
|
||||||
|
seqlens_32 = (
|
||||||
|
seqlens_expanded
|
||||||
|
if (
|
||||||
|
forward_mode.is_target_verify()
|
||||||
|
or forward_mode.is_draft_extend()
|
||||||
|
)
|
||||||
|
else cache_seqlens_int32
|
||||||
|
)
|
||||||
|
paged_mqa_schedule_metadata = deep_gemm.get_paged_mqa_logits_metadata(
|
||||||
|
seqlens_32, 64, deep_gemm.get_num_sms()
|
||||||
|
)
|
||||||
|
except (ImportError, ModuleNotFoundError):
|
||||||
|
paged_mqa_schedule_metadata = None
|
||||||
|
|
||||||
metadata = NSAMetadata(
|
metadata = NSAMetadata(
|
||||||
page_size=self.real_page_size,
|
page_size=self.real_page_size,
|
||||||
cache_seqlens_int32=cache_seqlens_int32,
|
cache_seqlens_int32=cache_seqlens_int32,
|
||||||
@@ -718,6 +772,7 @@ class NativeSparseAttnBackend(
|
|||||||
cu_seqlens_k=cu_seqlens_k,
|
cu_seqlens_k=cu_seqlens_k,
|
||||||
page_table_1=page_table_1,
|
page_table_1=page_table_1,
|
||||||
flashmla_metadata=flashmla_metadata,
|
flashmla_metadata=flashmla_metadata,
|
||||||
|
paged_mqa_schedule_metadata=paged_mqa_schedule_metadata,
|
||||||
nsa_cache_seqlens_int32=nsa_cache_seqlens_int32,
|
nsa_cache_seqlens_int32=nsa_cache_seqlens_int32,
|
||||||
nsa_cu_seqlens_q=nsa_cu_seqlens_q,
|
nsa_cu_seqlens_q=nsa_cu_seqlens_q,
|
||||||
nsa_cu_seqlens_k=nsa_cu_seqlens_k,
|
nsa_cu_seqlens_k=nsa_cu_seqlens_k,
|
||||||
@@ -853,6 +908,33 @@ class NativeSparseAttnBackend(
|
|||||||
metadata.nsa_cache_seqlens_int32[: seqlens_expanded.shape[0]].copy_(
|
metadata.nsa_cache_seqlens_int32[: seqlens_expanded.shape[0]].copy_(
|
||||||
nsa_cache_seqlens
|
nsa_cache_seqlens
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Update DeepGEMM paged MQA schedule metadata outside the captured graph.
|
||||||
|
if is_cuda() and (
|
||||||
|
forward_mode.is_decode_or_idle()
|
||||||
|
or forward_mode.is_target_verify()
|
||||||
|
or forward_mode.is_draft_extend()
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
import deep_gemm
|
||||||
|
|
||||||
|
seqlens_32 = (
|
||||||
|
seqlens_expanded
|
||||||
|
if (
|
||||||
|
forward_mode.is_target_verify()
|
||||||
|
or forward_mode.is_draft_extend()
|
||||||
|
)
|
||||||
|
else metadata.cache_seqlens_int32
|
||||||
|
)
|
||||||
|
new_schedule = deep_gemm.get_paged_mqa_logits_metadata(
|
||||||
|
seqlens_32, 64, deep_gemm.get_num_sms()
|
||||||
|
)
|
||||||
|
if metadata.paged_mqa_schedule_metadata is None:
|
||||||
|
metadata.paged_mqa_schedule_metadata = new_schedule
|
||||||
|
else:
|
||||||
|
metadata.paged_mqa_schedule_metadata.copy_(new_schedule)
|
||||||
|
except (ImportError, ModuleNotFoundError):
|
||||||
|
metadata.paged_mqa_schedule_metadata = None
|
||||||
seqlens_expanded_size = seqlens_expanded.shape[0]
|
seqlens_expanded_size = seqlens_expanded.shape[0]
|
||||||
assert (
|
assert (
|
||||||
metadata.nsa_cache_seqlens_int32 is not None
|
metadata.nsa_cache_seqlens_int32 is not None
|
||||||
@@ -1595,6 +1677,7 @@ class NativeSparseAttnBackend(
|
|||||||
return NSAIndexerMetadata(
|
return NSAIndexerMetadata(
|
||||||
attn_metadata=self.forward_metadata,
|
attn_metadata=self.forward_metadata,
|
||||||
topk_transform_method=self.get_topk_transform_method(),
|
topk_transform_method=self.get_topk_transform_method(),
|
||||||
|
paged_mqa_schedule_metadata=self.forward_metadata.paged_mqa_schedule_metadata,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _compute_flashmla_metadata(self, cache_seqlens: torch.Tensor, seq_len_q: int):
|
def _compute_flashmla_metadata(self, cache_seqlens: torch.Tensor, seq_len_q: int):
|
||||||
|
|||||||
Reference in New Issue
Block a user