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):