@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 0a2c2dc3f1
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 10, 15:15 UTC

fixed mypy warnings for files vllm/v1/attention with TEMPORARY workaround (#31465)

Signed-off-by: Zhuohao Yang <zy242@cornell.edu> Co-authored-by: Zhuohao Yang <zy242@cornell.edu> Co-authored-by: Wentao Ye <44945378+yewentao256@users.noreply.github.com>

Jack Yang committed Jan 6, 2026 at 23:08 UTC 0a2c2dc3f14620de291e67d6d26fca72b09f5617
18 files changed +140 -56
tools/pre_commit/mypy.py
+1 -1
@@ -41,6 +41,7 @@ FILES = [
41 "vllm/usage",
42 "vllm/utils",
43 "vllm/worker",
44 + "vllm/v1/attention",
45 "vllm/v1/core",
46 "vllm/v1/engine",
47 "vllm/v1/executor",
@@ -60,7 +61,6 @@ SEPARATE_GROUPS = [
61 "vllm/lora",
62 "vllm/model_executor",
63 # v1 related
63 - "vllm/v1/attention",
64 "vllm/v1/kv_offload",
65 "vllm/v1/spec_decode",
66 "vllm/v1/structured_output",
vllm/attention/backends/abstract.py
+9 -3
@@ -2,6 +2,7 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 from abc import ABC, abstractmethod
5 +from enum import Enum
6 from typing import TYPE_CHECKING, ClassVar, Generic, Protocol, TypeVar, get_args
7
8 import torch
@@ -14,7 +15,7 @@ if TYPE_CHECKING:
15 from vllm.v1.attention.backends.utils import KVCacheLayoutType
16
17
17 -class AttentionType:
18 +class AttentionType(str, Enum):
19 """
20 Attention type.
21 Use string to be compatible with `torch.compile`.
@@ -193,7 +194,7 @@ class AttentionBackend(ABC):
194 head_size: int,
195 dtype: torch.dtype,
196 kv_cache_dtype: "CacheDType | None",
196 - block_size: int | None,
197 + block_size: int,
198 use_mla: bool,
199 has_sink: bool,
200 use_sparse: bool,
@@ -207,7 +208,7 @@ class AttentionBackend(ABC):
208 head_size: int,
209 dtype: torch.dtype,
210 kv_cache_dtype: "CacheDType | None",
210 - block_size: int | None,
211 + block_size: int,
212 use_mla: bool,
213 has_sink: bool,
214 use_sparse: bool,
@@ -290,6 +291,11 @@ class AttentionLayer(Protocol):
291
292
293 class AttentionImpl(ABC, Generic[T]):
294 + # Required attributes that all impls should have
295 + num_heads: int
296 + head_size: int
297 + scale: float
298 +
299 # Whether the attention impl can return the softmax lse for decode.
300 # Some features like decode context parallelism require the softmax lse.
301 can_return_lse_for_decode: bool = False
vllm/model_executor/layers/attention_layer_base.py
+3 -1
@@ -4,7 +4,7 @@
4
5 from abc import ABC, abstractmethod
6
7 -from vllm.attention.backends.abstract import AttentionBackend
7 +from vllm.attention.backends.abstract import AttentionBackend, AttentionImpl
8 from vllm.config import VllmConfig
9 from vllm.v1.kv_cache_interface import KVCacheSpec
10
@@ -18,6 +18,8 @@ class AttentionLayerBase(ABC):
18 from different layer types.
19 """
20
21 + impl: "AttentionImpl"
22 +
23 @abstractmethod
24 def get_attn_backend(self) -> type[AttentionBackend]:
25 """Get the attention backend class for this layer."""
vllm/v1/attention/backends/flash_attn.py
+34 -8
@@ -167,7 +167,7 @@ class FlashAttentionBackend(AttentionBackend):
167 head_size: int,
168 dtype: torch.dtype,
169 kv_cache_dtype: CacheDType | None,
170 - block_size: int,
170 + block_size: int | None,
171 use_mla: bool,
172 has_sink: bool,
173 use_sparse: bool,
@@ -354,7 +354,11 @@ class FlashAttentionMetadataBuilder(AttentionMetadataBuilder[FlashAttentionMetad
354 aot_schedule = False
355
356 max_num_splits = 0 # 0 means use FA3's heuristics, not CG compatible
357 - if self.use_full_cuda_graph and num_actual_tokens <= self.max_cudagraph_size:
357 + if (
358 + self.use_full_cuda_graph
359 + and self.max_cudagraph_size is not None
360 + and num_actual_tokens <= self.max_cudagraph_size
361 + ):
362 # NOTE(woosuk): Setting num_splits > 1 may increase the memory
363 # usage, because the intermediate buffers of size [num_splits,
364 # num_heads, num_tokens, head_size] are allocated. Therefore,
@@ -599,6 +603,9 @@ class FlashAttentionImpl(AttentionImpl):
603 We use torch's .expand() to avoid duplicating values
604 """
605 assert output is not None, "Output tensor must be provided."
606 + assert self.vllm_flash_attn_version is not None, (
607 + "FlashAttention version not detected."
608 + )
609
610 if output_scale is not None or output_block_scale is not None:
611 raise NotImplementedError(
@@ -697,6 +704,11 @@ class FlashAttentionImpl(AttentionImpl):
704 )
705 return output
706 else:
707 + sliding_window_size = (
708 + list(self.sliding_window)
709 + if self.sliding_window is not None
710 + else None
711 + )
712 flash_attn_varlen_func(
713 q=query[:num_actual_tokens],
714 k=key_cache,
@@ -709,7 +721,7 @@ class FlashAttentionImpl(AttentionImpl):
721 softmax_scale=self.scale,
722 causal=attn_metadata.causal,
723 alibi_slopes=self.alibi_slopes,
712 - window_size=self.sliding_window,
724 + window_size=sliding_window_size,
725 block_table=block_table,
726 softcap=self.logits_soft_cap,
727 scheduler_metadata=scheduler_metadata,
@@ -764,12 +776,19 @@ class FlashAttentionImpl(AttentionImpl):
776 k_descale: torch.Tensor | None = None,
777 v_descale: torch.Tensor | None = None,
778 ) -> torch.Tensor:
779 + assert self.vllm_flash_attn_version is not None, (
780 + "FlashAttention version not detected."
781 + )
782 +
783 cu_seqlens_q = attn_metadata.query_start_loc
784 max_seqlen_q = attn_metadata.max_query_len
785 block_table = attn_metadata.block_table
786
787 query = query.contiguous()
788 query_across_dcp = get_dcp_group().all_gather(query, dim=1)
789 + sliding_window_size = (
790 + list(self.sliding_window) if self.sliding_window is not None else None
791 + )
792 context_attn_out, context_lse = flash_attn_varlen_func(
793 q=query_across_dcp,
794 k=key_cache,
@@ -782,7 +801,7 @@ class FlashAttentionImpl(AttentionImpl):
801 softmax_scale=self.scale,
802 causal=False,
803 alibi_slopes=self.alibi_slopes,
785 - window_size=self.sliding_window,
804 + window_size=sliding_window_size,
805 block_table=block_table,
806 softcap=self.logits_soft_cap,
807 return_softmax_lse=True,
@@ -813,7 +832,7 @@ class FlashAttentionImpl(AttentionImpl):
832 softmax_scale=self.scale,
833 causal=attn_metadata.causal,
834 alibi_slopes=self.alibi_slopes,
816 - window_size=self.sliding_window,
835 + window_size=sliding_window_size,
836 softcap=self.logits_soft_cap,
837 return_softmax_lse=True,
838 fa_version=self.vllm_flash_attn_version,
@@ -850,6 +869,10 @@ class FlashAttentionImpl(AttentionImpl):
869 attn_metadata: Encoder attention metadata
870 layer: The attention layer
871 """
872 + assert self.vllm_flash_attn_version is not None, (
873 + "FlashAttention version not detected."
874 + )
875 +
876 # For encoder attention, process FP8 quantization if needed
877 if self.kv_cache_dtype.startswith("fp8"):
878 raise NotImplementedError(
@@ -868,6 +891,9 @@ class FlashAttentionImpl(AttentionImpl):
891 )
892
893 # Call flash attention directly on Q, K, V tensors
894 + sliding_window_size = (
895 + list(self.sliding_window) if self.sliding_window is not None else None
896 + )
897 flash_attn_varlen_func(
898 q=query,
899 k=key,
@@ -880,7 +906,7 @@ class FlashAttentionImpl(AttentionImpl):
906 softmax_scale=self.scale,
907 causal=False, # Encoder attention is bidirectional
908 alibi_slopes=self.alibi_slopes,
883 - window_size=self.sliding_window,
909 + window_size=sliding_window_size,
910 softcap=self.logits_soft_cap,
911 fa_version=self.vllm_flash_attn_version,
912 q_descale=layer._q_scale.expand(descale_shape),
@@ -1020,7 +1046,7 @@ def cascade_attention(
1046 max_seqlen_k=common_prefix_len,
1047 softmax_scale=softmax_scale,
1048 causal=False,
1023 - window_size=sliding_window,
1049 + window_size=list(sliding_window),
1050 block_table=block_table[:1],
1051 softcap=logits_soft_cap,
1052 return_softmax_lse=True,
@@ -1048,7 +1074,7 @@ def cascade_attention(
1074 max_seqlen_k=max_kv_len - common_prefix_len,
1075 softmax_scale=softmax_scale,
1076 causal=True,
1051 - window_size=sliding_window,
1077 + window_size=list(sliding_window),
1078 block_table=block_table[:, num_common_kv_blocks:],
1079 softcap=logits_soft_cap,
1080 return_softmax_lse=True,
vllm/v1/attention/backends/flash_attn_diffkv.py
+9 -1
@@ -113,6 +113,9 @@ class FlashAttentionDiffKVImpl(FlashAttentionImpl):
113 We use torch's .expand() to avoid duplicating values
114 """
115 assert output is not None, "Output tensor must be provided."
116 + assert self.vllm_flash_attn_version is not None, (
117 + "FlashAttention version not detected."
118 + )
119
120 if output_scale is not None or output_block_scale is not None:
121 raise NotImplementedError(
@@ -214,6 +217,11 @@ class FlashAttentionDiffKVImpl(FlashAttentionImpl):
217 )
218 return output
219 else:
220 + sliding_window_size = (
221 + list(self.sliding_window)
222 + if self.sliding_window is not None
223 + else None
224 + )
225 flash_attn_varlen_func(
226 q=query[:num_actual_tokens],
227 k=key_cache,
@@ -226,7 +234,7 @@ class FlashAttentionDiffKVImpl(FlashAttentionImpl):
234 softmax_scale=self.scale,
235 causal=attn_metadata.causal,
236 alibi_slopes=self.alibi_slopes,
229 - window_size=self.sliding_window,
237 + window_size=sliding_window_size,
238 block_table=block_table,
239 softcap=self.logits_soft_cap,
240 scheduler_metadata=scheduler_metadata,
vllm/v1/attention/backends/flashinfer.py
+6 -5
@@ -530,11 +530,12 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
530 self._decode_wrappers_cudagraph: dict[
531 int, BatchDecodeWithPagedKVCacheWrapper
532 ] = {}
533 - self._decode_cudagraph_max_bs = min(
534 - (1 + num_spec_tokens) * max_num_reqs,
535 - self.compilation_config.max_cudagraph_capture_size,
536 - )
537 -
533 + self._decode_cudagraph_max_bs = (1 + num_spec_tokens) * max_num_reqs
534 + if self.compilation_config.max_cudagraph_capture_size is not None:
535 + self._decode_cudagraph_max_bs = min(
536 + self._decode_cudagraph_max_bs,
537 + self.compilation_config.max_cudagraph_capture_size,
538 + )
539 try:
540 self.dcp_world_size = get_dcp_group().world_size
541 self.dcp_rank = get_dcp_group().rank_in_group
vllm/v1/attention/backends/flex_attention.py
+1 -1
@@ -215,7 +215,7 @@ def physical_to_logical_mapping(
215 )
216
217 # Only process valid blocks to avoid garbage values
218 - num_blocks_per_seq = cdiv(seq_lens, block_size)
218 + num_blocks_per_seq: torch.Tensor = cdiv(seq_lens, block_size)
219 mask = (
220 torch.arange(max_num_blocks, device=device)[None, :]
221 < num_blocks_per_seq[:, None]
vllm/v1/attention/backends/gdn_attn.py
+11 -4
@@ -75,8 +75,10 @@ class GDNAttentionMetadataBuilder(AttentionMetadataBuilder[GDNAttentionMetadata]
75 self.compilation_config = vllm_config.compilation_config
76 self.speculative_config = vllm_config.speculative_config
77 self.kv_cache_spec = kv_cache_spec
78 +
79 if self.speculative_config:
79 - self.num_spec = self.speculative_config.num_speculative_tokens
80 + assert self.speculative_config.num_speculative_tokens is not None
81 + self.num_spec: int = self.speculative_config.num_speculative_tokens
82 else:
83 self.num_spec = 0
84 self.use_spec_decode = self.num_spec > 0
@@ -85,10 +87,15 @@ class GDNAttentionMetadataBuilder(AttentionMetadataBuilder[GDNAttentionMetadata]
87 self.use_full_cuda_graph = (
88 self.compilation_config.cudagraph_mode.has_full_cudagraphs()
89 )
88 - self.decode_cudagraph_max_bs = min(
89 - self.vllm_config.scheduler_config.max_num_seqs * (self.num_spec + 1),
90 - self.compilation_config.max_cudagraph_capture_size,
90 +
91 + self.decode_cudagraph_max_bs = (
92 + self.vllm_config.scheduler_config.max_num_seqs * (self.num_spec + 1)
93 )
94 + if self.compilation_config.max_cudagraph_capture_size is not None:
95 + self.decode_cudagraph_max_bs = min(
96 + self.decode_cudagraph_max_bs,
97 + self.compilation_config.max_cudagraph_capture_size,
98 + )
99
100 self.spec_state_indices_tensor = torch.empty(
101 (self.decode_cudagraph_max_bs, self.num_spec + 1),
vllm/v1/attention/backends/mamba2_attn.py
+3 -2
@@ -123,10 +123,11 @@ class Mamba2AttentionMetadataBuilder(
123 device: torch.device,
124 ):
125 super().__init__(kv_cache_spec, layer_names, vllm_config, device)
126 - self.chunk_size = vllm_config.model_config.get_mamba_chunk_size()
127 - assert self.chunk_size is not None, (
126 + chunk_size = vllm_config.model_config.get_mamba_chunk_size()
127 + assert chunk_size is not None, (
128 "chunk_size needs to be set in the model config for Mamba2 models"
129 )
130 + self.chunk_size: int = chunk_size
131
132 def _compute_chunk_metadata(
133 self,
vllm/v1/attention/backends/mamba_attn.py
+12 -6
@@ -69,10 +69,12 @@ class BaseMambaAttentionMetadataBuilder(AttentionMetadataBuilder[M], abc.ABC):
69
70 assert isinstance(kv_cache_spec, MambaSpec)
71 self.compilation_config = vllm_config.compilation_config
72 - self.decode_cudagraph_max_bs = min(
73 - self.vllm_config.scheduler_config.max_num_seqs,
74 - self.compilation_config.max_cudagraph_capture_size,
75 - )
72 + self.decode_cudagraph_max_bs = self.vllm_config.scheduler_config.max_num_seqs
73 + if self.compilation_config.max_cudagraph_capture_size is not None:
74 + self.decode_cudagraph_max_bs = min(
75 + self.decode_cudagraph_max_bs,
76 + self.compilation_config.max_cudagraph_capture_size,
77 + )
78
79 if self.vllm_config.cache_config.enable_prefix_caching:
80 self.state_indices_tensor = torch.empty(
@@ -150,9 +152,13 @@ class BaseMambaAttentionMetadataBuilder(AttentionMetadataBuilder[M], abc.ABC):
152 cdiv(common_attn_metadata.seq_lens, mamba_block_size) - 1
153 )
154 # -1 in case it's non-computed and causes later issues with indexing
153 - block_idx_last_computed_token = block_idx_last_computed_token.clamp(min=0)
155 + block_idx_last_computed_token = torch.clamp(
156 + block_idx_last_computed_token, min=0
157 + )
158 # -1 in the case we have a padded request (0 seq-len)
155 - block_idx_last_scheduled_token = block_idx_last_scheduled_token.clamp(min=0)
159 + block_idx_last_scheduled_token = torch.clamp(
160 + block_idx_last_scheduled_token, min=0
161 + )
162
163 return (
164 block_idx_last_computed_token,
vllm/v1/attention/backends/mla/aiter_triton_mla.py
+1 -1
@@ -62,7 +62,7 @@ class AiterTritonMLAImpl(AiterMLAImpl):
62 k,
63 v,
64 softmax_scale=softmax_scale,
65 - return_lse=return_softmax_lse,
65 + return_softmax_lse=return_softmax_lse,
66 **kwargs,
67 )
68 # Transpose the LSE if Triton MHA is used:
vllm/v1/attention/backends/mla/common.py
+21 -12
@@ -202,6 +202,7 @@ from vllm._aiter_ops import rocm_aiter_ops
202 from vllm.attention.backends.abstract import (
203 AttentionBackend,
204 AttentionLayer,
205 + AttentionMetadata,
206 MLAAttentionImpl,
207 )
208 from vllm.attention.backends.utils import get_mla_dims
@@ -251,13 +252,15 @@ class QueryLenSupport(Enum):
252
253
254 try:
254 - from vllm.vllm_flash_attn import flash_attn_varlen_func
255 + from vllm.vllm_flash_attn import ( # type: ignore[attr-defined]
256 + flash_attn_varlen_func,
257 + )
258
259 is_vllm_fa = True
260 except ImportError:
261 # For rocm use upstream flash attention
262 if current_platform.is_rocm():
260 - from flash_attn import flash_attn_varlen_func
263 + from flash_attn import flash_attn_varlen_func # type: ignore[no-redef]
264 is_vllm_fa = False
265
266 try:
@@ -386,7 +389,7 @@ D = TypeVar("D", bound=MLACommonDecodeMetadata)
389
390
391 @dataclass
389 -class MLACommonMetadata(Generic[D]):
392 +class MLACommonMetadata(AttentionMetadata, Generic[D]):
393 """Metadata for MLACommon.
394
395 NOTE: Please read the comment at the top of the file before trying to
@@ -434,7 +437,7 @@ class MLACommonMetadata(Generic[D]):
437
438
439 M = TypeVar("M", bound=MLACommonMetadata)
437 -A = TypeVar("A")
440 +A = TypeVar("A", bound=AttentionMetadata)
441
442
443 def use_flashinfer_prefill() -> bool:
@@ -617,7 +620,7 @@ class MLACommonMetadataBuilder(AttentionMetadataBuilder[M]):
620 self._fi_prefill_chunks: list[BatchPrefillWithRaggedKVCacheWrapper] = []
621
622 self._global_hyperparameters = infer_global_hyperparameters(
620 - get_per_layer_parameters(vllm_config, layer_names, MLACommonImpl)
623 + get_per_layer_parameters(vllm_config, layer_names, MLACommonImpl) # type: ignore[type-abstract]
624 )
625
626 if self._use_trtllm_ragged_prefill:
@@ -874,7 +877,7 @@ class MLACommonMetadataBuilder(AttentionMetadataBuilder[M]):
877 )
878 # Note(qcs): The max local context lengths
879 # padded to `dcp_local_block_size`.
877 - padded_local_context_lens_cpu = (
880 + padded_local_context_lens_cpu: torch.Tensor = (
881 cdiv(
882 context_lens_cpu,
883 self.dcp_virtual_block_size,
@@ -1171,7 +1174,9 @@ class MLACommonBaseImpl(MLAAttentionImpl[A], Generic[A]):
1174 )
1175
1176 def get_and_maybe_dequant_weights(layer: LinearBase):
1174 - if not isinstance(layer.quant_method, UnquantizedLinearMethod):
1177 + if layer.quant_method is not None and not isinstance(
1178 + layer.quant_method, UnquantizedLinearMethod
1179 + ):
1180 # NOTE: This should only be used offline, since it's O(N^3)
1181 eye = torch.eye(
1182 layer.input_size_per_partition,
@@ -1327,12 +1332,14 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1332 # v with 0s to match the qk head dim for attention backends that do
1333 # not support different headdims
1334 # We don't need to pad V if we are on a hopper system with FA3
1335 + device_capability = current_platform.get_device_capability()
1336 self._pad_v = self.vllm_flash_attn_version is None or not (
1337 self.vllm_flash_attn_version == 3
1332 - and current_platform.get_device_capability()[0] == 9
1338 + and device_capability is not None
1339 + and device_capability[0] == 9
1340 )
1341
1335 - self.dcp_world_size: int | None = None
1342 + self.dcp_world_size: int = -1
1343
1344 self.chunked_prefill_workspace_size = (
1345 MLACommonMetadataBuilder.determine_chunked_prefill_workspace_size(
@@ -1583,7 +1590,9 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1590 )
1591
1592 def get_and_maybe_dequant_weights(layer: LinearBase):
1586 - if not isinstance(layer.quant_method, UnquantizedLinearMethod):
1593 + if layer.quant_method is not None and not isinstance(
1594 + layer.quant_method, UnquantizedLinearMethod
1595 + ):
1596 # NOTE: This should only be used offline, since it's O(N^3)
1597 eye = torch.eye(
1598 layer.input_size_per_partition,
@@ -1875,7 +1884,7 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1884 ) -> None:
1885 # TODO (zyongye): Prefill function here
1886 assert attn_metadata.prefill is not None
1878 - assert self.dcp_world_size is not None
1887 + assert self.dcp_world_size != -1
1888
1889 has_context = attn_metadata.prefill.chunked_context is not None
1890 kv_nope = self.kv_b_proj(kv_c_normed)[0].view(
@@ -1975,7 +1984,7 @@ class MLACommonImpl(MLACommonBaseImpl[M], Generic[M]):
1984 # same expert outputs.
1985 return output.fill_(0)
1986
1978 - if self.dcp_world_size is None:
1987 + if self.dcp_world_size == -1:
1988 self.dcp_world_size = get_dcp_group().world_size
1989
1990 fp8_attention = self.kv_cache_dtype.startswith("fp8")
vllm/v1/attention/backends/mla/flashattn_mla.py
+9 -2
@@ -33,7 +33,10 @@ from vllm.v1.attention.backends.mla.common import (
33 )
34 from vllm.v1.attention.backends.utils import AttentionCGSupport
35 from vllm.v1.kv_cache_interface import AttentionSpec
36 -from vllm.vllm_flash_attn import flash_attn_varlen_func, get_scheduler_metadata
36 +from vllm.vllm_flash_attn import ( # type: ignore[attr-defined]
37 + flash_attn_varlen_func,
38 + get_scheduler_metadata,
39 +)
40
41 logger = init_logger(__name__)
42
@@ -181,7 +184,11 @@ class FlashAttnMLAMetadataBuilder(MLACommonMetadataBuilder[FlashAttnMLAMetadata]
184
185 # For Flash Attention MLA + full cudagraph
186 max_num_splits = 0
184 - if self.use_full_cuda_graph and num_decode_tokens <= self.max_cudagraph_size:
187 + if (
188 + self.use_full_cuda_graph
189 + and self.max_cudagraph_size is not None
190 + and num_decode_tokens <= self.max_cudagraph_size
191 + ):
192 # NOTE(woosuk): Setting num_splits > 1 may increase the memory
193 # usage, because the intermediate buffers of size [num_splits,
194 # num_heads, num_tokens, head_size] are allocated. Therefore,
vllm/v1/attention/backends/mla/flashmla_sparse.py
+4 -2
@@ -10,6 +10,7 @@ from vllm import _custom_ops as ops
10 from vllm.attention.backends.abstract import (
11 AttentionBackend,
12 AttentionLayer,
13 + AttentionMetadata,
14 MultipleOf,
15 )
16 from vllm.attention.backends.utils import get_mla_dims
@@ -124,7 +125,7 @@ class FlashMLASparseBackend(AttentionBackend):
125
126
127 @dataclass
127 -class FlashMLASparseMetadata:
128 +class FlashMLASparseMetadata(AttentionMetadata):
129 num_reqs: int
130 max_query_len: int
131 max_seq_len: int
@@ -718,7 +719,7 @@ class FlashMLASparseImpl(MLACommonBaseImpl[FlashMLASparseMetadata]):
719 )
720 self.softmax_scale = scale
721 assert indexer is not None
721 - self.topk_indices_buffer = indexer.topk_indices_buffer
722 + self.topk_indices_buffer: torch.Tensor | None = indexer.topk_indices_buffer
723 self.padding = 128 if current_platform.is_device_capability_family(100) else 64
724
725 if kv_cache_dtype == "fp8_ds_mla":
@@ -980,6 +981,7 @@ class FlashMLASparseImpl(MLACommonBaseImpl[FlashMLASparseMetadata]):
981 q = q[:num_actual_toks, ...]
982 k_c_normed = k_c_normed[:num_actual_toks, ...]
983 k_pe = k_pe[:num_actual_toks, ...]
984 + assert self.topk_indices_buffer is not None
985 topk_indices = self.topk_indices_buffer[:num_actual_toks]
986
987 q_nope, q_pe = q.split([self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1)
vllm/v1/attention/backends/mla/rocm_aiter_mla.py
+2 -1
@@ -236,7 +236,7 @@ class AiterMLAImpl(MLACommonImpl[AiterMLAMetadata]):
236 k=k,
237 v=v,
238 softmax_scale=softmax_scale,
239 - return_lse=return_softmax_lse,
239 + return_softmax_lse=return_softmax_lse,
240 **kwargs,
241 )
242
@@ -251,6 +251,7 @@ class AiterMLAImpl(MLACommonImpl[AiterMLAMetadata]):
251 ) -> tuple[torch.Tensor, torch.Tensor | None]:
252 assert kv_c_and_k_pe_cache.numel() > 0
253 assert attn_metadata.decode is not None
254 + assert attn_metadata.decode.max_qo_len is not None
255
256 if type(q) is tuple:
257 q = torch.cat(q, dim=-1)
vllm/v1/attention/backends/mla/rocm_aiter_mla_sparse.py
+4 -3
@@ -43,7 +43,7 @@ class ROCMAiterMLASparseBackend(AttentionBackend):
43 return "ROCM_AITER_MLA_SPARSE"
44
45 @staticmethod
46 - def get_metadata_cls() -> type[AttentionMetadata]:
46 + def get_metadata_cls() -> type["ROCMAiterMLASparseMetadata"]:
47 return ROCMAiterMLASparseMetadata
48
49 @staticmethod
@@ -74,7 +74,7 @@ class ROCMAiterMLASparseBackend(AttentionBackend):
74
75
76 @dataclass
77 -class ROCMAiterMLASparseMetadata:
77 +class ROCMAiterMLASparseMetadata(AttentionMetadata):
78 num_reqs: int
79 max_query_len: int
80 max_seq_len: int
@@ -223,7 +223,7 @@ class ROCMAiterMLASparseImpl(MLACommonBaseImpl[ROCMAiterMLASparseMetadata]):
223 )
224 self.softmax_scale = scale
225 assert indexer is not None
226 - self.topk_indices_buffer = indexer.topk_indices_buffer
226 + self.topk_indices_buffer: torch.Tensor | None = indexer.topk_indices_buffer
227 self.is_fp8bmm_enabled = rocm_aiter_ops.is_fp8bmm_enabled()
228
229 def _forward_bf16_kv(
@@ -294,6 +294,7 @@ class ROCMAiterMLASparseImpl(MLACommonBaseImpl[ROCMAiterMLASparseMetadata]):
294 # Convert from (N, B, L) to (B, N, L)
295 ql_nope = ql_nope.transpose(0, 1)
296
297 + assert self.topk_indices_buffer is not None
298 topk_indices = self.topk_indices_buffer[:num_actual_toks]
299
300 topk_indices_global = triton_convert_req_index_to_global_index(
vllm/v1/attention/backends/tree_attn.py
+3 -1
@@ -155,7 +155,9 @@ class TreeAttentionMetadataBuilder(AttentionMetadataBuilder[TreeAttentionMetadat
155 self.block_size = kv_cache_spec.block_size
156
157 spec_config = vllm_config.speculative_config
158 - spec_token_tree = (spec := spec_config) and spec.speculative_token_tree
158 + spec_token_tree: str | None = None
159 + if spec := spec_config:
160 + spec_token_tree = spec.speculative_token_tree
161 tree_choices: list[tuple[int, ...]] = (
162 ast.literal_eval(spec_token_tree) if spec_token_tree is not None else [(0,)]
163 )
vllm/v1/attention/backends/utils.py
+7 -2
@@ -469,6 +469,7 @@ def get_kv_cache_layout():
469 # Format specified by the code.
470 global _KV_CACHE_LAYOUT_OVERRIDE
471
472 + cache_layout: Literal["NHD", "HND"] | None = None
473 if _KV_CACHE_LAYOUT_OVERRIDE is not None:
474 cache_layout = _KV_CACHE_LAYOUT_OVERRIDE
475 logger.info_once(
@@ -524,7 +525,11 @@ def get_per_layer_parameters(
525 to use during `plan`.
526 """
527
527 - layers = get_layers_from_vllm_config(vllm_config, AttentionLayerBase, layer_names)
528 + layers = get_layers_from_vllm_config(
529 + vllm_config,
530 + AttentionLayerBase, # type: ignore[type-abstract]
531 + layer_names,
532 + )
533 per_layer_params: dict[str, PerLayerParameters] = {}
534
535 for key, layer in layers.items():
@@ -1125,7 +1130,7 @@ class KVSharingFastPrefillMetadata(Protocol):
1130
1131 def create_fast_prefill_custom_backend(
1132 prefix: str,
1128 - underlying_attn_backend: AttentionBackend,
1133 + underlying_attn_backend: type[AttentionBackend],
1134 ) -> type[AttentionBackend]:
1135 underlying_builder = underlying_attn_backend.get_builder_cls()
1136