Skip to content

Commit 441dc63

Browse files
reidliu41reidliu41
andauthored
[Frontend] improve vllm serve --help display (#18643)
Signed-off-by: reidliu41 <reid201711@gmail.com> Co-authored-by: reidliu41 <reid201711@gmail.com>
1 parent d55e446 commit 441dc63

File tree

4 files changed

+74
-5
lines changed

4 files changed

+74
-5
lines changed

vllm/entrypoints/cli/main.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import vllm.entrypoints.cli.openai
1010
import vllm.entrypoints.cli.serve
1111
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
1313
from vllm.utils import FlexibleArgumentParser
1414

1515
CMD_MODULES = [
@@ -32,7 +32,10 @@ def signal_handler(sig, frame):
3232
def main():
3333
cli_env_setup()
3434

35-
parser = FlexibleArgumentParser(description="vLLM CLI")
35+
parser = FlexibleArgumentParser(
36+
description="vLLM CLI",
37+
epilog=VLLM_SERVE_PARSER_EPILOG,
38+
)
3639
parser.add_argument('-v',
3740
'--version',
3841
action='version',

vllm/entrypoints/cli/serve.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from vllm.entrypoints.openai.api_server import run_server
1212
from vllm.entrypoints.openai.cli_args import (make_arg_parser,
1313
validate_parsed_serve_args)
14+
from vllm.entrypoints.utils import (VLLM_SERVE_PARSER_EPILOG,
15+
show_filtered_argument_or_group_from_help)
1416
from vllm.logger import init_logger
1517
from vllm.usage.usage_lib import UsageContext
1618
from vllm.utils import FlexibleArgumentParser, get_tcp_uri
@@ -77,7 +79,10 @@ def subparser_init(
7779
"https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html#cli-reference"
7880
)
7981

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
8186

8287

8388
def cmd_init() -> list[CLISubcommand]:

vllm/entrypoints/utils.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313

1414
logger = init_logger(__name__)
1515

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+
1623

1724
async def listen_for_disconnect(request: Request) -> None:
1825
"""Returns if a disconnect message is received"""
@@ -158,3 +165,55 @@ def _validate_truncation_size(
158165
tokenization_kwargs["max_length"] = truncate_prompt_tokens
159166

160167
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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
import warnings
3434
import weakref
3535
from argparse import (Action, ArgumentDefaultsHelpFormatter, ArgumentParser,
36-
ArgumentTypeError, _ArgumentGroup)
36+
ArgumentTypeError, RawDescriptionHelpFormatter,
37+
_ArgumentGroup)
3738
from asyncio import FIRST_COMPLETED, AbstractEventLoop, Task
3839
from collections import UserDict, defaultdict
3940
from collections.abc import (AsyncGenerator, Awaitable, Generator, Hashable,
@@ -1323,7 +1324,8 @@ def __call__(self, parser, namespace, values, option_string=None):
13231324
"Expected 'true' or 'false'.")
13241325

13251326

1326-
class SortedHelpFormatter(ArgumentDefaultsHelpFormatter):
1327+
class SortedHelpFormatter(ArgumentDefaultsHelpFormatter,
1328+
RawDescriptionHelpFormatter):
13271329
"""SortedHelpFormatter that sorts arguments by their option strings."""
13281330

13291331
def _split_lines(self, text, width):

0 commit comments

Comments
 (0)