[Bugfix] Use DP index for dense DP weight updates and EC CPU region (#56950)

Signed-off-by: lxy-alexander <lxy_alexander@outlook.com> Signed-off-by: aoshen02 <aoshen02@users.noreply.github.com> Co-authored-by: aoshen02 <aoshen02@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: aoshen02 <aoshen@inferact.ai> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

Alexander Lee committed Sep 17, 2026 at 10:44 UTC 9e1cd262cbf43b3f3839a28cfa151e2e4b27e2d8
4 files changed +45 -7
tests/v1/ec_connector/unit/cpu/test_ec_shared_region.py
+28
@@ -13,6 +13,8 @@ from unittest.mock import MagicMock, patch
13 import pytest
14 import torch
15
16 +from vllm.config import ParallelConfig
17 +from vllm.distributed.ec_transfer.ec_connector.cpu import common
18 from vllm.distributed.ec_transfer.ec_connector.cpu.ec_shared_region import (
19 ECSharedRegion,
20 _wait_for_file_size,
@@ -95,6 +97,32 @@ def test_second_instance_opens_existing_file_and_shares_memory():
97 r1.cleanup()
98
99
100 +def test_dense_dp_engines_get_distinct_regions(monkeypatch):
101 + """Dense DP engines reset data_parallel_rank to 0 but share instance_id,
102 + so the region must be keyed by data_parallel_index."""
103 + monkeypatch.setattr(common, "_get_encoder_cache_hidden_dim", lambda cfg: 8)
104 + instance_id = str(uuid.uuid4())
105 + regions = []
106 + try:
107 + for dp_index in range(2):
108 + parallel_config = ParallelConfig(
109 + data_parallel_size=2, data_parallel_rank=dp_index
110 + )
111 + parallel_config.reconfigure_for_independent_dp_rank()
112 + cfg = MagicMock()
113 + cfg.instance_id = instance_id
114 + cfg.parallel_config = parallel_config
115 + cfg.model_config.dtype = torch.float16
116 + cfg.ec_transfer_config.ec_connector_extra_config = {"ec_cpu_bytes": 64}
117 + regions.append(common.create_ec_shared_region(cfg))
118 +
119 + assert all(r._is_creator for r in regions)
120 + assert regions[0]._mmap_path != regions[1]._mmap_path
121 + finally:
122 + for r in regions:
123 + r.cleanup()
124 +
125 +
126 def test_only_creator_unlinks_file_on_cleanup():
127 """Critical contract: if the non-creator unlinks, the creator's mmap path
128 becomes a dangling backing file and a third opener would create a new one
tests/v1/worker/test_gpu_worker_weight_transfer.py
+14 -4
@@ -11,7 +11,7 @@ import pytest
11 import torch
12 import torch.nn as nn
13
14 -from vllm.config import VllmConfig, get_current_vllm_config
14 +from vllm.config import ParallelConfig, VllmConfig, get_current_vllm_config
15 from vllm.lora.layers import BaseLayerWithLoRA
16 from vllm.v1.worker.gpu_model_runner import _get_parameter_for_reload
17 from vllm.v1.worker.gpu_worker import Worker
@@ -136,12 +136,22 @@ def test_rank_local_update_selects_worker_payload(rank, expected):
136 assert worker._weight_update_active is True
137
138
139 -def test_rank_local_update_includes_data_parallel_rank():
139 +def test_rank_local_update_uses_data_parallel_index_after_reconfigure():
140 engine = _RecordingEngine()
141 worker = _make_worker(engine)
142 worker.rank = 0
143 - worker.vllm_config.parallel_config.data_parallel_size = 4
144 - worker.vllm_config.parallel_config.data_parallel_rank = 2
143 + parallel_config = ParallelConfig(
144 + data_parallel_size=4,
145 + data_parallel_rank=2,
146 + )
147 + assert parallel_config.data_parallel_rank == 2
148 + assert parallel_config.data_parallel_index == 2
149 +
150 + parallel_config.reconfigure_for_independent_dp_rank()
151 + assert parallel_config.data_parallel_rank == 0
152 + assert parallel_config.data_parallel_index == 2
153 +
154 + worker.vllm_config.parallel_config = parallel_config
155 Worker.start_weight_update(worker)
156
157 Worker.update_weights(
vllm/distributed/ec_transfer/ec_connector/cpu/common.py
+2 -2
@@ -99,8 +99,8 @@ def create_ec_shared_region(vllm_config: "VllmConfig") -> ECSharedRegion:
99 ec_config = vllm_config.ec_transfer_config
100 assert ec_config is not None, "ec_transfer_config required to build region"
101
102 - dp_rank = vllm_config.parallel_config.data_parallel_rank
103 - engine_id = f"{vllm_config.instance_id}_dp{dp_rank}"
102 + dp_index = vllm_config.parallel_config.data_parallel_index
103 + engine_id = f"{vllm_config.instance_id}_dp{dp_index}"
104
105 dtype = vllm_config.model_config.dtype
106 hidden_dim = _get_encoder_cache_hidden_dim(vllm_config)
vllm/v1/worker/gpu_worker.py
+1 -1
@@ -1449,7 +1449,7 @@ class Worker(WorkerBase):
1449 if isinstance(update_info, list):
1450 parallel_config = self.vllm_config.parallel_config
1451 local_update_info = update_info[
1452 - parallel_config.data_parallel_rank * parallel_config.world_size
1452 + parallel_config.data_parallel_index * parallel_config.world_size
1453 + self.rank
1454 ]
1455 else: