diff --git a/vllm/distributed/device_communicators/pynccl.py b/vllm/distributed/device_communicators/pynccl.py
index 2fc35e8..f2d6675 100644
--- a/vllm/distributed/device_communicators/pynccl.py
+++ b/vllm/distributed/device_communicators/pynccl.py
@@ -371,6 +371,35 @@ class PyNcclCommunicator:
     def group_end(self):
         self.nccl.ncclGroupEnd()
 
+    def suspend(self):
+        """Destroy NCCL communicator to release IPC handles before
+        cuda-checkpoint. Call resume() with a fresh unique_id to rebuild."""
+        if self.disabled or not self.available:
+            return
+        stream = current_stream()
+        stream.synchronize()
+        self.nccl.ncclCommDestroy(self.comm)
+        self.comm = None
+        self.disabled = True
+        logger.info("PyNcclCommunicator suspended (rank %d)", self.rank)
+
+    def resume(self, unique_id: ncclUniqueId):
+        """Rebuild NCCL communicator with a fresh unique_id after
+        cuda-checkpoint restore."""
+        if not self.available:
+            return
+        with torch.cuda.device(self.device):
+            self.comm = self.nccl.ncclCommInitRank(
+                self.world_size, unique_id, self.rank
+            )
+            self.disabled = False
+            # Warmup all_reduce
+            data = torch.zeros(1, device=self.device)
+            self.all_reduce(data)
+            current_stream().synchronize()
+            del data
+        logger.info("PyNcclCommunicator resumed (rank %d)", self.rank)
+
     def register_comm_window(self, tensor: torch.Tensor):
         return self.nccl.ncclCommWindowRegister(
             self.comm,
diff --git a/vllm/distributed/parallel_state.py b/vllm/distributed/parallel_state.py
index 338cb1f..8129061 100644
--- a/vllm/distributed/parallel_state.py
+++ b/vllm/distributed/parallel_state.py
@@ -317,6 +317,9 @@ class GroupCoordinator:
         self.unique_name = _get_unique_name(group_name)
         _register_group(self)
 
+        self._group_ranks = group_ranks
+        self._torch_distributed_backend = torch_distributed_backend
+
         self.rank = torch.distributed.get_rank()
         self.local_rank = local_rank
 
@@ -998,6 +1001,53 @@ class GroupCoordinator:
         if self.mq_broadcaster is not None:
             self.mq_broadcaster = None
 
+    def suspend_nccl(self):
+        """Tear down NCCL resources (device_group + pynccl_comm) before
+        cuda-checkpoint.  Gloo cpu_group is kept alive for coordination."""
+        if self.world_size <= 1:
+            return
+        if hasattr(self, "device_group"):
+            torch.distributed.destroy_process_group(self.device_group)
+            del self.device_group
+        if (self.device_communicator is not None
+                and self.device_communicator.pynccl_comm is not None):
+            self.device_communicator.pynccl_comm.suspend()
+
+    def resume_nccl(self):
+        """Rebuild NCCL resources after cuda-checkpoint restore.
+        Uses the surviving gloo cpu_group to distribute a fresh NCCL ID.
+
+        Replays the full group_ranks creation loop so that all ranks in
+        the world group call new_group in the same order as initialization."""
+        if self.world_size <= 1:
+            return
+        from vllm.distributed.device_communicators.pynccl_wrapper import (
+            ncclUniqueId,
+        )
+        for ranks in self._group_ranks:
+            device_group = torch.distributed.new_group(
+                ranks, backend=self._torch_distributed_backend
+            )
+            if self.rank in ranks:
+                self.device_group = device_group
+        if self.device_communicator is not None:
+            self.device_communicator.device_group = self.device_group
+        if self.rank_in_group == 0:
+            pynccl_comm = self.device_communicator.pynccl_comm
+            unique_id = pynccl_comm.nccl.ncclGetUniqueId()
+        else:
+            unique_id = ncclUniqueId()
+        tensor = torch.ByteTensor(list(unique_id.internal))
+        torch.distributed.broadcast(
+            tensor, src=self.ranks[0], group=self.cpu_group
+        )
+        byte_list = tensor.tolist()
+        for i, byte in enumerate(byte_list):
+            unique_id.internal[i] = byte
+        if (self.device_communicator is not None
+                and self.device_communicator.pynccl_comm is not None):
+            self.device_communicator.pynccl_comm.resume(unique_id)
+
     def prepare_communication_buffer_for_model(self, model: torch.nn.Module):
         if self.device_communicator is not None:
             self.device_communicator.prepare_communication_buffer_for_model(model)
@@ -1575,6 +1625,24 @@ def destroy_model_parallel():
     _EP = None
 
 
+def suspend_all_nccl():
+    """Suspend NCCL communicators on all model-parallel groups.
+    Call before cuda-checkpoint."""
+    for group in [_TP, _DCP, _PCP, _PP, _DP, _EP]:
+        if group is not None:
+            group.suspend_nccl()
+    logger.info("All NCCL communicators suspended")
+
+
+def resume_all_nccl():
+    """Resume NCCL communicators on all model-parallel groups.
+    Call after cuda-checkpoint restore."""
+    for group in [_EP, _DP, _PP, _PCP, _DCP, _TP]:
+        if group is not None:
+            group.resume_nccl()
+    logger.info("All NCCL communicators resumed")
+
+
 def destroy_distributed_environment():
     global _WORLD, _NODE_COUNT
     if _WORLD:
diff --git a/vllm/v1/worker/gpu_worker.py b/vllm/v1/worker/gpu_worker.py
index 1e13650..83ca0e7 100644
--- a/vllm/v1/worker/gpu_worker.py
+++ b/vllm/v1/worker/gpu_worker.py
@@ -172,6 +172,17 @@ class Worker(WorkerBase):
         else:
             return nullcontext()
 
+    def suspend_nccl(self) -> None:
+        """Tear down NCCL communicators before cuda-checkpoint."""
+        torch.cuda.synchronize()
+        from vllm.distributed.parallel_state import suspend_all_nccl
+        suspend_all_nccl()
+
+    def resume_nccl(self) -> None:
+        """Rebuild NCCL communicators after cuda-checkpoint restore."""
+        from vllm.distributed.parallel_state import resume_all_nccl
+        resume_all_nccl()
+
     def initialize_cache(self, num_gpu_blocks: int, num_cpu_blocks: int) -> None:
         self.cache_config.num_gpu_blocks = num_gpu_blocks
         self.cache_config.num_cpu_blocks = num_cpu_blocks
