158158 set_potential_max_tokens ,
159159 set_weight_prefetch_method ,
160160 should_skip_allreduce_across_dp_group ,
161+ sparse_kv_cache_has_indexer ,
161162 vllm_version_is ,
162163)
163164from vllm_ascend .worker .npu_input_batch import NPUInputBatch
@@ -4260,20 +4261,29 @@ def _allocate_kv_cache_tensors(self, kv_cache_config: KVCacheConfig) -> dict[str
42604261 # for deepseek v3.2, we split the kv cache according to the corresponding ratio
42614262 kv_cache_spec = layer_kv_cache_spec [layer_name ]
42624263 current_sparse_c8 = kv_cache_spec_uses_sparse_c8 (kv_cache_spec )
4263- sparse_kv_cache_ratio = kv_cache_spec .sparse_kv_cache_ratio
4264-
4265- # A5 sparse C8: (ckv_ratio, qli_ratio, qli_scale_ratio, None)
4266- # A3 sparse C8: (k_ratio, v_ratio, qli_ratio, qli_scale_ratio)
4267- if current_sparse_c8 and get_ascend_device_type () == AscendDeviceType .A5 :
4268- k_tensor_split_factor = sparse_kv_cache_ratio [0 ] # ckv
4269- v_tensor_split_factor = None # merged
4270- dsa_k_tensor_split_factor = sparse_kv_cache_ratio [1 ] # qli_tensor
4271- dsa_k_scale_tensor_split_factor = sparse_kv_cache_ratio [2 ] # qli_scale
4264+ has_indexer_cache = sparse_kv_cache_has_indexer (kv_cache_spec )
4265+
4266+ if has_indexer_cache :
4267+ sparse_kv_cache_ratio = kv_cache_spec .sparse_kv_cache_ratio
4268+
4269+ # A5 sparse C8: (ckv_ratio, qli_ratio, qli_scale_ratio, None)
4270+ # A3 sparse C8: (k_ratio, v_ratio, qli_ratio, qli_scale_ratio)
4271+ if current_sparse_c8 and get_ascend_device_type () == AscendDeviceType .A5 :
4272+ k_tensor_split_factor = sparse_kv_cache_ratio [0 ] # ckv
4273+ v_tensor_split_factor = None # merged
4274+ dsa_k_tensor_split_factor = sparse_kv_cache_ratio [1 ] # qli_tensor
4275+ dsa_k_scale_tensor_split_factor = sparse_kv_cache_ratio [2 ] # qli_scale
4276+ else :
4277+ k_tensor_split_factor = sparse_kv_cache_ratio [0 ]
4278+ v_tensor_split_factor = sparse_kv_cache_ratio [1 ]
4279+ dsa_k_tensor_split_factor = sparse_kv_cache_ratio [2 ]
4280+ dsa_k_scale_tensor_split_factor = (
4281+ sparse_kv_cache_ratio [3 ] if current_sparse_c8 else None
4282+ )
42724283 else :
4273- k_tensor_split_factor = sparse_kv_cache_ratio [0 ]
4274- v_tensor_split_factor = sparse_kv_cache_ratio [1 ]
4275- dsa_k_tensor_split_factor = sparse_kv_cache_ratio [2 ]
4276- dsa_k_scale_tensor_split_factor = sparse_kv_cache_ratio [3 ] if current_sparse_c8 else None
4284+ assert not current_sparse_c8
4285+ k_dim , v_dim , _ = kv_cache_spec .sparse_head_dim
4286+ k_tensor_split_factor , v_tensor_split_factor = calc_split_factor ([k_dim , v_dim ])
42774287 else :
42784288 k_dim , v_dim = self ._get_attention_kv_cache_dims (layer_name , current_kv_cache_spec )
42794289 assert k_dim > 0 and v_dim > 0
@@ -4296,9 +4306,9 @@ def _allocate_kv_cache_tensors(self, kv_cache_config: KVCacheConfig) -> dict[str
42964306 dsa_k_tensor_size = None
42974307 dsa_k_scale_tensor_size = None
42984308 #### for deepseek sparse attention
4299- if self .use_sparse :
4309+ if self .use_sparse and has_indexer_cache :
43004310 dsa_k_tensor_size = int (kv_cache_tensor .size // dsa_k_tensor_split_factor )
4301- if self .use_sparse and current_sparse_c8 :
4311+ if self .use_sparse and has_indexer_cache and current_sparse_c8 :
43024312 dsa_k_scale_tensor_size = int (kv_cache_tensor .size // dsa_k_scale_tensor_split_factor )
43034313
43044314 # Allocate raw int8 tensors. Even bf16/fp16 KV cache entries
@@ -4317,7 +4327,7 @@ def _allocate_kv_cache_tensors(self, kv_cache_config: KVCacheConfig) -> dict[str
43174327 alignment ,
43184328 )
43194329
4320- if self .use_sparse :
4330+ if self .use_sparse and has_indexer_cache :
43214331 assert dsa_k_tensor_size is not None
43224332
43234333 if current_sparse_c8 :
@@ -4342,7 +4352,9 @@ def _allocate_kv_cache_tensors(self, kv_cache_config: KVCacheConfig) -> dict[str
43424352 # shared the attn kvcache for all shared layers
43434353 if "attn" in layer_name_inner and "linear_attn" not in layer_name_inner :
43444354 if self .use_sparse :
4345- if current_sparse_c8 :
4355+ if not has_indexer_cache :
4356+ kv_cache_raw_tensors [layer_name_inner ] = (k_tensor , v_tensor )
4357+ elif current_sparse_c8 :
43464358 if get_ascend_device_type () == AscendDeviceType .A5 :
43474359 kv_cache_raw_tensors [layer_name_inner ] = (
43484360 k_tensor , dsa_k_tensor , dsa_k_scale_tensor
@@ -4487,8 +4499,9 @@ def _reshape_kv_cache_tensors(
44874499 # _allocate_kv_cache_tensors; route them to the dedicated
44884500 # elif branch below before the sparse branch tries to
44894501 # unpack them as a (k, v, dsa_k[, scale]) tuple.
4490- if self .use_sparse and "cache_only_layers" not in layer_name :
4491- current_sparse_c8 = kv_cache_spec_uses_sparse_c8 (current_kv_cache_spec )
4502+ current_sparse_c8 = kv_cache_spec_uses_sparse_c8 (current_kv_cache_spec )
4503+ has_indexer_cache = sparse_kv_cache_has_indexer (current_kv_cache_spec )
4504+ if self .use_sparse and has_indexer_cache and "cache_only_layers" not in layer_name :
44924505 if current_sparse_c8 :
44934506 if get_ascend_device_type () == AscendDeviceType .A5 :
44944507 raw_k_tensor , raw_dsa_k_tensor , raw_dsa_k_scale_tensor = kv_cache_raw_tensors [ # type: ignore
@@ -4672,7 +4685,7 @@ def _reshape_kv_cache_tensors(
46724685 else :
46734686 v_cache = raw_v_tensor .view (v_cache_dtype ).view (v_shape )
46744687
4675- if self .use_sparse :
4688+ if self .use_sparse and has_indexer_cache :
46764689 dsa_k_cache_shape = (
46774690 num_blocks ,
46784691 current_kv_cache_spec .block_size ,
@@ -4974,14 +4987,25 @@ def get_kv_cache_spec(self) -> dict[str, KVCacheSpec]:
49744987
49754988 elif isinstance (attn_module , MLAAttention ):
49764989 if self .use_sparse :
4990+ has_indexer = attn_module .impl .has_indexer
4991+ if has_indexer :
4992+ sparse_head_dim = self .sparse_head_dim
4993+ else :
4994+ # Layers that reuse another layer's top-k indices only
4995+ # need the MLA latent and RoPE caches.
4996+ sparse_head_dim = (
4997+ self .model_config .hf_text_config .kv_lora_rank ,
4998+ self .model_config .hf_text_config .qk_rope_head_dim ,
4999+ 0 ,
5000+ )
49775001 kv_cache_spec [layer_name ] = AscendMLAAttentionSpec (
49785002 block_size = self .block_size ,
49795003 num_kv_heads = 1 ,
4980- head_size = sum (self . sparse_head_dim ),
4981- sparse_head_dim = self . sparse_head_dim ,
5004+ head_size = sum (sparse_head_dim ),
5005+ sparse_head_dim = sparse_head_dim ,
49825006 dtype = self .kv_cache_dtype ,
49835007 cache_dtype_str = self .vllm_config .cache_config .cache_dtype ,
4984- cache_sparse_c8 = self .ascend_config .is_sparse_c8_layer (layer_name ),
5008+ cache_sparse_c8 = has_indexer and self .ascend_config .is_sparse_c8_layer (layer_name ),
49855009 )
49865010 elif spec := attn_module .get_kv_cache_spec (self .vllm_config ):
49875011 if getattr (attn_module .impl , "fa_quant_layer" , False ):
0 commit comments