# SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project import argparse import inspect import uvloop from vllm.entrypoints.cli.types import CLISubcommand from vllm.entrypoints.launchers.cli_args import ( make_arg_parser, validate_parsed_serve_args, ) from vllm.entrypoints.launchers.render.entry import run_launch_fastapi from vllm.entrypoints.serve.utils.api_utils import VLLM_SUBCMD_PARSER_EPILOG from vllm.logger import init_logger from vllm.utils.argparse_utils import FlexibleArgumentParser logger = init_logger(__name__) DESCRIPTION = "Launch individual vLLM components." class LaunchSubcommandBase(CLISubcommand): """The base class of subcommands for `vllm launch`.""" help: str @classmethod def add_cli_args(cls, parser: FlexibleArgumentParser) -> None: """Add the CLI arguments to the parser. By default, uses the subcommand's docstring as the description and adds the standard vLLM serving arguments. Subclasses can override to add component-specific arguments. """ if cls.__doc__: parser.description = inspect.cleandoc(cls.__doc__) make_arg_parser(parser) @staticmethod def cmd(args: argparse.Namespace) -> None: raise NotImplementedError class RenderSubcommand(LaunchSubcommandBase): """`vllm launch render` starts a GPU-less rendering server for preprocessing and postprocessing only. ```bash vllm launch render meta-llama/Llama-3.2-1B-Instruct --port 8100 ``` This command reuses the standard serving parser, so model, frontend, networking, and related CLI options follow the same conventions as [`vllm serve`](https://docs.vllm.ai/en/latest/cli/serve/). """ name = "render" help = "Launch a GPU-less rendering server (preprocessing and postprocessing only)." @staticmethod def cmd(args: argparse.Namespace) -> None: uvloop.run(run_launch_fastapi(args)) class LaunchSubcommand(CLISubcommand): """The `launch` subcommand for the vLLM CLI. Uses nested sub-subcommands so each component can define its own arguments independently (e.g. ``vllm launch render``). """ name = "launch" @staticmethod def cmd(args: argparse.Namespace) -> None: if hasattr(args, "model_tag") and args.model_tag is not None: args.model = args.model_tag args.launch_command(args) def validate(self, args: argparse.Namespace) -> None: validate_parsed_serve_args(args) def subparser_init( self, subparsers: argparse._SubParsersAction ) -> FlexibleArgumentParser: launch_parser = subparsers.add_parser( self.name, help=DESCRIPTION, description=DESCRIPTION, usage=f"vllm {self.name} [options]", ) launch_subparsers = launch_parser.add_subparsers( required=True, dest="launch_component" ) for cmd_cls in LaunchSubcommandBase.__subclasses__(): cmd_subparser = launch_subparsers.add_parser( cmd_cls.name, help=cmd_cls.help, usage=f"vllm {self.name} {cmd_cls.name} [options]", ) cmd_subparser.set_defaults(launch_command=cmd_cls.cmd) cmd_cls.add_cli_args(cmd_subparser) cmd_subparser.epilog = VLLM_SUBCMD_PARSER_EPILOG.format( subcmd=f"{self.name} {cmd_cls.name}" ) return launch_parser def cmd_init() -> list[CLISubcommand]: return [LaunchSubcommand()]