main
py 152 lines 4.93 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Tests for mamba attention backend selectors."""
4
5 from types import SimpleNamespace
6
7 import pytest
8 import torch
9
10 from vllm.model_executor.layers.mamba.abstract import MambaBase
11 from vllm.model_executor.layers.mamba.linear.minimax_linear_attn import (
12 MiniMaxText01LinearAttention,
13 )
14 from vllm.model_executor.layers.mamba.mamba_mixer import MambaMixer
15 from vllm.model_executor.layers.mamba.mamba_mixer2 import MambaMixer2
16 from vllm.model_executor.layers.mamba.short_conv import ShortConv
17 from vllm.v1.attention.backends.linear_attn import LinearAttentionBackend
18 from vllm.v1.attention.backends.mamba1_attn import Mamba1AttentionBackend
19 from vllm.v1.attention.backends.mamba2_attn import Mamba2AttentionBackend
20 from vllm.v1.attention.backends.registry import MambaAttentionBackendEnum
21 from vllm.v1.attention.backends.short_conv_attn import ShortConvAttentionBackend
22
23
24 @pytest.mark.parametrize(("use_replayssm", "expected_blocks"), [(False, 3), (True, 0)])
25 def test_replayssm_does_not_reserve_speculative_state_blocks(
26 use_replayssm, expected_blocks
27 ):
28 layer = SimpleNamespace(
29 get_state_shape=lambda: ((2,),),
30 get_state_dtype=lambda: (torch.float32,),
31 mamba_type=MambaAttentionBackendEnum.MAMBA2,
32 is_kv_cache_tp_replicated=False,
33 )
34 vllm_config = SimpleNamespace(
35 cache_config=SimpleNamespace(
36 mamba_block_size=1,
37 mamba_page_size_padded=None,
38 mamba_cache_mode="none",
39 use_replayssm=use_replayssm,
40 ),
41 num_speculative_tokens=3,
42 )
43
44 spec = MambaBase.get_kv_cache_spec(layer, vllm_config)
45
46 assert spec is not None
47 assert spec.num_speculative_blocks == expected_blocks
48
49
50 @pytest.mark.parametrize(
51 "layer_class, init_kwargs, expected_backend, expected_mamba_type",
52 [
53 (
54 MambaMixer,
55 dict(
56 hidden_size=128,
57 ssm_state_size=16,
58 conv_kernel_size=4,
59 intermediate_size=256,
60 time_step_rank=8,
61 use_conv_bias=True,
62 use_bias=False,
63 use_rms_norm=True,
64 ),
65 Mamba1AttentionBackend,
66 MambaAttentionBackendEnum.MAMBA1,
67 ),
68 (
69 MambaMixer2,
70 dict(
71 hidden_size=128,
72 ssm_state_size=16,
73 conv_kernel_size=4,
74 intermediate_size=256,
75 use_conv_bias=True,
76 use_bias=False,
77 n_groups=1,
78 num_heads=8,
79 head_dim=32,
80 ),
81 Mamba2AttentionBackend,
82 MambaAttentionBackendEnum.MAMBA2,
83 ),
84 (
85 MiniMaxText01LinearAttention,
86 dict(
87 config=SimpleNamespace(
88 hidden_size=256,
89 num_attention_heads=8,
90 head_dim=32,
91 num_hidden_layers=12,
92 block=64,
93 ),
94 prefix="layers.0.self_attn",
95 ),
96 LinearAttentionBackend,
97 MambaAttentionBackendEnum.LINEAR,
98 ),
99 (
100 ShortConv,
101 dict(
102 config=SimpleNamespace(conv_L_cache=32, conv_bias=True),
103 dim=128,
104 layer_idx=0,
105 ),
106 ShortConvAttentionBackend,
107 MambaAttentionBackendEnum.SHORT_CONV,
108 ),
109 ],
110 )
111 def test_mamba_layers_get_attn_backend(
112 default_vllm_config,
113 dist_init,
114 layer_class,
115 init_kwargs,
116 expected_backend,
117 expected_mamba_type,
118 ):
119 """Test that Mamba-like layers return the correct attention backend."""
120 if layer_class is MiniMaxText01LinearAttention:
121 init_kwargs["vllm_config"] = default_vllm_config
122 layer = layer_class(**init_kwargs)
123
124 backend_class = layer.get_attn_backend()
125 assert backend_class is expected_backend
126 assert layer.mamba_type == expected_mamba_type
127
128
129 @pytest.mark.parametrize(
130 "layer_class,expected_backend,expected_mamba_type",
131 [
132 (MambaMixer, Mamba1AttentionBackend, MambaAttentionBackendEnum.MAMBA1),
133 (MambaMixer2, Mamba2AttentionBackend, MambaAttentionBackendEnum.MAMBA2),
134 (
135 MiniMaxText01LinearAttention,
136 LinearAttentionBackend,
137 MambaAttentionBackendEnum.LINEAR,
138 ),
139 (ShortConv, ShortConvAttentionBackend, MambaAttentionBackendEnum.SHORT_CONV),
140 ],
141 )
142 def test_mamba_layers_have_unified_interface(
143 layer_class, expected_backend, expected_mamba_type
144 ):
145 """Test that all Mamba layers have the unified get_attn_backend
146 interface."""
147 assert hasattr(layer_class, "get_attn_backend"), (
148 f"{layer_class.__name__} should have get_attn_backend method"
149 )
150 assert hasattr(layer_class, "mamba_type"), (
151 f"{layer_class.__name__} should have mamba_type property"
152 )