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 12, 09:45 UTC
[Misc] Remove redundant `ClassRegistry` (#29681)
Signed-off-by: DarkLight1337 <tlleungac@connect.ust.hk> Signed-off-by: Cyrus Leung <cyrus.tl.leung@gmail.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Cyrus Leung committed
Nov 29, 2025 at 07:24 UTC
7675ba30de041269988f9307b3fcb65e410a3857
5 files changed
+25
-49
tests/models/multimodal/processing/test_common.py
+1
-1
@@ -233,7 +233,7 @@ def _test_processing_correctness(
233
)
234
235
model_cls = MULTIMODAL_REGISTRY._get_model_cls(model_config)
236
- factories = MULTIMODAL_REGISTRY._processor_factories[model_cls]
236
+ factories = model_cls._processor_factory
237
ctx = InputProcessingContext(
238
model_config,
239
tokenizer=cached_tokenizer_from_config(model_config),
tests/models/multimodal/processing/test_tensor_schema.py
+1
-1
@@ -193,7 +193,7 @@ def test_model_tensor_schema(model_id: str):
193
model_cls = MULTIMODAL_REGISTRY._get_model_cls(model_config)
194
assert supports_multimodal(model_cls)
195
196
- factories = MULTIMODAL_REGISTRY._processor_factories[model_cls]
196
+ factories = model_cls._processor_factory
197
198
inputs_parse_methods = []
199
for attr_name in dir(model_cls):
vllm/model_executor/models/interfaces.py
+7
@@ -32,11 +32,13 @@ if TYPE_CHECKING:
32
from vllm.config import VllmConfig
33
from vllm.model_executor.models.utils import WeightsMapper
34
from vllm.multimodal.inputs import MultiModalFeatureSpec
35
+ from vllm.multimodal.registry import _ProcessorFactories
36
from vllm.sequence import IntermediateTensors
37
else:
38
VllmConfig = object
39
WeightsMapper = object
40
MultiModalFeatureSpec = object
41
+ _ProcessorFactories = object
42
IntermediateTensors = object
43
44
logger = init_logger(__name__)
@@ -87,6 +89,11 @@ class SupportsMultiModal(Protocol):
89
A set indicating CPU-only multimodal fields.
90
"""
91
92
+ _processor_factory: ClassVar[_ProcessorFactories]
93
+ """
94
+ Set internally by `MultiModalRegistry.register_processor`.
95
+ """
96
+
97
@classmethod
98
def get_placeholder_str(cls, modality: str, i: int) -> str | None:
99
"""
vllm/multimodal/registry.py
+10
-14
@@ -2,14 +2,11 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
from collections.abc import Mapping
4
from dataclasses import dataclass
5
-from typing import TYPE_CHECKING, Generic, Protocol, TypeVar
6
-
7
-import torch.nn as nn
5
+from typing import TYPE_CHECKING, Generic, Protocol, TypeVar, cast
6
7
from vllm.config.multimodal import BaseDummyOptions
8
from vllm.logger import init_logger
9
from vllm.transformers_utils.tokenizer import AnyTokenizer, cached_tokenizer_from_config
12
-from vllm.utils.collection_utils import ClassRegistry
10
11
from .cache import BaseMultiModalProcessorCache
12
from .processing import (
@@ -26,10 +23,11 @@ from .profiling import (
23
24
if TYPE_CHECKING:
25
from vllm.config import ModelConfig
26
+ from vllm.model_executor.models.interfaces import SupportsMultiModal
27
28
logger = init_logger(__name__)
29
32
-N = TypeVar("N", bound=type[nn.Module])
30
+N = TypeVar("N", bound=type["SupportsMultiModal"])
31
_I = TypeVar("_I", bound=BaseProcessingInfo)
32
_I_co = TypeVar("_I_co", bound=BaseProcessingInfo, covariant=True)
33
@@ -95,9 +93,6 @@ class MultiModalRegistry:
93
A registry that dispatches data processing according to the model.
94
"""
95
98
- def __init__(self) -> None:
99
- self._processor_factories = ClassRegistry[nn.Module, _ProcessorFactories]()
100
-
96
def _extract_mm_options(
97
self,
98
model_config: "ModelConfig",
@@ -207,7 +202,7 @@ class MultiModalRegistry:
202
"""
203
204
def wrapper(model_cls: N) -> N:
210
- if self._processor_factories.contains(model_cls, strict=True):
205
+ if "_processor_factory" in model_cls.__dict__:
206
logger.warning(
207
"Model class %s already has a multi-modal processor "
208
"registered to %s. It is overwritten by the new one.",
@@ -215,7 +210,7 @@ class MultiModalRegistry:
210
self,
211
)
212
218
- self._processor_factories[model_cls] = _ProcessorFactories(
213
+ model_cls._processor_factory = _ProcessorFactories(
214
info=info,
215
dummy_inputs=dummy_inputs,
216
processor=processor,
@@ -225,12 +220,13 @@ class MultiModalRegistry:
220
221
return wrapper
222
228
- def _get_model_cls(self, model_config: "ModelConfig"):
223
+ def _get_model_cls(self, model_config: "ModelConfig") -> "SupportsMultiModal":
224
# Avoid circular import
225
from vllm.model_executor.model_loader import get_model_architecture
226
227
model_cls, _ = get_model_architecture(model_config)
233
- return model_cls
228
+ assert hasattr(model_cls, "_processor_factory")
229
+ return cast("SupportsMultiModal", model_cls)
230
231
def _create_processing_ctx(
232
self,
@@ -248,7 +244,7 @@ class MultiModalRegistry:
244
tokenizer: AnyTokenizer | None = None,
245
) -> BaseProcessingInfo:
246
model_cls = self._get_model_cls(model_config)
251
- factories = self._processor_factories[model_cls]
247
+ factories = model_cls._processor_factory
248
ctx = self._create_processing_ctx(model_config, tokenizer)
249
return factories.info(ctx)
250
@@ -266,7 +262,7 @@ class MultiModalRegistry:
262
raise ValueError(f"{model_config.model} is not a multimodal model")
263
264
model_cls = self._get_model_cls(model_config)
269
- factories = self._processor_factories[model_cls]
265
+ factories = model_cls._processor_factory
266
267
ctx = self._create_processing_ctx(model_config, tokenizer)
268
vllm/utils/collection_utils.py
+6
-33
@@ -6,64 +6,37 @@ Contains helpers that are applied to collections.
6
This is similar in concept to the `collections` module.
7
"""
8
9
-from collections import UserDict, defaultdict
9
+from collections import defaultdict
10
from collections.abc import Callable, Generator, Hashable, Iterable, Mapping
11
from typing import Generic, Literal, TypeVar
12
13
from typing_extensions import TypeIs, assert_never
14
15
T = TypeVar("T")
16
-U = TypeVar("U")
16
17
_K = TypeVar("_K", bound=Hashable)
18
_V = TypeVar("_V")
19
20
22
-class ClassRegistry(UserDict[type[T], _V]):
23
- """
24
- A registry that acts like a dictionary but searches for other classes
25
- in the MRO if the original class is not found.
26
- """
27
-
28
- def __getitem__(self, key: type[T]) -> _V:
29
- for cls in key.mro():
30
- if cls in self.data:
31
- return self.data[cls]
32
-
33
- raise KeyError(key)
34
-
35
- def __contains__(self, key: object) -> bool:
36
- return self.contains(key)
37
-
38
- def contains(self, key: object, *, strict: bool = False) -> bool:
39
- if not isinstance(key, type):
40
- return False
41
-
42
- if strict:
43
- return key in self.data
44
-
45
- return any(cls in self.data for cls in key.mro())
46
-
47
-
48
-class LazyDict(Mapping[str, T], Generic[T]):
21
+class LazyDict(Mapping[str, _V], Generic[_V]):
22
"""
23
Evaluates dictionary items only when they are accessed.
24
25
Adapted from: https://stackoverflow.com/a/47212782/5082708
26
"""
27
55
- def __init__(self, factory: dict[str, Callable[[], T]]):
28
+ def __init__(self, factory: dict[str, Callable[[], _V]]):
29
self._factory = factory
57
- self._dict: dict[str, T] = {}
30
+ self._dict: dict[str, _V] = {}
31
59
- def __getitem__(self, key: str) -> T:
32
+ def __getitem__(self, key: str) -> _V:
33
if key not in self._dict:
34
if key not in self._factory:
35
raise KeyError(key)
36
self._dict[key] = self._factory[key]()
37
return self._dict[key]
38
66
- def __setitem__(self, key: str, value: Callable[[], T]):
39
+ def __setitem__(self, key: str, value: Callable[[], _V]):
40
self._factory[key] = value
41
42
def __iter__(self):