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],