@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 5e65d6b2ad
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 14, 05:30 UTC

fix[DP][v1]: Prevent hangs from mismatched worker configurations (#26218)

Signed-off-by: Ayush Satyam <ayushsatyam146@gmail.com>

Ayush Satyam committed Oct 8, 2025 at 11:25 UTC 5e65d6b2adf64d1548c3b25ccc52ad55fcfe8044
3 files changed +46 -11
vllm/config/parallel.py
+9
@@ -336,6 +336,9 @@ class ParallelConfig:
336 graph from input ids/embeddings to the final hidden states,
337 excluding anything before input ids/embeddings and after
338 the final hidden states.
339 +
340 + This hash is also used for DP worker configuration validation
341 + to prevent hangs from mismatched collective communication patterns.
342 """
343 factors: list[Any] = []
344 factors.append(self.pipeline_parallel_size)
@@ -343,6 +346,12 @@ class ParallelConfig:
346 factors.append(self.enable_expert_parallel)
347 factors.append(self.data_parallel_size)
348 factors.append(envs.VLLM_ALL2ALL_BACKEND)
349 + factors.append(self.enable_eplb)
350 + if self.enable_eplb:
351 + factors.append(self.eplb_config.log_balancedness)
352 + factors.append(self.eplb_config.window_size)
353 + factors.append(self.eplb_config.step_interval)
354 + factors.append(self.eplb_config.num_redundant_experts)
355 return hashlib.sha256(str(factors).encode()).hexdigest()
356
357 def __post_init__(self) -> None:
vllm/v1/engine/core.py
+14 -10
@@ -681,17 +681,21 @@ class EngineCoreProc(EngineCore):
681 # external LB case for our colocated front-end to use (coordinator
682 # only runs with rank 0).
683 dp_stats_address = self.frontend_stats_publish_address
684 - handshake_socket.send(
685 - msgspec.msgpack.encode(
686 - {
687 - "status": "READY",
688 - "local": local_client,
689 - "headless": headless,
690 - "num_gpu_blocks": num_gpu_blocks,
691 - "dp_stats_address": dp_stats_address,
692 - }
684 +
685 + # Include config hash for DP configuration validation
686 + ready_msg = {
687 + "status": "READY",
688 + "local": local_client,
689 + "headless": headless,
690 + "num_gpu_blocks": num_gpu_blocks,
691 + "dp_stats_address": dp_stats_address,
692 + }
693 + if vllm_config.parallel_config.data_parallel_size > 1:
694 + ready_msg["parallel_config_hash"] = (
695 + vllm_config.parallel_config.compute_hash()
696 )
694 - )
697 +
698 + handshake_socket.send(msgspec.msgpack.encode(ready_msg))
699
700 @staticmethod
701 def startup_handshake(
vllm/v1/engine/utils.py
+23 -1
@@ -73,6 +73,7 @@ class EngineHandshakeMetadata:
73
74 addresses: EngineZmqAddresses
75 parallel_config: dict[str, Union[int, str, list[int]]]
76 + parallel_config_hash: Optional[str] = None
77
78
79 class CoreEngineProcManager:
@@ -867,7 +868,8 @@ def wait_for_engine_startup(
868 )
869
870 if status == "HELLO" and engine.state == CoreEngineState.NEW:
870 - # Send init message with DP config info.
871 + # Send init message with DP config info and config hash.
872 + # The config hash ensures all DP workers have compatible configs.
873 init_message = msgspec.msgpack.encode(
874 EngineHandshakeMetadata(
875 addresses=addresses,
@@ -880,6 +882,9 @@ def wait_for_engine_startup(
882 "data_parallel_size",
883 )
884 },
885 + parallel_config_hash=parallel_config.compute_hash()
886 + if parallel_config.data_parallel_size > 1
887 + else None,
888 )
889 )
890 handshake_socket.send_multipart((eng_identity, init_message), copy=False)
@@ -900,6 +905,23 @@ def wait_for_engine_startup(
905 if addresses.frontend_stats_publish_address is None:
906 addresses.frontend_stats_publish_address = msg.get("dp_stats_address")
907
908 + # Validate config hash consistency across DP workers
909 + if parallel_config.data_parallel_size > 1:
910 + worker_config_hash = msg.get("parallel_config_hash")
911 + expected_hash = parallel_config.compute_hash()
912 + if worker_config_hash != expected_hash:
913 + raise RuntimeError(
914 + f"Configuration mismatch detected for engine "
915 + f"{eng_index}. All DP workers must have identical "
916 + f"configurations for parameters that affect collective "
917 + f"communication (e.g., enable_eplb, "
918 + f"eplb_config.log_balancedness). "
919 + f"Worker hash: {worker_config_hash}, "
920 + f"Expected hash: {expected_hash}. "
921 + f"Please ensure all workers are started with the same "
922 + f"command-line arguments."
923 + )
924 +
925 start_pending[0 if local else 1] -= 1
926 engine.state = CoreEngineState.READY
927 else: