2323 import tests.ut.distributed.ascend_store._mock_deps # noqa: F401, E402
2424"""
2525
26+ import importlib .util
2627import logging
2728import os
2829import sys
2930import types
31+ from typing import Any
3032from unittest .mock import MagicMock
3133
3234# ---------------------------------------------------------------------------
3335# Mock torch / torch_npu
3436# ---------------------------------------------------------------------------
35- if "torch" not in sys .modules :
37+ if "torch" not in sys .modules and importlib . util . find_spec ( "torch" ) is None :
3638 _torch = types .ModuleType ("torch" )
3739 _torch .Tensor = MagicMock # type: ignore[attr-defined]
3840 _torch .bool = "bool" # type: ignore[attr-defined]
3941 _torch .float16 = "float16" # type: ignore[attr-defined]
42+ _torch .float32 = "float32" # type: ignore[attr-defined]
4043 _torch .zeros = MagicMock (return_value = MagicMock ()) # type: ignore[attr-defined]
4144 _torch .sum = MagicMock (return_value = 0 ) # type: ignore[attr-defined]
4245 _torch .device = MagicMock () # type: ignore[attr-defined]
5659# ---------------------------------------------------------------------------
5760# Mock vllm modules
5861# ---------------------------------------------------------------------------
62+ _MOCK_VLLM_DEPS = importlib .util .find_spec ("vllm" ) is None
5963_vllm_mock_modules = [
6064 "vllm" ,
6165 "vllm.config" ,
8387 "vllm.v1.attention" ,
8488 "vllm.v1.attention.backend" ,
8589 "vllm.v1.core" ,
90+ "vllm.v1.core.block_pool" ,
8691 "vllm.v1.core.kv_cache_manager" ,
8792 "vllm.v1.core.kv_cache_utils" ,
8893 "vllm.v1.core.sched" ,
8994 "vllm.v1.core.sched.output" ,
95+ "vllm.v1.core.single_type_kv_cache_manager" ,
9096 "vllm.v1.kv_cache_interface" ,
97+ "vllm.v1.kv_cache_spec_registry" ,
9198 "vllm.v1.outputs" ,
9299 "vllm.v1.request" ,
93100 "vllm.v1.serial_utils" ,
94101]
95- for _mod_name in _vllm_mock_modules :
96- if _mod_name not in sys .modules :
97- sys .modules [_mod_name ] = MagicMock ()
102+ if _MOCK_VLLM_DEPS :
103+ for _mod_name in _vllm_mock_modules :
104+ if _mod_name not in sys .modules :
105+ sys .modules [_mod_name ] = MagicMock ()
98106
99- sys .modules ["vllm.utils.math_utils" ].cdiv = lambda a , b : - (- a // b ) # type: ignore[attr-defined]
100- sys .modules ["vllm.logger" ].logger = logging .getLogger ("vllm" ) # type: ignore[attr-defined]
107+ if _MOCK_VLLM_DEPS :
108+ sys .modules ["vllm.utils.math_utils" ].cdiv = lambda a , b : - (- a // b ) # type: ignore[attr-defined]
109+ sys .modules ["vllm.logger" ].logger = logging .getLogger ("vllm" ) # type: ignore[attr-defined]
101110
102- _base_mod = sys .modules ["vllm.distributed.kv_transfer.kv_connector.v1.base" ]
111+ _base_mod : Any = (
112+ sys .modules ["vllm.distributed.kv_transfer.kv_connector.v1.base" ] if _MOCK_VLLM_DEPS else types .SimpleNamespace ()
113+ )
103114_base_mod .KVConnectorBase_V1 = type ("KVConnectorBase_V1" , (), {"__init__" : lambda self , ** kw : None }) # type: ignore[attr-defined]
104115_base_mod .KVConnectorMetadata = type ("KVConnectorMetadata" , (), {}) # type: ignore[attr-defined]
105116_base_mod .KVConnectorWorkerMetadata = type ("KVConnectorWorkerMetadata" , (), {}) # type: ignore[attr-defined]
106117_base_mod .KVConnectorRole = MagicMock () # type: ignore[attr-defined]
107118_base_mod .KVConnectorRole .SCHEDULER = "SCHEDULER"
108119_base_mod .KVConnectorRole .WORKER = "WORKER"
109120
110- _events_mod = sys .modules ["vllm.distributed.kv_events" ]
121+ _events_mod : Any = sys .modules ["vllm.distributed.kv_events" ] if _MOCK_VLLM_DEPS else types . SimpleNamespace ()
111122_events_mod .KVCacheEvent = type ("KVCacheEvent" , (), {}) # type: ignore[attr-defined]
112123_events_mod .KVConnectorKVEvents = type ("KVConnectorKVEvents" , (), {}) # type: ignore[attr-defined]
113124
@@ -127,14 +138,212 @@ def __getattr__(self, name):
127138 {"__init__" : lambda self , ** kwargs : self .__dict__ .update (kwargs )},
128139)
129140
130- _kv_cache_utils_mod = sys .modules ["vllm.v1.core.kv_cache_utils" ]
141+ _kv_cache_utils_mod : Any = sys .modules ["vllm.v1.core.kv_cache_utils" ] if _MOCK_VLLM_DEPS else types . SimpleNamespace ()
131142_kv_cache_utils_mod .BlockHash = bytes # type: ignore[attr-defined]
132143_kv_cache_utils_mod .maybe_convert_block_hash = lambda x : x # type: ignore[attr-defined]
133144
134- _sched_output_mod = sys .modules ["vllm.v1.core.sched.output" ]
145+
146+ class _FakeKVCacheBlock :
147+ def __init__ (self , block_id = 0 , ** kwargs ):
148+ self .block_id = block_id
149+ self .__dict__ .update (kwargs )
150+
151+
152+ class _FakeKVCacheSpec :
153+ def __init__ (self , block_size = 16 , ** kwargs ):
154+ self .block_size = block_size
155+ for key , value in kwargs .items ():
156+ setattr (self , key , value )
157+
158+ def __eq__ (self , other ):
159+ return type (self ) is type (other ) and self .__dict__ == getattr (other , "__dict__" , {})
160+
161+ def copy_with_new_block_size (self , block_size ):
162+ kwargs = self .__dict__ .copy ()
163+ kwargs ["block_size" ] = block_size
164+ return type (self )(** kwargs )
165+
166+ @property
167+ def page_size_bytes (self ):
168+ num_kv_heads = getattr (self , "num_kv_heads" , 1 )
169+ head_size = getattr (self , "head_size" , 1 )
170+ dtype = getattr (self , "dtype" , None )
171+ dtype_size = getattr (dtype , "itemsize" , None )
172+ if dtype_size is None and dtype is not None and hasattr (dtype , "element_size" ):
173+ dtype_size = dtype .element_size ()
174+ return self .block_size * num_kv_heads * head_size * int (dtype_size or 1 ) * 2
175+
176+
177+ class _FakeFullAttentionSpec (_FakeKVCacheSpec ):
178+ pass
179+
180+
181+ class _FakeSlidingWindowSpec (_FakeKVCacheSpec ):
182+ def __init__ (self , block_size = 16 , sliding_window = 32 , ** kwargs ):
183+ super ().__init__ (block_size = block_size , sliding_window = sliding_window , ** kwargs )
184+
185+
186+ class _FakeMambaSpec (_FakeKVCacheSpec ):
187+ def __init__ (self , block_size = 16 , ** kwargs ):
188+ super ().__init__ (block_size = block_size , ** kwargs )
189+ self .num_speculative_blocks = getattr (self , "num_speculative_blocks" , 0 )
190+
191+
192+ class _FakeUniformTypeKVCacheSpecs (_FakeKVCacheSpec ):
193+ def __init__ (self , block_size = 16 , kv_cache_specs = None , ** kwargs ):
194+ super ().__init__ (block_size = block_size , ** kwargs )
195+ self .kv_cache_specs = kv_cache_specs or {}
196+
197+ @classmethod
198+ def from_specs (cls , kv_cache_specs ):
199+ if not kv_cache_specs :
200+ return None
201+ first_spec = next (iter (kv_cache_specs .values ()))
202+ return cls (
203+ block_size = getattr (first_spec , "block_size" , 16 ),
204+ kv_cache_specs = kv_cache_specs ,
205+ )
206+
207+
208+ class _FakeKVCacheGroupSpec :
209+ def __init__ (self , layer_names = None , kv_cache_spec = None , is_eagle_group = False ):
210+ self .layer_names = layer_names or []
211+ self .kv_cache_spec = kv_cache_spec or _FakeFullAttentionSpec ()
212+ self .is_eagle_group = is_eagle_group
213+
214+
215+ class _FakeKVCacheConfig :
216+ def __init__ (self , num_blocks = 1 , kv_cache_tensors = None , kv_cache_groups = None ):
217+ self .num_blocks = num_blocks
218+ self .kv_cache_tensors = kv_cache_tensors or []
219+ self .kv_cache_groups = kv_cache_groups or []
220+
221+
222+ _kv_cache_utils_mod .KVCacheBlock = _FakeKVCacheBlock # type: ignore[attr-defined]
223+ _kv_cache_utils_mod .BlockHashList = list # type: ignore[attr-defined]
224+
225+
226+ class _FakeBlockPool :
227+ def __init__ (self , * args , ** kwargs ):
228+ self .null_block = _FakeKVCacheBlock (block_id = 0 )
229+ self ._next_block_id = 1
230+
231+ def get_new_blocks (self , num_blocks ):
232+ blocks = []
233+ for _ in range (num_blocks ):
234+ blocks .append (_FakeKVCacheBlock (block_id = self ._next_block_id ))
235+ self ._next_block_id += 1
236+ return blocks
237+
238+
239+ if _MOCK_VLLM_DEPS :
240+ sys .modules ["vllm.v1.core.block_pool" ].BlockPool = _FakeBlockPool # type: ignore[attr-defined]
241+
242+
243+ class _FakeSingleTypeKVCacheManager :
244+ def __init__ (self , * args , ** kwargs ):
245+ self ._mock = MagicMock ()
246+
247+ def __getattr__ (self , name ):
248+ return getattr (self ._mock , name )
249+
250+ @classmethod
251+ def reachable_block_mask (
252+ cls ,
253+ start_block ,
254+ end_block ,
255+ alignment_tokens ,
256+ kv_cache_spec ,
257+ use_eagle ,
258+ retention_interval = None ,
259+ num_prompt_tokens = None ,
260+ ):
261+ return None
262+
263+ @classmethod
264+ def find_longest_cache_hit (
265+ cls ,
266+ block_hashes ,
267+ max_length ,
268+ kv_cache_group_ids ,
269+ block_pool ,
270+ kv_cache_spec ,
271+ drop_eagle_block = False ,
272+ alignment_tokens = 16 ,
273+ dcp_world_size = 1 ,
274+ pcp_world_size = 1 ,
275+ ):
276+ computed : tuple [list [object ], ...] = tuple ([] for _ in kv_cache_group_ids )
277+ max_blocks = max_length // kv_cache_spec .block_size
278+ for block_hash in list (block_hashes )[:max_blocks ]:
279+ cached = block_pool .get_cached_block (block_hash , kv_cache_group_ids )
280+ if not cached :
281+ break
282+ for blocks , block in zip (computed , cached ):
283+ blocks .append (block )
284+ if drop_eagle_block and computed and computed [0 ]:
285+ for blocks in computed :
286+ blocks .pop ()
287+ return computed
288+
289+
290+ class _FakeSlidingWindowManager (_FakeSingleTypeKVCacheManager ):
291+ @classmethod
292+ def reachable_block_mask (
293+ cls ,
294+ start_block ,
295+ end_block ,
296+ alignment_tokens ,
297+ kv_cache_spec ,
298+ use_eagle ,
299+ retention_interval = None ,
300+ num_prompt_tokens = None ,
301+ ):
302+ if alignment_tokens is None :
303+ return None
304+ per_segment = max (alignment_tokens // kv_cache_spec .block_size , 1 )
305+ return [(idx + 1 ) % per_segment == 0 for idx in range (start_block , end_block )]
306+
307+
308+ _single_type_mod : Any = (
309+ sys .modules ["vllm.v1.core.single_type_kv_cache_manager" ] if _MOCK_VLLM_DEPS else types .SimpleNamespace ()
310+ )
311+ _single_type_mod .SingleTypeKVCacheManager = _FakeSingleTypeKVCacheManager # type: ignore[attr-defined]
312+ _single_type_mod .FullAttentionManager = _FakeSingleTypeKVCacheManager # type: ignore[attr-defined]
313+ _single_type_mod .SlidingWindowManager = _FakeSlidingWindowManager # type: ignore[attr-defined]
314+ _single_type_mod .MambaManager = _FakeSingleTypeKVCacheManager # type: ignore[attr-defined]
315+ _single_type_mod .spec_manager_map = { # type: ignore[attr-defined]
316+ _FakeFullAttentionSpec : _FakeSingleTypeKVCacheManager ,
317+ _FakeSlidingWindowSpec : _FakeSlidingWindowManager ,
318+ _FakeMambaSpec : _FakeSingleTypeKVCacheManager ,
319+ }
320+
321+ _kv_interface_mod : Any = sys .modules ["vllm.v1.kv_cache_interface" ] if _MOCK_VLLM_DEPS else types .SimpleNamespace ()
322+ _kv_interface_mod .KVCacheSpec = _FakeKVCacheSpec # type: ignore[attr-defined]
323+ _kv_interface_mod .FullAttentionSpec = _FakeFullAttentionSpec # type: ignore[attr-defined]
324+ _kv_interface_mod .SlidingWindowSpec = _FakeSlidingWindowSpec # type: ignore[attr-defined]
325+ _kv_interface_mod .MambaSpec = _FakeMambaSpec # type: ignore[attr-defined]
326+ _kv_interface_mod .UniformTypeKVCacheSpecs = _FakeUniformTypeKVCacheSpecs # type: ignore[attr-defined]
327+ _kv_interface_mod .KVCacheGroupSpec = _FakeKVCacheGroupSpec # type: ignore[attr-defined]
328+ _kv_interface_mod .KVCacheConfig = _FakeKVCacheConfig # type: ignore[attr-defined]
329+
330+
331+ class _FakeKVCacheSpecRegistry :
332+ @classmethod
333+ def get_manager_class (cls , kv_cache_spec ):
334+ if isinstance (kv_cache_spec , _FakeSlidingWindowSpec ):
335+ return _FakeSlidingWindowManager
336+ return _FakeSingleTypeKVCacheManager
337+
338+
339+ if _MOCK_VLLM_DEPS :
340+ sys .modules ["vllm.v1.kv_cache_spec_registry" ].KVCacheSpecRegistry = _FakeKVCacheSpecRegistry # type: ignore[attr-defined]
341+
342+ _sched_output_mod : Any = sys .modules ["vllm.v1.core.sched.output" ] if _MOCK_VLLM_DEPS else types .SimpleNamespace ()
135343_sched_output_mod .NewRequestData = MagicMock # type: ignore[attr-defined]
136344
137- sys .modules ["vllm.envs" ].VLLM_RPC_BASE_PATH = "/tmp/vllm_rpc" # type: ignore[attr-defined]
345+ if _MOCK_VLLM_DEPS :
346+ sys .modules ["vllm.envs" ].VLLM_RPC_BASE_PATH = "/tmp/vllm_rpc" # type: ignore[attr-defined]
138347
139348# ---------------------------------------------------------------------------
140349# Mock external backends
0 commit comments