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 9, 05:00 UTC
[Refactor] Make Renderer an abstract class (#33479)
Signed-off-by: DarkLight1337 <tlleungac@connect.ust.hk>
Cyrus Leung committed
Feb 1, 2026 at 10:36 UTC
a358e4dffe10ebff2c44434958bcc190ad2e5542
12 files changed
+49
-50
vllm/engine/protocol.py
+2
-2
@@ -11,7 +11,7 @@ from vllm.lora.request import LoRARequest
11
from vllm.outputs import PoolingRequestOutput, RequestOutput
12
from vllm.plugins.io_processors import IOProcessor
13
from vllm.pooling_params import PoolingParams
14
-from vllm.renderers import RendererLike
14
+from vllm.renderers import BaseRenderer
15
from vllm.sampling_params import SamplingParams
16
from vllm.tasks import SupportedTask
17
from vllm.v1.engine import EngineCoreRequest
@@ -28,7 +28,7 @@ class EngineClient(ABC):
28
29
@property
30
@abstractmethod
31
- def renderer(self) -> RendererLike: ...
31
+ def renderer(self) -> BaseRenderer: ...
32
33
@property
34
@abstractmethod
vllm/renderers/__init__.py
+2
-2
@@ -2,11 +2,11 @@
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4
from .params import ChatParams, TokenizeParams, merge_kwargs
5
-from .protocol import RendererLike
5
+from .protocol import BaseRenderer
6
from .registry import RendererRegistry, renderer_from_config
7
8
__all__ = [
9
- "RendererLike",
9
+ "BaseRenderer",
10
"RendererRegistry",
11
"renderer_from_config",
12
"ChatParams",
vllm/renderers/deepseek_v32.py
+4
-6
@@ -15,18 +15,18 @@ from vllm.tokenizers import cached_get_tokenizer
15
from vllm.tokenizers.deepseek_v32 import DeepseekV32Tokenizer
16
17
from .params import ChatParams
18
-from .protocol import RendererLike
18
+from .protocol import BaseRenderer
19
20
logger = init_logger(__name__)
21
22
23
-class DeepseekV32Renderer(RendererLike):
23
+class DeepseekV32Renderer(BaseRenderer):
24
@classmethod
25
def from_config(
26
cls,
27
config: ModelConfig,
28
tokenizer_kwargs: dict[str, Any],
29
- ) -> "RendererLike":
29
+ ) -> "BaseRenderer":
30
return cls(config, tokenizer_kwargs)
31
32
def __init__(
@@ -34,9 +34,7 @@ class DeepseekV32Renderer(RendererLike):
34
config: ModelConfig,
35
tokenizer_kwargs: dict[str, Any],
36
) -> None:
37
- super().__init__()
38
-
39
- self.config = config
37
+ super().__init__(config)
38
39
if config.skip_tokenizer_init:
40
tokenizer = None
vllm/renderers/grok2.py
+4
-6
@@ -15,18 +15,18 @@ from vllm.tokenizers import cached_get_tokenizer
15
from vllm.tokenizers.grok2 import Grok2Tokenizer
16
17
from .params import ChatParams
18
-from .protocol import RendererLike
18
+from .protocol import BaseRenderer
19
20
logger = init_logger(__name__)
21
22
23
-class Grok2Renderer(RendererLike):
23
+class Grok2Renderer(BaseRenderer):
24
@classmethod
25
def from_config(
26
cls,
27
config: ModelConfig,
28
tokenizer_kwargs: dict[str, Any],
29
- ) -> "RendererLike":
29
+ ) -> "BaseRenderer":
30
return cls(config, tokenizer_kwargs)
31
32
def __init__(
@@ -34,9 +34,7 @@ class Grok2Renderer(RendererLike):
34
config: ModelConfig,
35
tokenizer_kwargs: dict[str, Any],
36
) -> None:
37
- super().__init__()
38
-
39
- self.config = config
37
+ super().__init__(config)
38
39
if config.skip_tokenizer_init:
40
tokenizer = None
vllm/renderers/hf.py
+4
-5
@@ -34,7 +34,7 @@ from vllm.transformers_utils.processor import cached_get_processor
34
from vllm.utils.func_utils import supports_kw
35
36
from .params import ChatParams
37
-from .protocol import RendererLike
37
+from .protocol import BaseRenderer
38
39
if TYPE_CHECKING:
40
from vllm.multimodal.inputs import MultiModalDataDict, MultiModalUUIDDict
@@ -584,13 +584,13 @@ def replace_vision_chunk_video_placeholder(
584
return prompt_raw
585
586
587
-class HfRenderer(RendererLike):
587
+class HfRenderer(BaseRenderer):
588
@classmethod
589
def from_config(
590
cls,
591
config: ModelConfig,
592
tokenizer_kwargs: dict[str, Any],
593
- ) -> "RendererLike":
593
+ ) -> "BaseRenderer":
594
return cls(config, tokenizer_kwargs)
595
596
def __init__(
@@ -598,9 +598,8 @@ class HfRenderer(RendererLike):
598
config: ModelConfig,
599
tokenizer_kwargs: dict[str, Any],
600
) -> None:
601
- super().__init__()
601
+ super().__init__(config)
602
603
- self.config = config
603
self.use_unified_vision_chunk = getattr(
604
config.hf_config, "use_unified_vision_chunk", False
605
)
vllm/renderers/mistral.py
+4
-6
@@ -17,7 +17,7 @@ from vllm.tokenizers.mistral import MistralTokenizer
17
from vllm.utils.async_utils import make_async
18
19
from .params import ChatParams
20
-from .protocol import RendererLike
20
+from .protocol import BaseRenderer
21
22
logger = init_logger(__name__)
23
@@ -49,13 +49,13 @@ def safe_apply_chat_template(
49
raise ValueError(str(e)) from e
50
51
52
-class MistralRenderer(RendererLike):
52
+class MistralRenderer(BaseRenderer):
53
@classmethod
54
def from_config(
55
cls,
56
config: ModelConfig,
57
tokenizer_kwargs: dict[str, Any],
58
- ) -> "RendererLike":
58
+ ) -> "BaseRenderer":
59
return cls(config, tokenizer_kwargs)
60
61
def __init__(
@@ -63,9 +63,7 @@ class MistralRenderer(RendererLike):
63
config: ModelConfig,
64
tokenizer_kwargs: dict[str, Any],
65
) -> None:
66
- super().__init__()
67
-
68
- self.config = config
66
+ super().__init__(config)
67
68
if config.skip_tokenizer_init:
69
tokenizer = None
vllm/renderers/protocol.py
+16
-8
@@ -1,7 +1,8 @@
1
# SPDX-License-Identifier: Apache-2.0
2
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
import asyncio
4
-from typing import TYPE_CHECKING, Any, Protocol
4
+from abc import ABC, abstractmethod
5
+from typing import TYPE_CHECKING, Any
6
7
from vllm.inputs import EmbedsPrompt, TextPrompt, TokensPrompt
8
from vllm.tokenizers import TokenizerLike
@@ -19,19 +20,26 @@ if TYPE_CHECKING:
20
)
21
22
22
-class RendererLike(Protocol):
23
- config: "ModelConfig"
24
- _async_tokenizer: AsyncMicrobatchTokenizer
25
-
23
+class BaseRenderer(ABC):
24
@classmethod
25
+ @abstractmethod
26
def from_config(
27
cls,
28
config: "ModelConfig",
29
tokenizer_kwargs: dict[str, Any],
31
- ) -> "RendererLike":
30
+ ) -> "BaseRenderer":
31
raise NotImplementedError
32
33
+ def __init__(self, config: "ModelConfig") -> None:
34
+ super().__init__()
35
+
36
+ self.config = config
37
+
38
+ # Lazy initialization since offline LLM doesn't use async
39
+ self._async_tokenizer: AsyncMicrobatchTokenizer | None = None
40
+
41
@property
42
+ @abstractmethod
43
def tokenizer(self) -> TokenizerLike | None:
44
raise NotImplementedError
45
@@ -43,8 +51,7 @@ class RendererLike(Protocol):
51
return tokenizer
52
53
def get_async_tokenizer(self) -> AsyncMicrobatchTokenizer:
46
- # Lazy initialization since offline LLM doesn't use async
47
- if not hasattr(self, "_async_tokenizer"):
54
+ if self._async_tokenizer is None:
55
self._async_tokenizer = AsyncMicrobatchTokenizer(self.get_tokenizer())
56
57
return self._async_tokenizer
@@ -104,6 +111,7 @@ class RendererLike(Protocol):
111
) -> list[TextPrompt | TokensPrompt | EmbedsPrompt]:
112
return self.render_completions(prompt_input, prompt_embeds)
113
114
+ @abstractmethod
115
def render_messages(
116
self,
117
messages: list["ChatCompletionMessageParam"],
vllm/renderers/registry.py
+3
-3
@@ -7,7 +7,7 @@ from vllm.logger import init_logger
7
from vllm.tokenizers.registry import tokenizer_args_from_config
8
from vllm.utils.import_utils import resolve_obj_by_qualname
9
10
-from .protocol import RendererLike
10
+from .protocol import BaseRenderer
11
12
if TYPE_CHECKING:
13
from vllm.config import ModelConfig
@@ -43,7 +43,7 @@ class RendererRegistry:
43
44
return None
45
46
- def load_renderer_cls(self, renderer_mode: str) -> type[RendererLike]:
46
+ def load_renderer_cls(self, renderer_mode: str) -> type[BaseRenderer]:
47
if renderer_mode not in self.renderers:
48
raise ValueError(f"No renderer registered for {renderer_mode=!r}.")
49
@@ -57,7 +57,7 @@ class RendererRegistry:
57
renderer_mode: str,
58
config: "ModelConfig",
59
tokenizer_kwargs: dict[str, Any],
60
- ) -> RendererLike:
60
+ ) -> BaseRenderer:
61
renderer_cls = self.load_renderer_cls(renderer_mode)
62
return renderer_cls.from_config(config, tokenizer_kwargs)
63
vllm/renderers/terratorch.py
+4
-6
@@ -14,24 +14,22 @@ from vllm.logger import init_logger
14
from vllm.tokenizers import TokenizerLike
15
16
from .params import ChatParams
17
-from .protocol import RendererLike
17
+from .protocol import BaseRenderer
18
19
logger = init_logger(__name__)
20
21
22
-class TerratorchRenderer(RendererLike):
22
+class TerratorchRenderer(BaseRenderer):
23
@classmethod
24
def from_config(
25
cls,
26
config: "ModelConfig",
27
tokenizer_kwargs: dict[str, Any],
28
- ) -> "RendererLike":
28
+ ) -> "BaseRenderer":
29
return cls(config)
30
31
def __init__(self, config: ModelConfig) -> None:
32
- super().__init__()
33
-
34
- self.config = config
32
+ super().__init__(config)
33
34
if not config.skip_tokenizer_init:
35
raise ValueError("Terratorch renderer requires `skip_tokenizer_init=True`")
vllm/v1/engine/async_llm.py
+2
-2
@@ -24,7 +24,7 @@ from vllm.multimodal import MULTIMODAL_REGISTRY, MultiModalRegistry
24
from vllm.outputs import STREAM_FINISHED, PoolingRequestOutput, RequestOutput
25
from vllm.plugins.io_processors import get_io_processor
26
from vllm.pooling_params import PoolingParams
27
-from vllm.renderers import RendererLike, merge_kwargs
27
+from vllm.renderers import BaseRenderer, merge_kwargs
28
from vllm.sampling_params import RequestOutputKind, SamplingParams
29
from vllm.tasks import SupportedTask
30
from vllm.tokenizers import TokenizerLike
@@ -844,7 +844,7 @@ class AsyncLLM(EngineClient):
844
return self.input_processor.get_tokenizer()
845
846
@property
847
- def renderer(self) -> RendererLike:
847
+ def renderer(self) -> BaseRenderer:
848
return self.input_processor.renderer
849
850
async def is_tracing_enabled(self) -> bool:
vllm/v1/engine/input_processor.py
+2
-2
@@ -29,7 +29,7 @@ from vllm.multimodal.parse import ModalityDataItems, MultiModalDataItems
29
from vllm.multimodal.processing.context import set_request_id
30
from vllm.multimodal.utils import argsort_mm_positions
31
from vllm.pooling_params import PoolingParams
32
-from vllm.renderers import RendererLike
32
+from vllm.renderers import BaseRenderer
33
from vllm.sampling_params import _SAMPLING_EPS, SamplingParams
34
from vllm.tokenizers import TokenizerLike
35
from vllm.tokenizers.mistral import MistralTokenizer
@@ -96,7 +96,7 @@ class InputProcessor:
96
return self.input_preprocessor.get_tokenizer()
97
98
@property
99
- def renderer(self) -> RendererLike:
99
+ def renderer(self) -> BaseRenderer:
100
return self.input_preprocessor.renderer
101
102
def _validate_logprobs(
vllm/v1/engine/llm_engine.py
+2
-2
@@ -21,7 +21,7 @@ from vllm.multimodal import MULTIMODAL_REGISTRY, MultiModalRegistry
21
from vllm.outputs import PoolingRequestOutput, RequestOutput
22
from vllm.plugins.io_processors import get_io_processor
23
from vllm.pooling_params import PoolingParams
24
-from vllm.renderers import RendererLike
24
+from vllm.renderers import BaseRenderer
25
from vllm.sampling_params import SamplingParams
26
from vllm.tasks import SupportedTask
27
from vllm.tokenizers import TokenizerLike
@@ -367,7 +367,7 @@ class LLMEngine:
367
return self.input_processor.get_tokenizer()
368
369
@property
370
- def renderer(self) -> RendererLike:
370
+ def renderer(self) -> BaseRenderer:
371
return self.input_processor.renderer
372
373
def do_log_stats(self) -> None: