[UX] Improve data-parallel launch validation (#49124)

Signed-off-by: Taneem Ibrahim <taneem.ibrahim@gmail.com> Co-authored-by: Wentao Ye <44945378+yewentao256@users.noreply.github.com>

Taneem Ibrahim committed Jul 24, 2026 at 10:16 UTC 453f01783d44abc3f325bcc6efadf4246ec18873
1 file changed +52 -23
vllm/engine/arg_utils.py
+52 -23
@@ -1955,12 +1955,21 @@ class EngineArgs:
1955 assert not headless or not self.data_parallel_hybrid_lb, (
1956 "data_parallel_hybrid_lb is not applicable in headless mode"
1957 )
1958 - assert not (self.data_parallel_hybrid_lb and self.data_parallel_external_lb), (
1959 - "data_parallel_hybrid_lb and data_parallel_external_lb cannot both be True."
1960 - )
1961 - assert self.data_parallel_backend == "mp" or self.nnodes == 1, (
1962 - "nnodes > 1 is only supported with data_parallel_backend=mp"
1963 - )
1958 + if self.data_parallel_hybrid_lb and self.data_parallel_external_lb:
1959 + raise ValueError(
1960 + "Invalid data-parallel launch options: "
1961 + "`--data-parallel-hybrid-lb` and "
1962 + "`--data-parallel-external-lb` cannot be enabled together. "
1963 + "Enable only one load-balancing mode."
1964 + )
1965 + if self.nnodes > 1 and self.data_parallel_backend != "mp":
1966 + raise ValueError(
1967 + "Invalid data-parallel launch options: "
1968 + f"`--nnodes {self.nnodes}` requires "
1969 + "`--data-parallel-backend mp`; got "
1970 + f"`--data-parallel-backend {self.data_parallel_backend}`. "
1971 + "Use the MP backend or set `--nnodes 1`."
1972 + )
1973 inferred_data_parallel_rank = 0
1974 if self.nnodes > 1:
1975 world_size = (
@@ -1971,13 +1980,22 @@ class EngineArgs:
1980 world_size_within_dp = (
1981 self.pipeline_parallel_size * self.tensor_parallel_size
1982 )
1983 + if world_size % self.nnodes != 0:
1984 + raise ValueError(
1985 + "Invalid data-parallel launch options: "
1986 + f"`--nnodes {self.nnodes}` must evenly divide the total "
1987 + f"world size ({world_size}). Adjust `--nnodes`, "
1988 + "`--data-parallel-size`, `--pipeline-parallel-size`, or "
1989 + "`--tensor-parallel-size`."
1990 + )
1991 + if not 0 <= self.node_rank < self.nnodes:
1992 + raise ValueError(
1993 + "Invalid data-parallel launch options: `--node-rank` must "
1994 + f"be between 0 and {self.nnodes - 1}; got "
1995 + f"`--node-rank {self.node_rank}`. Set it to this node's "
1996 + "zero-based index."
1997 + )
1998 local_world_size = world_size // self.nnodes
1975 - assert world_size % self.nnodes == 0, (
1976 - f"world_size={world_size} must be divisible by nnodes={self.nnodes}."
1977 - )
1978 - assert self.node_rank < self.nnodes, (
1979 - f"node_rank={self.node_rank} must be less than nnodes={self.nnodes}."
1980 - )
1999 inferred_data_parallel_rank = (
2000 self.node_rank * local_world_size
2001 ) // world_size_within_dp
@@ -2008,14 +2026,21 @@ class EngineArgs:
2026 )
2027 # Local DP rank = 1, use pure-external LB.
2028 if data_parallel_external_lb:
2011 - assert self.data_parallel_rank is not None, (
2012 - "data_parallel_rank or node_rank must be specified if "
2013 - "data_parallel_external_lb is enable."
2014 - )
2015 - assert self.data_parallel_size_local in (1, None), (
2016 - "data_parallel_size_local must be 1 or None when data_parallel_rank "
2017 - "is set"
2018 - )
2029 + if self.data_parallel_rank is None:
2030 + raise ValueError(
2031 + "Invalid data-parallel launch options: "
2032 + "`--data-parallel-external-lb` requires a data-parallel "
2033 + "rank. Set `--data-parallel-rank`, or set "
2034 + "`--data-parallel-size` greater than 1 and use `--nnodes` "
2035 + "with `--node-rank` so the rank can be inferred."
2036 + )
2037 + if self.data_parallel_size_local not in (1, None):
2038 + raise ValueError(
2039 + "Invalid data-parallel launch options: an external "
2040 + "data-parallel rank requires `--data-parallel-size-local "
2041 + f"1`; got {self.data_parallel_size_local}. Set it to 1 or "
2042 + "omit it."
2043 + )
2044 data_parallel_size_local = 1
2045 # Use full external lb if we have local_size of 1.
2046 self.data_parallel_hybrid_lb = False
@@ -2050,9 +2075,13 @@ class EngineArgs:
2075 self.node_rank,
2076 )
2077 else:
2053 - assert not self.data_parallel_hybrid_lb, (
2054 - "data_parallel_size_local must be set to use data_parallel_hybrid_lb."
2055 - )
2078 + if self.data_parallel_hybrid_lb:
2079 + raise ValueError(
2080 + "Invalid data-parallel launch options: "
2081 + "`--data-parallel-hybrid-lb` requires "
2082 + "`--data-parallel-size-local`. Set it to the number of "
2083 + "data-parallel ranks on this node."
2084 + )
2085
2086 if self.data_parallel_backend == "ray" and (
2087 envs.VLLM_RAY_DP_PACK_STRATEGY == "span"