main
py 99 lines 3.56 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
4 import argparse
5 import os
6 import sys
7 import typing
8
9 from vllm import envs
10 from vllm.entrypoints.cli.benchmark.base import BenchmarkSubcommandBase
11 from vllm.entrypoints.cli.types import CLISubcommand
12 from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG
13 from vllm.logger import init_logger
14
15 if typing.TYPE_CHECKING:
16 from vllm.utils.argparse_utils import FlexibleArgumentParser
17 else:
18 FlexibleArgumentParser = argparse.ArgumentParser
19
20 logger = init_logger(__name__)
21
22
23 def maybe_exec_rust_bench() -> None:
24 if sys.argv[1:3] != ["bench", "serve"] or not envs.VLLM_USE_RUST_BENCH:
25 return
26
27 rust_cli = envs.VLLM_RUST_FRONTEND_PATH
28 if rust_cli is None:
29 raise RuntimeError(
30 "VLLM_USE_RUST_BENCH=1 requires VLLM_RUST_FRONTEND_PATH "
31 "to resolve to the vllm-rs binary."
32 )
33
34 logger.info("Delegating `vllm bench serve` to Rust binary at %s.", rust_cli)
35 os.execv(rust_cli, [rust_cli, "bench", "serve", *sys.argv[3:]])
36
37
38 def _import_bench_subcommand_modules() -> None:
39 # Imported lazily so `BenchmarkSubcommandBase` subclasses register only
40 # when `vllm bench` is actually invoked.
41 import vllm.entrypoints.cli.benchmark.latency # noqa: F401
42 import vllm.entrypoints.cli.benchmark.mm_processor # noqa: F401
43 import vllm.entrypoints.cli.benchmark.serve # noqa: F401
44 import vllm.entrypoints.cli.benchmark.startup # noqa: F401
45 import vllm.entrypoints.cli.benchmark.sweep # noqa: F401
46 import vllm.entrypoints.cli.benchmark.throughput # noqa: F401
47
48
49 class BenchmarkSubcommand(CLISubcommand):
50 """The `bench` subcommand for the vLLM CLI."""
51
52 name = "bench"
53 help = "vLLM bench subcommand."
54
55 @staticmethod
56 def cmd(args: argparse.Namespace) -> None:
57 args.dispatch_function(args)
58
59 def validate(self, args: argparse.Namespace) -> None:
60 pass
61
62 def subparser_init(
63 self, subparsers: argparse._SubParsersAction
64 ) -> FlexibleArgumentParser:
65 bench_parser = subparsers.add_parser(
66 self.name,
67 help=self.help,
68 description=self.help,
69 usage=f"vllm {self.name} <bench_type> [options]",
70 )
71 bench_subparsers = bench_parser.add_subparsers(required=True, dest="bench_type")
72
73 # Only build the nested bench subparsers when the user is actually
74 # invoking `bench`; otherwise we'd drag in imports
75 # unnecessarily on every `vllm --help` and `vllm serve`.
76 # Scan for the first positional arg so global flags (e.g. `-v`)
77 # before the subcommand don't break detection.
78 first_positional = next(
79 (arg for arg in sys.argv[1:] if not arg.startswith("-")), None
80 )
81 if first_positional == self.name:
82 _import_bench_subcommand_modules()
83 for cmd_cls in BenchmarkSubcommandBase.__subclasses__():
84 cmd_subparser = bench_subparsers.add_parser(
85 cmd_cls.name,
86 help=cmd_cls.help,
87 description=cmd_cls.help,
88 usage=f"vllm {self.name} {cmd_cls.name} [options]",
89 )
90 cmd_subparser.set_defaults(dispatch_function=cmd_cls.cmd)
91 cmd_cls.add_cli_args(cmd_subparser)
92 cmd_subparser.epilog = VLLM_SUBCMD_PARSER_EPILOG.format(
93 subcmd=f"{self.name} {cmd_cls.name}"
94 )
95 return bench_parser
96
97
98 def cmd_init() -> list[CLISubcommand]:
99 return [BenchmarkSubcommand()]