mirror of
https://github.com/vllm-project/vllm.git
synced 2026-10-28 09:45:26 +08:00
[Frontend] Consolidate startup utils. (#62390)
Signed-off-by: wang.yuqi <yuqi.wang@daocloud.io>
This commit is contained in:
1 parent
a3cee21d0b
commit
5caabdbb65
38 files changed
+312
-302
No files matched your search
@@ -1004,11 +1004,13 @@ steps:
|
||||
- tests/entrypoints/unit_tests
|
||||
- tests/entrypoints/rl/weight_transfer
|
||||
- tests/entrypoints/launchers
|
||||
- tests/entrypoints/common
|
||||
- vllm/platforms/rocm.py
|
||||
commands:
|
||||
- pytest -v -s entrypoints/unit_tests
|
||||
- pytest -v -s entrypoints/rl/weight_transfer
|
||||
- pytest -v -s entrypoints/launchers
|
||||
- pytest -v -s entrypoints/common
|
||||
|
||||
- label: ":amd: (MI300) Entrypoints Integration (Responses API)" # TBD
|
||||
timeout_in_minutes: 50
|
||||
|
||||
@@ -34,9 +34,11 @@ steps:
|
||||
- vllm/utils/flashinfer.py
|
||||
- tests/entrypoints/unit_tests
|
||||
- tests/entrypoints/launchers
|
||||
- tests/entrypoints/common
|
||||
commands:
|
||||
- pytest -v -s entrypoints/unit_tests
|
||||
- pytest -v -s entrypoints/launchers
|
||||
- pytest -v -s entrypoints/common
|
||||
mirror:
|
||||
amd:
|
||||
label: ":amd: (MI355 DPX) Entrypoints Unit"
|
||||
|
||||
@@ -183,7 +183,7 @@ DownloadKernelsSubcommand = auto_mock(
|
||||
"vllm.entrypoints.cli.download_kernels", "DownloadKernelsSubcommand"
|
||||
)
|
||||
sweep_subcommands = auto_mock("vllm.benchmarks.sweep.cli", "SUBCOMMANDS")
|
||||
openai_cli_args = auto_mock("vllm.entrypoints.launchers", "cli_args")
|
||||
openai_cli_args = auto_mock("vllm.entrypoints.common", "cli_args")
|
||||
run_batch = auto_mock("vllm.entrypoints.launchers", "run_batch")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -137,7 +137,7 @@ Remove these arguments to continue."
|
||||
/// recognizes but does not support yet.
|
||||
///
|
||||
/// Source of truth in Python vLLM:
|
||||
/// - `vllm.entrypoints.openai.cli_args.make_arg_parser(...)`
|
||||
/// - `vllm.entrypoints.common.cli_args.make_arg_parser(...)`
|
||||
/// - `vllm.entrypoints.cli.serve.ServeSubcommand.subparser_init(...)`
|
||||
///
|
||||
/// These are not part of `EngineArgs`, `AsyncEngineArgs`, `BaseFrontendArgs`,
|
||||
@@ -384,8 +384,8 @@ pub struct EngineUnsupportedArgs {
|
||||
/// does not support yet.
|
||||
///
|
||||
/// Source of truth in Python vLLM:
|
||||
/// - `vllm.entrypoints.openai.cli_args.BaseFrontendArgs`
|
||||
/// - `vllm.entrypoints.openai.cli_args.FrontendArgs`
|
||||
/// - `vllm.entrypoints.common.cli_args.BaseFrontendArgs`
|
||||
/// - `vllm.entrypoints.common.cli_args.FrontendArgs`
|
||||
///
|
||||
/// These are not engine args. They belong to the Python OpenAI-compatible
|
||||
/// frontend / API-server layer itself, for example chat-template configuration,
|
||||
|
||||
@@ -481,7 +481,7 @@ def test_compilation_config():
|
||||
|
||||
|
||||
def test_trust_request_mm_kwargs_cli():
|
||||
from vllm.entrypoints.launchers.cli_args import FrontendArgs
|
||||
from vllm.entrypoints.common.cli_args import FrontendArgs
|
||||
|
||||
parser = FrontendArgs.add_cli_args(FlexibleArgumentParser())
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ by the Cohere v2 chat API:
|
||||
* ``vllm/renderers/registry.py``: new ``"cohere"`` renderer entry.
|
||||
* ``vllm/tokenizers/registry.py``: new ``"cohere"`` tokenizer entry
|
||||
(aliased to the cached HF tokenizer).
|
||||
* ``vllm/entrypoints/openai/cli_args.py``: new
|
||||
* ``vllm/entrypoints/common/cli_args.py``: new
|
||||
``cohere_is_reasoning_model`` field.
|
||||
* ``vllm/config/model.py``: ``"cohere"`` added to ``TokenizerMode``
|
||||
Literal.
|
||||
@@ -18,7 +18,7 @@ import typing
|
||||
import pytest
|
||||
|
||||
from vllm.config.model import TokenizerMode
|
||||
from vllm.entrypoints.launchers.cli_args import BaseFrontendArgs, make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import BaseFrontendArgs, make_arg_parser
|
||||
from vllm.renderers.registry import RENDERER_REGISTRY
|
||||
from vllm.tokenizers.registry import TokenizerRegistry
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
Whitespace-only changes.
+2
-2
@@ -6,10 +6,10 @@ from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
import vllm.entrypoints.launchers.cli_args as cli_args_module
|
||||
import vllm.entrypoints.common.cli_args as cli_args_module
|
||||
from tests.utils import VLLM_PATH
|
||||
from vllm.engine.arg_utils import AsyncEngineArgs
|
||||
from vllm.entrypoints.launchers.cli_args import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
make_arg_parser,
|
||||
validate_parsed_serve_args,
|
||||
)
|
||||
File renamed without changes.
@@ -0,0 +1,69 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
from argparse import Namespace
|
||||
|
||||
from vllm.entrypoints.common import startup
|
||||
from vllm.entrypoints.common.startup import redact_sensitive_args
|
||||
|
||||
|
||||
class TestRedactSensitiveArgs:
|
||||
API_KEY = "sk-test-secret-12345"
|
||||
|
||||
def test_redact_replaces_sensitive_values_only(self):
|
||||
args = {
|
||||
"api_key": self.API_KEY,
|
||||
"hf_token": "hf_secret",
|
||||
"watermark_config": {"algorithm": "gumbel", "key": 42},
|
||||
"other": "visible",
|
||||
}
|
||||
redacted = redact_sensitive_args(args)
|
||||
assert redacted == {
|
||||
"api_key": "***",
|
||||
"hf_token": "***",
|
||||
"watermark_config": "***",
|
||||
"other": "visible",
|
||||
}
|
||||
# original dict must not be mutated
|
||||
assert args == {
|
||||
"api_key": self.API_KEY,
|
||||
"hf_token": "hf_secret",
|
||||
"watermark_config": {"algorithm": "gumbel", "key": 42},
|
||||
"other": "visible",
|
||||
}
|
||||
|
||||
def test_no_sensitive_fields_returns_original(self):
|
||||
args = {"model_tag": "org/model", "other": "visible"}
|
||||
assert redact_sensitive_args(args) is args
|
||||
|
||||
def test_api_key_not_in_log(self, monkeypatch, caplog):
|
||||
non_default = {
|
||||
"model_tag": "org/model",
|
||||
"default_chat_template_kwargs": {"enable_thinking": False},
|
||||
"api_key": self.API_KEY,
|
||||
"enable_auto_tool_choice": True,
|
||||
"tool_call_parser": "qwen3_coder",
|
||||
}
|
||||
monkeypatch.setattr(startup, "get_non_default_args", lambda args: non_default)
|
||||
with caplog.at_level("INFO", logger="vllm.entrypoints.common.startup"):
|
||||
startup.log_non_default_args(args=Namespace())
|
||||
message = caplog.text
|
||||
assert self.API_KEY not in message
|
||||
assert "'api_key': '***'" in message
|
||||
# non-sensitive args are still logged
|
||||
assert "org/model" in message
|
||||
assert "qwen3_coder" in message
|
||||
|
||||
def test_hf_token_not_in_log(self, monkeypatch, caplog):
|
||||
hf_token = "hf_TESTTOKENVALUE123"
|
||||
non_default = {
|
||||
"model_tag": "org/model",
|
||||
"hf_token": hf_token,
|
||||
"tool_call_parser": "qwen3_coder",
|
||||
}
|
||||
monkeypatch.setattr(startup, "get_non_default_args", lambda args: non_default)
|
||||
with caplog.at_level("INFO", logger="vllm.entrypoints.common.startup"):
|
||||
startup.log_non_default_args(args=Namespace())
|
||||
message = caplog.text
|
||||
assert hf_token not in message
|
||||
assert "'hf_token': '***'" in message
|
||||
assert "org/model" in message
|
||||
@@ -417,7 +417,7 @@ def test_rust_frontend_launch_log_redacts_credentials(monkeypatch):
|
||||
Credentials must not reach the log line."""
|
||||
import subprocess as subprocess_mod
|
||||
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
from vllm.v1.utils import RustFrontendProcessManager
|
||||
|
||||
@@ -469,7 +469,7 @@ def test_rust_frontend_uses_config_model_as_model_tag(monkeypatch, caplog, tmp_p
|
||||
"""Config-only model selection must be forwarded to the Rust frontend."""
|
||||
import subprocess as subprocess_mod
|
||||
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
from vllm.v1.utils import RustFrontendProcessManager
|
||||
|
||||
@@ -517,7 +517,7 @@ def test_rust_frontend_inherits_grpc_listener(monkeypatch):
|
||||
"""The Python-bound gRPC socket is passed to Rust like the HTTP one."""
|
||||
import subprocess as subprocess_mod
|
||||
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
from vllm.v1.utils import RustFrontendProcessManager
|
||||
|
||||
@@ -577,7 +577,7 @@ def test_rust_frontend_inherits_grpc_listener(monkeypatch):
|
||||
|
||||
def test_rust_frontend_spawn_failure_cleans_up_listeners(tmp_path):
|
||||
"""No child owns the listeners when Popen fails, so the parent removes them."""
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
from vllm.v1.utils import RustFrontendProcessManager
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from starlette.datastructures import State
|
||||
|
||||
import vllm.entrypoints.launchers.render.app_state as app_state_mod
|
||||
from vllm.config import ModelConfig, VllmConfig
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ from vllm.entrypoints.cli.launch import (
|
||||
RenderSubcommand,
|
||||
cmd_init,
|
||||
)
|
||||
from vllm.entrypoints.common import startup
|
||||
from vllm.snapshot.controller import (
|
||||
LocalSnapshotTools,
|
||||
SnapshotCreateError,
|
||||
@@ -159,9 +160,7 @@ def test_snapshot_environment_contract(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
capsys: pytest.CaptureFixture[str],
|
||||
):
|
||||
from vllm.entrypoints.serve.utils import api_utils
|
||||
|
||||
monkeypatch.setattr(api_utils, "cli_env_setup", pytest.fail)
|
||||
monkeypatch.setattr(startup, "cli_env_setup", pytest.fail)
|
||||
secret = "snapshot-secret"
|
||||
monkeypatch.setenv("VLLM_API_KEY", secret)
|
||||
monkeypatch.setenv("VLLM_USER_SETTING", secret)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from fastapi import FastAPI
|
||||
from starlette.testclient import TestClient
|
||||
|
||||
from vllm.entrypoints.launchers.cli_args import FrontendArgs
|
||||
from vllm.entrypoints.common.cli_args import FrontendArgs
|
||||
from vllm.entrypoints.serve.middleware.register import init_entrypoints_middleware
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
|
||||
import asyncio
|
||||
from argparse import Namespace
|
||||
|
||||
import pytest
|
||||
from fastapi import FastAPI, Request
|
||||
@@ -11,7 +9,6 @@ from vllm.entrypoints.generate.base.protocol import StreamOptions
|
||||
from vllm.entrypoints.serve.utils import api_utils
|
||||
from vllm.entrypoints.serve.utils.api_utils import (
|
||||
get_max_tokens,
|
||||
redact_sensitive_args,
|
||||
should_include_usage,
|
||||
)
|
||||
|
||||
@@ -165,66 +162,3 @@ class TestGetMaxTokens:
|
||||
input_length=150,
|
||||
default_sampling_params={"max_tokens": 2048},
|
||||
)
|
||||
|
||||
|
||||
class TestRedactSensitiveArgs:
|
||||
API_KEY = "sk-test-secret-12345"
|
||||
|
||||
def test_redact_replaces_sensitive_values_only(self):
|
||||
args = {
|
||||
"api_key": self.API_KEY,
|
||||
"hf_token": "hf_secret",
|
||||
"watermark_config": {"algorithm": "gumbel", "key": 42},
|
||||
"other": "visible",
|
||||
}
|
||||
redacted = redact_sensitive_args(args)
|
||||
assert redacted == {
|
||||
"api_key": "***",
|
||||
"hf_token": "***",
|
||||
"watermark_config": "***",
|
||||
"other": "visible",
|
||||
}
|
||||
# original dict must not be mutated
|
||||
assert args == {
|
||||
"api_key": self.API_KEY,
|
||||
"hf_token": "hf_secret",
|
||||
"watermark_config": {"algorithm": "gumbel", "key": 42},
|
||||
"other": "visible",
|
||||
}
|
||||
|
||||
def test_no_sensitive_fields_returns_original(self):
|
||||
args = {"model_tag": "org/model", "other": "visible"}
|
||||
assert redact_sensitive_args(args) is args
|
||||
|
||||
def test_api_key_not_in_log(self, monkeypatch, caplog):
|
||||
non_default = {
|
||||
"model_tag": "org/model",
|
||||
"default_chat_template_kwargs": {"enable_thinking": False},
|
||||
"api_key": self.API_KEY,
|
||||
"enable_auto_tool_choice": True,
|
||||
"tool_call_parser": "qwen3_coder",
|
||||
}
|
||||
monkeypatch.setattr(api_utils, "get_non_default_args", lambda args: non_default)
|
||||
with caplog.at_level("INFO", logger="vllm.entrypoints.serve.utils.api_utils"):
|
||||
api_utils.log_non_default_args(args=Namespace())
|
||||
message = caplog.text
|
||||
assert self.API_KEY not in message
|
||||
assert "'api_key': '***'" in message
|
||||
# non-sensitive args are still logged
|
||||
assert "org/model" in message
|
||||
assert "qwen3_coder" in message
|
||||
|
||||
def test_hf_token_not_in_log(self, monkeypatch, caplog):
|
||||
hf_token = "hf_TESTTOKENVALUE123"
|
||||
non_default = {
|
||||
"model_tag": "org/model",
|
||||
"hf_token": hf_token,
|
||||
"tool_call_parser": "qwen3_coder",
|
||||
}
|
||||
monkeypatch.setattr(api_utils, "get_non_default_args", lambda args: non_default)
|
||||
with caplog.at_level("INFO", logger="vllm.entrypoints.serve.utils.api_utils"):
|
||||
api_utils.log_non_default_args(args=Namespace())
|
||||
message = caplog.text
|
||||
assert hf_token not in message
|
||||
assert "'hf_token': '***'" in message
|
||||
assert "org/model" in message
|
||||
@@ -17,8 +17,8 @@ import pytest
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from vllm_add_dummy_endpoint_plugin import DummyAdminEndpointPlugin
|
||||
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.launchers.app import build_app
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.plugins import load_endpoint_plugins
|
||||
from vllm.plugins.endpoint_plugins.interface import (
|
||||
EndpointPlugin,
|
||||
|
||||
@@ -42,6 +42,7 @@ SILENT_GROUPS = [
|
||||
"tests/entrypoints/serve",
|
||||
"tests/entrypoints/tool_parsers",
|
||||
"tests/entrypoints/unit_tests",
|
||||
"tests/entrypoints/common",
|
||||
"tests/kernels/attention",
|
||||
"tests/kernels/core",
|
||||
"tests/kernels/helion",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
import argparse
|
||||
|
||||
from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
from .plot import SweepPlotArgs
|
||||
|
||||
@@ -9,7 +9,7 @@ import typing
|
||||
from vllm import envs
|
||||
from vllm.entrypoints.cli.benchmark.base import BenchmarkSubcommandBase
|
||||
from vllm.entrypoints.cli.types import CLISubcommand
|
||||
from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.logger import init_logger
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
|
||||
@@ -7,12 +7,12 @@ import inspect
|
||||
import uvloop
|
||||
|
||||
from vllm.entrypoints.cli.types import CLISubcommand
|
||||
from vllm.entrypoints.launchers.cli_args import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
make_arg_parser,
|
||||
validate_parsed_serve_args,
|
||||
)
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.entrypoints.launchers.render.entry import run_launch_fastapi
|
||||
from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.logger import init_logger
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
|
||||
@@ -49,10 +49,7 @@ def main():
|
||||
import vllm.entrypoints.cli.run_batch
|
||||
import vllm.entrypoints.cli.serve
|
||||
import vllm.entrypoints.cli.snapshot
|
||||
from vllm.entrypoints.serve.utils.api_utils import (
|
||||
VLLM_SUBCMD_PARSER_EPILOG,
|
||||
cli_env_setup,
|
||||
)
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG, cli_env_setup
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
CMD_MODULES = [
|
||||
|
||||
@@ -34,7 +34,7 @@ from fastapi.responses import Response
|
||||
|
||||
from vllm.engine.arg_utils import EngineArgs
|
||||
from vllm.entrypoints.cli.types import CLISubcommand
|
||||
from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.logger import init_logger
|
||||
from vllm.model_executor.model_loader.weight_cache.protocol import (
|
||||
check_ipc_platform_support,
|
||||
|
||||
@@ -7,7 +7,7 @@ import importlib.metadata
|
||||
import typing
|
||||
|
||||
from vllm.entrypoints.cli.types import CLISubcommand
|
||||
from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.logger import init_logger
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
|
||||
@@ -10,15 +10,15 @@ import uvloop
|
||||
import vllm
|
||||
import vllm.envs as envs
|
||||
from vllm.entrypoints.cli.types import CLISubcommand
|
||||
from vllm.entrypoints.launchers.api_server.entry import run_server, setup_server
|
||||
from vllm.entrypoints.launchers.cli_args import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
make_arg_parser,
|
||||
propagate_flash_late_interaction,
|
||||
validate_parsed_serve_args,
|
||||
)
|
||||
from vllm.entrypoints.common.startup import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.entrypoints.launchers.api_server.entry import run_server, setup_server
|
||||
from vllm.entrypoints.launchers.dp_supervisor import run_dp_supervisor
|
||||
from vllm.entrypoints.launchers.launcher import create_server_socket
|
||||
from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
|
||||
from vllm.logger import init_logger
|
||||
from vllm.reasoning import ReasoningParserManager
|
||||
from vllm.usage.usage_lib import UsageContext
|
||||
|
||||
@@ -114,7 +114,7 @@ class SnapshotSubcommand(CLISubcommand):
|
||||
"create", help="Create a snapshot from an initialized TP1 engine."
|
||||
)
|
||||
if self.create_requested:
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
|
||||
create_parser = make_arg_parser(create_parser)
|
||||
else:
|
||||
|
||||
@@ -17,6 +17,10 @@ from vllm.engine.arg_utils import AsyncEngineArgs, optional_type
|
||||
from vllm.entrypoints.anthropic.protocol import (
|
||||
AnthropicDisabledThinkingEffortOption,
|
||||
)
|
||||
from vllm.entrypoints.launchers.utils.constants import (
|
||||
H11_MAX_HEADER_COUNT_DEFAULT,
|
||||
H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT,
|
||||
)
|
||||
from vllm.entrypoints.openai.models.protocol import LoRAModulePath
|
||||
from vllm.logger import init_logger
|
||||
from vllm.renderers.chat_utils import (
|
||||
@@ -27,11 +31,6 @@ from vllm.tool_parsers import ToolParserManager
|
||||
from vllm.tool_parsers.tool_strict_level import ToolStrictLevelName
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
from .utils.constants import (
|
||||
H11_MAX_HEADER_COUNT_DEFAULT,
|
||||
H11_MAX_INCOMPLETE_EVENT_SIZE_DEFAULT,
|
||||
)
|
||||
|
||||
logger = init_logger(__name__)
|
||||
|
||||
|
||||
@@ -571,3 +570,33 @@ def propagate_flash_late_interaction(args, engine_args) -> None:
|
||||
engine_args.pooler_config = PoolerConfig(enable_flash_late_interaction=False)
|
||||
else:
|
||||
engine_args.pooler_config.enable_flash_late_interaction = False
|
||||
|
||||
|
||||
def init_parser_plugin(args: argparse.Namespace):
|
||||
from vllm.reasoning import ReasoningParserManager
|
||||
|
||||
if args.tool_parser_plugin and len(args.tool_parser_plugin) > 3:
|
||||
ToolParserManager.import_tool_parser(args.tool_parser_plugin)
|
||||
|
||||
if args.reasoning_parser_plugin and len(args.reasoning_parser_plugin) > 3:
|
||||
ReasoningParserManager.import_reasoning_parser(args.reasoning_parser_plugin)
|
||||
|
||||
|
||||
def validate_api_server_args(args: argparse.Namespace):
|
||||
from vllm.reasoning import ReasoningParserManager
|
||||
|
||||
valid_tool_parses = ToolParserManager.list_registered()
|
||||
if args.enable_auto_tool_choice and args.tool_call_parser not in valid_tool_parses:
|
||||
raise KeyError(
|
||||
f"invalid tool call parser: {args.tool_call_parser} "
|
||||
f"(chose from {{ {','.join(valid_tool_parses)} }})"
|
||||
)
|
||||
|
||||
valid_reasoning_parsers = ReasoningParserManager.list_registered()
|
||||
if (
|
||||
reasoning_parser := args.structured_outputs_config.reasoning_parser
|
||||
) and reasoning_parser not in valid_reasoning_parsers:
|
||||
raise KeyError(
|
||||
f"invalid reasoning parser: {reasoning_parser} "
|
||||
f"(chose from {{ {','.join(valid_reasoning_parsers)} }})"
|
||||
)
|
||||
@@ -0,0 +1,149 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
import dataclasses
|
||||
import os
|
||||
from argparse import Namespace
|
||||
from logging import Logger
|
||||
from string import Template
|
||||
from typing import Any
|
||||
|
||||
from vllm import EngineArgs, envs
|
||||
from vllm.logger import current_formatter_type, init_logger
|
||||
|
||||
logger = init_logger(__name__)
|
||||
|
||||
|
||||
def log_version_and_model(lgr: Logger, version: str, model_name: str) -> None:
|
||||
if envs.VLLM_DISABLE_LOG_LOGO or (formatter := current_formatter_type(lgr)) is None:
|
||||
message = "vLLM server version %s, serving model %s"
|
||||
else:
|
||||
logo_template = Template(
|
||||
"\n ${w}█ █ █▄ ▄█${r}\n"
|
||||
" ${o}▄▄${r} ${b}▄█${r} ${w}█ █ █ ▀▄▀ █${r} version ${w}%s${r}\n"
|
||||
" ${o}█${r}${b}▄█▀${r} ${w}█ █ █ █${r} model ${w}%s${r}\n"
|
||||
" ${b}▀▀${r} ${w}▀▀▀▀▀ ▀▀▀▀▀ ▀ ▀${r}\n"
|
||||
)
|
||||
colors = {
|
||||
"w": "\033[1m", # bold, default foreground
|
||||
"o": "\033[93m", # orange
|
||||
"b": "\033[94m", # blue
|
||||
"r": "\033[0m", # reset
|
||||
}
|
||||
if formatter != "color":
|
||||
# monochrome logo (no ansi escape codes)
|
||||
colors = dict.fromkeys(colors, "")
|
||||
|
||||
message = logo_template.substitute(colors)
|
||||
|
||||
lgr.info(message, version, model_name)
|
||||
|
||||
|
||||
VLLM_SUBCMD_PARSER_EPILOG = (
|
||||
"For full list: vllm {subcmd} --help=all\n"
|
||||
"For a section: vllm {subcmd} --help=ModelConfig (case-insensitive)\n" # noqa: E501
|
||||
"For a flag: vllm {subcmd} --help=max-model-len (_ or - accepted)\n" # noqa: E501
|
||||
"Documentation: https://docs.vllm.ai\n"
|
||||
)
|
||||
|
||||
|
||||
# Fields whose values must never be logged verbatim.
|
||||
_SENSITIVE_ARG_FIELDS = frozenset({"api_key", "hf_token", "watermark_config"})
|
||||
|
||||
|
||||
def redact_sensitive_args(args: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Return a copy of `args` with sensitive values redacted for logging."""
|
||||
if not any(key in _SENSITIVE_ARG_FIELDS for key in args):
|
||||
return args
|
||||
return {
|
||||
key: ("***" if key in _SENSITIVE_ARG_FIELDS else value)
|
||||
for key, value in args.items()
|
||||
}
|
||||
|
||||
|
||||
def get_non_default_args(args: Namespace | EngineArgs) -> dict[str, Any]:
|
||||
from vllm.entrypoints.common.cli_args import make_arg_parser
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
non_default_args = {}
|
||||
|
||||
# Handle Namespace
|
||||
if isinstance(args, Namespace):
|
||||
parser = make_arg_parser(FlexibleArgumentParser())
|
||||
for arg, default in vars(parser.parse_args([])).items():
|
||||
if default != getattr(args, arg):
|
||||
non_default_args[arg] = getattr(args, arg)
|
||||
|
||||
# Handle EngineArgs instance
|
||||
elif isinstance(args, EngineArgs):
|
||||
default_args = EngineArgs(model=args.model) # Create default instance
|
||||
for field in dataclasses.fields(args):
|
||||
current_val = getattr(args, field.name)
|
||||
default_val = getattr(default_args, field.name)
|
||||
if current_val != default_val:
|
||||
non_default_args[field.name] = current_val
|
||||
if default_args.model != EngineArgs.model:
|
||||
non_default_args["model"] = default_args.model
|
||||
else:
|
||||
raise TypeError(
|
||||
"Unsupported argument type. Must be Namespace or EngineArgs instance."
|
||||
)
|
||||
|
||||
return non_default_args
|
||||
|
||||
|
||||
def log_non_default_args(args: Namespace | EngineArgs):
|
||||
non_default_args = get_non_default_args(args)
|
||||
logger.info("non-default args: %s", redact_sensitive_args(non_default_args))
|
||||
|
||||
|
||||
def _jsonify_arg_value(value: Any) -> Any:
|
||||
if value is None or isinstance(value, bool | int | float | str):
|
||||
return value
|
||||
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
||||
return {
|
||||
key: _jsonify_arg_value(val)
|
||||
for key, val in dataclasses.asdict(value).items()
|
||||
}
|
||||
if isinstance(value, dict):
|
||||
return {str(key): _jsonify_arg_value(val) for key, val in value.items()}
|
||||
if isinstance(value, tuple | list):
|
||||
return [_jsonify_arg_value(item) for item in value]
|
||||
if (model_dump := getattr(value, "model_dump", None)) is not None:
|
||||
return _jsonify_arg_value(model_dump(mode="json"))
|
||||
if (to_dict := getattr(value, "dict", None)) is not None:
|
||||
return _jsonify_arg_value(to_dict())
|
||||
return repr(value)
|
||||
|
||||
|
||||
def jsonify_non_default_args(
|
||||
args: Namespace | EngineArgs,
|
||||
*,
|
||||
exclude: set[str] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
non_default_args = get_non_default_args(args)
|
||||
if exclude is not None:
|
||||
for key in exclude:
|
||||
non_default_args.pop(key, None)
|
||||
|
||||
return {key: _jsonify_arg_value(value) for key, value in non_default_args.items()}
|
||||
|
||||
|
||||
def cli_env_setup():
|
||||
# The safest multiprocessing method is `spawn`, as the default `fork` method
|
||||
# is not compatible with some accelerators. The default method will be
|
||||
# changing in future versions of Python, so we should use it explicitly when
|
||||
# possible.
|
||||
#
|
||||
# We only set it here in the CLI entrypoint, because changing to `spawn`
|
||||
# could break some existing code using vLLM as a library. `spawn` will cause
|
||||
# unexpected behavior if the code is not protected by
|
||||
# `if __name__ == "__main__":`.
|
||||
#
|
||||
# References:
|
||||
# - https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods
|
||||
# - https://pytorch.org/docs/stable/notes/multiprocessing.html#cuda-in-multiprocessing
|
||||
# - https://pytorch.org/docs/stable/multiprocessing.html#sharing-cuda-tensors
|
||||
# - https://docs.habana.ai/en/latest/PyTorch/Getting_Started_with_PyTorch_and_Gaudi/Getting_Started_with_PyTorch.html?highlight=multiprocessing#torch-multiprocessing-for-dataloaders
|
||||
if "VLLM_WORKER_MULTIPROC_METHOD" not in os.environ:
|
||||
logger.debug("Setting VLLM_WORKER_MULTIPROC_METHOD to 'spawn'")
|
||||
os.environ["VLLM_WORKER_MULTIPROC_METHOD"] = "spawn"
|
||||
@@ -7,7 +7,7 @@ from typing import cast
|
||||
from starlette.datastructures import State
|
||||
|
||||
from vllm.engine.protocol import EngineClient
|
||||
from vllm.entrypoints.launchers.cli_args import resolve_default_chat_template_kwargs
|
||||
from vllm.entrypoints.common.cli_args import resolve_default_chat_template_kwargs
|
||||
from vllm.entrypoints.mcp.tool_server import init_tool_server
|
||||
from vllm.entrypoints.openai.models.protocol import BaseModelPath
|
||||
from vllm.entrypoints.openai.models.serving import OpenAIServingModels
|
||||
|
||||
@@ -15,9 +15,8 @@ from typing import Any
|
||||
import vllm.envs as envs
|
||||
from vllm.engine.arg_utils import AsyncEngineArgs
|
||||
from vllm.engine.protocol import EngineClient
|
||||
from vllm.entrypoints.common.cli_args import init_parser_plugin
|
||||
from vllm.logger import configure_logging_from_args, init_logger
|
||||
from vllm.reasoning import ReasoningParserManager
|
||||
from vllm.tool_parsers import ToolParserManager
|
||||
from vllm.usage.usage_lib import UsageContext
|
||||
from vllm.utils.system_utils import decorate_logs
|
||||
|
||||
@@ -51,7 +50,7 @@ async def build_async_engine_client(
|
||||
# Context manager to handle engine_client lifecycle
|
||||
# Ensures everything is shutdown and cleaned up on error/exit
|
||||
engine_args = AsyncEngineArgs.from_cli_args(args)
|
||||
from ..cli_args import propagate_flash_late_interaction
|
||||
from vllm.entrypoints.common.cli_args import propagate_flash_late_interaction
|
||||
|
||||
propagate_flash_late_interaction(args, engine_args)
|
||||
if client_config:
|
||||
@@ -181,11 +180,7 @@ async def run_server_worker(
|
||||
listen_address, sock, args, client_config=None, **uvicorn_kwargs
|
||||
) -> None:
|
||||
"""Run a single API server worker."""
|
||||
if args.tool_parser_plugin and len(args.tool_parser_plugin) > 3:
|
||||
ToolParserManager.import_tool_parser(args.tool_parser_plugin)
|
||||
|
||||
if args.reasoning_parser_plugin and len(args.reasoning_parser_plugin) > 3:
|
||||
ReasoningParserManager.import_reasoning_parser(args.reasoning_parser_plugin)
|
||||
init_parser_plugin(args)
|
||||
|
||||
peer_loads = None
|
||||
if client_config and "api_server_loads" in client_config:
|
||||
@@ -209,13 +204,12 @@ async def run_server_worker(
|
||||
def main():
|
||||
import uvloop
|
||||
|
||||
from vllm.entrypoints.serve.utils.api_utils import cli_env_setup
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
from ..cli_args import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
make_arg_parser,
|
||||
validate_parsed_serve_args,
|
||||
)
|
||||
from vllm.entrypoints.common.startup import cli_env_setup
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
# NOTE(simon):
|
||||
# This section should be in sync with vllm/entrypoints/cli/main.py for CLI
|
||||
|
||||
@@ -43,7 +43,7 @@ import uvloop
|
||||
|
||||
from vllm import envs
|
||||
from vllm.engine.arg_utils import AsyncEngineArgs
|
||||
from vllm.entrypoints.serve.utils.api_utils import log_version_and_model
|
||||
from vllm.entrypoints.common.startup import log_version_and_model
|
||||
from vllm.logger import configure_logging_from_args, init_logger
|
||||
from vllm.usage.usage_lib import UsageContext
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
@@ -14,14 +14,16 @@ from fastapi import FastAPI
|
||||
|
||||
from vllm import envs
|
||||
from vllm.engine.protocol import EngineClient
|
||||
from vllm.entrypoints.launchers.utils.ssl import SSLCertRefresher
|
||||
from vllm.entrypoints.serve.utils.api_utils import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
init_parser_plugin,
|
||||
validate_api_server_args,
|
||||
)
|
||||
from vllm.entrypoints.common.startup import (
|
||||
log_non_default_args,
|
||||
log_version_and_model,
|
||||
)
|
||||
from vllm.entrypoints.launchers.utils.ssl import SSLCertRefresher
|
||||
from vllm.logger import init_logger
|
||||
from vllm.reasoning import ReasoningParserManager
|
||||
from vllm.tool_parsers import ToolParserManager
|
||||
from vllm.tracing import instrument
|
||||
from vllm.utils.network_utils import find_process_using_port, is_valid_ipv6_address
|
||||
from vllm.utils.system_utils import set_ulimit
|
||||
@@ -359,36 +361,12 @@ def create_server_unix_socket(path: str) -> socket.socket:
|
||||
return sock
|
||||
|
||||
|
||||
def validate_api_server_args(args):
|
||||
valid_tool_parses = ToolParserManager.list_registered()
|
||||
if args.enable_auto_tool_choice and args.tool_call_parser not in valid_tool_parses:
|
||||
raise KeyError(
|
||||
f"invalid tool call parser: {args.tool_call_parser} "
|
||||
f"(chose from {{ {','.join(valid_tool_parses)} }})"
|
||||
)
|
||||
|
||||
valid_reasoning_parsers = ReasoningParserManager.list_registered()
|
||||
if (
|
||||
reasoning_parser := args.structured_outputs_config.reasoning_parser
|
||||
) and reasoning_parser not in valid_reasoning_parsers:
|
||||
raise KeyError(
|
||||
f"invalid reasoning parser: {reasoning_parser} "
|
||||
f"(chose from {{ {','.join(valid_reasoning_parsers)} }})"
|
||||
)
|
||||
|
||||
|
||||
@instrument(span_name="API server setup")
|
||||
def setup_server(args, *, reuse_port: bool):
|
||||
"""Validate API server args and create the server socket."""
|
||||
log_version_and_model(logger, VLLM_VERSION, args.model)
|
||||
log_non_default_args(args)
|
||||
|
||||
if args.tool_parser_plugin and len(args.tool_parser_plugin) > 3:
|
||||
ToolParserManager.import_tool_parser(args.tool_parser_plugin)
|
||||
|
||||
if args.reasoning_parser_plugin and len(args.reasoning_parser_plugin) > 3:
|
||||
ReasoningParserManager.import_reasoning_parser(args.reasoning_parser_plugin)
|
||||
|
||||
init_parser_plugin(args)
|
||||
validate_api_server_args(args)
|
||||
|
||||
# workaround to make sure that we bind the port before the engine is set up.
|
||||
|
||||
@@ -5,7 +5,7 @@ from argparse import Namespace
|
||||
from starlette.datastructures import State
|
||||
|
||||
from vllm.config import VllmConfig
|
||||
from vllm.entrypoints.launchers.cli_args import resolve_default_chat_template_kwargs
|
||||
from vllm.entrypoints.common.cli_args import resolve_default_chat_template_kwargs
|
||||
from vllm.entrypoints.mcp.tool_server import init_tool_server
|
||||
from vllm.entrypoints.openai.models.protocol import BaseModelPath
|
||||
from vllm.entrypoints.openai.models.serving import OpenAIModelRegistry
|
||||
|
||||
@@ -108,13 +108,12 @@ async def run_launch_fastapi(args: argparse.Namespace) -> None:
|
||||
if __name__ == "__main__":
|
||||
import uvloop
|
||||
|
||||
from vllm.entrypoints.serve.utils.api_utils import cli_env_setup
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
from ..cli_args import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
make_arg_parser,
|
||||
validate_parsed_serve_args,
|
||||
)
|
||||
from vllm.entrypoints.common.startup import cli_env_setup
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
cli_env_setup()
|
||||
parser = FlexibleArgumentParser(
|
||||
|
||||
@@ -31,6 +31,7 @@ from vllm.config import config
|
||||
from vllm.connections import HTTPResponseSizeExceededError, global_http_connection
|
||||
from vllm.engine.arg_utils import AsyncEngineArgs
|
||||
from vllm.engine.protocol import EngineClient
|
||||
from vllm.entrypoints.common.cli_args import BaseFrontendArgs
|
||||
from vllm.entrypoints.openai.chat_completion.protocol import (
|
||||
ChatCompletionRequest,
|
||||
ChatCompletionResponse,
|
||||
@@ -69,7 +70,6 @@ from vllm.utils.mem_constants import MiB_bytes
|
||||
from vllm.version import __version__ as VLLM_VERSION
|
||||
|
||||
from .api_server.entry import init_app_state
|
||||
from .cli_args import BaseFrontendArgs
|
||||
|
||||
logger = init_logger(__name__)
|
||||
|
||||
|
||||
@@ -29,16 +29,17 @@ from vllm.config.model import (
|
||||
from vllm.config.quantization import QuantizationConfigArgs
|
||||
from vllm.engine.arg_utils import EngineArgs
|
||||
from vllm.entrypoints.common.offline import _O, _R, OfflineInferenceMixin
|
||||
from vllm.entrypoints.common.startup import log_non_default_args
|
||||
from vllm.entrypoints.generate.beam_search.offline import BeamSearchOfflineMixin
|
||||
from vllm.entrypoints.pooling.offline import PoolingOfflineMixin
|
||||
from vllm.entrypoints.rl.offline import RLOfflineMixin
|
||||
from vllm.entrypoints.serve.utils.api_utils import log_non_default_args
|
||||
from vllm.inputs import PromptType
|
||||
from vllm.logger import configure_logging_if_needed, init_logger
|
||||
from vllm.lora.request import LoRARequest
|
||||
from vllm.model_executor.layers.quantization import QuantizationMethods
|
||||
from vllm.outputs import PoolingRequestOutput, RequestOutput
|
||||
from vllm.platforms import current_platform
|
||||
from vllm.renderers import ChatParams
|
||||
from vllm.renderers.chat_utils import (
|
||||
ChatCompletionMessageParam,
|
||||
ChatTemplateContentFormatOption,
|
||||
@@ -52,8 +53,6 @@ from vllm.v1.engine import PauseMode
|
||||
from vllm.v1.engine.llm_engine import LLMEngine
|
||||
from vllm.v1.sample.logits_processor import LogitsProcessor
|
||||
|
||||
from ..renderers import ChatParams
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from vllm.v1.metrics.reader import Metric
|
||||
|
||||
|
||||
@@ -2,13 +2,8 @@
|
||||
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
||||
|
||||
import asyncio
|
||||
import dataclasses
|
||||
import functools
|
||||
import os
|
||||
from argparse import Namespace
|
||||
from http import HTTPStatus
|
||||
from logging import Logger
|
||||
from string import Template
|
||||
from typing import Any
|
||||
|
||||
from fastapi import Request
|
||||
@@ -17,23 +12,13 @@ from fastapi.responses import JSONResponse, Response, StreamingResponse
|
||||
from pydantic import BaseModel
|
||||
from starlette.background import BackgroundTask, BackgroundTasks
|
||||
|
||||
from vllm import envs
|
||||
from vllm.engine.arg_utils import EngineArgs
|
||||
from vllm.entrypoints.generate.base.protocol import StreamOptions
|
||||
from vllm.entrypoints.openai.models.protocol import LoRAModulePath
|
||||
from vllm.logger import current_formatter_type, init_logger
|
||||
from vllm.logger import init_logger
|
||||
from vllm.platforms import current_platform
|
||||
from vllm.utils.argparse_utils import FlexibleArgumentParser
|
||||
|
||||
logger = init_logger(__name__)
|
||||
|
||||
VLLM_SUBCMD_PARSER_EPILOG = (
|
||||
"For full list: vllm {subcmd} --help=all\n"
|
||||
"For a section: vllm {subcmd} --help=ModelConfig (case-insensitive)\n" # noqa: E501
|
||||
"For a flag: vllm {subcmd} --help=max-model-len (_ or - accepted)\n" # noqa: E501
|
||||
"Documentation: https://docs.vllm.ai\n"
|
||||
)
|
||||
|
||||
|
||||
async def listen_for_disconnect(request: Request) -> None:
|
||||
"""Returns if a disconnect message is received."""
|
||||
@@ -216,27 +201,6 @@ def load_aware_call(func):
|
||||
return wrapper
|
||||
|
||||
|
||||
def cli_env_setup():
|
||||
# The safest multiprocessing method is `spawn`, as the default `fork` method
|
||||
# is not compatible with some accelerators. The default method will be
|
||||
# changing in future versions of Python, so we should use it explicitly when
|
||||
# possible.
|
||||
#
|
||||
# We only set it here in the CLI entrypoint, because changing to `spawn`
|
||||
# could break some existing code using vLLM as a library. `spawn` will cause
|
||||
# unexpected behavior if the code is not protected by
|
||||
# `if __name__ == "__main__":`.
|
||||
#
|
||||
# References:
|
||||
# - https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods
|
||||
# - https://pytorch.org/docs/stable/notes/multiprocessing.html#cuda-in-multiprocessing
|
||||
# - https://pytorch.org/docs/stable/multiprocessing.html#sharing-cuda-tensors
|
||||
# - https://docs.habana.ai/en/latest/PyTorch/Getting_Started_with_PyTorch_and_Gaudi/Getting_Started_with_PyTorch.html?highlight=multiprocessing#torch-multiprocessing-for-dataloaders
|
||||
if "VLLM_WORKER_MULTIPROC_METHOD" not in os.environ:
|
||||
logger.debug("Setting VLLM_WORKER_MULTIPROC_METHOD to 'spawn'")
|
||||
os.environ["VLLM_WORKER_MULTIPROC_METHOD"] = "spawn"
|
||||
|
||||
|
||||
def get_max_tokens(
|
||||
max_model_len: int,
|
||||
max_tokens: int | None,
|
||||
@@ -276,87 +240,6 @@ def get_max_tokens(
|
||||
)
|
||||
|
||||
|
||||
def get_non_default_args(args: Namespace | EngineArgs) -> dict[str, Any]:
|
||||
from vllm.entrypoints.launchers.cli_args import make_arg_parser
|
||||
|
||||
non_default_args = {}
|
||||
|
||||
# Handle Namespace
|
||||
if isinstance(args, Namespace):
|
||||
parser = make_arg_parser(FlexibleArgumentParser())
|
||||
for arg, default in vars(parser.parse_args([])).items():
|
||||
if default != getattr(args, arg):
|
||||
non_default_args[arg] = getattr(args, arg)
|
||||
|
||||
# Handle EngineArgs instance
|
||||
elif isinstance(args, EngineArgs):
|
||||
default_args = EngineArgs(model=args.model) # Create default instance
|
||||
for field in dataclasses.fields(args):
|
||||
current_val = getattr(args, field.name)
|
||||
default_val = getattr(default_args, field.name)
|
||||
if current_val != default_val:
|
||||
non_default_args[field.name] = current_val
|
||||
if default_args.model != EngineArgs.model:
|
||||
non_default_args["model"] = default_args.model
|
||||
else:
|
||||
raise TypeError(
|
||||
"Unsupported argument type. Must be Namespace or EngineArgs instance."
|
||||
)
|
||||
|
||||
return non_default_args
|
||||
|
||||
|
||||
def _jsonify_arg_value(value: Any) -> Any:
|
||||
if value is None or isinstance(value, bool | int | float | str):
|
||||
return value
|
||||
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
||||
return {
|
||||
key: _jsonify_arg_value(val)
|
||||
for key, val in dataclasses.asdict(value).items()
|
||||
}
|
||||
if isinstance(value, dict):
|
||||
return {str(key): _jsonify_arg_value(val) for key, val in value.items()}
|
||||
if isinstance(value, tuple | list):
|
||||
return [_jsonify_arg_value(item) for item in value]
|
||||
if (model_dump := getattr(value, "model_dump", None)) is not None:
|
||||
return _jsonify_arg_value(model_dump(mode="json"))
|
||||
if (to_dict := getattr(value, "dict", None)) is not None:
|
||||
return _jsonify_arg_value(to_dict())
|
||||
return repr(value)
|
||||
|
||||
|
||||
def jsonify_non_default_args(
|
||||
args: Namespace | EngineArgs,
|
||||
*,
|
||||
exclude: set[str] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
non_default_args = get_non_default_args(args)
|
||||
if exclude is not None:
|
||||
for key in exclude:
|
||||
non_default_args.pop(key, None)
|
||||
|
||||
return {key: _jsonify_arg_value(value) for key, value in non_default_args.items()}
|
||||
|
||||
|
||||
# Fields whose values must never be logged verbatim.
|
||||
_SENSITIVE_ARG_FIELDS = frozenset({"api_key", "hf_token", "watermark_config"})
|
||||
|
||||
|
||||
def redact_sensitive_args(args: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Return a copy of `args` with sensitive values redacted for logging."""
|
||||
if not any(key in _SENSITIVE_ARG_FIELDS for key in args):
|
||||
return args
|
||||
return {
|
||||
key: ("***" if key in _SENSITIVE_ARG_FIELDS else value)
|
||||
for key, value in args.items()
|
||||
}
|
||||
|
||||
|
||||
def log_non_default_args(args: Namespace | EngineArgs):
|
||||
non_default_args = get_non_default_args(args)
|
||||
logger.info("non-default args: %s", redact_sensitive_args(non_default_args))
|
||||
|
||||
|
||||
def should_include_usage(
|
||||
stream_options: StreamOptions | None, enable_force_include_usage: bool
|
||||
) -> tuple[bool, bool]:
|
||||
@@ -393,31 +276,6 @@ def process_lora_modules(
|
||||
return lora_modules
|
||||
|
||||
|
||||
def log_version_and_model(lgr: Logger, version: str, model_name: str) -> None:
|
||||
if envs.VLLM_DISABLE_LOG_LOGO or (formatter := current_formatter_type(lgr)) is None:
|
||||
message = "vLLM server version %s, serving model %s"
|
||||
else:
|
||||
logo_template = Template(
|
||||
"\n ${w}█ █ █▄ ▄█${r}\n"
|
||||
" ${o}▄▄${r} ${b}▄█${r} ${w}█ █ █ ▀▄▀ █${r} version ${w}%s${r}\n"
|
||||
" ${o}█${r}${b}▄█▀${r} ${w}█ █ █ █${r} model ${w}%s${r}\n"
|
||||
" ${b}▀▀${r} ${w}▀▀▀▀▀ ▀▀▀▀▀ ▀ ▀${r}\n"
|
||||
)
|
||||
colors = {
|
||||
"w": "\033[1m", # bold, default foreground
|
||||
"o": "\033[93m", # orange
|
||||
"b": "\033[94m", # blue
|
||||
"r": "\033[0m", # reset
|
||||
}
|
||||
if formatter != "color":
|
||||
# monochrome logo (no ansi escape codes)
|
||||
colors = dict.fromkeys(colors, "")
|
||||
|
||||
message = logo_template.substitute(colors)
|
||||
|
||||
lgr.info(message, version, model_name)
|
||||
|
||||
|
||||
async def validate_json_request(raw_request: Request):
|
||||
content_type = raw_request.headers.get("content-type", "").lower()
|
||||
media_type = content_type.split(";", maxsplit=1)[0]
|
||||
|
||||
@@ -176,7 +176,7 @@ async def wait_for_release_marker(
|
||||
|
||||
|
||||
def parse_vllm_args(argv: list[str]) -> Any:
|
||||
from vllm.entrypoints.launchers.cli_args import (
|
||||
from vllm.entrypoints.common.cli_args import (
|
||||
make_arg_parser,
|
||||
validate_parsed_serve_args,
|
||||
)
|
||||
|
||||
+2
-2
@@ -331,7 +331,7 @@ class RustFrontendProcessManager:
|
||||
inherited_fds.append(grpc_fd)
|
||||
if stats_update_address is not None:
|
||||
cmd.extend(["--coordinator-address", stats_update_address])
|
||||
from vllm.entrypoints.serve.utils.api_utils import jsonify_non_default_args
|
||||
from vllm.entrypoints.common.startup import jsonify_non_default_args
|
||||
|
||||
args_dict = jsonify_non_default_args(
|
||||
args,
|
||||
@@ -366,7 +366,7 @@ class RustFrontendProcessManager:
|
||||
|
||||
# The subprocess needs the real values, but the log must not carry
|
||||
# credentials such as api_key or hf_token.
|
||||
from vllm.entrypoints.serve.utils.api_utils import redact_sensitive_args
|
||||
from vllm.entrypoints.common.startup import redact_sensitive_args
|
||||
|
||||
redacted_json = json.dumps(redact_sensitive_args(args_dict), sort_keys=True)
|
||||
logger.info("Launching Rust frontend: %s", " ".join(cmd[:-1] + [redacted_json]))
|
||||
|
||||
Reference in new issue
Block a user