@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 441dc63ac7
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 15, 08:30 UTC

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

Signed-off-by: reidliu41 <reid201711@gmail.com> Co-authored-by: reidliu41 <reid201711@gmail.com>

Reid committed May 24, 2025 at 15:53 UTC 441dc63ac7414cc9a7c75af678bef0fb673760ea
4 files changed +74 -5
vllm/entrypoints/cli/main.py
+5 -2
@@ -9,7 +9,7 @@ import vllm.entrypoints.cli.collect_env
9 import vllm.entrypoints.cli.openai
10 import vllm.entrypoints.cli.serve
11 import vllm.version
12 -from vllm.entrypoints.utils import cli_env_setup
12 +from vllm.entrypoints.utils import VLLM_SERVE_PARSER_EPILOG, cli_env_setup
13 from vllm.utils import FlexibleArgumentParser
14
15 CMD_MODULES = [
@@ -32,7 +32,10 @@ def register_signal_handlers():
32 def main():
33 cli_env_setup()
34
35 - parser = FlexibleArgumentParser(description="vLLM CLI")
35 + parser = FlexibleArgumentParser(
36 + description="vLLM CLI",
37 + epilog=VLLM_SERVE_PARSER_EPILOG,
38 + )
39 parser.add_argument('-v',
40 '--version',
41 action='version',
vllm/entrypoints/cli/serve.py
+6 -1
@@ -11,6 +11,8 @@ from vllm.entrypoints.cli.types import CLISubcommand
11 from vllm.entrypoints.openai.api_server import run_server
12 from vllm.entrypoints.openai.cli_args import (make_arg_parser,
13 validate_parsed_serve_args)
14 +from vllm.entrypoints.utils import (VLLM_SERVE_PARSER_EPILOG,
15 + show_filtered_argument_or_group_from_help)
16 from vllm.logger import init_logger
17 from vllm.usage.usage_lib import UsageContext
18 from vllm.utils import FlexibleArgumentParser, get_tcp_uri
@@ -77,7 +79,10 @@ class ServeSubcommand(CLISubcommand):
79 "https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html#cli-reference"
80 )
81
80 - return make_arg_parser(serve_parser)
82 + serve_parser = make_arg_parser(serve_parser)
83 + show_filtered_argument_or_group_from_help(serve_parser)
84 + serve_parser.epilog = VLLM_SERVE_PARSER_EPILOG
85 + return serve_parser
86
87
88 def cmd_init() -> list[CLISubcommand]:
vllm/entrypoints/utils.py
+59
@@ -13,6 +13,13 @@ from vllm.logger import init_logger
13
14 logger = init_logger(__name__)
15
16 +VLLM_SERVE_PARSER_EPILOG = (
17 + "Tip: Use `vllm serve --help=<keyword>` to explore arguments from help.\n"
18 + " - To view a argument group: --help=ModelConfig\n"
19 + " - To view a single argument: --help=max-num-seqs\n"
20 + " - To search by keyword: --help=max\n"
21 + " - To list all groups: --help=listgroup")
22 +
23
24 async def listen_for_disconnect(request: Request) -> None:
25 """Returns if a disconnect message is received"""
@@ -158,3 +165,55 @@ def _validate_truncation_size(
165 tokenization_kwargs["max_length"] = truncate_prompt_tokens
166
167 return truncate_prompt_tokens
168 +
169 +
170 +def show_filtered_argument_or_group_from_help(parser):
171 + import sys
172 + for arg in sys.argv:
173 + if arg.startswith('--help='):
174 + search_keyword = arg.split('=', 1)[1]
175 +
176 + # List available groups
177 + if search_keyword == 'listgroup':
178 + print("\nAvailable argument groups:")
179 + for group in parser._action_groups:
180 + if group.title and not group.title.startswith(
181 + "positional arguments"):
182 + print(f" - {group.title}")
183 + if group.description:
184 + print(" " + group.description.strip())
185 + print()
186 + sys.exit(0)
187 +
188 + # For group search
189 + formatter = parser._get_formatter()
190 + for group in parser._action_groups:
191 + if group.title and group.title.lower() == search_keyword.lower(
192 + ):
193 + formatter.start_section(group.title)
194 + formatter.add_text(group.description)
195 + formatter.add_arguments(group._group_actions)
196 + formatter.end_section()
197 + print(formatter.format_help())
198 + sys.exit(0)
199 +
200 + # For single arg
201 + matched_actions = []
202 +
203 + for group in parser._action_groups:
204 + for action in group._group_actions:
205 + # search option name
206 + if any(search_keyword.lower() in opt.lower()
207 + for opt in action.option_strings):
208 + matched_actions.append(action)
209 +
210 + if matched_actions:
211 + print(f"\nParameters matching '{search_keyword}':\n")
212 + formatter = parser._get_formatter()
213 + formatter.add_arguments(matched_actions)
214 + print(formatter.format_help())
215 + sys.exit(0)
216 +
217 + print(f"\nNo group or parameter matching '{search_keyword}'")
218 + print("Tip: use `--help=listgroup` to view all groups.")
219 + sys.exit(1)
vllm/utils.py
+4 -2
@@ -33,7 +33,8 @@ import uuid
33 import warnings
34 import weakref
35 from argparse import (Action, ArgumentDefaultsHelpFormatter, ArgumentParser,
36 - ArgumentTypeError, _ArgumentGroup)
36 + ArgumentTypeError, RawDescriptionHelpFormatter,
37 + _ArgumentGroup)
38 from asyncio import FIRST_COMPLETED, AbstractEventLoop, Task
39 from collections import UserDict, defaultdict
40 from collections.abc import (AsyncGenerator, Awaitable, Generator, Hashable,
@@ -1323,7 +1324,8 @@ class StoreBoolean(Action):
1324 "Expected 'true' or 'false'.")
1325
1326
1326 -class SortedHelpFormatter(ArgumentDefaultsHelpFormatter):
1327 +class SortedHelpFormatter(ArgumentDefaultsHelpFormatter,
1328 + RawDescriptionHelpFormatter):
1329 """SortedHelpFormatter that sorts arguments by their option strings."""
1330
1331 def _split_lines(self, text, width):