@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 7675ba30de
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 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):