[Renderer] Warm up the renderer properly. (#50408)
Signed-off-by: wang.yuqi <yuqi.wang@daocloud.io>
wang.yuqi committed
Jul 31, 2026 at 19:46 UTC
f5ffc59b6abbf317708d4c319702bac2b2aa8e72
6 files changed
+50
-46
vllm/entrypoints/generate/api_router.py
-2
@@ -140,8 +140,6 @@ async def init_generate_state(
140
if "generate" in supported_tasks
141
else None
142
)
143
- if state.openai_serving_chat is not None:
144
- state.openai_serving_chat.warmup()
143
state.openai_serving_completion = (
144
OpenAIServingCompletion(
145
engine_client,
vllm/entrypoints/llm.py
+3
@@ -55,6 +55,7 @@ from vllm.v1.engine import PauseMode
55
from vllm.v1.engine.llm_engine import LLMEngine
56
from vllm.v1.sample.logits_processor import LogitsProcessor
57
58
+from ..renderers import ChatParams
59
from .offline_utils import _O, _R, OfflineInferenceMixin
60
61
if TYPE_CHECKING:
@@ -352,6 +353,8 @@ class LLM(BeamSearchOfflineMixin, PoolingOfflineMixin, OfflineInferenceMixin):
353
self.chat_template = load_chat_template(chat_template)
354
self.input_processor = self.llm_engine.input_processor
355
356
+ self.renderer.warmup(ChatParams(chat_template=self.chat_template))
357
+
358
# The renderer thread pool is only consumed by the async renderer
359
# path; the synchronous `LLM` entrypoint runs multimodal
360
# preprocessing serially. Warn so the setting is not a silent
vllm/entrypoints/openai/api_server.py
+2
@@ -426,6 +426,7 @@ async def init_app_state(
426
default_chat_template_kwargs=args.default_chat_template_kwargs,
427
log_error_stack=args.log_error_stack,
428
)
429
+ state.online_renderer.warmup()
430
431
state.online_derenderer = OnlineDerenderer(
432
model_config=engine_client.model_config,
@@ -529,6 +530,7 @@ async def init_render_app_state(
530
default_chat_template_kwargs=args.default_chat_template_kwargs,
531
log_error_stack=args.log_error_stack,
532
)
533
+ state.online_renderer.warmup()
534
535
state.online_derenderer = OnlineDerenderer(
536
model_config=vllm_config.model_config,
vllm/entrypoints/openai/chat_completion/serving.py
-10
@@ -60,7 +60,6 @@ from vllm.logprobs import Logprob
60
from vllm.outputs import RequestOutput
61
from vllm.parser import ParserManager
62
from vllm.parser.abstract_parser import Parser
63
-from vllm.renderers import ChatParams
63
from vllm.renderers.online_renderer import OnlineRenderer
64
from vllm.sampling_params import BeamSearchParams, SamplingParams
65
from vllm.tokenizers import TokenizerLike
@@ -178,15 +177,6 @@ class OpenAIServingChat(GenerateBaseServing):
177
self.supports_code_interpreter = False
178
self.python_tool = None
179
181
- def warmup(self) -> None:
182
- self.renderer.warmup(
183
- ChatParams(
184
- chat_template=self.chat_template,
185
- chat_template_content_format=self.chat_template_content_format,
186
- chat_template_kwargs=self.default_chat_template_kwargs,
187
- )
188
- )
189
-
180
def _effective_chat_template_kwargs(
181
self, request: ChatCompletionRequest
182
) -> dict[str, Any]:
vllm/renderers/base.py
+35
-33
@@ -243,42 +243,44 @@ class BaseRenderer(ABC, Generic[_T]):
243
"""
244
from vllm.entrypoints.chat_utils import ChatTemplateResolutionError
245
246
- try:
247
- logger.debug("Warming up chat template processing...")
248
- start_time = time.perf_counter()
249
-
250
- self.render_chat([[{"role": "user", "content": "warmup"}]], chat_params)
251
-
252
- elapsed = time.perf_counter() - start_time
253
- logger.debug("Chat template warmup completed in %.3fs", elapsed)
254
- except ChatTemplateResolutionError:
255
- logger.debug("This model does not support chat template.")
256
- except Exception:
257
- logger.warning("Chat template warmup failed", exc_info=True)
258
-
259
- if self.mm_processor:
246
+ # prevent MM processor hangs
247
+ with set_default_torch_num_threads(1):
248
try:
261
- logger.debug("Warming up multi-modal processing...")
262
- self._warmup_mm_processor(
263
- self.mm_processor,
264
- log_prefix="Multi-modal",
265
- )
266
- except Exception:
267
- logger.warning("Multi-modal warmup failed")
268
- finally:
269
- self.clear_mm_cache()
249
+ logger.debug("Warming up chat template processing...")
250
+ start_time = time.perf_counter()
251
271
- if self._readonly_mm_processor is not None:
272
- try:
273
- logger.debug("Warming up readonly multi-modal processing...")
274
- self._warmup_mm_processor(
275
- self._readonly_mm_processor,
276
- log_prefix="Readonly multi-modal",
277
- )
252
+ self.render_chat([[{"role": "user", "content": "warmup"}]], chat_params)
253
+
254
+ elapsed = time.perf_counter() - start_time
255
+ logger.debug("Chat template warmup completed in %.3fs", elapsed)
256
+ except ChatTemplateResolutionError:
257
+ logger.debug("This model does not support chat template.")
258
except Exception:
279
- logger.warning("Readonly multi-modal warmup failed")
280
- finally:
281
- self._clear_processor_cache(self._readonly_mm_processor)
259
+ logger.warning("Chat template warmup failed", exc_info=True)
260
+
261
+ if self.mm_processor:
262
+ try:
263
+ logger.debug("Warming up multi-modal processing...")
264
+ self._warmup_mm_processor(
265
+ self.mm_processor,
266
+ log_prefix="Multi-modal",
267
+ )
268
+ except Exception:
269
+ logger.warning("Multi-modal warmup failed")
270
+ finally:
271
+ self.clear_mm_cache()
272
+
273
+ if self._readonly_mm_processor is not None:
274
+ try:
275
+ logger.debug("Warming up readonly multi-modal processing...")
276
+ self._warmup_mm_processor(
277
+ self._readonly_mm_processor,
278
+ log_prefix="Readonly multi-modal",
279
+ )
280
+ except Exception:
281
+ logger.warning("Readonly multi-modal warmup failed")
282
+ finally:
283
+ self._clear_processor_cache(self._readonly_mm_processor)
284
285
async def clear_mm_cache_async(self) -> None:
286
"""Serialize clear_mm_cache through the multimodal executor to avoid
vllm/renderers/online_renderer.py
+10
-1
@@ -36,7 +36,7 @@ from vllm.inputs import (
36
)
37
from vllm.logger import init_logger
38
from vllm.parser import Parser, ParserManager
39
-from vllm.renderers import BaseRenderer, merge_kwargs
39
+from vllm.renderers import BaseRenderer, ChatParams, merge_kwargs
40
from vllm.renderers.inputs.preprocess import (
41
parse_model_prompt,
42
prompt_to_seq,
@@ -105,6 +105,15 @@ class OnlineRenderer:
105
self.supports_browsing = False
106
self.supports_code_interpreter = False
107
108
+ def warmup(self) -> None:
109
+ self.renderer.warmup(
110
+ ChatParams(
111
+ chat_template=self.chat_template,
112
+ chat_template_content_format=self.chat_template_content_format,
113
+ chat_template_kwargs=self.default_chat_template_kwargs,
114
+ )
115
+ )
116
+
117
async def render_chat(
118
self,
119
request: ChatCompletionRequest,