torch.distributed.tensor
Создано: 13 июня 2025 г. | Последнее обновление: 1 июля 2026 г.
Примечание
torch.distributed.tensor в настоящее время находится в альфа-версии и продолжает разрабатываться. Мы обеспечиваем обратную совместимость для большинства API, перечисленных в документации, однако при необходимости API могут измениться.
PyTorch DTensor (распределённый тензор)
PyTorch DTensor предоставляет простые и гибкие примитивы разбиения тензоров на части, которые прозрачно обрабатывают распределённую логику, включая распределённое хранение, вычисления операторов и коллективные коммуникации между устройствами и узлами. DTensor можно использовать для создания различных решений для параллельных вычислений и поддержки представления sharded state_dict при работе с многомерным разбиением на части.
Примеры нативных решений PyTorch для параллельных вычислений, построенных на основе DTensor:
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
-
run_check (bool, необязательный) – выполнить проверку согласованности метаданных каждого локального тензора между рангами, чтобы подтвердить корректность; это потребует дополнительных коммуникаций. Если в
- Возвращает:
-
Объект
DTensor - Вызывает исключения:
-
ValueError – Если
placementsсодержит разные типы редукцииPartial(например, одновременноPartial("sum")иPartial("max")). Для всех размещений Partial должна использоваться одна и та же операция редукции. - Тип возвращаемого значения:
Примечание
При вызове
run_check=Falseпользователь должен самостоятельно убедиться, что переданный локальный тензор корректен для всех рангов (то есть тензор разбит на части для размещенияShard(dim)или реплицирован для размещенияReplicate()). В противном случае поведение созданного DTensor не определено.Примечание
from_localявляется дифференцируемым;requires_gradсозданного объектаDTensorзависит от того, установлен ли дляlocal_tensorфлаг requires_grad.Примечание
При обратном проходе
from_localобеспечивает следующие гарантии размещения градиента. Для каждого измерения сетки размещение градиента определяется следующим образом:Размещение при прямом проходе
Размещение градиента
ShardShardReplicateReplicatePartialReplicateЕсли размещение при прямом проходе —
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. - Тип возвращаемого значения:
Примечание
full_tensorявляется дифференцируемым.
-
redistribute(device_mesh=None, placements=None, *, async_op=False, forward_dtype=None, backward_dtype=None)[исходный код] -
redistributeвыполняет необходимые коллективные операции для перераспределения текущего DTensor: изменяет его текущие размещения на новые или переносит его из текущего DeviceMesh в новый. Например, можно преобразовать DTensor с разбиением на части в реплицированный DTensor, указав размещение Replicate для каждого измерения DeviceMesh.При перераспределении в новые размещения по одному измерению сетки устройств выполняются следующие операции, включающие коллективные коммуникации или локальные действия:
-
Shard(dim)->Replicate():all_gather -
Shard(src_dim)->Shard(dst_dim):all_to_all -
Replicate()->Shard(dim): локальное разбиение на части (то естьtorch.chunk) -
Partial()->Replicate():all_reduce -
Partial()->Shard(dim):reduce_scatter -
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. По умолчанию: репликация по всем измерениям сетки
-
device_mesh (
- Именованные аргументы:
-
- 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 - Тип возвращаемого значения:
Примечание
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и дождаться готовности локального тензора. - Тип возвращаемого значения:
Примечание
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.
- Тип возвращаемого значения:
-
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 содержит частичное значение глобального тензора. Пользователь может перераспределить DTensorPartialв размещение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.
-
tensor (torch.Tensor) – torch.Tensor для распределения. Если требуется разбить тензор по измерению, размер которого не делится нацело на число устройств в соответствующем измерении сетки, для разбиения и рассылки фрагментов используется семантика
- Именованные аргументы:
-
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 должна использоваться одна и та же операция редукции. - Тип возвращаемого значения:
Примечание
При инициализации 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, а также при необходимости преобразует его входы/выходы во время выполнения с помощью трех предоставленных пользователем функций обратного вызова.Поведение трех функций обратного вызова:
-
partition_fnразбивает параметры/буферы модуля до выполнения (то есть преобразует обычные параметрыtorch.Tensorв параметрыDTensor). Все параметры/буферы, не преобразованные функциейpartition_fn, после этого реплицируются междуdevice_mesh. Еслиpartition_fnравенNone, реплицируются все параметры/буферы. -
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()либо с перераспределением в другие размещения.
-
module (
- Возвращает:
-
Модуль, все параметры/буферы которого являются объектами
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
-
requires_grad (bool, необязательно) – следует ли autograd записывать операции над возвращаемым
- Возвращает:
-
Объект
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
-
dtype (
- Возвращает:
-
Объект
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
-
dtype (
- Возвращает:
-
Объект
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) – значение, которым заполняется выходной тензор.
-
size (int...) – последовательность целых чисел, задающая форму выходного
- Именованные аргументы:
-
-
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
-
dtype (
- Возвращает:
-
Объект
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.- Параметры:
- Именованные аргументы:
-
-
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
-
dtype (
- Возвращает:
-
Объект
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, значения которого равномерно распределены отbasestart доbaseend включительно в логарифмическом масштабе с основаниемbase.- Параметры:
- Именованные аргументы:
-
-
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
-
base (float, необязательно) – основание логарифма. По умолчанию:
- Возвращает:
-
Объект
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
-
dtype (
- Возвращает:
-
Объект
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
-
dtype (
- Возвращает:
-
Объект
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
- выводит количество коллективных операций на уровне модуля
- выводит операции dTensor, не относящиеся к тривиальным операциям, и информацию о модуле
- выводит операции, не относящиеся к тривиальным операциям
- выводит все операции
-
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_total_counts()[исходный код] -
- Тип возвращаемого значения:
-
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. Если буферы не будут использоваться после выхода из контекста, их можно включить в этот список, чтобы избежать дополнительных затрат времени на восстановление.
-
mesh (
- Тип возвращаемого значения:
-
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, позволяющий передаватьDTensors функции, написанной для применения кtorch.Tensors. Для этого извлекаются локальные компонентыDTensor, вызывается функция, а выходные данные оборачиваются вDTensorсогласноout_placements.- Параметры:
-
-
func (Callable) – функция, применяемая к каждому локальному фрагменту
DTensors. -
out_placements (Union[
PlacementType, Tuple[PlacementType, …]]) – требуемые размещенияDTensors в уплощенном выходном значенииfunc. Если уплощенноеoutput— это одно значение,out_placementsдолжно иметь типPlacementType. Если же уплощенноеoutputсодержит несколько значений,out_placementsдолжно быть кортежем значенийPlacementType, соответствующих уплощенномуoutputодин к одному. Кроме того, для выходных данныхTensorв качестве их размещения используетсяPlacementType(значениеTuple[Placement]). Для выходных данных, не являющихся Tensor,PlacementTypeдолжно бытьNone. Обратите внимание: единственное исключение — отсутствие аргументаDTensor. В этом случае, даже еслиout_placementsне являетсяNone, функция должна игнорировать требуемые размещения, поскольку она не работает сDTensors. -
in_placements (Tuple[
PlacementType, …], optional) – требуемые размещенияDTensors в уплощенных входных данных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) – подсказка о размещении градиентаDTensors, соответствующего уплощенному входному DTensor. Этот аргумент позволяет пользователю передать вto_local()подсказку на случай, если компоновка градиента локального входного тензора не совпадает с компоновкой его входногоDTensor. Если параметр не задан, предполагается, что компоновка градиента локального входного тензора совпадает с компоновкой исходного входногоDTensor, и она используется при вычислении градиента. Значение по умолчанию: None. -
device_mesh (
DeviceMesh, optional) – сетка устройств, на которой размещаются выходныеDTensors. Если параметр не задан, сетка определяется по сетке устройств первого входногоDTensor. Значение по умолчанию: None.
-
func (Callable) – функция, применяемая к каждому локальному фрагменту
- Именованные аргументы:
-
-
redistribute_inputs (bool, optional) – логическое значение, указывающее, нужно ли повторно разбивать входные
DTensors, если их размещения отличаются от требуемых размещений входных данных. Если это значение равно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, а также их обратные типы описаны в документации по локальным типам SPMDspmd_types: meta-pytorch/spmd_types Для входных размещений Replicate, если размещение градиента не задано, по умолчанию используется Replicate (R), а не Invariant (I). Требуется установленный пакетspmd_types. Значение по умолчанию: False.
-
redistribute_inputs (bool, optional) – логическое значение, указывающее, нужно ли повторно разбивать входные
- Возвращает:
-
Callable, применяющийfuncк каждому локальному фрагменту входногоDTensorи возвращающийDTensor, созданный из возвращаемого значенияfunc. - Вызывает исключения:
-
-
AssertionError – Для любых выходных данных, не являющихся DTensor, соответствующее размещение выходных данных в
out_placementsдолжно быть None. Если это не так, будет вызвано AssertionError. -
ValueError – Если
redistribute_inputs=False, но входнойDTensorтребуется перераспределить согласноin_placements.
-
AssertionError – Для любых выходных данных, не являющихся DTensor, соответствующее размещение выходных данных в
Пример
>>> 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) в программе являются реплицированнымиDTensors во время вычисления оператора.Предупреждение
Это может привести к неправильным результатам, если
torch.Tensors на самом деле не реплицированы; используйте эту возможность на свое усмотрение.- Тип возвращаемого значения:
-
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 можно реплицировать. Будьте осторожны при использовании этой возможности, так как она может привести к незаметным ошибкам.
© 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