Apply Tensor Parallelism in PyTorch by parallelizing modules or sub-modules based on a user-specified plan. We parallelize module or sub_modules based on a parallelize_plan. The parallelize_plan contains :class:`ParallelStyle`, which indicates how user wants the module or sub_module
( # type: ignore[return]
module: nn.Module,
device_mesh: DeviceMesh,
parallelize_plan: Union[ParallelStyle, Dict[str, ParallelStyle]],
tp_mesh_dim: int = 0,
)
| 23 | |
| 24 | |
| 25 | def parallelize_module( # type: ignore[return] |
| 26 | module: nn.Module, |
| 27 | device_mesh: DeviceMesh, |
| 28 | parallelize_plan: Union[ParallelStyle, Dict[str, ParallelStyle]], |
| 29 | tp_mesh_dim: int = 0, |
| 30 | ) -> nn.Module: |
| 31 | """ |
| 32 | Apply Tensor Parallelism in PyTorch by parallelizing modules or sub-modules based on a user-specified plan. |
| 33 | |
| 34 | We parallelize module or sub_modules based on a parallelize_plan. The parallelize_plan contains |
| 35 | :class:`ParallelStyle`, which indicates how user wants the module or sub_module |
| 36 | to be parallelized. |
| 37 | |
| 38 | User can also specify different parallel style per module fully qualified name (FQN). |
| 39 | The API supports 2D parallelism natively by accepting an n-dimension device_mesh |
| 40 | and users just need to specify the dimension where we perform tensor parallelism on. |
| 41 | |
| 42 | Args: |
| 43 | module (:class:`nn.Module`): |
| 44 | Module to be parallelized. |
| 45 | device_mesh (:class:`DeviceMesh`): |
| 46 | Object which describes the mesh topology |
| 47 | of devices for the DTensor. |
| 48 | parallelize_plan (Union[:class:`ParallelStyle`, Dict[str, :class:`ParallelStyle`]]): |
| 49 | The plan used to parallelize the module. It can be either a |
| 50 | :class:`ParallelStyle` object which contains how |
| 51 | we prepare input/output for Tensor Parallelism or it can be a |
| 52 | dict of module FQN and its corresponding :class:`ParallelStyle` object. |
| 53 | tp_mesh_dim (int): |
| 54 | The dimension of ``device_mesh`` where we perform |
| 55 | Tensor Parallelism on. |
| 56 | |
| 57 | Return: |
| 58 | A :class:`nn.Module` object parallelized. |
| 59 | |
| 60 | Example:: |
| 61 | >>> # xdoctest: +SKIP("distributed") |
| 62 | >>> from torch.distributed.tensor.parallel import parallelize_module, ColwiseParallel |
| 63 | >>> |
| 64 | >>> # Define the module. |
| 65 | >>> m = Model(...) |
| 66 | >>> m = parallelize_module(m, ColwiseParallel()) |
| 67 | >>> |
| 68 | |
| 69 | .. warning:: |
| 70 | Currently, there are some constraints which makes it hard for complicated modules |
| 71 | like ``MultiheadAttention`` to work out of box for Tensor or Sequence Parallelism. |
| 72 | We recommend users to try ``ColwiseParallel`` and ``RowwiseParallel`` for each parameter |
| 73 | or submodule and there might be some code changes needed now. |
| 74 | """ |
| 75 | torch._C._log_api_usage_once("torch.distributed.tensor.parallel.parallelize_module") |
| 76 | |
| 77 | # instantiate a TP RNG state tracker if it's not there |
| 78 | if is_rng_supported_mesh(device_mesh) and not isinstance( |
| 79 | random._rng_tracker, TensorParallelRNGTracker |
| 80 | ): |
| 81 | random._rng_tracker = TensorParallelRNGTracker(device_mesh.device_type) |
| 82 | # TODO: we should allow user to pass in the default seed from a config |
searching dependent graphs…