diff --git a/docs/cli/README.md b/docs/cli/README.md index a7de6d7192ac9..b512a4f4baed0 100644 --- a/docs/cli/README.md +++ b/docs/cli/README.md @@ -16,6 +16,16 @@ Available Commands: vllm {chat,complete,serve,bench,collect-env,run-batch} ``` +When passing JSON CLI arguments, the following sets of arguments are equivalent: + +- `--json-arg '{"key1": "value1", "key2": {"key3": "value2"}}'` +- `--json-arg.key1 value1 --json-arg.key2.key3 value2` + +Additionally, list elements can be passed individually using `+`: + +- `--json-arg '{"key4": ["value3", "value4", "value5"]}'` +- `--json-arg.key4+ value3 --json-arg.key4+='value4,value5'` + ## serve Start the vLLM OpenAI Compatible API server. diff --git a/docs/configuration/engine_args.md b/docs/configuration/engine_args.md index c3c1d5a1c362d..e7ca08b5577c4 100644 --- a/docs/configuration/engine_args.md +++ b/docs/configuration/engine_args.md @@ -11,6 +11,16 @@ Engine arguments control the behavior of the vLLM engine. The engine argument classes, [EngineArgs][vllm.engine.arg_utils.EngineArgs] and [AsyncEngineArgs][vllm.engine.arg_utils.AsyncEngineArgs], are a combination of the configuration classes defined in [vllm.config][]. Therefore, if you are interested in developer documentation, we recommend looking at these configuration classes as they are the source of truth for types, defaults and docstrings. +When passing JSON CLI arguments, the following sets of arguments are equivalent: + +- `--json-arg '{"key1": "value1", "key2": {"key3": "value2"}}'` +- `--json-arg.key1 value1 --json-arg.key2.key3 value2` + +Additionally, list elements can be passed individually using `+`: + +- `--json-arg '{"key4": ["value3", "value4", "value5"]}'` +- `--json-arg.key4+ value3 --json-arg.key4+='value4,value5'` + ## `EngineArgs` --8<-- "docs/argparse/engine_args.md" diff --git a/vllm/engine/arg_utils.py b/vllm/engine/arg_utils.py index c9dc99cad2d0e..4d4ce4c78e9f2 100644 --- a/vllm/engine/arg_utils.py +++ b/vllm/engine/arg_utils.py @@ -178,17 +178,8 @@ def _compute_kwargs(cls: ConfigType) -> dict[str, Any]: kwargs[name] = {"default": default, "help": help} # Set other kwargs based on the type hints - json_tip = """Should either be a valid JSON string or JSON keys -passed individually. For example, the following sets of arguments are -equivalent: - -- `--json-arg '{"key1": "value1", "key2": {"key3": "value2"}}'`\n -- `--json-arg.key1 value1 --json-arg.key2.key3 value2` - -Additionally, list elements can be passed individually using `+`: - -- `--json-arg '{"key4": ["value3", "value4", "value5"]}'`\n -- `--json-arg.key4+ value3 --json-arg.key4+='value4,value5'`""" + json_tip = ("Should either be a valid JSON string or JSON keys passed " + "individually.") if dataclass_cls is not None: def parse_dataclass(val: str, cls=dataclass_cls) -> Any: @@ -1831,13 +1822,3 @@ def human_readable_int(value): # Regular plain number. return int(value) - - -# These functions are used by sphinx to build the documentation -def _engine_args_parser(): - return EngineArgs.add_cli_args(FlexibleArgumentParser()) - - -def _async_engine_args_parser(): - return AsyncEngineArgs.add_cli_args(FlexibleArgumentParser(), - async_args_only=True) diff --git a/vllm/utils/__init__.py b/vllm/utils/__init__.py index 7a0abf5b59f64..a4997226ea3f6 100644 --- a/vllm/utils/__init__.py +++ b/vllm/utils/__init__.py @@ -1669,11 +1669,19 @@ class FlexibleArgumentParser(ArgumentParser): """ArgumentParser that allows both underscore and dash in names.""" _deprecated: set[Action] = set() + _json_tip: str = ( + "When passing JSON CLI arguments, the following sets of arguments " + "are equivalent:\n" + ' --json-arg \'{"key1": "value1", "key2": {"key3": "value2"}}\'\n' + " --json-arg.key1 value1 --json-arg.key2.key3 value2\n\n" + "Additionally, list elements can be passed individually using +:\n" + ' --json-arg \'{"key4": ["value3", "value4", "value5"]}\'\n' + " --json-arg.key4+ value3 --json-arg.key4+=\'value4,value5\'\n\n") def __init__(self, *args, **kwargs): - # Set the default 'formatter_class' to SortedHelpFormatter - if 'formatter_class' not in kwargs: - kwargs['formatter_class'] = SortedHelpFormatter + # Set the default "formatter_class" to SortedHelpFormatter + if "formatter_class" not in kwargs: + kwargs["formatter_class"] = SortedHelpFormatter super().__init__(*args, **kwargs) if sys.version_info < (3, 13): @@ -1715,6 +1723,13 @@ class FlexibleArgumentParser(ArgumentParser): self._action_groups.append(group) return group + def format_help(self) -> str: + # Add tip about JSON arguments to the epilog + epilog = self.epilog or "" + if not epilog.startswith(FlexibleArgumentParser._json_tip): + self.epilog = FlexibleArgumentParser._json_tip + epilog + return super().format_help() + def parse_args( # type: ignore[override] self, args: list[str] | None = None,