Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions components/src/dynamo/frontend/vllm_protocol.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,15 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

"""Compatibility imports for vLLM's frontend helpers and OpenAI protocol types."""
"""Shared imports for vLLM's frontend helpers and OpenAI protocol types."""
Comment thread
JulienDarve marked this conversation as resolved.
Resolved

from importlib.util import find_spec

# vLLM 0.32 moved the chat helpers to vllm.renderers.
if find_spec("vllm.renderers.chat_utils") is not None:
from vllm.renderers.chat_utils import load_chat_template, make_tool_call_id
else:
from vllm.entrypoints.chat_utils import load_chat_template, make_tool_call_id

try:
_HAS_GENERATE_PROTOCOL = (
find_spec("vllm.entrypoints.generate.base.protocol") is not None
)
except ModuleNotFoundError:
_HAS_GENERATE_PROTOCOL = False

if _HAS_GENERATE_PROTOCOL:
# vLLM 0.29 moved the shared types out of the OpenAI engine package.
from vllm.entrypoints.generate.base.protocol import (
DeltaFunctionCall,
DeltaMessage,
DeltaToolCall,
FunctionDefinition,
)
else:
# vLLM 0.27 and 0.28 expose the same types at the legacy path.
from vllm.entrypoints.openai.engine.protocol import (
DeltaFunctionCall,
DeltaMessage,
DeltaToolCall,
FunctionDefinition,
)
from vllm.entrypoints.generate.base.protocol import (
DeltaFunctionCall,
DeltaMessage,
DeltaToolCall,
FunctionDefinition,
)
from vllm.renderers.chat_utils import load_chat_template, make_tool_call_id

__all__ = [
"DeltaFunctionCall",
Expand Down
13 changes: 2 additions & 11 deletions components/src/dynamo/vllm/capacity.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,6 @@
logger = logging.getLogger(__name__)


def has_vllm_output_clamping() -> bool:
"""vLLM 0.32 caps oversized output budgets instead of rejecting them.

Remove when the CPU and XPU images reach vLLM 0.32.
"""
from vllm.version import __version_tuple__

return __version_tuple__[:2] >= (0, 32)


def publish_vllm_token_budget(runtime_config: Any, max_model_len: int | None) -> None:
"""Publish vLLM's request-overflow contract to the Dynamo frontend."""
if max_model_len is None:
Expand All @@ -31,7 +21,8 @@ def publish_vllm_token_budget(runtime_config: Any, max_model_len: int | None) ->
TokenBudget(
combined_limit=max_model_len,
reject_prompt_overflow=True,
reject_total_overflow=not has_vllm_output_clamping(),
# vLLM caps oversized output budgets instead of rejecting them.
reject_total_overflow=False,
),
)

Expand Down
11 changes: 3 additions & 8 deletions components/src/dynamo/vllm/embedding_worker_processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,10 @@
def _resolve_engine_utils(
vllm_config: VllmConfig, process_count: int
) -> tuple[Any, Any]:
# vLLM 0.32 replaces address allocation with supervisor-bound listeners.
get_addresses = getattr(engine_utils, "get_engine_zmq_addresses", None)
if get_addresses is not None:
return get_addresses(vllm_config, process_count), None
bind_listeners = getattr(engine_utils, "bind_engine_zmq_listeners", None)
if bind_listeners is None:
raise RuntimeError(
f"vLLM {vllm.__version__} provides neither get_engine_zmq_addresses "
"nor bind_engine_zmq_listeners"
f"vLLM {vllm.__version__} provides no bind_engine_zmq_listeners"
)
listeners = bind_listeners(vllm_config, process_count)
return listeners.addresses, listeners
Expand All @@ -72,8 +67,8 @@ def _client_listeners(
_LISTENER_FDS_ENV = "DYN_VLLM_EMBEDDING_LISTENER_FDS"
_CHILD_ROLE = "child"
_RPC_BASE_PATH_ENV = "VLLM_RPC_BASE_PATH"
# Re-check the launch shape when either supported pin moves.
_VERIFIED_VLLM_VERSIONS = ("0.31.0", "0.32.0")
# Re-check the launch shape when the supported pin moves.
_VERIFIED_VLLM_VERSIONS = ("0.32.0",)


def is_embedding_process_child() -> bool:
Expand Down
8 changes: 1 addition & 7 deletions components/src/dynamo/vllm/realtime/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import uuid
from collections.abc import AsyncGenerator, Awaitable, Callable, Coroutine
from contextlib import aclosing
from importlib.util import find_spec
from typing import Any

import numpy as np
Expand Down Expand Up @@ -94,15 +93,10 @@ def build_realtime_text_factories(
from vllm.entrypoints.openai.chat_completion.serving import OpenAIServingChat
from vllm.entrypoints.serve.engine.protocol import ErrorResponse
from vllm.inputs import tokens_input
from vllm.renderers.chat_utils import load_chat_template
from vllm.renderers.online_renderer import OnlineRenderer
from vllm.sampling_params import RequestOutputKind, SamplingParams

# vLLM 0.32 moved the chat helpers to vllm.renderers.
if find_spec("vllm.renderers.chat_utils") is not None:
from vllm.renderers.chat_utils import load_chat_template
else:
from vllm.entrypoints.chat_utils import load_chat_template

class RealtimeServingChat(OpenAIServingChat):
async def chat_completion_stream_generator(
self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,21 @@ def launch_context(vllm_config, executor_class, log_stats, addresses):
parent_config = _vllm_config()
monkeypatch.delenv(processes._ROLE_ENV, raising=False)
monkeypatch.setattr(processes, "_short_rpc_directory", lambda: rpc_directory)
# Stand in for vLLM's supervisor-bound EngineZmqListeners.
zmq_listeners = SimpleNamespace(
addresses=addresses,
inputs=[
SimpleNamespace(socket=Mock(**{"fileno.return_value": 100 + i}))
for i in range(process_count)
],
outputs=[
SimpleNamespace(socket=Mock(**{"fileno.return_value": 200 + i}))
for i in range(process_count)
],
cleanup=Mock(),
)
monkeypatch.setattr(
engine_utils, "get_engine_zmq_addresses", lambda *_: addresses, raising=False
engine_utils, "bind_engine_zmq_listeners", lambda *_: zmq_listeners
)
monkeypatch.setattr(processes, "launch_core_engines", launch_context)
monkeypatch.setattr(processes.Executor, "get_class", lambda _config: object)
Expand Down Expand Up @@ -281,6 +294,7 @@ def launch_context(vllm_config, executor_class, log_stats, addresses):
assert len(children) == process_count - 1
assert group.engine_manager is engine_manager
group.cleanup()
zmq_listeners.cleanup.assert_called_once()


def test_child_attaches_without_launching_engine(monkeypatch):
Expand Down
12 changes: 6 additions & 6 deletions container/compliance/base_sboms/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@
"platform": "linux/amd64"
},
{
"baseline_digest": "sha256:95ac815038c4b3537b173798bfe3b89bdf525a52bd653cd14d4deb01f1062be7",
"baseline_digest": "sha256:20509fabe50dda62c09c0786d1a6effa299d3dbdddcc49331b93e65144652a8c",
"baseline_image": "vllm/vllm-openai-xpu",
"baseline_sbom": "vllm-openai-xpu@95ac8150-amd64.cdx.json",
"baseline_tag": "v0.31.0",
"from_digest": "sha256:95ac815038c4b3537b173798bfe3b89bdf525a52bd653cd14d4deb01f1062be7",
"baseline_sbom": "vllm-openai-xpu@20509fab-amd64.cdx.json",
"baseline_tag": "v0.32.0",
"from_digest": "sha256:20509fabe50dda62c09c0786d1a6effa299d3dbdddcc49331b93e65144652a8c",
"from_image": "vllm/vllm-openai-xpu",
"from_tag": "v0.31.0",
"from_tag": "v0.32.0",
"platform": "linux/amd64"
},
{
Expand Down Expand Up @@ -162,6 +162,6 @@
"platform": "platform pinned for layer-prefix verification, e.g. linux/amd64"
},
"format": "CycloneDX 1.6 JSON, slim filter (drop properties/hashes/dependencies; keep evidence). Hard cap 5 MB per file.",
"generated_at": "2026-10-22T15:27:12+00:00",
"generated_at": "2026-10-23T22:47:45+00:00",
"schema_version": 2
}
Loading
Loading