@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 2e225f7bd2
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 5, 23:30 UTC

[Renderer] Consolidate factory methods (#38218)

Signed-off-by: DarkLight1337 <tlleungac@connect.ust.hk>

Cyrus Leung committed Mar 26, 2026 at 20:19 UTC 2e225f7bd23f533e3ffd909fd5596a85f352c518
16 files changed +33 -233
tests/entrypoints/openai/chat_completion/test_chat_error.py
+3 -5
@@ -16,7 +16,7 @@ from vllm.entrypoints.openai.models.serving import OpenAIServingModels
16 from vllm.entrypoints.serve.render.serving import OpenAIServingRender
17 from vllm.outputs import CompletionOutput, RequestOutput
18 from vllm.renderers.hf import HfRenderer
19 -from vllm.tokenizers.registry import tokenizer_args_from_config
19 +from vllm.tokenizers.registry import cached_tokenizer_from_config
20 from vllm.v1.engine.async_llm import AsyncLLM
21
22 MODEL_NAME = "openai-community/gpt2"
@@ -72,11 +72,9 @@ class MockVllmConfig:
72
73
74 def _build_renderer(model_config: MockModelConfig):
75 - _, tokenizer_name, _, kwargs = tokenizer_args_from_config(model_config)
76 -
77 - return HfRenderer.from_config(
75 + return HfRenderer(
76 MockVllmConfig(model_config, parallel_config=MockParallelConfig()),
79 - tokenizer_kwargs={**kwargs, "tokenizer_name": tokenizer_name},
77 + cached_tokenizer_from_config(model_config),
78 )
79
80
tests/entrypoints/openai/chat_completion/test_serving_chat.py
+3 -5
@@ -41,7 +41,7 @@ from vllm.renderers.hf import HfRenderer
41 from vllm.renderers.mistral import MistralRenderer
42 from vllm.tokenizers import get_tokenizer
43 from vllm.tokenizers.mistral import MistralTokenizer
44 -from vllm.tokenizers.registry import tokenizer_args_from_config
44 +from vllm.tokenizers.registry import cached_tokenizer_from_config
45 from vllm.tool_parsers import ToolParserManager
46 from vllm.v1.engine.async_llm import AsyncLLM
47
@@ -553,11 +553,9 @@ class MockVllmConfig:
553
554
555 def _build_renderer(model_config: MockModelConfig):
556 - _, tokenizer_name, _, kwargs = tokenizer_args_from_config(model_config)
557 -
558 - return HfRenderer.from_config(
556 + return HfRenderer(
557 MockVllmConfig(model_config, parallel_config=MockParallelConfig()),
560 - tokenizer_kwargs={**kwargs, "tokenizer_name": tokenizer_name},
558 + cached_tokenizer_from_config(model_config),
559 )
560
561
tests/entrypoints/openai/completion/test_completion_error.py
+3 -5
@@ -16,7 +16,7 @@ from vllm.entrypoints.openai.models.serving import OpenAIServingModels
16 from vllm.entrypoints.serve.render.serving import OpenAIServingRender
17 from vllm.outputs import CompletionOutput, RequestOutput
18 from vllm.renderers.hf import HfRenderer
19 -from vllm.tokenizers.registry import tokenizer_args_from_config
19 +from vllm.tokenizers.registry import cached_tokenizer_from_config
20 from vllm.v1.engine.async_llm import AsyncLLM
21
22 MODEL_NAME = "openai-community/gpt2"
@@ -93,11 +93,9 @@ def _build_serving_completion(engine: AsyncLLM) -> OpenAIServingCompletion:
93
94
95 def _build_renderer(model_config: MockModelConfig):
96 - _, tokenizer_name, _, kwargs = tokenizer_args_from_config(model_config)
97 -
98 - return HfRenderer.from_config(
96 + return HfRenderer(
97 MockVllmConfig(model_config, parallel_config=MockParallelConfig()),
100 - tokenizer_kwargs={**kwargs, "tokenizer_name": tokenizer_name},
98 + cached_tokenizer_from_config(model_config),
99 )
100
101
tests/entrypoints/openai/completion/test_lora_resolvers.py
+3 -5
@@ -18,7 +18,7 @@ from vllm.entrypoints.serve.render.serving import OpenAIServingRender
18 from vllm.lora.request import LoRARequest
19 from vllm.lora.resolver import LoRAResolver, LoRAResolverRegistry
20 from vllm.renderers.hf import HfRenderer
21 -from vllm.tokenizers.registry import tokenizer_args_from_config
21 +from vllm.tokenizers.registry import cached_tokenizer_from_config
22 from vllm.v1.engine.async_llm import AsyncLLM
23
24 MODEL_NAME = "openai-community/gpt2"
@@ -101,11 +101,9 @@ def register_mock_resolver():
101
102
103 def _build_renderer(model_config: MockModelConfig):
104 - _, tokenizer_name, _, kwargs = tokenizer_args_from_config(model_config)
105 -
106 - return HfRenderer.from_config(
104 + return HfRenderer(
105 MockVllmConfig(model_config, parallel_config=MockParallelConfig()),
108 - tokenizer_kwargs={**kwargs, "tokenizer_name": tokenizer_name},
106 + cached_tokenizer_from_config(model_config),
107 )
108
109
tests/renderers/test_completions.py
-3
@@ -15,7 +15,6 @@ from vllm.inputs import SingletonPrompt
15 from vllm.renderers import TokenizeParams
16 from vllm.renderers.hf import HfRenderer
17 from vllm.renderers.inputs.preprocess import parse_model_prompt, prompt_to_seq
18 -from vllm.tokenizers.registry import tokenizer_args_from_config
18
19 MODEL_NAME = "openai-community/gpt2"
20
@@ -81,8 +80,6 @@ def _build_renderer(
80 truncation_side: str = "left",
81 max_chars_per_token: int = 1,
82 ):
84 - _, tokenizer_name, _, kwargs = tokenizer_args_from_config(model_config)
85 -
83 renderer = HfRenderer(
84 MockVllmConfig(model_config, parallel_config=MockParallelConfig()),
85 tokenizer=(
tests/renderers/test_process_multi_modal_uuids.py
+3 -5
@@ -8,7 +8,7 @@ from vllm.assets.video import VideoAsset
8 from vllm.config import CacheConfig, ModelConfig, VllmConfig
9 from vllm.multimodal.parse import parse_mm_uuids
10 from vllm.renderers.hf import HfRenderer
11 -from vllm.tokenizers.registry import tokenizer_args_from_config
11 +from vllm.tokenizers.registry import cached_tokenizer_from_config
12
13 cherry_pil_image = ImageAsset("cherry_blossom").pil_image
14 stop_pil_image = ImageAsset("stop_sign").pil_image
@@ -29,11 +29,9 @@ def _build_renderer(
29 cache_config=CacheConfig(enable_prefix_caching=enable_prefix_caching),
30 )
31
32 - _, tokenizer_name, _, kwargs = tokenizer_args_from_config(model_config)
33 -
34 - return HfRenderer.from_config(
32 + return HfRenderer(
33 vllm_config,
36 - tokenizer_kwargs={**kwargs, "tokenizer_name": tokenizer_name},
34 + cached_tokenizer_from_config(model_config),
35 )
36
37
vllm/config/model.py
+3 -1
@@ -542,7 +542,9 @@ class ModelConfig:
542
543 # Set default tokenizer modes based on model architecture
544 if self.tokenizer_mode == "auto":
545 - if arch == "Grok1ForCausalLM":
545 + if self.model_impl == "terratorch":
546 + self.tokenizer_mode = "terratorch"
547 + elif arch == "Grok1ForCausalLM":
548 self.tokenizer_mode = "grok2"
549 elif arch == "MoonshotKimiaForCausalLM":
550 self.tokenizer_mode = "kimi_audio"
vllm/renderers/base.py
-9
@@ -69,15 +69,6 @@ _T = TypeVar("_T", bound=TokenizerLike, default=TokenizerLike)
69
70
71 class BaseRenderer(ABC, Generic[_T]):
72 - @classmethod
73 - @abstractmethod
74 - def from_config(
75 - cls,
76 - config: "VllmConfig",
77 - tokenizer_kwargs: dict[str, Any],
78 - ) -> "BaseRenderer":
79 - raise NotImplementedError
80 -
72 def __init__(self, config: "VllmConfig", tokenizer: _T | None) -> None:
73 super().__init__()
74
vllm/renderers/deepseek_v32.py
-20
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any
3
5 -from vllm.config import VllmConfig
4 from vllm.entrypoints.chat_utils import (
5 ChatCompletionMessageParam,
6 ConversationMessage,
@@ -10,7 +8,6 @@ from vllm.entrypoints.chat_utils import (
8 parse_chat_messages_async,
9 )
10 from vllm.logger import init_logger
13 -from vllm.tokenizers import cached_get_tokenizer
11 from vllm.tokenizers.deepseek_v32 import DeepseekV32Tokenizer
12
13 from .base import BaseRenderer
@@ -22,23 +19,6 @@ logger = init_logger(__name__)
19
20
21 class DeepseekV32Renderer(BaseRenderer[DeepseekV32Tokenizer]):
25 - @classmethod
26 - def from_config( # type: ignore[override]
27 - cls,
28 - config: VllmConfig,
29 - tokenizer_kwargs: dict[str, Any],
30 - ) -> "DeepseekV32Renderer":
31 - model_config = config.model_config
32 - if model_config.skip_tokenizer_init:
33 - tokenizer = None
34 - else:
35 - tokenizer = cached_get_tokenizer(
36 - tokenizer_cls=DeepseekV32Tokenizer,
37 - **tokenizer_kwargs,
38 - )
39 -
40 - return cls(config, tokenizer)
41 -
22 def render_messages(
23 self,
24 messages: list[ChatCompletionMessageParam],
vllm/renderers/grok2.py
-20
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any
3
5 -from vllm.config import VllmConfig
4 from vllm.entrypoints.chat_utils import (
5 ChatCompletionMessageParam,
6 ConversationMessage,
@@ -10,7 +8,6 @@ from vllm.entrypoints.chat_utils import (
8 parse_chat_messages_async,
9 )
10 from vllm.logger import init_logger
13 -from vllm.tokenizers import cached_get_tokenizer
11 from vllm.tokenizers.grok2 import Grok2Tokenizer
12
13 from .base import BaseRenderer
@@ -22,23 +19,6 @@ logger = init_logger(__name__)
19
20
21 class Grok2Renderer(BaseRenderer[Grok2Tokenizer]):
25 - @classmethod
26 - def from_config( # type: ignore[override]
27 - cls,
28 - config: VllmConfig,
29 - tokenizer_kwargs: dict[str, Any],
30 - ) -> "Grok2Renderer":
31 - model_config = config.model_config
32 - if model_config.skip_tokenizer_init:
33 - tokenizer = None
34 - else:
35 - tokenizer = cached_get_tokenizer(
36 - tokenizer_cls=Grok2Tokenizer,
37 - **tokenizer_kwargs,
38 - )
39 -
40 - return cls(config, tokenizer)
41 -
22 def render_messages(
23 self,
24 messages: list[ChatCompletionMessageParam],
vllm/renderers/hf.py
+1 -22
@@ -27,8 +27,7 @@ from vllm.entrypoints.chat_utils import (
27 )
28 from vllm.inputs import MultiModalDataDict, MultiModalUUIDDict
29 from vllm.logger import init_logger
30 -from vllm.tokenizers import cached_get_tokenizer
31 -from vllm.tokenizers.hf import CachedHfTokenizer, HfTokenizer
30 +from vllm.tokenizers.hf import HfTokenizer
31 from vllm.transformers_utils.chat_templates import get_chat_template_fallback_path
32 from vllm.transformers_utils.processor import cached_get_processor
33 from vllm.utils.func_utils import supports_kw
@@ -604,26 +603,6 @@ def replace_vision_chunk_video_placeholder(
603
604
605 class HfRenderer(BaseRenderer[HfTokenizer]):
607 - @classmethod
608 - def from_config( # type: ignore[override]
609 - cls,
610 - config: VllmConfig,
611 - tokenizer_kwargs: dict[str, Any],
612 - ) -> "HfRenderer":
613 - model_config = config.model_config
614 - if model_config.skip_tokenizer_init:
615 - tokenizer = None
616 - else:
617 - tokenizer = cast(
618 - HfTokenizer,
619 - cached_get_tokenizer(
620 - tokenizer_cls=CachedHfTokenizer, # type: ignore[type-abstract]
621 - **tokenizer_kwargs,
622 - ),
623 - )
624 -
625 - return cls(config, tokenizer)
626 -
606 def __init__(
607 self,
608 config: VllmConfig,
vllm/renderers/kimi_audio.py deleted
-49
@@ -1,49 +0,0 @@
1 -# SPDX-License-Identifier: Apache-2.0
2 -# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any, cast
4 -
5 -from vllm.config import VllmConfig
6 -from vllm.tokenizers.kimi_audio import KimiAudioTokenizer
7 -from vllm.tokenizers.registry import get_tokenizer
8 -
9 -from .hf import HfRenderer, HfTokenizer
10 -
11 -
12 -class KimiAudioRenderer(HfRenderer):
13 - """Renderer for Kimi-Audio models.
14 -
15 - This renderer uses HfRenderer internally with a custom TikToken tokenizer.
16 - """
17 -
18 - @classmethod
19 - def from_config( # type: ignore[override]
20 - cls,
21 - config: VllmConfig,
22 - tokenizer_kwargs: dict[str, Any],
23 - ) -> "HfRenderer":
24 - """Create an HfRenderer instance for Kimi-Audio models."""
25 - model_config = config.model_config
26 - if model_config.skip_tokenizer_init:
27 - tokenizer = None
28 - else:
29 - # Extract tokenizer_name from kwargs (already processed by
30 - # tokenizer_args_from_config for ModelScope/GGUF/etc)
31 - tokenizer_name = tokenizer_kwargs.pop(
32 - "tokenizer_name", model_config.tokenizer
33 - )
34 - # Remove tokenizer_cls from kwargs to avoid duplicate argument
35 - tokenizer_kwargs = {
36 - k: v for k, v in tokenizer_kwargs.items() if k != "tokenizer_cls"
37 - }
38 - # Use get_tokenizer directly instead of cached_get_tokenizer
39 - # (KimiAudioTokenizer doesn't work with get_cached_tokenizer)
40 - tokenizer = cast(
41 - HfTokenizer,
42 - get_tokenizer(
43 - tokenizer_name,
44 - tokenizer_cls=KimiAudioTokenizer, # type: ignore[arg-type]
45 - **tokenizer_kwargs,
46 - ),
47 - )
48 -
49 - return HfRenderer(config, tokenizer)
vllm/renderers/mistral.py
-19
@@ -1,7 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from concurrent.futures import ThreadPoolExecutor
4 -from typing import Any
4
5 from vllm.config import VllmConfig
6 from vllm.entrypoints.chat_utils import (
@@ -11,7 +10,6 @@ from vllm.entrypoints.chat_utils import (
10 parse_chat_messages_async,
11 )
12 from vllm.logger import init_logger
14 -from vllm.tokenizers import cached_get_tokenizer
13 from vllm.tokenizers.mistral import MistralTokenizer
14 from vllm.utils.async_utils import make_async
15
@@ -51,23 +49,6 @@ def safe_apply_chat_template(
49
50
51 class MistralRenderer(BaseRenderer[MistralTokenizer]):
54 - @classmethod
55 - def from_config( # type: ignore[override]
56 - cls,
57 - config: VllmConfig,
58 - tokenizer_kwargs: dict[str, Any],
59 - ) -> "MistralRenderer":
60 - model_config = config.model_config
61 - if model_config.skip_tokenizer_init:
62 - tokenizer = None
63 - else:
64 - tokenizer = cached_get_tokenizer(
65 - tokenizer_cls=MistralTokenizer,
66 - **tokenizer_kwargs,
67 - )
68 -
69 - return cls(config, tokenizer)
70 -
52 def __init__(
53 self,
54 config: VllmConfig,
vllm/renderers/qwen_vl.py deleted
-28
@@ -1,28 +0,0 @@
1 -# SPDX-License-Identifier: Apache-2.0
2 -# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any
4 -
5 -from vllm.config import VllmConfig
6 -from vllm.tokenizers import cached_get_tokenizer
7 -from vllm.tokenizers.qwen_vl import QwenVLTokenizer
8 -
9 -from .hf import HfRenderer
10 -
11 -
12 -class QwenVLRenderer(HfRenderer):
13 - @classmethod
14 - def from_config( # type: ignore[override]
15 - cls,
16 - config: VllmConfig,
17 - tokenizer_kwargs: dict[str, Any],
18 - ) -> "HfRenderer":
19 - model_config = config.model_config
20 - if model_config.skip_tokenizer_init:
21 - tokenizer = None
22 - else:
23 - tokenizer = cached_get_tokenizer(
24 - tokenizer_cls=QwenVLTokenizer,
25 - **tokenizer_kwargs,
26 - )
27 -
28 - return HfRenderer(config, tokenizer)
vllm/renderers/registry.py
+14 -23
@@ -1,10 +1,14 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 from dataclasses import dataclass, field
4 -from typing import TYPE_CHECKING, Any
4 +from typing import TYPE_CHECKING
5
6 from vllm.logger import init_logger
7 -from vllm.tokenizers.registry import tokenizer_args_from_config
7 +from vllm.tokenizers import TokenizerLike
8 +from vllm.tokenizers.registry import (
9 + cached_tokenizer_from_config,
10 + tokenizer_args_from_config,
11 +)
12 from vllm.utils.import_utils import resolve_obj_by_qualname
13
14 from .base import BaseRenderer
@@ -19,9 +23,9 @@ _VLLM_RENDERERS = {
23 "deepseek_v32": ("deepseek_v32", "DeepseekV32Renderer"),
24 "hf": ("hf", "HfRenderer"),
25 "grok2": ("grok2", "Grok2Renderer"),
22 - "kimi_audio": ("kimi_audio", "KimiAudioRenderer"),
26 + "kimi_audio": ("hf", "HfRenderer"),
27 "mistral": ("mistral", "MistralRenderer"),
24 - "qwen_vl": ("qwen_vl", "QwenVLRenderer"),
28 + "qwen_vl": ("hf", "HfRenderer"),
29 "terratorch": ("terratorch", "TerratorchRenderer"),
30 }
31
@@ -58,10 +62,10 @@ class RendererRegistry:
62 self,
63 renderer_mode: str,
64 config: "VllmConfig",
61 - tokenizer_kwargs: dict[str, Any],
65 + tokenizer: TokenizerLike | None,
66 ) -> BaseRenderer:
67 renderer_cls = self.load_renderer_cls(renderer_mode)
64 - return renderer_cls.from_config(config, tokenizer_kwargs)
68 + return renderer_cls(config, tokenizer)
69
70
71 RENDERER_REGISTRY = RendererRegistry(
@@ -76,20 +80,7 @@ RENDERER_REGISTRY = RendererRegistry(
80 def renderer_from_config(config: "VllmConfig", **kwargs):
81 model_config = config.model_config
82
79 - tokenizer_mode, tokenizer_name, args, kwargs = tokenizer_args_from_config(
80 - model_config, **kwargs
81 - )
82 -
83 - if (
84 - model_config.tokenizer_mode == "auto"
85 - and model_config.model_impl == "terratorch"
86 - ):
87 - renderer_mode = "terratorch"
88 - else:
89 - renderer_mode = tokenizer_mode
90 -
91 - return RENDERER_REGISTRY.load_renderer(
92 - renderer_mode,
93 - config,
94 - tokenizer_kwargs={**kwargs, "tokenizer_name": tokenizer_name},
95 - )
83 + tokenizer = cached_tokenizer_from_config(model_config, **kwargs)
84 + renderer_mode, *_ = tokenizer_args_from_config(model_config, **kwargs)
85 +
86 + return RENDERER_REGISTRY.load_renderer(renderer_mode, config, tokenizer)
vllm/renderers/terratorch.py
-14
@@ -1,8 +1,6 @@
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 -from typing import Any
3
5 -from vllm.config import VllmConfig
4 from vllm.entrypoints.chat_utils import (
5 ChatCompletionMessageParam,
6 ConversationMessage,
@@ -20,18 +18,6 @@ logger = init_logger(__name__)
18
19
20 class TerratorchRenderer(BaseRenderer):
23 - @classmethod
24 - def from_config(
25 - cls,
26 - config: VllmConfig, # type: ignore[override]
27 - tokenizer_kwargs: dict[str, Any],
28 - ) -> "TerratorchRenderer":
29 - model_config = config.model_config
30 - if not model_config.skip_tokenizer_init:
31 - raise ValueError("Terratorch renderer requires `skip_tokenizer_init=True`")
32 -
33 - return cls(config, None)
34 -
21 def render_messages(
22 self,
23 messages: list[ChatCompletionMessageParam],