Spec-Zone.ru › PyTorch 2.14

torch.distributed.tensor

Создано: 13 июня 2025 г. | Последнее обновление: 1 июля 2026 г.

Примечание

torch.distributed.tensor в настоящее время находится в альфа-версии и продолжает разрабатываться. Мы обеспечиваем обратную совместимость для большинства API, перечисленных в документации, однако при необходимости API могут измениться.

PyTorch DTensor (распределённый тензор)

PyTorch DTensor предоставляет простые и гибкие примитивы разбиения тензоров на части, которые прозрачно обрабатывают распределённую логику, включая распределённое хранение, вычисления операторов и коллективные коммуникации между устройствами и узлами. DTensor можно использовать для создания различных решений для параллельных вычислений и поддержки представления sharded state_dict при работе с многомерным разбиением на части.

Примеры нативных решений PyTorch для параллельных вычислений, построенных на основе DTensor:

  • Параллелизм по тензорам
  • FSDP2

DTensor следует модели программирования SPMD (одна программа, множество данных), позволяя пользователям писать распределённые программы так, будто это программа для одного устройства с теми же свойствами сходимости. Она предоставляет единый формат разбиения тензоров на части (макет DTensor), задаваемый с помощью DeviceMesh и Placement:

  • DeviceMesh представляет топологию устройств и средства коммуникации кластера в виде n-мерного массива.
  • Placement описывает макет разбиения логического тензора на части в DeviceMesh. DTensor поддерживает три типа размещения: Shard, Replicate и Partial.

API класса DTensor

DTensor является подклассом torch.Tensor. Это означает, что созданный DTensor можно использовать почти так же, как torch.Tensor, в том числе запускать различные операторы PyTorch так, будто они выполняются на одном устройстве, обеспечивая корректные распределённые вычисления для операторов PyTorch.

Помимо существующих методов torch.Tensor, класс также предоставляет набор дополнительных методов для взаимодействия с torch.Tensor, redistribute макета DTensor в новый DTensor, получения полного содержимого тензора на всех устройствах и т. д.

class torch.distributed.tensor.DTensor(**kwargs)

DTensor (распределённый тензор) — это подкласс torch.Tensor, обеспечивающий абстракцию, аналогичную работе с одним устройством, для программирования с использованием torch.Tensor на нескольких устройствах. Он описывает макет распределённого разбиения тензора на части (макет DTensor) с помощью DeviceMesh и следующих типов Placement:

  • Shard: тензор разбивается на части по измерению тензора dim на устройствах измерения DeviceMesh
  • Replicate: тензор реплицируется на устройствах измерения DeviceMesh
  • Partial: на устройствах измерения DeviceMesh для тензора ожидается редукция

При вызове операторов PyTorch DTensor переопределяет их для выполнения распределённых вычислений и при необходимости инициирует коммуникации. Вместе с вычислением оператора DTensor будет корректно преобразовывать или распространять размещения (макет DTensor) в соответствии с семантикой самого оператора и создавать новые выходные данные DTensor.

Чтобы обеспечить численную корректность распределённых вычислений DTensor с разбиением на части при вызове операторов PyTorch, DTensor требует, чтобы каждый аргумент оператора типа Tensor был DTensor.

Примечание

Прямое использование конструктора подкласса Tensor здесь не является рекомендуемым способом создания DTensor (то есть он некорректно обрабатывает autograd и поэтому не является публичным API). Инструкции по созданию DTensor см. в разделе create_dtensor.

__create_chunk_list__() [исходный код]

Возвращает список ChunkStorageMetadata — объекта dataclass, описывающего размер и смещение локальной части или реплики на текущем ранге. У DTensor на каждом ранге есть одна локальная часть или реплика, поэтому возвращаемый список обычно содержит только один элемент.

Этот dunder-метод используется в основном для распределённых контрольных точек.

Возвращает:

Объект List[ChunkStorageMetadata], представляющий размер и смещение части на текущем ранге.

static from_local(local_tensor, device_mesh=None, placements=None, *, run_check=False, shape=None, stride=None, grad_placements=None) [исходный код]

Создаёт DTensor из локального torch.Tensor на каждом ранге в соответствии с заданными device_mesh и placements.

Параметры:
  • local_tensor (torch.Tensor) – локальный torch.Tensor на каждом ранге.
  • device_mesh (DeviceMesh, необязательный) – DeviceMesh, в который помещается тензор. Если не задан, вызов должен выполняться в контекстном менеджере DeviceMesh. Значение по умолчанию: None
  • placements (List[Placement], необязательный) – размещения, описывающие, как поместить локальный torch.Tensor в DeviceMesh; количество элементов должно совпадать с device_mesh.ndim.
Именованные аргументы:
  • run_check (bool, необязательный) – выполнить проверку согласованности метаданных каждого локального тензора между рангами, чтобы подтвердить корректность; это потребует дополнительных коммуникаций. Если в placements имеется Replicate, данные с первого ранга измерения сетки устройств будут переданы остальным рангам. Значение по умолчанию: False
  • shape (torch.Size, необязательный) – список целых чисел, задающий размер DTensor, построенного на основе local_tensor. Укажите его, если размеры local_tensor различаются на разных рангах. Если значение не задано, shape вычисляется исходя из предположения, что заданный распределённый тензор равномерно разбит на части между рангами. Значение по умолчанию: None
  • stride (tuple, необязательный) – список целых чисел, задающий шаг DTensor. Если значение не задано, stride вычисляется исходя из предположения, что заданный распределённый тензор равномерно разбит на части между рангами. Значение по умолчанию: None
  • grad_placements (List[Placement], необязательный) – задаёт ожидаемые размещения входного градиента. Перед выходом из DTensor входной градиент (обычный тензор) будет перераспределён в соответствии с этим размещением. Если значение не задано, используются приведённые ниже гарантии размещения по умолчанию. Значение по умолчанию: None
Возвращает:

Объект DTensor

Вызывает исключения:

ValueError – Если placements содержит разные типы редукции Partial (например, одновременно Partial("sum") и Partial("max")). Для всех размещений Partial должна использоваться одна и та же операция редукции.

Тип возвращаемого значения:

DTensor

Примечание

При вызове run_check=False пользователь должен самостоятельно убедиться, что переданный локальный тензор корректен для всех рангов (то есть тензор разбит на части для размещения Shard(dim) или реплицирован для размещения Replicate()). В противном случае поведение созданного DTensor не определено.

Примечание

from_local является дифференцируемым; requires_grad созданного объекта DTensor зависит от того, установлен ли для local_tensor флаг requires_grad.

Примечание

При обратном проходе from_local обеспечивает следующие гарантии размещения градиента. Для каждого измерения сетки размещение градиента определяется следующим образом:

Размещение при прямом проходе

Размещение градиента

Shard

Shard

Replicate

Replicate

Partial

Replicate

Если размещение при прямом проходе — Partial, мы всегда перераспределяем градиент в Replicate, а не оставляем его в Partial. Это может быть не самым эффективным вариантом, но позволяет избежать неоднозначности и обеспечивает более ясную семантику градиентов для пользователей.

full_tensor(*, grad_placements=None) [исходный код]

Возвращает полный тензор этого DTensor. Для этого выполняются необходимые коллективные операции: сбор локальных тензоров с других рангов в его DeviceMesh и их объединение. Это синтаксический сахар для следующего кода:

dtensor.redistribute(placements=[Replicate()] * mesh.ndim).to_local()

Именованные аргументы:

grad_placements (List[Placement], необязательный) – размещения задают будущий макет градиента для полного тензора, возвращаемого этой функцией. full_tensor преобразует DTensor в полный torch.Tensor, который впоследствии может использоваться в коде не в исходном реплицированном макете DTensor. Этот аргумент служит подсказкой для autograd на случай, если макет градиента возвращённого тензора не совпадает с исходным реплицированным макетом DTensor. Если значение не задано, предполагается, что макет градиента полного тензора будет реплицированным.

Возвращает:

Объект torch.Tensor, представляющий полный тензор этого DTensor.

Тип возвращаемого значения:

Tensor

Примечание

full_tensor является дифференцируемым.

redistribute(device_mesh=None, placements=None, *, async_op=False, forward_dtype=None, backward_dtype=None) [исходный код]

redistribute выполняет необходимые коллективные операции для перераспределения текущего DTensor: изменяет его текущие размещения на новые или переносит его из текущего DeviceMesh в новый. Например, можно преобразовать DTensor с разбиением на части в реплицированный DTensor, указав размещение Replicate для каждого измерения DeviceMesh.

При перераспределении в новые размещения по одному измерению сетки устройств выполняются следующие операции, включающие коллективные коммуникации или локальные действия:

  1. Shard(dim) -> Replicate(): all_gather
  2. Shard(src_dim) -> Shard(dst_dim): all_to_all
  3. Replicate() -> Shard(dim): локальное разбиение на части (то есть torch.chunk)
  4. Partial() -> Replicate(): all_reduce
  5. Partial() -> Shard(dim): reduce_scatter
  6. Shard(dim) -> Partial("sum"): локальное заполнение нулями. Это преобразование, выполняемое только по явному запросу, создаёт на каждом ранге локальный тензор глобального размера и не требует коммуникаций.

Из преобразований в Partial этот публичный API поддерживает только Shard(dim) -> Partial("sum"). Каждый ранг размещает свою локальную часть в тензоре нулей логической формы по соответствующему смещению; таким образом, суммирование по рангам восстанавливает исходный логический тензор.

redistribute корректно определяет необходимые этапы перераспределения для DTensor, созданных как на одномерной, так и на N-мерной сетке DeviceMesh.

Параметры:
  • device_mesh (DeviceMesh, необязательный) – DeviceMesh, в который помещается DTensor. Если значение не задано, используется DeviceMesh текущего DTensor. Значение по умолчанию: None
  • placements (List[Placement], необязательный) – новые размещения, описывающие, как поместить DTensor в DeviceMesh; количество элементов должно совпадать с device_mesh.ndim. По умолчанию: репликация по всем измерениям сетки
Именованные аргументы:
  • async_op (bool, необязательный) – выполнять ли операцию перераспределения DTensor асинхронно. Значение по умолчанию: False
  • forward_dtype (torch.dtype, необязательный) – преобразовать локальный тензор к типу forward_dtype перед выполнением коллективной операции прямого прохода. Результирующий DTensor будет иметь тип forward_dtype. Если задано None, преобразование не выполняется. Значение по умолчанию: None
  • backward_dtype (torch.dtype, необязательный) – преобразовать градиент к типу backward_dtype перед выполнением коллективной операции обратного прохода. После операции градиент всегда преобразуется обратно к типу исходного DTensor. Если задано None, коллективная операция обратного прохода выполняется с типом исходного DTensor (а не forward_dtype). Значение по умолчанию: None
Возвращает:

Объект DTensor

Тип возвращаемого значения:

DTensor

Примечание

redistribute допускает вычисление производных второго порядка: пользователю не нужно беспокоиться о формуле обратного прохода для операции перераспределения или её совместимости с autograd при вычислении производных второго порядка. Дифференцирование более высокого порядка не тестировалось (но может работать).

Примечание

redistribute в настоящее время поддерживает перераспределение DTensor только в пределах одной и той же DeviceMesh. Если вам нужно перераспределять DTensor в другую DeviceMesh, создайте issue.

to_local(*, grad_placements=None) [исходный код]

Возвращает локальный тензор этого DTensor на текущем ранге. При разбиении на части возвращается локальная часть представления логического тензора, а при репликации — реплика на текущем ранге.

Именованные аргументы:

grad_placements (List[Placement], необязательный) – размещения задают будущий макет градиента для тензора, возвращаемого этой функцией. to_local преобразует DTensor в локальный тензор, который впоследствии может использоваться в коде не в исходном макете DTensor. Этот аргумент служит подсказкой для autograd на случай, если макет градиента возвращённого тензора не совпадает с исходным макетом DTensor. Если значение не задано, предполагается, что макет градиента останется таким же, как у исходного DTensor, и будет использоваться для вычисления градиента.

Возвращает:

Объект torch.Tensor или AsyncCollectiveTensor, представляющий локальный тензор на текущем ранге. Если возвращён объект AsyncCollectiveTensor, локальный тензор ещё не готов (то есть коммуникация не завершена). В этом случае необходимо вызвать wait и дождаться готовности локального тензора.

Тип возвращаемого значения:

Tensor

Примечание

to_local является дифференцируемым; requires_grad возвращённого локального тензора зависит от того, установлен ли для DTensor флаг requires_grad.

property device_mesh: DeviceMesh

Атрибут DeviceMesh, связанный с этим объектом DTensor.

Примечание

device_mesh — свойство только для чтения, его нельзя задать.

property placements: tuple[Placement, ...]

Атрибут placements этого DTensor, описывающий его макет в соответствующей DeviceMesh.

Примечание

placements — свойство только для чтения, его нельзя задать.

DeviceMesh как средство распределённой коммуникации

DeviceMesh была создана на основе DTensor как абстракция для описания топологии устройств кластера и представления многомерных средств коммуникации (поверх ProcessGroup). Подробные инструкции по созданию и использованию DeviceMesh см. в руководстве по DeviceMesh.

Типы размещения DTensor

DTensor поддерживает следующие типы Placement для каждого измерения DeviceMesh:

class torch.distributed.tensor.placement_types.Shard [источник]

Размещение Shard(dim) описывает разбиение DTensor по измерению тензора dim относительно соответствующего измерения DeviceMesh, при котором каждый ранг в измерении DeviceMesh содержит только часть/фрагмент глобального тензора. Размещение Shard(dim) следует семантике torch.chunk(dim): последние фрагменты в измерении DeviceMesh могут быть пустыми, если размер измерения тензора не делится нацело на размер измерения DeviceMesh. Размещение Shard можно использовать во всех API DTensor (например, distribute_tensor, from_local и т. д.).

Параметры:

dim (int) – Измерение тензора, по которому DTensor разбивается относительно соответствующего измерения DeviceMesh.

Предупреждение

Разбиение по измерению тензора, размер которого не делится нацело на размер измерения DeviceMesh, в настоящее время является экспериментальным и может измениться.

Примечание

При проверке, похоже ли размещение на shard, используйте _is_shard_like() вместо isinstance(p, Shard), чтобы также учитывать _StridedShard.

static local_shard_size_and_offset(curr_local_size, num_chunks, rank) [источник]

По размеру текущего локального тензора (который уже может быть разбит по некоторым измерениям) вычисляет размер и смещение нового локального фрагмента с учетом заданного числа частей (num_chunks обычно равно размеру текущего измерения разбиения).

Примечание: смещение нового локального фрагмента отсчитывается относительно текущего разбитого тензора, а не глобального. См. _utils.compute_local_shape_and_global_offset, чтобы вычислить глобальное смещение.

Возвращает (размер нового локального фрагмента, смещение)

Тип возвращаемого значения:

tuple[_RankTypeT, _RankTypeT]

class torch.distributed.tensor.placement_types._StridedShard(dim, *, split_factor=1, sf=None) [источник]

_StridedShard изначально был добавлен для поддержки разбиения 2D FSDP2 + TP, при котором тензор сначала разбивается по измерению TP-сетки, а затем по измерению FSDP-сетки. Мы называем это разбиением справа налево, противоположным разбиению слева направо, используемому по умолчанию. См. пример ниже:

tensor shape: [8, 8]
mesh: [[0, 1], [2, 3]], names=("dp", "tp")
placements: [Shard(0), Shard(0)]

При разбиении по умолчанию тензор сначала разбивается по измерению сетки «dp», а затем по измерению «tp». Результат разбиения будет следующим:

Rank    |   Mesh Coordinate |   Shard Index
------------------------------------------------
0       |   (0, 0)          |   0 (row 0-1)
1       |   (0, 1)          |   1 (row 2-3)
2       |   (1, 0)          |   2 (row 4-5)
3       |   (1, 1)          |   3 (row 6-7)

При разбиении FSDP2 + TP порядок обратный: тензор сначала разбивается по измерению сетки «tp», а затем по измерению «dp». Такое разбиение справа налево даст следующий результат:

Rank    |   Mesh Coordinate |   Shard Index
------------------------------------------------
0       |   (0, 0)          |   0 (row 0-1)
1       |   (0, 1)          |   2 (row 4-5)
2       |   (1, 0)          |   1 (row 2-3)
3       |   (1, 1)          |   3 (row 6-7)

В результате любая попытка перераспределить этот DTensor в полную реплику приведет к неправильному результату, поскольку перераспределение из фрагментов в реплику всегда выполняется справа налево, независимо от того, использовалось ли разбиение слева направо или справа налево. Чтобы решить эту проблему, мы используем размещение _StridedShard, которое позволяет согласовать разбиение справа налево с соглашением слева направо как при распределении тензора, так и при его перераспределении.

С помощью _StridedShard разбиение справа налево, показанное выше, можно представить так:

tensor shape: [8, 8]
mesh: [[0, 1], [2, 3]], names=("dp", "tp")
placements: [_StridedShard(0, split_factor=2), Shard(0)]

Обработка placements слева направо даст тот же результат, отличный от результата при использовании размещения Shard:

Rank    |   Mesh Coordinate |   Shard Index
------------------------------------------------
0       |   (0, 0)          |   0 (row 0-1)
1       |   (0, 1)          |   2 (row 4-5)
2       |   (1, 0)          |   1 (row 2-3)
3       |   (1, 1)          |   3 (row 6-7)

Аргумент split_factor — это число существующих фрагментов по измерению разбиения тензора до обработки размещения _StridedShard, как если бы разбиение выполнялось справа налево. В приведенном выше примере тензор сначала нужно разбить на 2 фрагмента по измерению «tp», а затем разбить по измерению «dp». Поэтому split_factor размещения _StridedShard по измерению «dp» равно 2.

local_shard_size_and_offset(curr_local_size, num_chunks, rank, offset_mode=_StridedShardOffsetMode.FIRST) [источник]

Вычисляет размер и смещение(я) локального фрагмента для размещения _StridedShard.

В отличие от обычного размещения Shard, при котором смещения непрерывны, _StridedShard создает разреженные (страйдовые) смещения из-за семантики разбиения справа налево. Этот метод вычисляет фактические индексы, принадлежащие локальному фрагменту.

Параметры:
  • self (_StridedShard) – Экземпляр размещения _StridedShard.
  • curr_local_size (int) – Текущий размер измерения тензора, который нужно разбить.
  • num_chunks (int) – Число частей, на которые нужно разделить измерение (обычно равно размеру измерения сетки).
  • rank (RankType) – Индекс ранга, для которого вычисляется фрагмент.
  • offset_mode (_StridedShardOffsetMode) – Управляет материализацией смещений. FIRST возвращает только первое смещение как int, ALL возвращает все смещения как список, а NONE пропускает материализацию смещений. Значение по умолчанию — FIRST.
Возвращает:
Кортеж, содержащий:
  • local_shard_size (int): Число элементов в локальном фрагменте для этого ранга.
  • offset (int | list[int] | None): Определяется параметром offset_mode. FIRST возвращает первое смещение как int, ALL возвращает список всех смещений, а NONE возвращает None.
Тип возвращаемого значения:

tuple

property split_factor: int | SymInt
class torch.distributed.tensor.placement_types.Replicate [источник]

Размещение Replicate() описывает репликацию DTensor по соответствующему измерению DeviceMesh: каждый ранг в измерении DeviceMesh содержит реплику глобального тензора. Размещение Replicate можно использовать во всех API DTensor (например, distribute_tensor, DTensor.from_local и т. д.).

class torch.distributed.tensor.placement_types.Partial [источник]
ALL_REDUCE_OPS: tuple[str, ...] = ('sum', 'avg', 'min', 'max', 'product')

Размещение Partial(reduce_op) описывает DTensor, для которого ожидается редукция по указанному измерению DeviceMesh: каждый ранг в измерении DeviceMesh содержит частичное значение глобального тензора. Пользователь может перераспределить DTensor Partial в размещение Replicate или Shard(dim) по указанному измерению DeviceMesh с помощью redistribute; при этом необходимые операции обмена данными будут выполнены автоматически (например, allreduce, reduce_scatter).

Параметры:

reduce_op (str, optional) –

Операция редукции, используемая для преобразования частичного DTensor в реплицированный/разделенный DTensor. Соответствует операциям редукции, поддерживаемым torch.distributed.ReduceOp. Значение по умолчанию: «sum».

Поддерживаемые значения:

  • "sum": Поэлементное суммирование по всем рангам.
  • "avg": Поэлементное усреднение по всем рангам.
  • "min": Поэлементный минимум по всем рангам.
  • "max": Поэлементный максимум по всем рангам.
  • "product": Поэлементное произведение по всем рангам.
  • "band": Побитовое И по всем рангам (только для целочисленных тензоров).
  • "bor": Побитовое ИЛИ по всем рангам (только для целочисленных тензоров).
  • "bxor": Побитовое исключающее ИЛИ по всем рангам (только для целочисленных тензоров).

Примечание

Размещение Partial может быть результатом операций DTensor, вызвано DTensor.from_local или получено при перераспределении размещения Shard в Partial("sum").

LINEAR_REDUCE_OPS: tuple[str, ...] = ('sum', 'avg')
class torch.distributed.tensor.placement_types._MaskPartial(reduce_op=None, mask_buffer=None, offset_shape=None, offset_dim=0, *args, **kwargs) [источник]

Размещение частичной маски, предназначенное для операции встраивания с разбиением по строкам, где необходимо замаскировать индексы и скорректировать их для локального фрагмента встраивания. Маскирование встраивания — это особый тип размещения Partial.

ПРИМЕЧАНИЕ: жизненный цикл этого размещения _MaskPartial соответствует жизненному циклу связанного DTensor, то есть indices_mask существует только в течение времени жизни DTensor.

mask_buffer: MaskBuffer
offset_dim: int = 0
offset_shape: Size | None = None
class torch.distributed.tensor.placement_types.Placement

Базовый класс типа Placement, описывающий размещение DTensor в DeviceMesh. Placement и DeviceMesh вместе могут описывать компоновку DTensor. Это базовый класс для трех основных типов размещения DTensor: Shard, Replicate и Partial.

Этот класс не предназначен для непосредственного использования и служит главным образом типовой заглушкой.

is_partial(self: torch._C._distributed.Placement, reduce_op: str | None = None) → bool
is_replicate(self: torch._C._distributed.Placement) → bool
is_shard(self: torch._C._distributed.Placement, dim: SupportsInt | SupportsIndex | None = None) → bool

Различные способы создания DTensor

There’re three ways to construct a DTensor:
  • distribute_tensor() создает DTensor из логического, или «глобального», torch.Tensor на каждом ранге. Это можно использовать для разбиения конечных torch.Tensor (например, параметров/буферов модели и входных данных).
  • DTensor.from_local() создает DTensor из локального torch.Tensor на каждом ранге. Это можно использовать для создания DTensor из промежуточных torch.Tensor (например, промежуточных тензоров активаций во время прямого/обратного прохода).
  • DTensor предоставляет специальные функции-фабрики тензоров (например, empty(), ones(), randn() и т. д.), позволяющие создавать различные DTensor, напрямую задавая DeviceMesh и Placement. В отличие от distribute_tensor(), здесь можно сразу выделить память для разбитого тензора на устройстве, вместо разбиения после инициализации памяти логического тензора.

Создание DTensor из логического torch.Tensor

Модель программирования SPMD (одна программа, множество данных) в torch.distributed запускает несколько процессов (например, с помощью torchrun) для выполнения одной и той же программы. Это означает, что модель внутри программы сначала инициализируется в разных процессах (например, модель может быть инициализирована на CPU, на устройстве meta или непосредственно на GPU, если памяти достаточно).

DTensor предоставляет API distribute_tensor(), который может разбивать веса модели или тензоры на DTensor, создавая DTensor из «логического» тензора в каждом процессе. Благодаря этому созданные DTensor соответствуют семантике одного устройства, что критически важно для численной корректности.

torch.distributed.tensor.distribute_tensor(tensor, device_mesh=None, placements=None, *, src_data_rank=0) [источник]

Распределяет конечный torch.Tensor (например, nn.Parameter/буферы) по device_mesh в соответствии с заданным placements. Ранг device_mesh и placements должен совпадать. Распределяемый tensor является логическим, или «глобальным», тензором; API использует tensor первого ранга измерения DeviceMesh как источник достоверных данных, чтобы сохранить семантику одного устройства. Если нужно создать DTensor в ходе вычислений Autograd, используйте вместо этого DTensor.from_local().

Параметры:
  • tensor (torch.Tensor) – torch.Tensor для распределения. Если требуется разбить тензор по измерению, размер которого не делится нацело на число устройств в соответствующем измерении сетки, для разбиения и рассылки фрагментов используется семантика torch.chunk. Поведение при неравномерном разбиении является экспериментальным и может измениться.
  • device_mesh (DeviceMesh, optional) – DeviceMesh для распределения тензора. Если параметр не задан, вызов должен выполняться в контекстном менеджере DeviceMesh. Значение по умолчанию: None.
  • placements (List[Placement], optional) – размещения, описывающие размещение тензора в DeviceMesh; число элементов должно совпадать с device_mesh.ndim. Если параметр не задан, тензор по умолчанию реплицируется между device_mesh, начиная с первого ранга каждого измерения device_mesh.
Именованные аргументы:

src_data_rank (int, optional) – ранг исходных данных логического/глобального тензора. Используется функцией distribute_tensor() для рассылки фрагментов/реплик другим рангам. По умолчанию в качестве исходных данных для сохранения семантики одного устройства используется group_rank=0 в каждом измерении DeviceMesh. Если явно передать None, функция distribute_tensor() использует локальные данные ранга вместо попытки сохранить семантику одного устройства с помощью рассылки. Значение по умолчанию: 0.

Возвращает:

Объект DTensor или XLAShardedTensor.

Вызывает исключения:

ValueError – Если placements содержит разные типы редукции Partial (например, одновременно Partial("sum") и Partial("max")). Для всех размещений Partial должна использоваться одна и та же операция редукции.

Тип возвращаемого значения:

DTensor

Примечание

При инициализации DeviceMesh с типом устройства xla функция distribute_tensor вместо этого возвращает XLAShardedTensor. Подробнее см. это обсуждение. Интеграция с XLA является экспериментальной и может измениться.

Помимо distribute_tensor(), DTensor также предоставляет API distribute_module(), упрощающий разбиение на уровне nn.Module.

torch.distributed.tensor.distribute_module(module, device_mesh=None, partition_fn=None, input_fn=None, output_fn=None) [источник]

Преобразует параметры/буферы модуля в DTensor, а также при необходимости преобразует его входы/выходы во время выполнения с помощью трех предоставленных пользователем функций обратного вызова.

Поведение трех функций обратного вызова:

  1. partition_fn разбивает параметры/буферы модуля до выполнения (то есть преобразует обычные параметры torch.Tensor в параметры DTensor). Все параметры/буферы, не преобразованные функцией partition_fn, после этого реплицируются между device_mesh. Если partition_fn равен None, реплицируются все параметры/буферы.
  2. input_fn / output_fn преобразуют входы/выходы модуля во время выполнения (например, преобразуют обычные входные тензоры в DTensor или преобразуют выходы DTensor обратно в обычные тензоры torch.Tensor).
Параметры:
  • module (nn.Module) – пользовательский модуль для разбиения.
  • device_mesh (DeviceMesh) – сетка устройств для размещения модуля. Если None, используется текущая сетка из окружающего контекста сетки.
  • partition_fn (Callable) – функция с сигнатурой partition_fn(name: str, module: nn.Module, device_mesh: DeviceMesh) -> None. Она вызывается для каждого подмодуля (включая сам module), где name — полное квалифицированное имя подмодуля ("" для модуля верхнего уровня), возвращаемое функцией nn.Module.named_modules(). Функция должна изменять module на месте, обычно вызывая distribute_tensor() и register_parameter() для замены выбранных параметров на параметры DTensor. Возвращаемое значение игнорируется. Если параметр не задан, все параметры модуля реплицируются между device_mesh.
  • input_fn (Callable) – функция с сигнатурой input_fn(module: nn.Module, inputs: Inputs, device_mesh: DeviceMesh) -> Inputs, где Inputs — кортеж позиционных аргументов для forward (по одному элементу на каждый позиционный аргумент, например (x,) для forward(self, x); именованные аргументы в input_fn не передаются). Устанавливается на module верхнего уровня как forward_pre_hook и возвращает новый кортеж аргументов той же структуры, что и inputs, обычно с преобразованием каждой записи torch.Tensor в DTensor. Этот кортеж заменяет inputs при фактическом вызове forward.
  • output_fn (Callable) – функция с сигнатурой output_fn(module: nn.Module, outputs: Outputs, device_mesh: DeviceMesh) -> Outputs, где Outputs — тип возвращаемого значения module.forward (один тензор или любая вложенная структура тензоров, например кортеж/словарь); обычно эти тензоры являются объектами DTensor. Устанавливается на module верхнего уровня как forward_hook и возвращает заменяющий результат той же структуры — обычно с преобразованием каждого DTensor обратно в обычный torch.Tensor с помощью DTensor.to_local() или DTensor.full_tensor() либо с перераспределением в другие размещения.
Возвращает:

Модуль, все параметры/буферы которого являются объектами DTensor (тот же объект module, измененный на месте).

Тип возвращаемого значения:
Module

Предупреждение

Ранее input_fn и output_fn принимали два аргумента (inputs, device_mesh) / (outputs, device_mesh). Эта форма устарела; используйте описанную выше форму с тремя аргументами.

Пример:

import torch.nn as nn
from torch.distributed.tensor import (
    DTensor,
    Replicate,
    Shard,
    distribute_module,
    distribute_tensor,
    init_device_mesh,
)


class MyModule(nn.Module):
    def __init__(self) -> None:
        super().__init__()
        self.fc = nn.Linear(8, 8)

    def forward(self, x):
        return self.fc(x)


mesh = init_device_mesh("cuda", (4,))


def shard_params(name, mod, mesh):
    if isinstance(mod, nn.Linear):
        for pname, param in mod.named_parameters(recurse=False):
            mod.register_parameter(
                pname, nn.Parameter(distribute_tensor(param, mesh, [Shard(0)]))
            )


# Replicate the input across the mesh before forward.
def to_replicated(mod, inputs, mesh):
    return tuple(
        distribute_tensor(x, mesh, [Replicate()])
        if isinstance(x, torch.Tensor)
        else x
        for x in inputs
    )


# Convert the DTensor output back to a plain torch.Tensor after forward.
def to_local(mod, outputs, mesh):
    return outputs.full_tensor() if isinstance(outputs, DTensor) else outputs


sharded = distribute_module(
    MyModule(),
    mesh,
    partition_fn=shard_params,
    input_fn=to_replicated,
    output_fn=to_local,
)

Примечание

При инициализации DeviceMesh с типом устройства xla функция distribute_module возвращает nn.Module с параметрами, аннотированными для PyTorch/XLA SPMD. Подробнее см. это обсуждение. Интеграция с XLA является экспериментальной и может измениться.

Функции-фабрики DTensor

DTensor также предоставляет специальные функции-фабрики тензоров, позволяющие создавать DTensor напрямую с помощью API функций-фабрик, аналогичных torch.Tensor (например, torch.ones, torch.empty и т. д.), дополнительно указывая DeviceMesh и Placement для создаваемого DTensor:

torch.distributed.tensor.zeros(*size, requires_grad=False, dtype=None, layout=torch.strided, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor, заполненный скалярным значением 0.

Параметры:

size (int...) – последовательность целых чисел, задающая форму выходного DTensor. Можно передать переменное число аргументов или коллекцию, например список или кортеж. Например: zeros(1,2,3..) или zeros([1,2,3..]) или zeros((1,2,3..))

Именованные аргументы:
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • dtype (torch.dtype, необязательно) – требуемый тип данных возвращаемого DTensor. По умолчанию: если None, используется глобальное значение по умолчанию (см. torch.set_default_dtype()).
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.ones(*size, dtype=None, layout=torch.strided, requires_grad=False, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor, заполненный скалярным значением 1, с формой, заданной переменным аргументом size.

Параметры:

size (int...) – последовательность целых чисел, задающая форму выходного DTensor. Можно передать переменное число аргументов или коллекцию, например список или кортеж. Например: ones(1,2,3..) или ones([1,2,3..]) или ones((1,2,3..))

Именованные аргументы:
  • dtype (torch.dtype, необязательно) – требуемый тип данных возвращаемого DTensor. По умолчанию: если None, используется глобальное значение по умолчанию (см. torch.set_default_dtype()).
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.empty(*size, dtype=None, layout=torch.strided, requires_grad=False, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor, заполненный неинициализированными данными. Форма DTensor задаётся переменным аргументом size.

Параметры:

size (int...) – последовательность целых чисел, задающая форму выходного DTensor. Можно передать переменное число аргументов или коллекцию, например список или кортеж. Например: empty(1,2,3..) или empty([1,2,3..]) или empty((1,2,3..))

Именованные аргументы:
  • dtype (torch.dtype, необязательно) – требуемый тип данных возвращаемого DTensor. По умолчанию: если None, используется глобальное значение по умолчанию (см. torch.set_default_dtype()). layout (torch.layout, необязательно): требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.full(size, fill_value, *, dtype=None, layout=torch.strided, requires_grad=False, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor, заполненный значением fill_value в соответствии с device_mesh и placements, с формой, заданной аргументом size.

Параметры:
  • size (int...) – последовательность целых чисел, задающая форму выходного DTensor. Можно передать переменное число аргументов или коллекцию, например список или кортеж. Например: ones(1,2,3..) или ones([1,2,3..]) или ones((1,2,3..))
  • fill_value (Scalar) – значение, которым заполняется выходной тензор.
Именованные аргументы:
  • dtype (torch.dtype, необязательно) – требуемый тип данных возвращаемого DTensor. По умолчанию: если None, используется глобальное значение по умолчанию (см. torch.set_default_dtype()).
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов.
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.linspace(start, end, steps, *, dtype=None, layout=torch.strided, requires_grad=False, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor размера steps, значения которого равномерно распределены от start до end.

Параметры:
  • start (float или DTensor) – начальное значение набора точек. Если это DTensor, он должен быть нульмерным
  • end (float или DTensor) – конечное значение набора точек. Если это DTensor, он должен быть нульмерным
  • steps (int) – размер создаваемого DTensor
Именованные аргументы:
  • dtype (torch.dtype, необязательно) – тип данных, используемый для вычислений. По умолчанию: если None, для вычислений используется глобальный тип данных по умолчанию (см. torch.set_default_dtype()), если start и end — вещественные числа; если одно из них комплексное, используется соответствующий комплексный тип данных.
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.logspace(start, end, steps, base=10.0, *, dtype=None, layout=torch.strided, requires_grad=False, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor размера steps, значения которого равномерно распределены от base start до base end включительно в логарифмическом масштабе с основанием base.

Параметры:
  • start (float или DTensor) – начальное значение набора точек. Если это DTensor, он должен быть нульмерным
  • end (float или DTensor) – конечное значение набора точек. Если это DTensor, он должен быть нульмерным
  • steps (int) – размер создаваемого DTensor
Именованные аргументы:
  • base (float, необязательно) – основание логарифма. По умолчанию: 10.0.
  • dtype (torch.dtype, необязательно) – тип данных, используемый для вычислений. По умолчанию: если None, для вычислений используется глобальный тип данных по умолчанию (см. torch.set_default_dtype()), если start и end — вещественные числа; если одно из них комплексное, используется соответствующий комплексный тип данных.
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.rand(*size, requires_grad=False, dtype=None, layout=torch.strided, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor, заполненный случайными числами из равномерного распределения на интервале [0, 1). Форма тензора задаётся переменным аргументом size.

Параметры:

size (int...) – последовательность целых чисел, задающая форму выходного DTensor. Можно передать переменное число аргументов или коллекцию, например список или кортеж. Например: ones(1,2,3..) или ones([1,2,3..]) или ones((1,2,3..))

Именованные аргументы:
  • dtype (torch.dtype, необязательно) – требуемый тип данных возвращаемого DTensor. По умолчанию: если None, используется глобальное значение по умолчанию (см. torch.set_default_dtype()).
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов.
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

torch.distributed.tensor.randn(*size, requires_grad=False, dtype=None, layout=torch.strided, device_mesh=None, placements=None) [исходный код]

Возвращает DTensor, заполненный случайными числами из нормального распределения со средним 0 и дисперсией 1. Форма тензора задаётся переменным аргументом size.

Параметры:

size (int...) – последовательность целых чисел, задающая форму выходного DTensor. Можно передать переменное число аргументов или коллекцию, например список или кортеж. Например: ones(1,2,3..) или ones([1,2,3..]) или ones((1,2,3..))

Именованные аргументы:
  • dtype (torch.dtype, необязательно) – требуемый тип данных возвращаемого DTensor. По умолчанию: если None, используется глобальное значение по умолчанию (см. torch.set_default_dtype()).
  • layout (torch.layout, необязательно) – требуемый формат возвращаемого DTensor. По умолчанию: torch.strided.
  • requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым DTensor. По умолчанию: False.
  • device_mesh – тип DeviceMesh, содержит информацию о сетке рангов.
  • placements – последовательность типа Placement: Shard, Replicate
Возвращает:

Объект DTensor на каждом ранге

Тип возвращаемого значения:

DTensor

Случайные операции

DTensor предоставляет функциональность распределённого генератора случайных чисел (RNG), обеспечивающую уникальные значения для случайных операций над секционированными тензорами и одинаковые значения для случайных операций над реплицированными тензорами. Эта система требует, чтобы все участвующие ранги (например, ранги SPMD) начинали с одинакового состояния генератора перед выполнением каждой случайной операции с DTensor. При соблюдении этого условия после завершения каждой такой операции все они оказываются в одном и том же состоянии. Во время случайных операций обмен данными для синхронизации состояний RNG не выполняется.

Операторы, принимающие именованный аргумент generator, используют переданный пользователем генератор, если он задан; в противном случае используется генератор устройства по умолчанию. Используемый генератор продвигается после операции с DTensor. Допускается использовать один и тот же генератор как для операций с DTensor, так и для операций без DTensor, однако в этом случае необходимо следить, чтобы операции без DTensor одинаково продвигали состояние генератора на всех рангах.

При использовании DTensor совместно с конвейерным параллелизмом ранги каждого этапа конвейера должны использовать разные начальные значения, а ранги внутри одного этапа конвейера — одинаковые.

Инфраструктура RNG в DTensor основана на алгоритме RNG на основе Philox и поддерживает любые серверные части на основе Philox (CUDA и другие устройства, подобные CUDA), но, к сожалению, пока не поддерживает серверную часть CPU.

Отладка

Ведение журналов

При запуске программы можно включить дополнительное ведение журналов с помощью переменной окружения TORCH_LOGS из torch._logging :

  • TORCH_LOGS=+dtensor будет отображать сообщения logging.DEBUG и все уровни выше.
  • TORCH_LOGS=dtensor будет отображать сообщения logging.INFO и выше.
  • TORCH_LOGS=-dtensor будет отображать сообщения logging.WARNING и выше.

Средства отладки

Для отладки программы, применившей DTensor, и более подробного изучения коллективных операций, выполняемых под капотом, DTensor предоставляет CommDebugMode:

class torch.distributed.tensor.debug.CommDebugMode

CommDebugMode — это менеджер контекста, который подсчитывает количество функциональных коллективных операций в своем контексте. Для этого используется TorchDispatchMode.

Примечание

Пока поддерживаются не все коллективные операции.

Пример использования

mod = ...
comm_mode = CommDebugMode()
with comm_mode:
    mod.sum().backward()
print(comm_mode.get_comm_counts())
generate_comm_debug_tracing_table(noise_level=3) [исходный код]

Создает подробную таблицу с информацией об операциях и трассировке коллективных операций на уровне модуля. Объем информации зависит от noise_level

  1. выводит количество коллективных операций на уровне модуля
  2. выводит операции dTensor, не относящиеся к тривиальным операциям, и информацию о модуле
  3. выводит операции, не относящиеся к тривиальным операциям
  4. выводит все операции
generate_json_dump(file_name='comm_mode_log.json', noise_level=3) [исходный код]

Создает JSON-файл для построения визуализации в браузере: 0. выводит количество коллективных операций на уровне модуля; 1. выводит операции dTensor, не относящиеся к тривиальным операциям; 2. выводит операции, не относящиеся к тривиальным операциям; 3. выводит все операции

get_comm_counts() [исходный код]

Возвращает количество операций обмена данными в виде словаря.

Возвращает:

Количество операций обмена данными в виде словаря.

Тип возвращаемого значения:

Dict[Any, int]

get_parameter_info() [исходный код]
Тип возвращаемого значения:

dict[str, dict[str, Any]]

get_sharding_info() [исходный код]
Тип возвращаемого значения:

dict[str, dict[str, Any]]

get_total_counts() [исходный код]
Тип возвращаемого значения:

int

log_comm_debug_tracing_table_to_file(file_name='comm_mode_log.txt', noise_level=3) [исходный код]

Альтернатива выводу CommDebugMode в консоль: записывает данные в указанный пользователем файл

Для визуализации разбиения DTensor размерности менее 3 DTensor предоставляет visualize_sharding():

torch.distributed.tensor.debug.visualize_sharding(dtensor, header='', use_rich=False) [исходный код]

Визуализирует разбиение в терминале для DTensor размерности 1D или 2D.

Примечание

Для этого необходим пакет tabulate либо rich и matplotlib. Для пустых тензоров информация о разбиении не выводится.

Экспериментальные функции

DTensor также предоставляет набор экспериментальных функций. Они либо находятся на стадии прототипирования, либо их базовая функциональность уже реализована, и теперь ожидаются отзывы пользователей. Если у вас есть отзывы об этих функциях, отправьте сообщение об ошибке в PyTorch.

torch.distributed.tensor.experimental.context_parallel(mesh, *, buffers=None, buffer_seq_dims=None, no_restore_buffers=None) [исходный код]

context_parallel — это экспериментальный API для включения параллелизма контекста (CP). Этот API выполняет два действия: 1) заменяет SDPA (torch.nn.functional.scaled_dot_product_attention) на вариант с поддержкой CP; 2) разбивает buffers по измерению последовательности, и каждый ранг сохраняет соответствующий фрагмент согласно mesh.

Параметры:
  • mesh (DeviceMesh) – сетка устройств для параллелизма контекста.
  • buffers (Optional[List[torch.Tensor]]) – буферы, использование которых зависит от измерения последовательности. Например, входной пакет, метки и буферы позиционных эмбеддингов. Для обеспечения точности эти буферы необходимо разбить по измерению последовательности. Разбиение выполняется на месте, форма буфера изменится в контексте. После завершения контекста буферы будут восстановлены. Чтобы указать буферы, которые не нужно восстанавливать, можно использовать no_restore_buffers. Обратите внимание: buffers не должен содержать nn.Parameter.
  • buffer_seq_dims (Optional[List[int]]) – измерения последовательности для buffers.
  • no_restore_buffers (Optional[Set[torch.Tensor]]) – буферы из этого набора не будут восстановлены после выхода из контекста. Этот набор должен быть подмножеством buffers. Если буферы не будут использоваться после выхода из контекста, их можно включить в этот список, чтобы избежать дополнительных затрат времени на восстановление.
Тип возвращаемого значения:

Generator[None, None, None]

Предупреждение

torch.distributed.tensor.experimental.context_parallel — экспериментальная функция-прототип в PyTorch. API может измениться.

torch.distributed.tensor.experimental.local_map(func=None, out_placements=None, in_placements=None, in_grad_placements=None, device_mesh=None, *, redistribute_inputs=False, spmd_types=False) [исходный код]

local_map() — это экспериментальный API, позволяющий передавать DTensor s функции, написанной для применения к torch.Tensor s. Для этого извлекаются локальные компоненты DTensor, вызывается функция, а выходные данные оборачиваются в DTensor согласно out_placements.

Параметры:
  • func (Callable) – функция, применяемая к каждому локальному фрагменту DTensor s.
  • out_placements (Union[PlacementType, Tuple[PlacementType, …]]) – требуемые размещения DTensor s в уплощенном выходном значении func. Если уплощенное output — это одно значение, out_placements должно иметь тип PlacementType. Если же уплощенное output содержит несколько значений, out_placements должно быть кортежем значений PlacementType, соответствующих уплощенному output один к одному. Кроме того, для выходных данных Tensor в качестве их размещения используется PlacementType (значение Tuple[Placement]). Для выходных данных, не являющихся Tensor, PlacementType должно быть None. Обратите внимание: единственное исключение — отсутствие аргумента DTensor. В этом случае, даже если out_placements не является None, функция должна игнорировать требуемые размещения, поскольку она не работает с DTensor s.
  • in_placements (Tuple[PlacementType, …], optional) – требуемые размещения DTensor s в уплощенных входных данных func. Если задано in_placements, local_map() проверит, совпадают ли размещения каждого аргумента DTensor с требуемыми размещениями. Если размещения не совпадают и redistribute_inputs равно False, будет вызвано исключение. Если же redistribute_inputs равно True, аргумент сначала будет перераспределен в соответствии с требуемыми размещениями фрагментов, прежде чем его локальный тензор будет передан в func. Единственное исключение — требуемые размещения не являются None, а аргумент является torch.Tensor. В этом случае проверка размещений пропускается, а аргумент напрямую передается в func. Если in_placements равно None, проверка размещений не выполняется. Значение по умолчанию: None
  • in_grad_placements (Tuple[PlacementType, …], optional) – подсказка о размещении градиента DTensor s, соответствующего уплощенному входному DTensor. Этот аргумент позволяет пользователю передать в to_local() подсказку на случай, если компоновка градиента локального входного тензора не совпадает с компоновкой его входного DTensor. Если параметр не задан, предполагается, что компоновка градиента локального входного тензора совпадает с компоновкой исходного входного DTensor, и она используется при вычислении градиента. Значение по умолчанию: None.
  • device_mesh (DeviceMesh, optional) – сетка устройств, на которой размещаются выходные DTensor s. Если параметр не задан, сетка определяется по сетке устройств первого входного DTensor. Значение по умолчанию: None.
Именованные аргументы:
  • redistribute_inputs (bool, optional) – логическое значение, указывающее, нужно ли повторно разбивать входные DTensor s, если их размещения отличаются от требуемых размещений входных данных. Если это значение равно False и размещение какого-либо входного DTensor отличается, будет вызвано исключение. Значение по умолчанию: False.
  • spmd_types (bool, optional) – если True, включает проверку типов SPMD во время выполнения для func. Локальным тензорам назначаются типы SPMD (V, R, I, P), определяемые по in_placements и in_grad_placements, а func выполняется со строгой проверкой типов. Это помогает выявлять ошибки корректности распределенных вычислений, например, является ли градиент локального тензора с репликацией Partial или Replicate. Значения V, R, I и P, а также их обратные типы описаны в документации по локальным типам SPMD spmd_types: meta-pytorch/spmd_types Для входных размещений Replicate, если размещение градиента не задано, по умолчанию используется Replicate (R), а не Invariant (I). Требуется установленный пакет spmd_types. Значение по умолчанию: False.
Возвращает:

Callable, применяющий func к каждому локальному фрагменту входного DTensor и возвращающий DTensor, созданный из возвращаемого значения func.

Вызывает исключения:
  • AssertionError – Для любых выходных данных, не являющихся DTensor, соответствующее размещение выходных данных в out_placements должно быть None. Если это не так, будет вызвано AssertionError.
  • ValueError – Если redistribute_inputs=False, но входной DTensor требуется перераспределить согласно in_placements.

Пример

>>> def mm_allreduce_forward(device_mesh, W, X):
>>>     partial_sum_tensor = torch.mm(W, X)
>>>     reduced_tensor = funcol.all_reduce(partial_sum_tensor, "sum", device_mesh)
>>>     return reduced_tensor
>>>
>>> W = torch.randn(12, 8, requires_grad=False)
>>> X = torch.randn(8, 16, requires_grad=False)
>>> Y = torch.mm(W, X)
>>> row_wise = [Shard(0)]  # row-wise sharding placements on 1-d mesh
>>> col_wise = [Shard(1)]  # col-wise sharding placements on 1-d mesh
>>>
>>> # local_mm_allreduce_forward is the function wrapped with DTensor/Tensor conversion
>>> local_mm_allreduce_forward = local_map(
>>>     mm_allreduce_forward,
>>>     out_placements=[Replicate()],
>>>     in_placements=[col_wise, row_wise],
>>>     device_mesh=device_mesh,
>>> )
>>>
>>> W_dt = distribute_tensor(
...     W, device_mesh, (col_wise)
... )  # col-wisely sharded W tensor
>>> X_dt = distribute_tensor(
...     X, device_mesh, (row_wise)
... )  # row-wisely sharded X tensor
>>> Y_dt = local_mm_allreduce_forward(
...     device_mesh, W_dt, X_dt
... )  # apply local_mm_allreduce_forward to DTensors

Примечание

В настоящее время этот API является экспериментальным и может измениться.

torch.distributed.tensor.experimental.register_sharding(op) [исходный код]

register_sharding() — это экспериментальный API, позволяющий пользователям регистрировать стратегии разбиения для оператора, если его входные и выходные тензоры являются DTensor. Это может быть полезно в следующих случаях: (1) для op не существует стратегии разбиения по умолчанию, например, если op — пользовательский оператор, не поддерживаемый DTensor; (2) пользователи хотят переопределить стратегии разбиения по умолчанию для существующих операторов.

Параметры:

op (Union[OpOverload, List[OpOverload]]) – оператор или список операторов, для которых регистрируется пользовательская функция разбиения.

Возвращает:

Декоратор функции, который можно использовать для обертывания функции, задающей стратегию разбиения для оператора, указанного в op. Определенная стратегия разбиения будет зарегистрирована в DTensor и переопределит стратегию по умолчанию, если оператор уже реализован в DTensor. Пользовательская функция разбиения принимает те же входные данные, что и исходный оператор (за исключением того, что аргумент типа torch.Tensor будет заменен объектом, подобным тензору, который DTensor использует внутри). Функция должна возвращать последовательность кортежей из двух элементов, каждый из которых задает допустимые размещения выходных данных и соответствующие им размещения входных данных.

Пример

>>> @register_sharding(aten._softmax.default)
>>> def custom_softmax_sharding(x, dim, half_to_float):
>>>     softmax_dim = dim if dim >= 0 else dim + x.ndim
>>>     acceptable_shardings = []
>>>
>>>     all_replicate = ([Replicate()], [Replicate(), None, None])
>>>     acceptable_shardings.append(all_replicate)
>>>
>>>     for sharding_dim in range(x.ndim):
>>>         if sharding_dim != softmax_dim:
>>>             all_sharded = (
>>>                 [Shard(sharding_dim)],
>>>                 [Shard(sharding_dim), None, None],
>>>             )
>>>             acceptable_shardings.append(all_sharded)
>>>
>>>     return acceptable_shardings

Примечание

В настоящее время этот API является экспериментальным и может измениться.

torch.distributed.tensor.experimental.implicit_replication() [исходный код]

Этот менеджер контекста позволяет DTensor неявно считать, что все не-DTensor (torch.Tensor) в программе являются реплицированными DTensor s во время вычисления оператора.

Предупреждение

Это может привести к неправильным результатам, если torch.Tensor s на самом деле не реплицированы; используйте эту возможность на свое усмотрение.

Тип возвращаемого значения:

Iterator[None]

Операции со смешанными Tensor и DTensor

Вы столкнулись со следующим сообщением об ошибке.

got mixed torch.Tensor and DTensor, need to convert all
torch.Tensor to DTensor before calling distributed operators!

Возможны два случая.

Случай 1: ошибка в пользовательском коде

Чаще всего эта ошибка возникает, когда создается обычный Tensor (с помощью фабричной функции), а затем выполняется операция с Tensor и DTensor, например:

tensor = torch.arange(10)
return tensor + dtensor

Операции со смешанными Tensor и DTensor запрещены: если входными данными какой-либо операции (например, torch.add) является DTensor, все входные данные типа Tensor также должны быть DTensor. Это связано с неоднозначностью семантики. Неизвестно, одинаков ли tensor на всех рангах или различается, поэтому мы предлагаем пользователю самостоятельно определить, как создать DTensor с корректными размещениями из tensor.

Если tensor действительно одинаков на каждом ранге, создайте реплицированный DTensor:

tensor = torch.arange(10)
tensor = DTensor.from_local(tensor, placements=(Replicate(),))
return tensor + dtensor

Ниже показано, как создать DTensor с фрагментами. Семантически это означает, что данные Tensor разделены между фрагментами, а операции выполняются над «полными объединенными данными».

tensor = torch.full([], RANK)
tensor = DTensor.from_local(tensor, placements=(Shard(0),))
return tensor + dtensor

Возможно, вы захотите выполнить с тензором и другие действия (это не единственные два варианта!).

Случай 2: ошибка возникла в коде фреймворка PyTorch

Иногда проблема заключается в том, что код фреймворка PyTorch пытается выполнить операции со смешанными Tensor и DTensor. Это ошибки в PyTorch; отправьте сообщение об ошибке, чтобы мы могли их исправить.

Пользователю остается только избегать операции, вызвавшей проблему, и отправить отчет об ошибке.

Для разработчиков PyTorch: один из способов исправить это — переписать код фреймворка PyTorch так, чтобы избежать операций со смешанными Tensor и DTensor (как в предыдущем разделе).

Для разработчиков PyTorch: второй способ — включить неявную репликацию DTensor в нужных местах кода фреймворка PyTorch. В этом случае для всех операций со смешанными Tensor и DTensor будет предполагаться, что не-DTensor можно реплицировать. Будьте осторожны при использовании этой возможности, так как она может привести к незаметным ошибкам.

  • Включение неявной репликации в Python
  • Включение неявной репликации в C++

© 2026, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://docs.pytorch.org/docs/2.14/distributed.tensor.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API