| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- --- baked-ours/models/deepseek_v4_1/sparse_mla.py 2026-09-10 19:56:14.000000000 +0200
- +++ baked/models/deepseek_v4_1/sparse_mla.py 2026-09-11 10:13:47.000000000 +0200
- @@ -20,14 +20,18 @@
- MultipleOf,
- )
- from vllm.v1.attention.backends.mla.compressor_utils import get_compressed_slot_mapping
- +from vllm.v1.attention.backends.utils import get_dcp_local_seq_lens
- from vllm.v1.attention.backends.mla.sparse_swa import (
- _LAYER_TYPE_C1A,
- _LAYER_TYPE_C2A,
- _LAYER_TYPE_SWAONLY,
- DeepseekSparseSWAMetadataBuilder,
- )
- +from vllm.logger import init_logger
- from vllm.v1.kv_cache_interface import AttentionSpec
-
- +logger = init_logger(__name__)
- +
- # v4.1 per-layer compress ratios: 0 = pure sliding window, 1 = full-length
- # compressed cache, 2 = ratio-2 compressed cache. Ratio-1 and ratio-2 layers
- # both attend over indexer topk indices into a shared compressed cache but
- @@ -58,6 +62,8 @@
- tile-scheduler plans from the v4.1 topology.
- """
-
- + supports_non_causal_multi_token_dcp: ClassVar[bool] = True
- +
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- compress_ratios = getattr(
- @@ -139,12 +145,23 @@
- req_id_per_token: torch.Tensor
- block_size: int
- topk_tokens: int
- + # DCP: the compressed cache is sharded over STATES with this interleave;
- + # block_size stays the per-rank kernel page (tokens). seq_lens are the
- + # global lengths (tokens); dcp_local_seq_lens this rank's share of the
- + # compressed length (states), None at DCP1.
- + cp_kv_cache_interleave_size: int = 1
- + seq_lens: torch.Tensor | None = None
- + dcp_local_seq_lens: torch.Tensor | None = None
-
-
- class DeepseekV4SparseMLAMetadataBuilder(
- AttentionMetadataBuilder[DeepseekV4FlashMLAMetadata]
- ):
- _cudagraph_support: ClassVar[AttentionCGSupport] = AttentionCGSupport.UNIFORM_BATCH
- + # The SM120 backend gathers queries / combines per token, so DSpark's
- + # non-causal multi-token decode is supported under DCP (the draft layers
- + # themselves are SWA-only and bypass the DCP path).
- + supports_non_causal_multi_token_dcp: ClassVar[bool] = True
-
- def __init__(
- self,
- @@ -155,9 +172,22 @@
- ) -> None:
- super().__init__(kv_cache_spec, layer_names, vllm_config, device)
- self.model_config = vllm_config.model_config
- + # DCP geometry (self.dcp_world_size / dcp_rank come from the base
- + # builder: process DCP for this sharded group). The V4.1 SM120 backend
- + # gathers queries and combines LSEs per token, so multi-token (DSpark)
- + # decodes stay decodes under DCP.
- + self.cp_kv_cache_interleave_size = (
- + vllm_config.parallel_config.cp_kv_cache_interleave_size
- + )
- + if self.dcp_world_size > 1 and self.cp_kv_cache_interleave_size != 1:
- + raise NotImplementedError(
- + "DeepSeek-V4.1 DCP supports cp_kv_cache_interleave_size=1 only"
- + )
- # Classify single-token queries (plus num_speculative_tokens via
- # supports_spec_as_decode=True) as decodes; longer queries go to prefill.
- - self._init_reorder_batch_threshold(1, supports_spec_as_decode=True)
- + self._init_reorder_batch_threshold(
- + 1, supports_spec_as_decode=True, supports_dcp_with_varlen=True
- + )
- self.topk_tokens = self.model_config.hf_config.index_topk
-
- max_num_batched_tokens = vllm_config.scheduler_config.max_num_batched_tokens
- @@ -174,6 +204,20 @@
- "DeepSeek V4.1 compressed-KV caches use compress_ratio 1 or 2; "
- f"got {self.compress_ratio}."
- )
- + if self.dcp_world_size > 1:
- + # Per-rank page geometry the state-space sharding relies on: the
- + # builder must see the kernel page (block_size tokens = num_states
- + # states per rank), never the manager block (x dcp).
- + assert self.kv_cache_spec.block_size % self.compress_ratio == 0
- + logger.info_once(
- + "DeepSeek-V4.1 compressed KV under DCP%d: ratio %d, %d tokens "
- + "(%d states) per page per rank, interleave %d",
- + self.dcp_world_size,
- + self.compress_ratio,
- + self.kv_cache_spec.block_size,
- + int(self.kv_cache_spec.num_states),
- + self.cp_kv_cache_interleave_size,
- + )
-
- # Pre-allocate compressed slot mapping buffer for CUDA graph address
- # stability when compress_ratio > 1.
- @@ -201,6 +245,17 @@
- int(self.kv_cache_spec.num_states),
- self.compress_ratio,
- out=self.compressed_slot_mapping_buffer,
- + dcp_world_size=self.dcp_world_size,
- + dcp_rank=self.dcp_rank,
- + cp_kv_cache_interleave_size=self.cp_kv_cache_interleave_size,
- + )
- + dcp_local_seq_lens = None
- + if self.dcp_world_size > 1:
- + dcp_local_seq_lens = get_dcp_local_seq_lens(
- + cm.seq_lens // self.compress_ratio,
- + self.dcp_world_size,
- + self.dcp_rank,
- + self.cp_kv_cache_interleave_size,
- )
-
- return DeepseekV4FlashMLAMetadata(
- @@ -214,6 +269,9 @@
- req_id_per_token=req_id_per_token,
- block_size=self.kv_cache_spec.block_size,
- topk_tokens=self.topk_tokens,
- + cp_kv_cache_interleave_size=self.cp_kv_cache_interleave_size,
- + seq_lens=cm.seq_lens,
- + dcp_local_seq_lens=dcp_local_seq_lens,
- )
-
-
|