Instructions to use Cccccz/HY with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use Cccccz/HY with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("Cccccz/HY", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
Download wan/distributed/device_communicators/cpu_communicator.py from Cccccz/HY: direct link, hf CLI and curl.
- Browser
- Download file 6.2 kB
-
https://huggingface.co/Cccccz/HY/resolve/main/wan/distributed/device_communicators/cpu_communicator.py
- Command line
-
hf download hf://Cccccz/HY/wan/distributed/device_communicators/cpu_communicator.py
-
curl -L -o cpu_communicator.py https://huggingface.co/Cccccz/HY/resolve/main/wan/distributed/device_communicators/cpu_communicator.py
6.2 kB
| # SPDX-License-Identifier: Apache-2.0 | |
| # Adapted from: https://github.com/vllm-project/vllm/blob/main/vllm/distributed/device_communicators/cpu_communicator.py | |
| # CPU-based communicator with optional shared memory optimization | |
| import os | |
| import torch | |
| from torch.distributed import ProcessGroup | |
| from platforms import current_platform | |
| from platforms.interface import CpuArchEnum | |
| from .base_device_communicator import DeviceCommunicatorBase | |
| class CpuCommunicator(DeviceCommunicatorBase): | |
| def __init__( | |
| self, | |
| cpu_group: ProcessGroup, | |
| device: torch.device | None = None, | |
| device_group: ProcessGroup | None = None, | |
| unique_name: str = "", | |
| ): | |
| super().__init__(cpu_group, device, device_group, unique_name) | |
| # Default to standard PyTorch distributed module | |
| self.dist_module = torch.distributed | |
| # Use shared memory optimization for x86 CPUs with tensor parallel | |
| if ( | |
| (current_platform.get_cpu_architecture() == CpuArchEnum.X86) | |
| and hasattr(torch.ops._C, "init_shm_manager") | |
| and unique_name.startswith("tp") | |
| ): | |
| # Enable shared memory for faster communication | |
| self.dist_module = _CPUSHMDistributed(self) | |
| def all_reduce( | |
| self, | |
| input_: torch.Tensor, | |
| op: torch.distributed.ReduceOp | None = torch.distributed.ReduceOp.SUM, | |
| ) -> torch.Tensor: | |
| # Perform all-reduce using distributed or shared memory module | |
| self.dist_module.all_reduce(input_, group=self.device_group, op=op) | |
| return input_ | |
| def gather( | |
| self, input_: torch.Tensor, dst: int = 0, dim: int = -1 | |
| ) -> torch.Tensor | None: | |
| """ | |
| NOTE: We assume that the input tensor is on the same device across | |
| all the ranks. | |
| NOTE: `dst` is the local rank of the destination rank. | |
| """ | |
| world_size = self.world_size | |
| assert ( | |
| -input_.dim() <= dim < input_.dim() | |
| ), f"Invalid dim ({dim}) for input tensor with shape {input_.size()}" | |
| # Normalize negative dimension to positive | |
| if dim < 0: | |
| # Convert negative dim to positive. | |
| dim += input_.dim() | |
| # Allocate output tensor. | |
| if self.rank_in_group == dst: | |
| # Destination rank prepares list to receive from all ranks | |
| gather_list = [torch.empty_like(input_) for _ in range(world_size)] | |
| else: | |
| gather_list = None | |
| # Gather. | |
| self.dist_module.gather( | |
| input_, gather_list, dst=self.ranks[dst], group=self.device_group | |
| ) | |
| if self.rank_in_group == dst: | |
| # Concatenate gathered tensors along specified dimension | |
| output_tensor = torch.cat(gather_list, dim=dim) | |
| else: | |
| output_tensor = None | |
| return output_tensor | |
| def all_gather(self, input_: torch.Tensor, dim: int = -1) -> torch.Tensor: | |
| # Normalize negative dimension to positive | |
| if dim < 0: | |
| # Convert negative dim to positive. | |
| dim += input_.dim() | |
| input_size = input_.size() | |
| # NOTE: we have to use concat-style all-gather here, | |
| # stack-style all-gather has compatibility issues with | |
| # torch.compile . see https://github.com/pytorch/pytorch/issues/138795 | |
| output_size = (input_size[0] * self.world_size,) + input_size[1:] | |
| # Allocate output tensor. | |
| output_tensor = torch.empty( | |
| output_size, dtype=input_.dtype, device=input_.device | |
| ) | |
| # All-gather: collect tensors from all ranks | |
| self.dist_module.all_gather_into_tensor( | |
| output_tensor, input_, group=self.device_group | |
| ) | |
| # Reshape: move world_size dimension to target dim position | |
| output_tensor = output_tensor.reshape((self.world_size,) + input_size) | |
| output_tensor = output_tensor.movedim(0, dim) | |
| output_tensor = output_tensor.reshape( | |
| input_size[:dim] | |
| + (self.world_size * input_size[dim],) | |
| + input_size[dim + 1 :] | |
| ) | |
| return output_tensor | |
| class _CPUSHMDistributed: | |
| """Shared memory distributed operations for CPU tensor parallel""" | |
| def __init__(self, communicator: CpuCommunicator): | |
| # Get unique instance identifier from environment | |
| instance_identifier = os.environ["VLLM_DIST_IDENT"] | |
| unique_name = communicator.unique_name | |
| instance_identifier = f"{instance_identifier}-{unique_name}" | |
| self.communicator = communicator | |
| # Create group identifier from rank list | |
| group_ranks = [str(rank) for rank in self.communicator.ranks] | |
| shm_group_identifier = f"[{'-'.join(group_ranks)}]" | |
| self.group_name = f"{instance_identifier}-{shm_group_identifier}-cpushm" | |
| # Initialize shared memory manager | |
| self.handle = self._init_cpu_shm() | |
| def _init_cpu_shm(self) -> int: | |
| handle = torch.ops._C.init_shm_manager( | |
| self.group_name, | |
| self.communicator.world_size, | |
| self.communicator.rank, | |
| ) | |
| torch.distributed.barrier(self.communicator.device_group) | |
| torch.ops._C.join_shm_manager( | |
| handle, | |
| self.group_name, | |
| ) | |
| torch.distributed.barrier(self.communicator.device_group) | |
| return int(handle) | |
| def all_reduce( | |
| self, input: torch.Tensor, group: ProcessGroup | None = None | |
| ) -> None: | |
| torch.ops._C.shm_allreduce(self.handle, input) | |
| def gather( | |
| self, | |
| input: torch.Tensor, | |
| gather_list: list[torch.Tensor] | None, | |
| dst: int = -1, | |
| group: ProcessGroup | None = None, | |
| ) -> None: | |
| # Note: different from the torch gather, here we use local dst rank. | |
| torch.ops._C.shm_gather( | |
| self.handle, | |
| input, | |
| gather_list, | |
| torch.distributed.get_group_rank(group, dst), | |
| ) | |
| def all_gather_into_tensor( | |
| self, | |
| output: torch.Tensor, | |
| input: torch.Tensor, | |
| group: ProcessGroup | None = None, | |
| ) -> None: | |
| torch.ops._C.shm_all_gather(self.handle, input, output) | |