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 15, 09:45 UTC
Update deprecated type hinting in `vllm/device_allocator` and `vllm/distributed` (#18126)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
Harry Mellor committed
May 14, 2025 at 12:07 UTC
dc372b9c8aa97b5da5d4049cdccdaccef950d499
23 files changed
+105
-105
pyproject.toml
-2
@@ -74,8 +74,6 @@ exclude = [
74
# Python 3.8 typing. TODO: Remove these excludes after v1.0.0
75
"vllm/attention/**/*.py" = ["UP006", "UP035"]
76
"vllm/core/**/*.py" = ["UP006", "UP035"]
77
-"vllm/device_allocator/**/*.py" = ["UP006", "UP035"]
78
-"vllm/distributed/**/*.py" = ["UP006", "UP035"]
77
"vllm/engine/**/*.py" = ["UP006", "UP035"]
78
"vllm/executor/**/*.py" = ["UP006", "UP035"]
79
"vllm/model_executor/model_loader/**/*.py" = ["UP006", "UP035"]
vllm/device_allocator/cumem.py
+5
-5
@@ -11,7 +11,7 @@ import dataclasses
11
import gc
12
import os
13
from contextlib import contextmanager
14
-from typing import Any, Callable, Dict, Optional, Tuple, Union
14
+from typing import Any, Callable, Optional, Union
15
16
import torch
17
@@ -63,7 +63,7 @@ except ModuleNotFoundError:
63
libcudart = None
64
65
# py_device, py_alignedSize, py_d_mem, py_p_memHandle
66
-HandleType = Tuple[int, int, int, int]
66
+HandleType = tuple[int, int, int, int]
67
68
69
@dataclasses.dataclass
@@ -148,9 +148,9 @@ class CuMemAllocator:
148
"Please track https://github.com/pytorch/pytorch/issues/147851 "
149
"for the latest updates.")
150
151
- self.pointer_to_data: Dict[int, AllocationData] = {}
151
+ self.pointer_to_data: dict[int, AllocationData] = {}
152
self.current_tag: str = CuMemAllocator.default_tag
153
- self.allocator_and_pools: Dict[str, Any] = {}
153
+ self.allocator_and_pools: dict[str, Any] = {}
154
155
def python_malloc_callback(self, allocation_handle: HandleType) -> None:
156
"""
@@ -172,7 +172,7 @@ class CuMemAllocator:
172
173
def sleep(
174
self,
175
- offload_tags: Optional[Union[Tuple[str, ...],
175
+ offload_tags: Optional[Union[tuple[str, ...],
176
str]] = None) -> None:
177
"""
178
Put the allocator in sleep mode.
vllm/distributed/communication_op.py
+2
-2
@@ -1,6 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
3
-from typing import Any, Dict, Optional, Union
3
+from typing import Any, Optional, Union
4
5
import torch
6
import torch.distributed
@@ -32,7 +32,7 @@ def tensor_model_parallel_gather(input_: torch.Tensor,
32
return get_tp_group().gather(input_, dst, dim)
33
34
35
-def broadcast_tensor_dict(tensor_dict: Optional[Dict[Any, Union[torch.Tensor,
35
+def broadcast_tensor_dict(tensor_dict: Optional[dict[Any, Union[torch.Tensor,
36
Any]]] = None,
37
src: int = 0):
38
if not torch.distributed.is_initialized():
vllm/distributed/device_communicators/base_device_communicator.py
+2
-2
@@ -1,5 +1,5 @@
1
# SPDX-License-Identifier: Apache-2.0
2
-from typing import Optional, Tuple
2
+from typing import Optional
3
4
import torch
5
import torch.distributed as dist
@@ -160,7 +160,7 @@ class DeviceCommunicatorBase:
160
161
def dispatch(
162
self, hidden_states: torch.Tensor,
163
- router_logits: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
163
+ router_logits: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
164
"""
165
Dispatch the hidden states and router logits to the appropriate device.
166
This is a no-op in the base class.
vllm/distributed/device_communicators/cpu_communicator.py
+2
-2
@@ -1,7 +1,7 @@
1
# SPDX-License-Identifier: Apache-2.0
2
3
import os
4
-from typing import List, Optional
4
+from typing import Optional
5
6
import torch
7
from torch.distributed import ProcessGroup
@@ -126,7 +126,7 @@ class _CPUSHMDistributed:
126
127
def gather(self,
128
input: torch.Tensor,
129
- gather_list: Optional[List[torch.Tensor]],
129
+ gather_list: Optional[list[torch.Tensor]],
130
dst: int = -1,
131
group: Optional[ProcessGroup] = None) -> None:
132
# Note: different from the torch gather, here we use local dst rank.
vllm/distributed/device_communicators/cuda_communicator.py
+2
-2
@@ -1,6 +1,6 @@
1
# SPDX-License-Identifier: Apache-2.0
2
3
-from typing import Optional, Tuple
3
+from typing import Optional
4
5
import torch
6
from torch.distributed import ProcessGroup
@@ -154,7 +154,7 @@ class CudaCommunicator(DeviceCommunicatorBase):
154
155
def dispatch(
156
self, hidden_states: torch.Tensor,
157
- router_logits: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
157
+ router_logits: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
158
assert self.all2all_impl is not None
159
hidden_states, router_logits = self.all2all_impl.dispatch(
160
hidden_states, router_logits)
vllm/distributed/device_communicators/cuda_wrapper.py
+4
-4
@@ -6,7 +6,7 @@ convenient for use when we just need to call a few functions.
6
7
import ctypes
8
from dataclasses import dataclass
9
-from typing import Any, Dict, List, Optional
9
+from typing import Any, Optional
10
11
# this line makes it possible to directly load `libcudart.so` using `ctypes`
12
import torch # noqa
@@ -32,7 +32,7 @@ class cudaIpcMemHandle_t(ctypes.Structure):
32
class Function:
33
name: str
34
restype: Any
35
- argtypes: List[Any]
35
+ argtypes: list[Any]
36
37
38
def find_loaded_library(lib_name) -> Optional[str]:
@@ -97,11 +97,11 @@ class CudaRTLibrary:
97
98
# class attribute to store the mapping from the path to the library
99
# to avoid loading the same library multiple times
100
- path_to_library_cache: Dict[str, Any] = {}
100
+ path_to_library_cache: dict[str, Any] = {}
101
102
# class attribute to store the mapping from library path
103
# to the corresponding dictionary
104
- path_to_dict_mapping: Dict[str, Dict[str, Any]] = {}
104
+ path_to_dict_mapping: dict[str, dict[str, Any]] = {}
105
106
def __init__(self, so_file: Optional[str] = None):
107
if so_file is None:
vllm/distributed/device_communicators/custom_all_reduce.py
+4
-4
@@ -1,7 +1,7 @@
1
# SPDX-License-Identifier: Apache-2.0
2
3
from contextlib import contextmanager
4
-from typing import List, Optional, Union
4
+from typing import Optional, Union
5
6
import torch
7
import torch.distributed as dist
@@ -276,7 +276,7 @@ class CustomAllreduce:
276
@staticmethod
277
def create_shared_buffer(size_in_bytes: int,
278
group: Optional[ProcessGroup] = None,
279
- uncached: Optional[bool] = False) -> List[int]:
279
+ uncached: Optional[bool] = False) -> list[int]:
280
pointer, handle = ops.allocate_shared_buffer_and_handle(size_in_bytes)
281
282
world_size = dist.get_world_size(group=group)
@@ -284,7 +284,7 @@ class CustomAllreduce:
284
handles = [None] * world_size
285
dist.all_gather_object(handles, handle, group=group)
286
287
- pointers: List[int] = []
287
+ pointers: list[int] = []
288
for i, h in enumerate(handles):
289
if i == rank:
290
pointers.append(pointer) # type: ignore
@@ -293,7 +293,7 @@ class CustomAllreduce:
293
return pointers
294
295
@staticmethod
296
- def free_shared_buffer(pointers: List[int],
296
+ def free_shared_buffer(pointers: list[int],
297
group: Optional[ProcessGroup] = None,
298
rank: Optional[int] = 0) -> None:
299
if rank is None:
vllm/distributed/device_communicators/custom_all_reduce_utils.py
+5
-4
@@ -7,8 +7,9 @@ import pickle
7
import subprocess
8
import sys
9
import tempfile
10
+from collections.abc import Sequence
11
from itertools import product
11
-from typing import Dict, List, Optional, Sequence
12
+from typing import Optional
13
14
import torch.distributed as dist
15
import torch.multiprocessing as mp
@@ -149,7 +150,7 @@ def can_actually_p2p(
150
p_src.join()
151
p_tgt.join()
152
assert p_src.exitcode == 0 and p_tgt.exitcode == 0
152
- result: List[bool] = []
153
+ result: list[bool] = []
154
for src, tgt in zip(batch_src, batch_tgt):
155
a = result_queue.get()
156
b = result_queue.get()
@@ -175,7 +176,7 @@ def can_actually_p2p(
176
# e.g. used by different vllm engines. The device id in the cache file is a
177
# **local** device id, i.e. from 0 to num_dev-1, where num_dev is the number
178
# of visible devices in the vllm engine.
178
-_gpu_p2p_access_cache: Optional[Dict[str, bool]] = None
179
+_gpu_p2p_access_cache: Optional[dict[str, bool]] = None
180
181
182
def gpu_p2p_access_check(src: int, tgt: int) -> bool:
@@ -204,7 +205,7 @@ def gpu_p2p_access_check(src: int, tgt: int) -> bool:
205
# only the local master process (with local_rank == 0) can
206
# enter this block to calculate the cache
207
logger.info("generating GPU P2P access cache in %s", path)
207
- cache: Dict[str, bool] = {}
208
+ cache: dict[str, bool] = {}
209
ids = list(range(num_dev))
210
# batch of all pairs of GPUs
211
batch_src, batch_tgt = zip(*list(product(ids, ids)))
vllm/distributed/device_communicators/pynccl_wrapper.py
+5
-5
@@ -24,7 +24,7 @@
24
import ctypes
25
import platform
26
from dataclasses import dataclass
27
-from typing import Any, Dict, List, Optional
27
+from typing import Any, Optional
28
29
import torch
30
from torch.distributed import ReduceOp
@@ -121,7 +121,7 @@ class ncclRedOpTypeEnum:
121
class Function:
122
name: str
123
restype: Any
124
- argtypes: List[Any]
124
+ argtypes: list[Any]
125
126
127
class NCCLLibrary:
@@ -210,11 +210,11 @@ class NCCLLibrary:
210
211
# class attribute to store the mapping from the path to the library
212
# to avoid loading the same library multiple times
213
- path_to_library_cache: Dict[str, Any] = {}
213
+ path_to_library_cache: dict[str, Any] = {}
214
215
# class attribute to store the mapping from library path
216
# to the corresponding dictionary
217
- path_to_dict_mapping: Dict[str, Dict[str, Any]] = {}
217
+ path_to_dict_mapping: dict[str, dict[str, Any]] = {}
218
219
def __init__(self, so_file: Optional[str] = None):
220
@@ -238,7 +238,7 @@ class NCCLLibrary:
238
raise e
239
240
if so_file not in NCCLLibrary.path_to_dict_mapping:
241
- _funcs: Dict[str, Any] = {}
241
+ _funcs: dict[str, Any] = {}
242
for func in NCCLLibrary.exported_functions:
243
f = getattr(self.lib, func.name)
244
f.restype = func.restype
vllm/distributed/device_communicators/shm_broadcast.py
+4
-4
@@ -8,7 +8,7 @@ from contextlib import contextmanager
8
from dataclasses import dataclass, field
9
from multiprocessing import shared_memory
10
from threading import Event
11
-from typing import Any, List, Optional, Tuple, Union
11
+from typing import Any, Optional, Union
12
from unittest.mock import patch
13
14
import torch
@@ -173,9 +173,9 @@ class ShmRingBuffer:
173
174
@dataclass
175
class Handle:
176
- local_reader_ranks: List[int] = field(default_factory=list)
176
+ local_reader_ranks: list[int] = field(default_factory=list)
177
178
- buffer_handle: Optional[Tuple[int, int, int, str]] = None
178
+ buffer_handle: Optional[tuple[int, int, int, str]] = None
179
local_subscribe_addr: Optional[str] = None
180
remote_subscribe_addr: Optional[str] = None
181
remote_addr_ipv6: bool = False
@@ -187,7 +187,7 @@ class MessageQueue:
187
self,
188
n_reader, # number of all readers
189
n_local_reader, # number of local readers through shared memory
190
- local_reader_ranks: Optional[List[int]] = None,
190
+ local_reader_ranks: Optional[list[int]] = None,
191
max_chunk_bytes: int = 1024 * 1024 * 10,
192
max_chunks: int = 10,
193
connect_ip: Optional[str] = None,
vllm/distributed/kv_transfer/kv_connector/base.py
+6
-6
@@ -8,7 +8,7 @@ The class provides two primary abstract methods:
8
"""
9
10
from abc import ABC, abstractmethod
11
-from typing import TYPE_CHECKING, List, Tuple, Union
11
+from typing import TYPE_CHECKING, Union
12
13
import torch
14
@@ -55,7 +55,7 @@ class KVConnectorBase(ABC):
55
self,
56
model_executable: torch.nn.Module,
57
model_input: "ModelInputForGPUWithSamplingMetadata",
58
- kv_caches: List[torch.Tensor],
58
+ kv_caches: list[torch.Tensor],
59
hidden_or_intermediate_states: Union[torch.Tensor,
60
IntermediateTensors],
61
) -> None:
@@ -71,7 +71,7 @@ class KVConnectorBase(ABC):
71
start and end layer information.
72
model_input (ModelInputForGPUWithSamplingMetadata): The input
73
metadata from vLLM.
74
- kv_caches (List[torch.Tensor]): List of KV caches (keys and values)
74
+ kv_caches (list[torch.Tensor]): List of KV caches (keys and values)
75
for each layer.
76
hidden_or_intermediate_states (Union[torch.Tensor,
77
IntermediateTensors]):
@@ -88,8 +88,8 @@ class KVConnectorBase(ABC):
88
def recv_kv_caches_and_hidden_states(
89
self, model_executable: torch.nn.Module,
90
model_input: "ModelInputForGPUWithSamplingMetadata",
91
- kv_caches: List[torch.Tensor]
92
- ) -> Tuple[Union[torch.Tensor, IntermediateTensors], bool,
91
+ kv_caches: list[torch.Tensor]
92
+ ) -> tuple[Union[torch.Tensor, IntermediateTensors], bool,
93
"ModelInputForGPUWithSamplingMetadata"]:
94
"""
95
Receive KV caches and hidden states from the connector.
@@ -104,7 +104,7 @@ class KVConnectorBase(ABC):
104
The model executable from vLLM modelrunner.
105
model_input (ModelInputForGPUWithSamplingMetadata):
106
The model input from vLLM modelrunner.
107
- kv_caches (List[torch.Tensor]):
107
+ kv_caches (list[torch.Tensor]):
108
List of KV caches for each layer.
109
110
Returns:
vllm/distributed/kv_transfer/kv_connector/factory.py
+3
-3
@@ -1,7 +1,7 @@
1
# SPDX-License-Identifier: Apache-2.0
2
3
import importlib
4
-from typing import TYPE_CHECKING, Callable, Dict, Type
4
+from typing import TYPE_CHECKING, Callable
5
6
import vllm.envs as envs
7
from vllm.distributed.kv_transfer.kv_connector.base import KVConnectorBaseType
@@ -18,7 +18,7 @@ logger = init_logger(__name__)
18
19
20
class KVConnectorFactory:
21
- _registry: Dict[str, Callable[[], Type[KVConnectorBaseType]]] = {}
21
+ _registry: dict[str, Callable[[], type[KVConnectorBaseType]]] = {}
22
23
@classmethod
24
def register_connector(cls, name: str, module_path: str,
@@ -27,7 +27,7 @@ class KVConnectorFactory:
27
if name in cls._registry:
28
raise ValueError(f"Connector '{name}' is already registered.")
29
30
- def loader() -> Type[KVConnectorBaseType]:
30
+ def loader() -> type[KVConnectorBaseType]:
31
module = importlib.import_module(module_path)
32
return getattr(module, class_name)
33
vllm/distributed/kv_transfer/kv_connector/lmcache_connector.py
+4
-4
@@ -7,7 +7,7 @@ The LMCacheConnector can (1) transfer KV caches between prefill vLLM worker
7
(2) offload and share KV caches.
8
"""
9
10
-from typing import TYPE_CHECKING, List, Tuple, Union
10
+from typing import TYPE_CHECKING, Union
11
12
import torch
13
@@ -63,8 +63,8 @@ class LMCacheConnector(KVConnectorBase):
63
def recv_kv_caches_and_hidden_states(
64
self, model_executable: torch.nn.Module,
65
model_input: "ModelInputForGPUWithSamplingMetadata",
66
- kv_caches: List[torch.Tensor]
67
- ) -> Tuple[Union[torch.Tensor, IntermediateTensors], bool,
66
+ kv_caches: list[torch.Tensor]
67
+ ) -> tuple[Union[torch.Tensor, IntermediateTensors], bool,
68
"ModelInputForGPUWithSamplingMetadata"]:
69
70
retrieve_status = self.lmcache_should_retrieve(model_input)
@@ -78,7 +78,7 @@ class LMCacheConnector(KVConnectorBase):
78
self,
79
model_executable: torch.nn.Module,
80
model_input: "ModelInputForGPUWithSamplingMetadata",
81
- kv_caches: List[torch.Tensor],
81
+ kv_caches: list[torch.Tensor],
82
hidden_or_intermediate_states: Union[torch.Tensor,
83
IntermediateTensors],
84
) -> None:
vllm/distributed/kv_transfer/kv_connector/mooncake_store_connector.py
+4
-4
@@ -6,7 +6,7 @@ The MooncakeStoreConnector transfers KV caches between prefill vLLM workers
6
database-style KVStore.
7
"""
8
import hashlib
9
-from typing import TYPE_CHECKING, List, Tuple, Union
9
+from typing import TYPE_CHECKING, Union
10
11
import torch
12
@@ -70,7 +70,7 @@ class MooncakeStoreConnector(KVConnectorBase):
70
self,
71
model_executable: torch.nn.Module,
72
model_input: "ModelInputForGPUWithSamplingMetadata",
73
- kv_caches: List[torch.Tensor],
73
+ kv_caches: list[torch.Tensor],
74
hidden_or_intermediate_states: Union[torch.Tensor,
75
IntermediateTensors],
76
) -> None:
@@ -113,8 +113,8 @@ class MooncakeStoreConnector(KVConnectorBase):
113
def recv_kv_caches_and_hidden_states(
114
self, model_executable: torch.nn.Module,
115
model_input: "ModelInputForGPUWithSamplingMetadata",
116
- kv_caches: List[torch.Tensor]
117
- ) -> Tuple[Union[torch.Tensor, IntermediateTensors], bool,
116
+ kv_caches: list[torch.Tensor]
117
+ ) -> tuple[Union[torch.Tensor, IntermediateTensors], bool,
118
"ModelInputForGPUWithSamplingMetadata"]:
119
bypass_model_exec = True
120
input_tokens_tensor = model_input.input_tokens
vllm/distributed/kv_transfer/kv_connector/simple_connector.py
+5
-5
@@ -8,7 +8,7 @@ MooncakePipe.
8
9
But the logic can be extended to support other pipe and lookup buffer.
10
"""
11
-from typing import TYPE_CHECKING, List, Optional, Tuple, Union
11
+from typing import TYPE_CHECKING, Optional, Union
12
13
import torch
14
@@ -133,7 +133,7 @@ class SimpleConnector(KVConnectorBase):
133
)
134
135
def select(self, input_tokens: Optional[torch.Tensor],
136
- roi: Optional[torch.Tensor]) -> List[Optional[torch.Tensor]]:
136
+ roi: Optional[torch.Tensor]) -> list[Optional[torch.Tensor]]:
137
138
assert self.consumer_buffer is not None, "Please initialize the "\
139
"consumer buffer before calling select."
@@ -152,7 +152,7 @@ class SimpleConnector(KVConnectorBase):
152
self,
153
model_executable: torch.nn.Module,
154
model_input: "ModelInputForGPUWithSamplingMetadata",
155
- kv_caches: List[torch.Tensor],
155
+ kv_caches: list[torch.Tensor],
156
hidden_or_intermediate_states: Union[torch.Tensor,
157
IntermediateTensors],
158
) -> None:
@@ -207,8 +207,8 @@ class SimpleConnector(KVConnectorBase):
207
def recv_kv_caches_and_hidden_states(
208
self, model_executable: torch.nn.Module,
209
model_input: "ModelInputForGPUWithSamplingMetadata",
210
- kv_caches: List[torch.Tensor]
211
- ) -> Tuple[Union[torch.Tensor, IntermediateTensors], bool,
210
+ kv_caches: list[torch.Tensor]
211
+ ) -> tuple[Union[torch.Tensor, IntermediateTensors], bool,
212
"ModelInputForGPUWithSamplingMetadata"]:
213
214
# When bypass_model_exec is set to False, it means that at least for one
vllm/distributed/kv_transfer/kv_connector/v1/nixl_connector.py
+2
-2
@@ -5,13 +5,13 @@ import threading
5
import time
6
import uuid
7
from collections import defaultdict
8
+from collections.abc import Iterator
9
from dataclasses import dataclass
9
-from typing import TYPE_CHECKING, Any, Iterator
10
+from typing import TYPE_CHECKING, Any, Optional
11
12
import msgspec
13
import torch
14
import zmq
14
-from typing_extensions import Optional
15
16
from vllm import envs
17
from vllm.config import VllmConfig
vllm/distributed/kv_transfer/kv_connector_agent.py
+4
-4
@@ -5,7 +5,7 @@ This implementation is a shim wrapper on two APIs exposed by `kv_connector`:
5
1. `send_kv_caches_and_hidden_states`
6
2. `recv_kv_caches_and_hidden_states
7
"""
8
-from typing import TYPE_CHECKING, List, Tuple, Union
8
+from typing import TYPE_CHECKING, Union
9
10
if TYPE_CHECKING:
11
from vllm.worker.model_runner import ModelInputForGPUWithSamplingMetadata
@@ -53,7 +53,7 @@ class KVTransferAgent:
53
self,
54
model_executable: torch.nn.Module,
55
model_input: "ModelInputForGPUWithSamplingMetadata",
56
- kv_caches: List[torch.Tensor],
56
+ kv_caches: list[torch.Tensor],
57
hidden_or_intermediate_states: Union[torch.Tensor,
58
IntermediateTensors],
59
) -> None:
@@ -68,8 +68,8 @@ class KVTransferAgent:
68
def recv_kv_caches_and_hidden_states(
69
self, model_executable: torch.nn.Module,
70
model_input: "ModelInputForGPUWithSamplingMetadata",
71
- kv_caches: List[torch.Tensor]
72
- ) -> Tuple[Union[torch.Tensor, IntermediateTensors], bool,
71
+ kv_caches: list[torch.Tensor]
72
+ ) -> tuple[Union[torch.Tensor, IntermediateTensors], bool,
73
"ModelInputForGPUWithSamplingMetadata"]:
74
75
return self.connector.recv_kv_caches_and_hidden_states(
vllm/distributed/kv_transfer/kv_lookup_buffer/base.py
+3
-3
@@ -13,7 +13,7 @@ These classes above are abstracted behind class `KVCacheBufferBase`.
13
"""
14
15
from abc import ABC, abstractmethod
16
-from typing import List, Optional
16
+from typing import Optional
17
18
import torch
19
@@ -93,7 +93,7 @@ class KVLookupBufferBase(KVCacheBufferBase):
93
@abstractmethod
94
def drop_select(
95
self, input_tokens: Optional[torch.Tensor],
96
- roi: Optional[torch.Tensor]) -> List[Optional[torch.Tensor]]:
96
+ roi: Optional[torch.Tensor]) -> list[Optional[torch.Tensor]]:
97
"""Select and *drop* KV cache entries from the lookup buffer.
98
99
The functionality is similar to the following python statements
@@ -111,7 +111,7 @@ class KVLookupBufferBase(KVCacheBufferBase):
111
roi (torch.Tensor): A binary mask on top of the input tokens
112
113
Returns:
114
- List[Optional[torch.Tensor]]: A list of tensors. Can be None.
114
+ list[Optional[torch.Tensor]]: A list of tensors. Can be None.
115
116
Raises:
117
NotImplementedError: This method must be implemented in subclasses.
vllm/distributed/kv_transfer/kv_lookup_buffer/simple_buffer.py
+7
-7
@@ -11,7 +11,7 @@
11
"""
12
import threading
13
from collections import deque
14
-from typing import Deque, List, Optional, Union
14
+from typing import Optional, Union
15
16
import torch
17
@@ -38,7 +38,7 @@ class SimpleBuffer(KVLookupBufferBase):
38
data_pipe: on device (e.g. GPU)
39
"""
40
41
- self.buffer: Deque[List[torch.Tensor]] = deque()
41
+ self.buffer: deque[list[torch.Tensor]] = deque()
42
43
self.buffer_size = 0
44
self.buffer_size_threshold = buffer_size_thresh
@@ -50,8 +50,8 @@ class SimpleBuffer(KVLookupBufferBase):
50
self.normal_signal = torch.tensor([0], device="cpu")
51
self.end_signal = None
52
53
- def _matches(self, tokens_roi_sender: List[torch.Tensor],
54
- tokens_roi_recver: List[torch.Tensor]):
53
+ def _matches(self, tokens_roi_sender: list[torch.Tensor],
54
+ tokens_roi_recver: list[torch.Tensor]):
55
56
# tokens_roi_sender: tokens and roi of the producer (in the buffer)
57
# tokens_roi_recver: tokens and roi of the consumer (query)
@@ -88,7 +88,7 @@ class SimpleBuffer(KVLookupBufferBase):
88
tensor = tensor.float()
89
self.data_pipe.send_tensor(tensor)
90
91
- def _get_element_size(self, data: Optional[Union[List, torch.Tensor]]):
91
+ def _get_element_size(self, data: Optional[Union[list, torch.Tensor]]):
92
93
if isinstance(data, torch.Tensor):
94
return data.element_size() * data.numel()
@@ -151,7 +151,7 @@ class SimpleBuffer(KVLookupBufferBase):
151
tokens_roi_recver = [input_tokens, roi]
152
153
def is_buffer_available(
154
- tokens_roi_recver: List[torch.Tensor], ) -> bool:
154
+ tokens_roi_recver: list[torch.Tensor], ) -> bool:
155
# perform input tokens and roi matching
156
# FIXME: this matching is O(n), ideally it should be O(1)
157
# but this buffer size won't (and shouldn't) be too large so
@@ -184,7 +184,7 @@ class SimpleBuffer(KVLookupBufferBase):
184
185
def drop_select(
186
self, input_tokens: Optional[torch.Tensor],
187
- roi: Optional[torch.Tensor]) -> List[Optional[torch.Tensor]]:
187
+ roi: Optional[torch.Tensor]) -> list[Optional[torch.Tensor]]:
188
189
assert self.request_handling_thread is None, \
190
"drop_select should be called by the KV cache consumer "\
vllm/distributed/kv_transfer/kv_pipe/pynccl_pipe.py
+3
-3
@@ -15,7 +15,7 @@
15
import threading
16
import time
17
from concurrent.futures import ThreadPoolExecutor
18
-from typing import Callable, Dict, Optional, Tuple
18
+from typing import Callable, Optional
19
20
import torch
21
@@ -35,7 +35,7 @@ class BrokenPipeException(Exception):
35
super().__init__(self.message)
36
37
38
-Metadata = Dict[str, Optional[torch.Tensor]]
38
+Metadata = dict[str, Optional[torch.Tensor]]
39
40
41
class PyNcclPipe(KVPipeBase):
@@ -83,7 +83,7 @@ class PyNcclPipe(KVPipeBase):
83
84
def _get_device_send_recv_impl(
85
self, group: StatelessProcessGroup
86
- ) -> Tuple[Callable[[torch.Tensor, int], None], Callable[
86
+ ) -> tuple[Callable[[torch.Tensor, int], None], Callable[
87
[torch.Tensor, int], None]]:
88
89
send: Callable[[torch.Tensor, int], None]
vllm/distributed/parallel_state.py
+22
-22
@@ -29,7 +29,7 @@ from collections import namedtuple
29
from contextlib import contextmanager, nullcontext
30
from dataclasses import dataclass
31
from multiprocessing import shared_memory
32
-from typing import Any, Callable, Dict, List, Optional, Tuple, Union
32
+from typing import Any, Callable, Optional, Union
33
from unittest.mock import patch
34
35
import torch
@@ -54,15 +54,15 @@ TensorMetadata = namedtuple("TensorMetadata", ["device", "dtype", "size"])
54
55
56
def _split_tensor_dict(
57
- tensor_dict: Dict[str, Union[torch.Tensor, Any]]
58
-) -> Tuple[List[Tuple[str, Any]], List[torch.Tensor]]:
57
+ tensor_dict: dict[str, Union[torch.Tensor, Any]]
58
+) -> tuple[list[tuple[str, Any]], list[torch.Tensor]]:
59
"""Split the tensor dictionary into two parts:
60
1. A list of (key, value) pairs. If the value is a tensor, it is replaced
61
by its metadata.
62
2. A list of tensors.
63
"""
64
- metadata_list: List[Tuple[str, Any]] = []
65
- tensor_list: List[torch.Tensor] = []
64
+ metadata_list: list[tuple[str, Any]] = []
65
+ tensor_list: list[torch.Tensor] = []
66
for key, value in tensor_dict.items():
67
if isinstance(value, torch.Tensor):
68
# Note: we cannot use `value.device` here,
@@ -78,7 +78,7 @@ def _split_tensor_dict(
78
return metadata_list, tensor_list
79
80
81
-_group_name_counter: Dict[str, int] = {}
81
+_group_name_counter: dict[str, int] = {}
82
83
84
def _get_unique_name(name: str) -> str:
@@ -94,7 +94,7 @@ def _get_unique_name(name: str) -> str:
94
return newname
95
96
97
-_groups: Dict[str, Callable[[], Optional["GroupCoordinator"]]] = {}
97
+_groups: dict[str, Callable[[], Optional["GroupCoordinator"]]] = {}
98
99
100
def _register_group(group: "GroupCoordinator") -> None:
@@ -182,7 +182,7 @@ class GroupCoordinator:
182
183
# available attributes:
184
rank: int # global rank
185
- ranks: List[int] # global ranks in the group
185
+ ranks: list[int] # global ranks in the group
186
world_size: int # size of the group
187
# difference between `local_rank` and `rank_in_group`:
188
# if we have a group of size 4 across two nodes:
@@ -201,7 +201,7 @@ class GroupCoordinator:
201
202
def __init__(
203
self,
204
- group_ranks: List[List[int]],
204
+ group_ranks: list[list[int]],
205
local_rank: int,
206
torch_distributed_backend: Union[str, Backend],
207
use_device_communicator: bool,
@@ -435,7 +435,7 @@ class GroupCoordinator:
435
return recv[0]
436
437
def broadcast_object_list(self,
438
- obj_list: List[Any],
438
+ obj_list: list[Any],
439
src: int = 0,
440
group: Optional[ProcessGroup] = None):
441
"""Broadcast the input object list.
@@ -518,11 +518,11 @@ class GroupCoordinator:
518
519
def broadcast_tensor_dict(
520
self,
521
- tensor_dict: Optional[Dict[str, Union[torch.Tensor, Any]]] = None,
521
+ tensor_dict: Optional[dict[str, Union[torch.Tensor, Any]]] = None,
522
src: int = 0,
523
group: Optional[ProcessGroup] = None,
524
metadata_group: Optional[ProcessGroup] = None
525
- ) -> Optional[Dict[str, Union[torch.Tensor, Any]]]:
525
+ ) -> Optional[dict[str, Union[torch.Tensor, Any]]]:
526
"""Broadcast the input tensor dictionary.
527
NOTE: `src` is the local rank of the source rank.
528
"""
@@ -536,7 +536,7 @@ class GroupCoordinator:
536
537
rank_in_group = self.rank_in_group
538
if rank_in_group == src:
539
- metadata_list: List[Tuple[Any, Any]] = []
539
+ metadata_list: list[tuple[Any, Any]] = []
540
assert isinstance(
541
tensor_dict,
542
dict), (f"Expecting a dictionary, got {type(tensor_dict)}")
@@ -603,10 +603,10 @@ class GroupCoordinator:
603
604
def send_tensor_dict(
605
self,
606
- tensor_dict: Dict[str, Union[torch.Tensor, Any]],
606
+ tensor_dict: dict[str, Union[torch.Tensor, Any]],
607
dst: Optional[int] = None,
608
all_gather_group: Optional["GroupCoordinator"] = None,
609
- ) -> Optional[Dict[str, Union[torch.Tensor, Any]]]:
609
+ ) -> Optional[dict[str, Union[torch.Tensor, Any]]]:
610
"""Send the input tensor dictionary.
611
NOTE: `dst` is the local rank of the source rank.
612
"""
@@ -626,7 +626,7 @@ class GroupCoordinator:
626
dst = (self.rank_in_group + 1) % self.world_size
627
assert dst < self.world_size, f"Invalid dst rank ({dst})"
628
629
- metadata_list: List[Tuple[Any, Any]] = []
629
+ metadata_list: list[tuple[Any, Any]] = []
630
assert isinstance(
631
tensor_dict,
632
dict), f"Expecting a dictionary, got {type(tensor_dict)}"
@@ -661,7 +661,7 @@ class GroupCoordinator:
661
self,
662
src: Optional[int] = None,
663
all_gather_group: Optional["GroupCoordinator"] = None,
664
- ) -> Optional[Dict[str, Union[torch.Tensor, Any]]]:
664
+ ) -> Optional[dict[str, Union[torch.Tensor, Any]]]:
665
"""Recv the input tensor dictionary.
666
NOTE: `src` is the local rank of the source rank.
667
"""
@@ -682,7 +682,7 @@ class GroupCoordinator:
682
assert src < self.world_size, f"Invalid src rank ({src})"
683
684
recv_metadata_list = self.recv_object(src=src)
685
- tensor_dict: Dict[str, Any] = {}
685
+ tensor_dict: dict[str, Any] = {}
686
for key, value in recv_metadata_list:
687
if isinstance(value, TensorMetadata):
688
tensor = torch.empty(value.size,
@@ -764,7 +764,7 @@ class GroupCoordinator:
764
765
def dispatch(
766
self, hidden_states: torch.Tensor,
767
- router_logits: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
767
+ router_logits: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
768
if self.device_communicator is not None:
769
return self.device_communicator.dispatch(hidden_states,
770
router_logits)
@@ -782,7 +782,7 @@ def get_world_group() -> GroupCoordinator:
782
return _WORLD
783
784
785
-def init_world_group(ranks: List[int], local_rank: int,
785
+def init_world_group(ranks: list[int], local_rank: int,
786
backend: str) -> GroupCoordinator:
787
return GroupCoordinator(
788
group_ranks=[ranks],
@@ -794,7 +794,7 @@ def init_world_group(ranks: List[int], local_rank: int,
794
795
796
def init_model_parallel_group(
797
- group_ranks: List[List[int]],
797
+ group_ranks: list[list[int]],
798
local_rank: int,
799
backend: str,
800
use_message_queue_broadcaster: bool = False,
@@ -1182,7 +1182,7 @@ def cleanup_dist_env_and_memory(shutdown_ray: bool = False):
1182
1183
1184
def in_the_same_node_as(pg: Union[ProcessGroup, StatelessProcessGroup],
1185
- source_rank: int = 0) -> List[bool]:
1185
+ source_rank: int = 0) -> list[bool]:
1186
"""
1187
This is a collective operation that returns if each rank is in the same node
1188
as the source rank. It tests if processes are attached to the same
vllm/distributed/utils.py
+7
-6
@@ -10,7 +10,8 @@ import pickle
10
import socket
11
import time
12
from collections import deque
13
-from typing import Any, Deque, Dict, Optional, Sequence, Tuple
13
+from collections.abc import Sequence
14
+from typing import Any, Optional
15
16
import torch
17
from torch.distributed import ProcessGroup, TCPStore
@@ -69,7 +70,7 @@ def split_tensor_along_last_dim(
70
71
72
def get_pp_indices(num_hidden_layers: int, pp_rank: int,
72
- pp_size: int) -> Tuple[int, int]:
73
+ pp_size: int) -> tuple[int, int]:
74
"""Try to evenly distribute layers across partitions.
75
76
If the number of layers is not divisible by the number of partitions,
@@ -132,15 +133,15 @@ class StatelessProcessGroup:
133
data_expiration_seconds: int = 3600 # 1 hour
134
135
# dst rank -> counter
135
- send_dst_counter: Dict[int, int] = dataclasses.field(default_factory=dict)
136
+ send_dst_counter: dict[int, int] = dataclasses.field(default_factory=dict)
137
# src rank -> counter
137
- recv_src_counter: Dict[int, int] = dataclasses.field(default_factory=dict)
138
+ recv_src_counter: dict[int, int] = dataclasses.field(default_factory=dict)
139
broadcast_send_counter: int = 0
139
- broadcast_recv_src_counter: Dict[int, int] = dataclasses.field(
140
+ broadcast_recv_src_counter: dict[int, int] = dataclasses.field(
141
default_factory=dict)
142
143
# A deque to store the data entries, with key and timestamp.
143
- entries: Deque[Tuple[str,
144
+ entries: deque[tuple[str,
145
float]] = dataclasses.field(default_factory=deque)
146
147
def __post_init__(self):