[Frontend] improve vllm serve --help display (#18643)

Signed-off-by: reidliu41 <reid201711@gmail.com>
Co-authored-by: reidliu41 <reid201711@gmail.com>
This commit is contained in:
Reid 2025-05-24 15:53:22 +08:00 committed by GitHub
parent d55e446d13
commit 441dc63ac7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 74 additions and 5 deletions

View File

@ -9,7 +9,7 @@ import vllm.entrypoints.cli.collect_env
import vllm.entrypoints.cli.openai
import vllm.entrypoints.cli.serve
import vllm.version
from vllm.entrypoints.utils import cli_env_setup
from vllm.entrypoints.utils import VLLM_SERVE_PARSER_EPILOG, cli_env_setup
from vllm.utils import FlexibleArgumentParser
CMD_MODULES = [
@ -32,7 +32,10 @@ def register_signal_handlers():
def main():
cli_env_setup()
parser = FlexibleArgumentParser(description="vLLM CLI")
parser = FlexibleArgumentParser(
description="vLLM CLI",
epilog=VLLM_SERVE_PARSER_EPILOG,
)
parser.add_argument('-v',
'--version',
action='version',

View File

@ -11,6 +11,8 @@ from vllm.entrypoints.cli.types import CLISubcommand
from vllm.entrypoints.openai.api_server import run_server
from vllm.entrypoints.openai.cli_args import (make_arg_parser,
validate_parsed_serve_args)
from vllm.entrypoints.utils import (VLLM_SERVE_PARSER_EPILOG,
show_filtered_argument_or_group_from_help)
from vllm.logger import init_logger
from vllm.usage.usage_lib import UsageContext
from vllm.utils import FlexibleArgumentParser, get_tcp_uri
@ -77,7 +79,10 @@ class ServeSubcommand(CLISubcommand):
"https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html#cli-reference"
)
return make_arg_parser(serve_parser)
serve_parser = make_arg_parser(serve_parser)
show_filtered_argument_or_group_from_help(serve_parser)
serve_parser.epilog = VLLM_SERVE_PARSER_EPILOG
return serve_parser
def cmd_init() -> list[CLISubcommand]:

View File

@ -13,6 +13,13 @@ from vllm.logger import init_logger
logger = init_logger(__name__)
VLLM_SERVE_PARSER_EPILOG = (
"Tip: Use `vllm serve --help=<keyword>` to explore arguments from help.\n"
" - To view a argument group: --help=ModelConfig\n"
" - To view a single argument: --help=max-num-seqs\n"
" - To search by keyword: --help=max\n"
" - To list all groups: --help=listgroup")
async def listen_for_disconnect(request: Request) -> None:
"""Returns if a disconnect message is received"""
@ -158,3 +165,55 @@ def _validate_truncation_size(
tokenization_kwargs["max_length"] = truncate_prompt_tokens
return truncate_prompt_tokens
def show_filtered_argument_or_group_from_help(parser):
import sys
for arg in sys.argv:
if arg.startswith('--help='):
search_keyword = arg.split('=', 1)[1]
# List available groups
if search_keyword == 'listgroup':
print("\nAvailable argument groups:")
for group in parser._action_groups:
if group.title and not group.title.startswith(
"positional arguments"):
print(f" - {group.title}")
if group.description:
print(" " + group.description.strip())
print()
sys.exit(0)
# For group search
formatter = parser._get_formatter()
for group in parser._action_groups:
if group.title and group.title.lower() == search_keyword.lower(
):
formatter.start_section(group.title)
formatter.add_text(group.description)
formatter.add_arguments(group._group_actions)
formatter.end_section()
print(formatter.format_help())
sys.exit(0)
# For single arg
matched_actions = []
for group in parser._action_groups:
for action in group._group_actions:
# search option name
if any(search_keyword.lower() in opt.lower()
for opt in action.option_strings):
matched_actions.append(action)
if matched_actions:
print(f"\nParameters matching '{search_keyword}':\n")
formatter = parser._get_formatter()
formatter.add_arguments(matched_actions)
print(formatter.format_help())
sys.exit(0)
print(f"\nNo group or parameter matching '{search_keyword}'")
print("Tip: use `--help=listgroup` to view all groups.")
sys.exit(1)

View File

@ -33,7 +33,8 @@ import uuid
import warnings
import weakref
from argparse import (Action, ArgumentDefaultsHelpFormatter, ArgumentParser,
ArgumentTypeError, _ArgumentGroup)
ArgumentTypeError, RawDescriptionHelpFormatter,
_ArgumentGroup)
from asyncio import FIRST_COMPLETED, AbstractEventLoop, Task
from collections import UserDict, defaultdict
from collections.abc import (AsyncGenerator, Awaitable, Generator, Hashable,
@ -1323,7 +1324,8 @@ class StoreBoolean(Action):
"Expected 'true' or 'false'.")
class SortedHelpFormatter(ArgumentDefaultsHelpFormatter):
class SortedHelpFormatter(ArgumentDefaultsHelpFormatter,
RawDescriptionHelpFormatter):
"""SortedHelpFormatter that sorts arguments by their option strings."""
def _split_lines(self, text, width):