[Frontend] Share regular and duplex chat initialization (#7646)

Signed-off-by: natureofnature <wzliu@connect.hku.hk>
This commit is contained in:
NATURE authored and GitHub committed 2026-10-07 10:49:34 +00:00
1 parent de253412b0
commit b21df3bcb6
3 files changed
+116 -69

No files matched your search

+39 -57
View File
@@ -737,16 +737,37 @@ async def _init_duplex_chat(
if "generate" not in supported_tasks:
return None
resolved_chat_template = await _resolve_chat_template(engine_client, args)
_init_chat_services(
engine_client, state, args, request_logger, resolved_chat_template, enable_chat=True, enable_batch=False
)
return state.openai_serving_chat
async def _resolve_chat_template(engine_client: EngineClient, args: Namespace) -> str | None:
resolved_chat_template = load_chat_template(args.chat_template)
if resolved_chat_template is None:
try:
tokenizer = await engine_client.get_tokenizer()
except Exception as exc:
logger.debug("Could not inspect tokenizer chat_template before duplex chat init: %s", exc)
logger.debug("Could not inspect tokenizer chat_template before serving init: %s", exc)
tokenizer = None
if tokenizer is None or getattr(tokenizer, "chat_template", None) is None:
resolved_chat_template = _load_model_chat_template_json(args.model)
return resolved_chat_template
def _init_chat_services(
engine_client: EngineClient,
state: State,
args: Namespace,
request_logger: RequestLogger | None,
resolved_chat_template: str | None,
*,
enable_chat: bool,
enable_batch: bool,
) -> None:
"""Share chat setup while callers retain capability and endpoint gating."""
state.online_renderer = OnlineRenderer(
model_config=engine_client.model_config,
renderer=engine_client.renderer,
@@ -759,8 +780,9 @@ async def _init_duplex_chat(
tool_parser=args.tool_call_parser,
reasoning_parser=args.structured_outputs_config.reasoning_parser,
default_chat_template_kwargs=args.default_chat_template_kwargs,
log_error_stack=args.log_error_stack,
)
return OmniOpenAIServingChat(
chat_kwargs = dict(
engine_client=engine_client,
models=state.openai_serving_models,
response_role=args.response_role,
@@ -780,6 +802,12 @@ async def _init_duplex_chat(
enable_log_outputs=args.enable_log_outputs,
enable_log_deltas=args.enable_log_deltas,
)
state.openai_serving_chat = OmniOpenAIServingChat(**chat_kwargs) if enable_chat else None
state.openai_serving_chat_batch = (
OmniOpenAIServingChatBatch(**chat_kwargs) if enable_chat and enable_batch else None
)
# Warm up template processing, not model inference, before serving requests.
state.online_renderer.warmup()
async def omni_init_app_state(
@@ -923,15 +951,7 @@ async def omni_init_app_state(
supported_tasks = set(await engine_client.get_supported_tasks())
logger.info("Supported tasks: %s", supported_tasks)
resolved_chat_template = load_chat_template(args.chat_template)
if resolved_chat_template is None:
try:
tokenizer = await engine_client.get_tokenizer()
except Exception as exc:
logger.debug("Could not inspect tokenizer chat_template before serving init: %s", exc)
tokenizer = None
if tokenizer is None or getattr(tokenizer, "chat_template", None) is None:
resolved_chat_template = _load_model_chat_template_json(args.model)
resolved_chat_template = await _resolve_chat_template(engine_client, args)
chat_template_config = ChatTemplateConfig(
chat_template=resolved_chat_template,
@@ -1003,21 +1023,14 @@ async def omni_init_app_state(
)
await state.openai_serving_models.init_static_loras()
# NOTE: kept aligned with upstream `init_app_state`:
# Use OnlineRenderer (replaced OpenAIServingRender which was removed upstream).
state.online_renderer = OnlineRenderer(
model_config=engine_client.model_config,
renderer=engine_client.renderer,
request_logger=request_logger,
chat_template=resolved_chat_template,
chat_template_content_format=args.chat_template_content_format,
trust_request_chat_template=args.trust_request_chat_template,
enable_auto_tools=args.enable_auto_tool_choice,
exclude_tools_when_tool_choice_none=args.exclude_tools_when_tool_choice_none,
tool_parser=args.tool_call_parser,
reasoning_parser=args.structured_outputs_config.reasoning_parser,
default_chat_template_kwargs=args.default_chat_template_kwargs,
log_error_stack=args.log_error_stack,
_init_chat_services(
engine_client,
state,
args,
request_logger,
resolved_chat_template,
enable_chat="generate" in supported_tasks,
enable_batch=True,
)
state.openai_serving_responses = (
@@ -1041,37 +1054,6 @@ async def omni_init_app_state(
else None
)
_chat_kwargs = dict(
engine_client=engine_client,
models=state.openai_serving_models,
response_role=args.response_role,
online_renderer=state.online_renderer,
request_logger=request_logger,
chat_template=resolved_chat_template,
chat_template_content_format=args.chat_template_content_format,
default_chat_template_kwargs=args.default_chat_template_kwargs,
trust_request_chat_template=args.trust_request_chat_template,
return_tokens_as_token_ids=args.return_tokens_as_token_ids,
enable_auto_tools=args.enable_auto_tool_choice,
exclude_tools_when_tool_choice_none=args.exclude_tools_when_tool_choice_none,
tool_parser=args.tool_call_parser,
reasoning_parser=args.structured_outputs_config.reasoning_parser,
enable_prompt_tokens_details=args.enable_prompt_tokens_details,
enable_force_include_usage=args.enable_force_include_usage,
enable_log_outputs=args.enable_log_outputs,
enable_log_deltas=args.enable_log_deltas,
)
state.openai_serving_chat = OmniOpenAIServingChat(**_chat_kwargs) if "generate" in supported_tasks else None
state.openai_serving_chat_batch = (
OmniOpenAIServingChatBatch(**_chat_kwargs) if "generate" in supported_tasks else None
)
# Warm up chat template processing to avoid first-request latency
# Upstream f5ffc59b6a removed OpenAIServingChat.warmup() and moved the
# warmup onto the renderer (OnlineRenderer.warmup()); mirror upstream.
state.online_renderer.warmup()
state.openai_serving_completion = (
OpenAIServingCompletion(
engine_client,