快捷键

torch.distributed.tensor._api 的源代码

# mypy: 允许未类型化装饰器
# mypy: 允许未类型化定义
© Meta Platforms, Inc. 及其关联公司
导入 检查
导入 警告
来自 collections.abc 导入 序列
来自 打字 导入 任意, 可调用, 角色, 可选
来自 typing_extensions 导入 已弃用

导入 火炬
导入 torch.distributed.tensor._dispatch 作为 op_dispatch
导入 torch.distributed.tensor._random 作为 随机
导入 torch.nn 作为 然后
来自 torch.distributed.device_mesh 导入 _网状资源, 设备网格
来自 torch.distributed.tensor._collective_utils 导入 检查张量元数据, 网格广播
来自 torch.distributed.tensor._dtensor_spec 导入 DTensorSpec, 张量元
来自 torch.distributed.tensor._redistribute 导入 (
    重新分配,
    重新分配本地张量,
)
来自 torch.distributed.tensor._utils 导入 (
    计算全局张量信息,
    计算局部形状和全局偏移,
    标准化到 torch 大小,
)
来自 torch.distributed.tensor.placement_types 导入 (
    部分支持,
    放置,
    复制,
    片段,
)


__all__ = [
    DTensor,
    "分布式张量",
    "分布式模块",
    "个",
    "空的",
    全部,
    随机,
    "randn",
    ,
]

aten = 火炬.操作.aten


# [PyTorch 张量之间的自动微分交互]
#
# 下面定义的自动微分函数正在被公共 API 使用
# (例如,from_local,to_local)以确保 DTensor 与 torch.Tensor
# 在自动微分引擎中协同工作。这
# 允许 DTensor 只存在于模块层次结构的一部分。
#
# 例如,我们有一个由子模块组成的模块
# A、B 和 C,执行流程如下:
#  输入(torch.Tensor) -> 模块 A -> 模块 B -> 模块 C -> 输出(torch.Tensor)
#
# 仅希望将模块 B 做成分片模块
# DTensor 参数,以下的前向/反向应该可以工作:
#
#  输入(torch.Tensor) -> 模块 A
#       -> DTensor 输入(from_local)-> 分片模块 B -> DTensor 输出
#           -> torch.Tensor 输出 (to_local) -> 模块 C
#
# 所以 from_local/to_local 必须是 Autograd 函数。
#
 _ToTorchTensor(火炬.自动微分.函数):
    @staticmethod
    def 前向(  # 类型:忽略[覆盖]
        ctx,
        输入: DTensor,
        grad_placements: 可选[序列[放置]],
    ):
        ctx.dtensor 规范 = 输入._spec
        ctx.梯度放置 = 梯度放置
        本地张量 = 输入._local_tensor

        需要在此处返回一个新的 Tensor 对象,作为自动微分元数据
        # 将被放入其中。所以我们不想污染 Tensor
        # 对象存储在此 DTensor 的_local_tensor 中。
        返回 本地张量.以查看方式(本地张量)

    @staticmethod
    def 反向(ctx, grad_output: 火炬.张量):  # 类型:忽略[覆盖]
        dtensor_spec = ctx.dtensor_spec
        网格 = dtensor 规范.网格
        梯度放置 = ctx.梯度放置
        dtensor 元数据 = dtensor 规范.张量元数据

        _, 张量步长 = 计算全局张量信息(
            grad_output, 网格, dtensor 规范.布局
        )
        张量步长 = 元组(张量步长)
        梯度放置 = 梯度放置  dtensor 规范.布局
        梯度规范 = DTensorSpec(
            网格,
            梯度放置,
            张量元=张量元(
                shape=dtensor 元数据.shape,
                步长=张量步长,
                数据类型=dtensor 元数据.数据类型,
            ),
        )

        返回 (
            DTensor(
                grad_output,
                毕业规范,
                需要梯度=grad_output.需要梯度,
            ),
            ,
        )


 _FromTorchTensor(火炬.自动微分.函数):
    @staticmethod
    def 前向(  # 类型:忽略[覆盖]
        ctx,  # pyre 忽略[2]: 参数必须进行注解。
        输入: 火炬.张量,
        装置网状结构: 设备网状结构,
        安排: 元组[放置, ...]
        运行检查: 布尔,
        shape: 可选[火炬.尺寸] = ,
        步长: 可选[元组[int, ...]] = ,
    ) -> DTensor:
        ctx.上次放置 = 布局
        ctx.上次设备网格 = 设备网状

        如果 形状  步长:
            张量形状, 张量步长 = shape, 步长
        elif not 形状  not 步长:
            # 如果不是默认的 run_check,我们假设用户确定每个
            # 级别具有相同的张量形状,我们只需使用那个来计算
            全局形状
            全局形状, global_stride = 计算全局张量信息(
                输入, 装置网状结构, 布局
            )
            张量形状, 张量步长 = 火炬.尺寸(全局形状), 元组(global_stride)
        否则:
            提升 运行时错误(
                f"找到形状:"{shape}, 步长:{步长}.",
                "请同时传递形状和步长。",
            )

        如果 装置网状结构.获取坐标()  :
            如果全局排名不参与设备网格,则
            简单地将局部张量设置为空张量
            输入 = 输入.新空(0, 需要梯度=输入.需要梯度)
        elif 运行检查:
            # TODO: 支持全局形状/步长未传递时的不均匀分片
            # 在检查 tensor_meta 期间构建全局 TensorMeta
            check_shape_stride = not 形状  not 步长
            检查张量元数据(输入, 检查形状步长=检查形状步长)
            # TODO: 查看是否需要运行此 run_check 逻辑
            相应的逆向
             索引, 位置  列举(安排):
                如果 布置.复制():
                    # 将广播排名为 0 的 tensor 广播到所有 rank
                    # 只有当 run_check 为 True 时才进行广播
                    输入 = 输入.连续()
                    网格广播(输入, 装置网状结构, 网格维度=索引)

        分布规范 = DTensorSpec(
            装置网状结构,
            安排,
            张量元=张量元(
                张量形状,
                张量步长,
                输入.数据类型,
            ),
        )

        # 我们想要一个与输入张量共享内存的新张量对象
        dist_tensor = DTensor(
            输入.以查看方式(输入),
            dist_spec,
            # dist tensor 的 requires_grad 依赖于输入是否
            # requires_grad 或不
            需要梯度=输入.需要梯度,
        )
        返回 dist_tensor

    @staticmethod
    def 反向(ctx, grad_output: DTensor):  # 类型:忽略[覆盖]
        上次放置 = ctx.上次放置
        上次设备网格 = ctx.上次设备网格

        # 在创建分布式张量时重新分配到放置位置
        # 以确保梯度布局匹配,我们可以直接返回
        # 本地梯度
        如果 grad_output.布局 != 前置放置:
            当前规范 = grad_output._spec
            目标规范 = DTensorSpec(
                前置设备网格,
                前置放置,
                张量元=grad_output.规范.张量元,
            )
            本地张量 = grad_output._local_tensor
            输出 = 重新分配本地张量(
                本地张量, 当前规范, 目标规范, 是否反向=真实
            )
            # TODO: 直接返回重新分配的本地张量,无需
            # 可微反向。检查这适用于所有情况是否合理。
            返回 输出, , , , , 

        # TODO: 现在反向也是可微分的了,添加测试
        # 测试更高层次的梯度。
        返回 grad_output.本地化(), , , , , 


 DTensor(火炬.张量):
    ""
``DTensor``(分布式张量)是 ``torch.Tensor`` 的子类,它提供了类似单设备的功能
抽象化以多设备 `torch.Tensor` 编程。它描述了分布式张量分片
布局(DTensor 布局)通过 :class:`DeviceMesh` 和以下类型的 :class:`Placement`:

* :class:`Shard`: 在 ``DeviceMesh`` 维度的设备上,沿张量维度 ``dim`` 分片的张量
* :class:`Replicate`: 在 ``DeviceMesh`` 维度的设备上复制的 Tensor
* :class:`Partial`: 张量在 ``DeviceMesh`` 维度的设备上正在等待缩减

当调用 PyTorch 运算符时,``DTensor`` 会覆盖 PyTorch 运算符以执行分片计算并在必要时进行通信。
与运算符计算一起,``DTensor`` 将正确地转换或传播放置(DTensor 布局),并根据运算符本身的语义生成新的 ``DTensor`` 输出。
当调用 PyTorch 运算符时,``DTensor`` 会覆盖 PyTorch 运算符以执行分片计算并在必要时进行通信。与运算符计算一起,``DTensor`` 将正确地转换或传播放置(DTensor 布局),并根据运算符本身的语义生成新的 ``DTensor`` 输出。

确保在调用 PyTorch 操作符时 ``DTensor`` 分片计算的数值正确性,``DTensor``
需要操作符的每个 Tensor 参数都是 DTensor。

.. note:: 在此处直接使用 Tensor 子类构造函数不是推荐创建 ``DTensor``
的方法(即它无法正确处理 autograd,因此不是公共 API)。请参阅 `create_dtensor`_
查看如何创建一个 ``DTensor`` 的部分。
"源代码"

    _本地张量: 火炬.张量
    规范: DTensorSpec
    __slots__ = ["_局部张量", "_spec"]

    # _op_dispatcher 实例作为类属性以处理运行时调度逻辑
    _op_dispatcher: op 分发.Op 分发器 = op 分发.沉浸式翻译器()

    @staticmethod
    @torch.禁用 dynamo
    def __new__(
        ,
        本地张量: 火炬.张量,
        规格: DTensorSpec,
        *,
        需要梯度: 布尔,
    ) -> DTensor:
        ""
从本地张量、设备网格和放置以及其他张量属性(例如形状、requires_grad、strides 等)构造一个 DTensor。
注意:这不是一个公开 API,它仅应被操作实现和内部使用。如果您想构造一个

.. 注意 :: 这不是一个公开 API,它仅应被操作实现和内部使用。如果您想构造一个
注意:这不是一个公开 API,它仅应被操作实现和内部使用。如果您想构造一个
从本地张量创建 DTensor,请考虑使用`DTensor.from_local`。
您想从一个“全局”张量(其中)构造一个 DTensor
已经初始化了张量,并想要对这个张量进行分片)
考虑使用 `distribute_tensor`。
"源代码"
        如果 本地张量.requires_grad  not 需要梯度:
            warnings.警告(
                "从 torch.Tensor 构建 DTensor 时,建议使用"
                "local_tensor.detach()并确保 requires_grad 一致性。"
            )

        # 新方法指导从 local_tensor 创建包装张量并添加
        # 放置规范,它不会进行实际分布
        断言 规格.张量元数据  not , "TensorMeta 不能为空!"
        r = 火炬.张量._make_wrapper_subclass(  # 类型: 忽略[attr-defined]
            ,
            规格.张量元.shape,
            strides=规格.张量元.步长,
            数据类型=本地张量.数据类型,
            设备=本地张量.设备,
            布局=本地张量.布局,
            需要梯度=需要梯度,
        )

        r._spec = 规范
        r._local_tensor = 本地张量
        返回 r

    # pyre-fixme[14]: `__repr__` 方法在 `DTensor` 中不一致地覆盖。
    # pyre-fixme[3]: 返回类型必须进行注解。
    def __repr__():  # 类型:忽略[覆盖]
        考虑对所有本地张量进行_all_gather 以更好地进行调试
        返回 f"DTensor(本地张量={._本地张量},设备网格={.规范.网格}, placements={.规范.安排})"

    def __张量展平__():
        ""
DTensor 转换为本地张量的协议
用于 PT2 追踪的协议
"源代码"
        返回 ["_局部张量"] (.规范, .需要梯度)

    @staticmethod
    def __张量展开__(内部张量, 展平规范, 外部尺寸, 外部步长):
        断言 展平规范  not , (
            "期望从 `__tensor_flatten__` 返回值中获取非 None 的 spec!"
        )
        本地张量 = 内部张量["_局部张量"]
        规格, requires_grad = 展平规范
        展平张量元数据 = 张量元(
            shape=外部尺寸,
            步长=外部步长,
            数据类型=规格.张量元.数据类型,
        )
        展开_spec = DTensorSpec(
            规格.网格,
            规格.安排,
            张量元=展平张量元数据,
        )
        返回 DTensor(
            本地张量,
            展平规范,
            需要梯度=需要梯度,
        )

    def 强制转换切线元数据():
        如果 not 任何(isinstance(p, 部分支持)  p  .安排):
            返回 self
        布局 = [
            复制() 如果 isinstance(p, 部分支持) 否则 p  p  .布局
        ]
        返回 .重新分配(装置网状结构=.装置网状结构, 安排=安排)

    def __coerce_same_metadata_as_tangent__(, 展平规范, 预期类型=):
        如果 预期类型  not :
            返回 

        (规格, _) = 展平规范  tensor_flatten()的结果
        返回 .重新分配(
            装置网状结构=.装置网状结构,
            安排=规格.安排,
        )

    @classmethod
    @torch.禁用 dynamo
    # pyre-fixme[3]: 返回类型必须进行注解。
    # pyre-fixme[2]: 参数必须进行注解。
    def __torch_dispatch__(, 函数, 类型, 参数=(), kwargs=):
        返回 DTensor._op_dispatcher.调度(
            函数,
            参数,
            kwargs  {},
        )

[文档] @staticmethod def 从本地( 本地张量: 火炬.张量, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , *, 运行检查: 布尔类型 = 错误, shape: 可选[火炬.尺寸] = , 步长: 可选[元组[int, ...]] = , ) -> DTensor: "" 从每个 rank 的本地 torch.Tensor 创建一个:class:`DTensor`。 根据指定的`device_mesh`和`placements`进行。 参数: local_tensor (torch.Tensor):每个 rank 的本地 torch.Tensor。 device_mesh (:class:`DeviceMesh`, optional): 可选的 DeviceMesh,用于放置 张量,如果未指定,必须在设备网格下调用 上下文管理器,默认:None 放置(List[:class:`Placement`],可选):放置列表 描述了如何在 DeviceMesh 上放置本地 torch.Tensor,必须 具有与 `device_mesh.ndim` 相同的元素数量。 关键字参数: run_check(布尔值,可选):以额外的通信成本,在各个 rank 之间执行 精确检查,以检查每个本地张量的元信息 确保正确性。如果`placements`中有`:class:`Replicate`,则 设备网格维度的第一排数据将被广播到其他排。默认:False 形状(torch.Size,可选):一个指定大小的 int 列表 形状(torch.Size,可选):一个指定大小的 int 列表 基于 `local_tensor` 构建的 DTensor。请注意,如果 ``local_tensor`` 的形状在不同排名之间不同,则需要提供。 如果不提供,``shape`` 将根据给定的分布式张量均匀分片到各个排名来计算。默认:None 如果不提供,``shape`` 将根据给定的分布式张量均匀分片到各个排名来计算。默认:None 张量在各个 rank 上均匀分配。默认:无 步长(tuple,可选):一个指定 DTensor 步长的 int 列表。 如果不提供,将假设给定的分布式 张量在各个 rank 上均匀分配。默认:无 返回: 一个 `DTensor` 对象 .. 注意:: 当 ``run_check=False`` 时,确保用户传入的本地张量在各个 rank 之间正确(即张量在 ``Shard(dim)`` 放置或 ``Replicate()`` 放置时已分片)。否则,创建的 DTensor 的行为是未定义的。 如果不是,则创建的 DTensor 的行为是未定义的。 如果不是,则创建的 DTensor 的行为是未定义的。 如果不是,则创建的 DTensor 的行为是未定义的。 .. 注意:: ``from_local`` 是可微分的,创建的 `requires_grad` 对象将取决于 `local_tensor` 是否需要梯度。 `DTensor` 对象的 `requires_grad` 将取决于 `local_tensor` 是否需要梯度。 "源代码" # 如果形状/数据类型相同,则无需运行_check,如果不同,则必须进行 allgather。 # 检查跨 rank 的元数据以检查大小/数据类型。 除非有复制,否则不应有数据通信 其中我们广播来自第一个排名的复制策略 在网格维度中 设备网状 = 设备网状 _网状资源.获取当前网状() 设备类型 = 装置网状结构.设备类型 根据设备网格的 device_type 将本地张量转换为所需的设备 如果 设备类型 != 本地张量.设备.类型 not 本地张量.是否是元数据: 本地张量 = 本地张量.(设备类型) 如果没有指定,则将默认放置设置为复制 如果 布局 : 布局 = [复制() _ 范围(装置网状结构.ndim] 否则: 布局 = 列表(安排) 索引, 位置 列举(安排): 将碎片维度标准化为正值 如果 布置.is_shard(): 位置 = 角色(片段, 布置) 如果 布置.维度 < 0: 安排[索引] = 片段(布置.维度 + 本地张量.ndim) `from_local` 可微,该函数创建的 dist 张量的梯度应该反向传播到 local_tensor,因此我们调用一个自动微分函数来构建 dist 张量。 应该将梯度反向传播到 local_tensor,因此我们调用一个自动微分函数来构建 dist 张量。 应该将梯度反向传播到 local_tensor,因此我们调用一个自动微分函数来构建 dist 张量。 返回 _FromTorchTensor.应用( # pyre-ignore[16]: 自动微分函数 本地张量, 装置网状结构, 元组(安排), 运行检查, shape, 步长, )
[文档] def to_local( self, *, grad_placements: Optional[Sequence[放置]] = None ) -> torch.Tensor: """ 获取此 DTensor 在其当前秩上的本地张量。对于分片,它返回 一个逻辑张量视图的本地分片,在复制时返回副本 其当前排名。 关键词参数: grad_placements (List[:class:`Placement`], 可选): 描述了 该函数返回的 Tensor 的任何梯度布局的未来布局。 `to_local` 将 DTensor 转换为本地张量,并返回本地张量。 `to_local` 将 DTensor 转换为本地张量,并返回本地张量。 可能不会在代码后续中用作原始 DTensor 布局。这个参数是用户提供给 autograd 的提示,如果返回的张量布局与原始 DTensor 布局不匹配。 如果未指定,我们将假设梯度布局保持不变。 如果返回的张量布局与原始 DTensor 布局不匹配,用户可以提供这个参数作为给 autograd 的提示。 如果未指定,我们将假设梯度布局保持与原始相同。 作为原始 DTensor 使用,并以此进行梯度计算。 返回: 一个 :class:`torch.Tensor` 或 ``AsyncCollectiveTensor`` 对象。它代表当前 rank 上的本地张量。当返回 ``AsyncCollectiveTensor`` 对象时, 本地张量。当返回 ``AsyncCollectiveTensor`` 对象时, 这意味着本地张量尚未准备好(即通信尚未完成)。在这种情况下,用户需要调用 `wait` 来等待本地张量准备好。 在此情况下,用户需要调用 `wait` 来等待本地张量准备好。 .. 注意:: `to_local` 是可微分的,返回的本地张量的 `requires_grad` 将取决于 `DTensor` 是否需要梯度。 注意:`to_local` 是可微分的,返回的本地张量的 `requires_grad` 将取决于 `DTensor` 是否需要梯度。 """ 如果没有启用 torch.is_grad_enabled() 返回 self._local_tensor 如果 grad_placements 不是 None 且不是 tuple 类型 grad_placements = tuple(grad_placements) return _ToTorchTensor.apply( self, grad_placements ) # pyre-ignore[16]: autograd func
[文档] def 重新分配( , 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , *, async_op: 布尔类型 = 错误, ) -> DTensor: "" ``redistribute`` 执行必要的集体操作,重新分配当前 DTensor 从其当前放置位置重新分配到新的放置位置,或者从其当前 DeviceMesh 重新分配到新的 DeviceMesh。例如,我们可以通过指定 DeviceMesh 每个维度的 Replicate 放置 来将分片 DTensor 转换为复制的 DTensor。 当从当前位置重新分配到同一设备网格维度的新位置时,我们 将执行以下操作,包括通信集体或本地操作: 碎片(维度)-> 复制():all_gather 2. ``Shard(src_dim)`` -> ``Shard(dst_dim)``: 全全映射 3. ``Replicate()`` -> ``Shard(dim)``: 本地分块(即 ``torch.chunk``) 4. ``Partial()`` -> ``Replicate()``: ``all_reduce`` 5. ``Partial()`` -> ``Shard(dim)``: ``reduce_scatter`` ``redistribute`` 将正确确定 DTensors 所需的重新分配步骤 在 1-D 或 N-D DeviceMesh 上创建的。 参数: device_mesh (:class:`DeviceMesh`, optional): 可选的 DeviceMesh,用于放置 DTensor。如果未指定,将使用当前 DTensor 的 DeviceMesh。 默认: None placements (List[:class:`Placement`], optional): 新的放置列表(可选) 描述了如何将 DTensor 放置到 DeviceMesh 中,必须 具有与 `device_mesh.ndim` 相同的元素数量。 默认:在所有网格维度上复制 关键字参数: async_op (bool, 可选): 是否执行 DTensor 重新分配操作 异步执行或否。默认:False 返回: 一个 `DTensor` 对象 .. note:: ``redistribute`` 可微分,这意味着用户无需担心 逆向分配操作的公式。 .. note:: ``redistribute`` 目前仅支持在同一 DeviceMesh 上重新分配 DTensor 如需将 DTensor 重新分发到不同的 DeviceMesh,请提交一个 issue。 "源代码" # 注意:此重分发 API 目前仅支持输出 地点重新分配的数量,即它总是创建一个新的 DTensor 对象,并保留原始对象不变。 如果未指定 device_mesh,则使用当前 device_mesh 设备网状 = 设备网状 .设备网状 如果未指定新放置,则引发错误 如果 布局 : 提升 运行时错误("需要放置来重新分配!") 布局 = 列表(安排) i, 位置 列举(安排): 如果 布置.是部分(): 提升 运行时错误( "不能重新分配到部分,重新分配到部分仅限内部使用!" ) elif isinstance(布置, 片段) 布置.维度 < 0: 将碎片维度标准化为正值 安排[i] = 片段(布置.维度 + .ndim) 布局 = 元组(安排) # pyre-fixme[16]: `Redistribute` has no attribute `apply`. 返回 重新分配.应用(, 装置网状结构, 安排, async_op)
[文档] def 全张量( self, *, grad_placements: Optional[Sequence[Placement]] = None ) -> torch.Tensor: """ 返回此 DTensor 的完整张量。它将执行必要的集体操作 收集其 DeviceMesh 中其他 rank 的本地张量并连接 他们放在一起。这是以下代码的语法糖: dtensor.redistribute(placements=[Replicate()] * mesh.ndim).to_local() 翻译为:dtensor.redistribute(放置=[Replicate()] * mesh.ndim).to_local() 关键词参数: grad_placements (List[:class:`Placement`], optional): 放置列表(可选):放置描述 该函数返回的完整张量任何梯度布局的未来布局 函数。 `full_tensor` 将 DTensor 转换为完整的 torch.Tensor,并返回 torch.tensor 可能不会用作代码中后续复制的 DTensor 布局。这个参数是用户提供给 autograd 的提示,如果返回的张量布局与原始复制的 DTensor 布局不匹配。 如果未指定,我们将假设整个张量的梯度布局为复制。 如果返回的张量布局与原始复制的 DTensor 布局不匹配,用户可以给出这个提示给 autograd。 如果未指定,我们将假设整个张量的梯度布局为复制。 返回值: 一个表示此 DTensor 完整张量的 :class:`torch.Tensor` 对象。 .. 注意:: ``full_tensor`` 是可微分的。 """ redist_res = self.redistribute( placements=[Replicate()] * self.device_mesh.ndim, async_op=False ) return _ToTorchTensor.apply(redist_res, grad_placements)
@property def 装置网状结构
() -> 设备网状结构: "" 与此 DTensor 对象关联的 :class:`DeviceMesh` 属性。 注意:``device_mesh`` 是只读属性,不能设置。 "源代码" 返回 .规范.网格 @property def 安排() -> 元组[放置, ...] "" 此 DTensor 的 placements 属性,用于描述此布局。 DTensor 在其 DeviceMesh 上的布局。 .. 注意:: ``placements`` 是只读属性,不能设置。 "源代码" 返回 .规范.布局 def 创建写入条目(, 完全限定名: 字符串, 对象: 任意): 来自 torch.distributed.checkpoint.planner_helpers 导入 ( 为 dtensor 创建写入条目, ) 如果 有属性(._本地张量, "__创建写入条目__"): 返回 ._本地张量.创建写入条目(完全限定名, 对象) # 类型: 忽略[attr-defined] elif isinstance(._本地张量, 火炬.张量): 返回 [为 dtensor 创建写入条目(完全限定名, 对象] 否则: 提升 运行时错误("不支持的张量类型!")
[文档] def __create_chunk_list__(self): """ 返回一个包含 ChunkStorageMetadata 的列表,该数据类描述了本地分片/副本的大小/偏移量 当前排名。对于 DTensor,每个排名将只有一个本地分片/副本,因此返回的列表通常只有一个元素。 返回一个元素。 该魔术方法主要用于分布式检查点目的。 返回: 表示当前 rank 上的分片大小/偏移量的`ChunkStorageMetadata`对象列表。 """ 从`torch.distributed.checkpoint.planner_helpers`导入( _create_chunk_from_dtensor, ) 如果 hasattr(self._local_tensor, "__create_chunk_list__"): 返回 self._local_tensor.__create_chunk_list__() # 忽略未定义的属性 elif isinstance(self._local_tensor, torch.Tensor): 返回[_从_dtensor 创建数据块](self) else: raise RuntimeError("不支持的张量类型!")
def 获取_tensor_shard__
(, 索引): 如果 有属性(._本地张量, 获取张量分片): 返回 ._本地张量.获取_tensor_shard__(索引) # 类型: 忽略[attr-defined] elif isinstance(._本地张量, 火炬.张量): 返回 .本地化() 否则: 提升 运行时错误("不支持的张量类型!") def 分配张量( 张量: 火炬.张量, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[安置]] = , *, src_data_rank: 可选[int] = 0, ) -> DTensor: "" 将一个叶子 `torch.Tensor`(即 nn.Parameter/buffers)分配到 `device_mesh`,按照指定的 `placements` 进行。`device_mesh` 和 `placements` 的秩必须相同。要分配的 `tensor` 是逻辑上的或“全局”张量,API 将会使用 到 `placements` 指定的地方。`device_mesh` 和 `placements` 的秩必须相同。要分配的 `tensor` 是逻辑上的或“全局”张量,API 将会使用 到 `placements` 指定的地方。`device_mesh` 和 `placements` 的秩必须相同。要分配的 `tensor` 是逻辑上的或“全局”张量,API 将会使用 设备网格维度的第一秩“tensor”作为真实来源以保留 如果您想在自动微分计算过程中构建 DTensor,请使用:meth:`DTensor.from_local` 张量(torch.Tensor):要分发的 torch.Tensor。注意,如果您 Args: tensor (torch.Tensor):torch.Tensor 要分发。注意,如果您 想要在不是网格维度中设备数量整除的维度上分割张量 我们使用 `torch.chunk` 来对张量进行语义分割并分散碎片 不均匀分割的行为是实验性的,可能会更改 语义到碎片化张量并分散碎片。不均匀分割的行为是实验性的,可能会更改 设备网格(:class:`DeviceMesh`,可选):用于分配设备的 DeviceMesh 张量,如果未指定,必须在 DeviceMesh 上下文中调用 管理器,默认:None 放置(List[:class:`Placement`],可选):放置列表 描述如何在 DeviceMesh 上放置张量,必须与`device_mesh.ndim`的元素数量相同。 如果未指定,则默认情况下将张量复制到`device_mesh`的每个维度的第一个秩。 默认情况下,将张量复制到`device_mesh`的每个维度的第一个秩。 从`device_mesh`的第一个秩开始复制张量到每个维度的第一个秩。 关键字参数: src_data_rank (int, optional): 源数据在逻辑/全局张量中的排名,它被用于 :meth:`distribute_tensor` 方法来将碎片/副本分散/广播到其他排名。 使用 :meth:`distribute_tensor` 方法将碎片/副本分散/广播到其他排名。 默认情况下,我们在每个 DeviceMesh 维度上使用 ``group_rank=0`` 作为源数据,以保持 单设备语义。如果显式传递 `None`,:meth:`distribute_tensor` 简单使用 使用本地数据而不是尝试通过散列/广播来保留单设备语义。 默认:0 返回: 一个 :class:`DTensor` 或 ``XLAShardedTensor`` 对象。 .. 注意:: 当使用 ``xla`` 设备类型初始化 DeviceMesh 时, 返回 `XLAShardedTensor` 而不是。参见 `此问题 `__ 以获取更多详细信息。XLA 集成是实验性的,可能会发生变化。 "源代码" 火炬._C._log_api_usage_once(torch.dtensor.distribute_tensor) # 获取默认设备网格,如果没有指定 设备网状 = 设备网状 _网状资源.获取当前网状() 设备类型 = 装置网状结构.设备类型 如果 设备类型 == "xla": try: # 调用 PyTorch/XLA SPMD 对 `xla` 后端类型设备网格。 # 这将返回 XLAShardedTensor 来自 torch_xla.distributed.spmd 导入 ( # type:ignore[导入] xla_distribute_tensor, ) 返回 xla_distribute_tensor(张量, 装置网状结构, 安排) # type:ignore[return-value] 除了 导入错误 作为 e: msg = 使用 DTensor API 与 xla 一起使用时,您必须安装 torch_xla 包! 提升 导入错误(信息) 来自 e 如果 not 张量.是否为叶子节点: 提升 运行时错误( "应使用 `distribute_tensor` 来分发叶子张量!但发现非叶子张量!" ) 如果张量不在该设备类型,则将其转换为相应的设备类型 如果 设备类型 != 张量.设备.类型 not 张量.是否是元数据: 张量 = 张量.(设备类型) 如果没有指定,则将默认放置设置为复制 如果 布局 : 布局 = [复制() _ 范围(装置网状结构.ndim] 如果 长度(安排) != 装置网状结构.ndim: 提升 ValueError( f"placements 的长度必须与 device_mesh.ndim 相同!" f"找到放置长度:"{长度(安排)},以及 device_mesh.ndim:{装置网状结构.ndim} ) 如果 isinstance(张量, DTensor): # 如果张量已经是 DTensor,我们需要检查: # 1. 如果两个设备网格属于同一父网格且可以进行进一步分片 # 则可以进一步分片。 # 2. 检查设备网格和放置是否相同 如果 张量.设备网状 != 装置网状结构: 提升 ValueError( f无法分配具有设备网格的 DTensor{张量.装置网状结构} " f"传输到不同的设备网格"{装置网状结构} ) 如果 张量.布局 != 元组(安排): 提升 ValueError( f"无法将具有放置的 DTensor 分配到"{张量.安排} " f"不同的放置"{安排}.您想调用吗? f"改为`redistribute`如何?" ) 返回 张量 本地张量 = 张量.detach() # TODO(xilun): 解决分片顺序问题 # 按照放置位置分配张量。 布局 = 列表(安排) 索引, 位置 列举(安排): 如果 布置.is_shard(): 位置 = 角色(片段, 布置) 如果 布置.维度 < 0: 标准化碎片放置维度 位置 = 片段(布置.维度 + 张量.ndim) 安排[索引] = 位置 本地张量 = 布置._shard_tensor( 本地张量, 装置网状结构, 索引, src_data_rank 源数据排名 ) elif 布置.复制(): 位置 = 角色(复制, 布置) 本地张量 = 布置._replicate_tensor( 本地张量, 装置网状结构, 索引, src_data_rank 源数据排名 ) 否则: 提升 运行时错误( f尝试分配具有不支持放置的张量{布置}在设备网格维度上{索引} ) 布局 = 元组(安排) 断言 本地张量 not , 分配张量时不应为空 # 从 DTensor 构造后断开传递给 DTensor 的本地张量 # 在 DTensor 上执行自动微分,而不是在本地张量上 规范 = DTensorSpec( 网格=装置网状结构, 安排=安排, 张量元=张量元( shape=张量.尺寸(), 步长=张量.步长(), 数据类型=张量.数据类型, ), ) 返回 DTensor( 本地张量.需要梯度_(张量.需要梯度), 规格, 需要梯度=张量.需要梯度, ) @deprecated(请使用 `distribute_tensor` 并将 `src_data_rank` 设置为 `None`) def _shard_tensor( full_tensor: 火炬.张量, 安排: 序列[片段] 装置网状结构: 可选[设备网状结构] = , ) -> DTensor: "" 根据指示的分区排列在本地对整个张量进行分区 返回包含本地分片的 DTensor。 ..警告:这是一个可能变更的私有 API。它跳过了 通信由 `distribute_tensor` 所需的其他通信。它仅 适用于所有等级都具有相同的 `full_tensor` 的情况。例如, 在分布式推理中,所有等级都从同一个 检查点加载。此 API 不会检查等级之间的数据相等性,因此 用户有责任确保 `full_tensor` 是相同的 分布。 参数: full_tensor (torch.Tensor): 要分片的完整张量。 placements (Sequence[:class:`Shard`]): 描述如何在 DeviceMesh 上放置局部张量的放置方式。 描述如何在 DeviceMesh 上放置局部张量。 device_mesh (:class:`DeviceMesh`, optional): 可选的 DeviceMesh,用于放置 DTensor。必须与放置数量具有相同的维度。 如果未指定,将从中当前上下文检索。 返回: 以分片作为其局部张量的 :class:`DTensor` 对象。 示例: >>> # xdoctest: +SKIP("需要 world_size 和 rank") >>> device_mesh = dist.init_device_mesh("cuda", (world_size,)) >>> full_tensor = torch.arange(world_size, device=f"cuda:{rank}") >>> dtensor = _shard_tensor(full_tensor, [Shard(1)], device_mesh) "源代码" 返回 分配张量(full_tensor, 装置网状结构, 安排, src_data_rank=) def 分布式模块( 模块: nn.模块, 装置网状结构: 可选[设备网状结构] = , 分区函数: 可选[可调用[[字符串, nn.模块, 设备网状结构] ]] = , input_fn: 可选[可调用[[nn.模块, 任意, 设备网状结构] ]] = , 输出函数: 可选[可调用[[nn.模块, 任意, 设备网状结构] ]] = , ) -> nn.模块: "" 此函数公开三个函数来控制模块的参数/输入/输出: 在运行时执行模块之前通过指定进行分片 ``partition_fn``(即允许用户将模块参数转换为:class:`DTensor`) 参数根据指定的 `partition_fn` 进行划分)。 2. 在运行时执行过程中通过指定 `input_fn` 和 `output_fn` 来控制模块的输入或输出。(例如:将输入转换为 :class:`DTensor`,将输出转换回 `torch.Tensor`) 指定 `input_fn` 和 `output_fn`。 (即:将输入转换为 :class:`DTensor`,将输出转换回 `torch.Tensor`) class:`nn.Module` 模块:要划分的用户模块。 参数: 模块 (:class:`nn.Module`):要划分的用户模块。 device_mesh (:class:`DeviceMesh`): 要放置模块的设备网格。 partition_fn (Callable): 分区参数的函数(即跨 ``device_mesh`` 分片参数)。如果未指定 ``partition_fn``, 则默认情况下,我们将 ``module`` 的所有模块参数复制到网格中。 如果 ``partition_fn`` 未指定,则默认情况下我们将 ``module`` 的所有模块参数复制到网格中。 输入函数(Callable):指定输入分布,即可以控制如何 模块的输入被分片。"input_fn" 将作为模块安装 ``forward_pre_hook``(前置转发钩子)。 输出文件名(Callable):指定输出分布,即可以控制如何 输出被分片,或者将其转换回 torch.Tensor。``output_fn``将被安装为模块``forward_hook``(前向钩子)。 安装为模块``forward_hook``(前向钩子)。 返回: 包含所有参数/缓冲区都是``DTensor``的模块。 .. 注意:: 当使用``xla``设备类型初始化 DeviceMesh 时,``distribute_module``。 返回带有 PyTorch/XLA SPMD 注解参数的 nn.Module。请参阅 `此问题 `__ 以获取更多详细信息。XLA 集成是实验性的,可能会发生变化。 "源代码" 火炬._C._log_api_usage_once("torch.dtensor.distribute_module") 已分发 = getattr(模块, _已应用分发模块", 错误) 如果 已分发: 提升 运行时错误( "分发模块应在模块上只调用一次," "但是这个模块已经被调用了!" ) 设备网状 = 设备网状 _网状资源.获取当前网状() 设备类型 = 装置网状结构.设备类型 如果 设备类型 == "xla": try: # 这个函数用于为自动分区标注所有模块参数 # PyTorch/XLA SPMD 或显式分区到 :class:`XLAShardedTensor` 参数 # 根据 `partition_fn` 指定的进行分区。 来自 torch_xla.distributed.spmd 导入 ( # type:ignore[导入] xla_distribute_module, ) 返回 xla_distribute_module( 模块, 装置网状结构, 分区函数, input_fn, 输出函数 ) # type:ignore[return-value] 除了 导入错误 作为 e: msg = 使用 DTensor API 与 xla 一起使用时,您必须安装 torch_xla 包! 提升 导入错误(信息) 来自 e def 复制模块参数缓冲区(m: nn.模块, 网格: 设备网状结构) -> : 此函数遍历直接模块参数 将所有非 DTensor 参数/缓冲区复制到 DTensor # 参数/缓冲区,如果它们尚未分区 # partition_fn,我们在这里不能轻易使用 `module._apply` # 因为不知道 partition_fn 内部发生了什么 用户可以做任何事情,例如安装钩子,我们希望 保留这些。 完整复制 = [复制()] * 网格.维数 , 参数 m.参数.项目(): 如果 参数 not not isinstance(参数, DTensor): m.注册参数( , nn.参数(分配张量(参数.数据, 网格, 完全复制)), ) , 缓冲区 m._缓冲区.项目(): 如果 缓冲区 not not isinstance(缓冲区, DTensor): m._缓冲区[] = 分配张量(缓冲区, 网格, 完全复制) 如果 分区函数 : # 如果未指定分区函数,则默认复制 所有模块的参数/缓冲区 名称, 子模块 模块.命名模块(): 复制模块参数缓冲区(子模块, 装置网状结构) 否则: 将 partition_fun 应用到子模块 名称, 子模块 模块.命名模块(): 分区函数(名称, 子模块, 装置网状结构) 复制模块参数缓冲区(子模块, 装置网状结构) # 将输入函数注册为模块前向预钩子 如果 输入函数 not : # 检查输入函数的签名 参数数量 = 长度(检查.签名(input_fn).参数) 如果 参数数量 == 2: # 输入函数仅接受输入和设备网格 warnings.警告( "弃用接受两个参数(inputs, device_mesh)的 input_fn," "请使用接受(module, inputs, device_mesh)的 input_fn 代替!", 未来警告, 栈级别=2, ) 模块.注册前向钩子( lambda _, 输入: input_fn(输入, 装置网状结构) 忽略调用参数 ) elif 参数数量 == 3: 输入_fn 接收模块、输入和设备网格 模块.注册前向钩子( lambda 模块, 输入: input_fn(模块, 输入, 装置网状结构) ) 否则: 提升 ValueError( f"input_fn 应该接受 3 个参数,但得到了 "{参数数量}个参数! ) # 将 output_fn 注册为模块前向钩子 如果 输出函数 not : 参数数量 = 长度(检查.签名(输出函数).参数) 如果 参数数量 == 2: 输出文件名只接受输出和设备网格 warnings.警告( "弃用接受两个参数(inputs, device_mesh)的 output_fn," "请使用接受(module, inputs, device_mesh)的 output_fn 代替!", 未来警告, 栈级别=2, ) 模块.注册前向钩子( lambda 模块, 输入, 输出: 输出函数(输出, 装置网状结构) 忽略调用参数 ) elif 参数数量 == 3: 模块.注册前向钩子( lambda 模块, 输入, 输出: 输出函数(模块, 输出, 装置网状结构) ) 否则: 提升 ValueError( f"output_fn 应该接受 3 个参数,但得到了 "{参数数量}个参数! ) 模块._distribute_module_applied = 真实 # 类型:忽略[赋值] 返回 模块 以下为张量工厂函数 API,用于直接创建 DTensor。我们需要 将工厂函数 API 分开,因为张量子类无法重写张量 工厂方法,我们需要用户使用用户意图的 device_mesh 和放置来创建合适的 DTensor。 def _dtensor_init_helper( # 类型:忽略[未指定类型定义] 初始化操作, 尺寸: 火炬.尺寸, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , **kwargs, ) -> DTensor: # from torch.distributed._tensor.placement_types import DTensorSpec, TensorMeta # 如果 device_mesh 为空,则使用 mesh 资源中的那个 设备网状 = 设备网状 _网状资源.获取当前网状() kwargs["设备"] = 装置网状结构.设备类型 如果没有指定,则将默认放置设置为复制 布局 = 布局 元组(复制() _ 范围(装置网状结构.ndim)) 检查设备网格与放置项 断言 装置网状结构.维数 == 长度(安排), ( "网格尺寸与放置长度不匹配" ) 断言 kwargs[布局] == 火炬.strided, "布局值不受支持!" 火炬步长 = 火炬._prims_common.使步长连续(尺寸) # 获取局部张量形状 本地形状, _ = 计算局部形状和全局偏移( 尺寸, 装置网状结构, 布局 ) # 初始化局部张量 如果 初始化操作 == 火炬.full: 填充值 = kwargs.弹出(填充值, 0) 本地张量 = 初始化操作(本地形状, 填充值, **kwargs) elif 初始化操作 == 火炬.随机 初始化操作 == 火炬.randn: 此张量元数据除了 `shape` 之外不使用 dtype = kwargs.获取("dtype", 火炬.获取默认数据类型()) 张量元数据 = 张量元(尺寸, (0,), 数据类型) 规范 = DTensorSpec(装置网状结构, 元组(安排), 张量元=张量元) 如果 随机.是否支持随机网格(装置网状结构) not 随机._rng_tracker: 随机._rng_tracker = 随机.基于偏移的 RNG 追踪器(装置网状结构) 断言 随机._rng_tracker not 随机._rng_tracker._distribute_region(规格): 本地张量 = 初始化操作(本地形状, **kwargs) 否则: 本地张量 = 初始化操作(本地形状, **kwargs) 规范 = DTensorSpec( 装置网状结构, 元组(安排), 张量元=张量元( 尺寸, torch_stride, 本地张量.数据类型, ), ) 返回 DTensor( 本地张量, 规格, 需要梯度=kwargs[requires_grad] ) def ( # 类型:忽略[未指定类型定义] *尺寸, 数据类型: 可选[火炬.数据类型] = , 布局: 火炬.布局 = 火炬.strided, 需要梯度: 布尔类型 = 错误, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , ) -> DTensor: "" 返回一个填充了标量值 1 的 :class:`DTensor`,其形状由变量参数 `size` 定义。 `size` (int...): 定义输出 :class:`DTensor` 形状的整数序列。 参数: size (int...): 定义输出 :class:`DTensor` 形状的整数序列。 可以是可变数量的参数或类似列表或元组的集合。 例如:ones(1,2,3..) 或 ones([1,2,3..]) 或 ones((1,2,3..)) 关键字参数: dtype (:class:`torch.dtype`,可选):返回 :class:`DTensor` 的期望数据类型。 默认:如果为 ``None``,则使用全局默认值(见 :func:`torch.set_default_dtype`)。 返回的 DTensor 的期望布局 (:class:`torch.layout`,可选): 默认:``torch.strided``。 requires_grad (bool,可选):如果 autograd 应记录操作。 返回 :class:`DTensor`。默认: ``False``。 device_mesh::class:`DeviceMesh` 类型,包含 ranks 的网格信息 放置序列::class:`Placement` 类型:``Shard``,``Replicate`` 返回: 每个 rank 上的 :class:`DTensor` 对象 "源代码" torch_size = 标准化到 torch 大小(尺寸) 返回 _dtensor_init_helper( 火炬., torch_size, 数据类型=数据类型, 布局=布局, 需要梯度=需要梯度, 装置网状结构=装置网状结构, 安排=安排, ) def 空的( # 类型:忽略[未指定类型定义] *尺寸, 数据类型: 可选[火炬.数据类型] = , 布局: 火炬.布局 = 火炬.strided, 需要梯度: 布尔类型 = 错误, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , ) -> DTensor: "" 返回一个填充未初始化数据的 :class:`DTensor`。 其形状由变量参数 `size` 定义。 参数: size (int...): 定义输出 :class:`DTensor` 形状的整数序列。 可以是可变数量的参数或类似列表或元组的集合。 例如:empty(1,2,3..) 或 empty([1,2,3..]) 或 empty((1,2,3..)) 关键字参数: dtype (:class:`torch.dtype`,可选):返回 :class:`DTensor` 的期望数据类型。 默认:如果为 ``None``,则使用全局默认值(见 :func:`torch.set_default_dtype`)。 layout (:class:`torch.layout`,可选):返回 :class:`DTensor` 的期望布局。 默认:``torch.strided``。 requires_grad (bool,可选):如果 autograd 应记录操作。 返回 :class:`DTensor`。默认: ``False``。 device_mesh::class:`DeviceMesh` 类型,包含 ranks 的网格信息 放置序列::class:`Placement` 类型:``Shard``,``Replicate`` 返回: 每个 rank 上的 :class:`DTensor` 对象 "源代码" torch_size = 标准化到 torch 大小(尺寸) 返回 _dtensor_init_helper( 火炬.空的, torch_size, 数据类型=数据类型, 布局=布局, 需要梯度=需要梯度, 装置网状结构=装置网状结构, 安排=安排, ) def full( # 类型:忽略[未指定类型定义] 尺寸, 填充值, *, 数据类型: 可选[火炬.数据类型] = , 布局: 火炬.布局 = 火炬.strided, 需要梯度: 布尔类型 = 错误, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , ) -> DTensor: "" 返回一个根据 `device_mesh` 和 `placements` 填充 `fill_value` 的 `:class:`DTensor`。 其形状由参数 `size` 定义。 参数: size (int...): 定义输出 :class:`DTensor` 形状的整数序列。 可以是可变数量的参数或类似列表或元组的集合。 例如:ones(1,2,3..) 或 ones([1,2,3..]) 或 ones((1,2,3..)) fill_value(标量):用于填充输出张量的值。 关键字参数: dtype (:class:`torch.dtype`,可选):返回 :class:`DTensor` 的期望数据类型。 默认:如果为 ``None``,则使用全局默认值(见 :func:`torch.set_default_dtype`)。 返回的 DTensor 的期望布局 (:class:`torch.layout`,可选): 默认:``torch.strided``。 requires_grad (bool,可选):如果 autograd 应记录操作。 返回 :class:`DTensor`。默认: ``False``。 device_mesh: :class:`DeviceMesh` 类型,包含 ranks 的网格信息。 放置序列::class:`Placement` 类型:``Shard``,``Replicate`` 返回: 每个 rank 上的 :class:`DTensor` 对象 "源代码" torch_size = 标准化到 torch 大小(尺寸) 返回 _dtensor_init_helper( 火炬.full, torch_size, 填充值=填充值, 数据类型=数据类型, 布局=布局, 需要梯度=需要梯度, 装置网状结构=装置网状结构, 安排=安排, ) def 随机( # 类型:忽略[未指定类型定义] *尺寸, 需要梯度: 布尔类型 = 错误, 数据类型: 可选[火炬.数据类型] = , 布局: 火炬.布局 = 火炬.strided, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , ) -> DTensor: "" 返回一个填充有均匀分布随机数的 :class:`DTensor` 的区间 ``[0, 1)``。张量的形状由变量 ``size`` 定义。 size(int...):定义输出 :class:`DTensor` 形状的整数序列。 参数: size (int...): 定义输出 :class:`DTensor` 形状的整数序列。 可以是可变数量的参数或类似列表或元组的集合。 例如:ones(1,2,3..) 或 ones([1,2,3..]) 或 ones((1,2,3..)) 关键字参数: dtype (:class:`torch.dtype`,可选):返回 :class:`DTensor` 的期望数据类型。 默认:如果为 ``None``,则使用全局默认值(见 :func:`torch.set_default_dtype`)。 返回的 DTensor 的期望布局 (:class:`torch.layout`,可选): 默认:``torch.strided``。 requires_grad (bool,可选):如果 autograd 应记录操作。 返回 :class:`DTensor`。默认: ``False``。 device_mesh: :class:`DeviceMesh` 类型,包含 ranks 的网格信息。 放置序列::class:`Placement` 类型:``Shard``,``Replicate`` 返回: 每个 rank 上的 :class:`DTensor` 对象 "源代码" torch_size = 标准化到 torch 大小(尺寸) 返回 _dtensor_init_helper( 火炬.随机, torch_size, 数据类型=数据类型, 布局=布局, 需要梯度=需要梯度, 装置网状结构=装置网状结构, 安排=安排, ) def randn( # 类型:忽略[未指定类型定义] *尺寸, 需要梯度: 布尔类型 = 错误, 数据类型: 可选[火炬.数据类型] = , 布局: 火炬.布局 = 火炬.strided, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , ) -> DTensor: "" 返回一个填充有正态分布随机数的 :class:`DTensor` 均值为 0,方差为 1。张量的形状由变量 size(int...):定义输出 :class:`DTensor` 形状的整数序列。 参数: size (int...): 定义输出 :class:`DTensor` 形状的整数序列。 可以是可变数量的参数或类似列表或元组的集合。 例如:ones(1,2,3..) 或 ones([1,2,3..]) 或 ones((1,2,3..)) 关键字参数: dtype (:class:`torch.dtype`,可选):返回 :class:`DTensor` 的期望数据类型。 默认:如果为 ``None``,则使用全局默认值(见 :func:`torch.set_default_dtype`)。 返回的 DTensor 的期望布局 (:class:`torch.layout`,可选): 默认:``torch.strided``。 requires_grad (bool,可选):如果 autograd 应记录操作。 返回 :class:`DTensor`。默认: ``False``。 device_mesh: :class:`DeviceMesh` 类型,包含 ranks 的网格信息。 放置序列::class:`Placement` 类型:``Shard``,``Replicate`` 返回: 每个 rank 上的 :class:`DTensor` 对象 "源代码" torch_size = 标准化到 torch 大小(尺寸) 返回 _dtensor_init_helper( 火炬.randn, torch_size, 数据类型=数据类型, 布局=布局, 需要梯度=需要梯度, 装置网状结构=装置网状结构, 安排=安排, ) def ( # 类型:忽略[未指定类型定义] *尺寸, 需要梯度: 布尔类型 = 错误, 数据类型: 可选[火炬.数据类型] = , 布局: 火炬.布局 = 火炬.strided, 装置网状结构: 可选[设备网状结构] = , 安排: 可选[序列[放置]] = , ) -> DTensor: "" 返回一个填充了标量值 0 的 :class:`DTensor`。 参数: size (int...): 定义输出 :class:`DTensor` 形状的整数序列。 可以是可变数量的参数或类似列表或元组的集合。 例如:zeros(1,2,3..) 或 zeros([1,2,3..]) 或 zeros((1,2,3..))。 关键字参数: requires_grad (bool,可选):如果 autograd 应记录操作。 返回 :class:`DTensor`。默认: ``False``。 dtype (:class:`torch.dtype`,可选):返回 :class:`DTensor` 的期望数据类型。 默认:如果为 ``None``,则使用全局默认值(见 :func:`torch.set_default_dtype`)。 layout (:class:`torch.layout`,可选):返回 :class:`DTensor` 的期望布局。 默认:``torch.strided``。 device_mesh::class:`DeviceMesh` 类型,包含 ranks 的网格信息 放置序列::class:`Placement` 类型:``Shard``,``Replicate`` 返回: 每个 rank 上的 :class:`DTensor` 对象 "源代码" torch_size = 标准化到 torch 大小(尺寸) 返回 _dtensor_init_helper( 火炬., torch_size, 数据类型=数据类型, 布局=布局, 需要梯度=需要梯度, 装置网状结构=装置网状结构, 安排=安排, )

© 版权所有 PyTorch 贡献者。

使用 Sphinx 构建,并使用 Read the Docs 提供的主题。

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

深入了解初学者和高级开发者的教程

查看教程

资源

查找开发资源,获取您的疑问解答

查看资源