From bb17a93c0fadd5490511f64f5b92562b404b035f Mon Sep 17 00:00:00 2001 From: Peuqui <43776522+Peuqui@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:54:00 +0200 Subject: [PATCH] [Bugfix][Qwen4Exp] Reduce the PLE offload config to DP1 before it is built The PLE offload process builds its own VllmConfig for the isolated Gloo world and forced DP1 only after construction. ParallelConfig takes the DP variables the process inherits from its GPU worker, and VllmConfig.__post_init__ derives the participating devices from them. For a GPU worker of DP rank 1 that sees only its own device, that lookup asks for device 1 and raises IndexError before DP1 is set. Build the parallel config first, reduce it to DP1/TP1/PP1, and pass it to VllmConfig. The regression test set the DP variables as envs attributes. Because VLLM_DP_RANK_LOCAL defaults to VLLM_DP_RANK, monkeypatch recorded the patched rank as its old value and restored local DP rank 1 as a module attribute, which broke the next test on a host with one visible GPU. Set them through set_lazy_env. Co-authored-by: Claude Signed-off-by: Peuqui <43776522+Peuqui@users.noreply.github.com> --- tests/v1/worker/test_ple_offload_worker.py | 9 ++++++--- vllm/v1/ple_offload/worker.py | 14 +++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/v1/worker/test_ple_offload_worker.py b/tests/v1/worker/test_ple_offload_worker.py index 57c915278a..25d51692dd 100644 --- a/tests/v1/worker/test_ple_offload_worker.py +++ b/tests/v1/worker/test_ple_offload_worker.py @@ -774,9 +774,12 @@ def test_offload_distributed_sets_config_only_for_model_parallel( # The Offload subprocess may inherit DP environment variables from a GPU # worker, but its isolated model-parallel world must always remain DP1. - monkeypatch.setattr(envs, "VLLM_DP_SIZE", 2) - monkeypatch.setattr(envs, "VLLM_DP_RANK", 1) - monkeypatch.setattr(envs, "VLLM_DP_RANK_LOCAL", 1) + # Through the environment, not as envs attributes: VLLM_DP_RANK_LOCAL + # defaults to VLLM_DP_RANK, so restoring it as an attribute would leave + # local DP rank 1 behind for the rest of the process. + set_lazy_env(monkeypatch, "VLLM_DP_SIZE", "2") + set_lazy_env(monkeypatch, "VLLM_DP_RANK", "1") + set_lazy_env(monkeypatch, "VLLM_DP_RANK_LOCAL", "1") monkeypatch.setattr( ple_offload_worker.dist, diff --git a/vllm/v1/ple_offload/worker.py b/vllm/v1/ple_offload/worker.py index f32d414636..0e190cc6e6 100644 --- a/vllm/v1/ple_offload/worker.py +++ b/vllm/v1/ple_offload/worker.py @@ -41,7 +41,7 @@ from cuda.bindings import driver as cuda_driver import vllm.envs as envs -from vllm.config import VllmConfig, set_current_vllm_config +from vllm.config import ParallelConfig, VllmConfig, set_current_vllm_config from vllm.distributed.parallel_state import ( ensure_model_parallel_initialized, init_distributed_environment, @@ -369,10 +369,13 @@ def _init_offload_distributed() -> None: # initialize_model_parallel reads the active VllmConfig in the current # vLLM version. Explicitly configure DP1/TP1/PP1 to match the isolated # world, regardless of any DP environment variables inherited from the GPU - # worker. The real DP/TP configuration is used later for model construction, - # registration, and request routing. - offload_config = VllmConfig() - offload_parallel_config = offload_config.parallel_config + # worker. ParallelConfig takes those variables at construction and + # VllmConfig.__post_init__ derives the participating devices from them, so + # the parallel config is reduced to DP1 before the VllmConfig is built: a DP + # rank that sees only its own GPU would otherwise look up the device at its + # inherited local DP rank. The real DP/TP configuration is used later for + # model construction, registration, and request routing. + offload_parallel_config = ParallelConfig() offload_parallel_config.data_parallel_size = 1 offload_parallel_config.data_parallel_size_local = 1 offload_parallel_config.data_parallel_rank = 0 @@ -385,6 +388,7 @@ def _init_offload_distributed() -> None: offload_parallel_config.world_size = 1 offload_parallel_config.nnodes = 1 offload_parallel_config.node_rank = 0 + offload_config = VllmConfig(parallel_config=offload_parallel_config) with set_current_vllm_config(offload_config): ensure_model_parallel_initialized( tensor_model_parallel_size=1,