Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 5 additions & 2 deletions vllm/entrypoints/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
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 = [
Expand All @@ -32,7 +32,10 @@ def signal_handler(sig, frame):
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',
Expand Down
7 changes: 6 additions & 1 deletion vllm/entrypoints/cli/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
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
Expand Down Expand Up @@ -77,7 +79,10 @@ def subparser_init(
"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]:
Expand Down
59 changes: 59 additions & 0 deletions vllm/entrypoints/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@

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"""
Expand Down Expand Up @@ -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)
6 changes: 4 additions & 2 deletions vllm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
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,
Expand Down Expand Up @@ -1323,7 +1324,8 @@ def __call__(self, parser, namespace, values, option_string=None):
"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):
Expand Down