torch.distributed

参考 torch.distributed.init_process_group() - 云+社区 - 腾讯云

目录

后端

PyTorch自带的后端

使用哪个后端?

常见的环境变量

基础

初始化

torch.distributed.is_available()[source]

torch.distributed.init_process_group(backend, init_method=None, timeout=datetime.timedelta(0, 1800), world_size=-1, rank=-1, store=None, group_name='')[source]

class torch.distributed.Backend

torch.distributed.get_backend(group=)[source]

torch.distributed.get_rank(group=)[source]

torch.distributed.get_world_size(group=)[source]

torch.distributed.is_initialized()[source]

torch.distributed.is_mpi_available()[source]

torch.distributed.is_nccl_available()[source]

TCP初始化

共享文件系统初始化

环境变量初始化

torch.distributed.new_group(ranks=None, timeout=datetime.timedelta(0, 1800), backend=None)[source]

点对点通信

torch.distributed.send(tensor, dst, group=, tag=0)[source]

torch.distributed.recv(tensor, src=None, group=, tag=0)[source]

torch.distributed.isend(tensor, dst, group=, tag=0)[source]

torch.distributed.irecv(tensor, src, group=, tag=0)[source]

同步和异步收集操作

收集函数

torch.distributed.broadcast(tensor, src, group=, async_op=False)[source]

torch.distributed.all_reduce(tensor, op=ReduceOp.SUM, group=, async_op=False)[source]

torch.distributed.reduce(tensor, dst, op=ReduceOp.SUM, group=, async_op=False)[source]

torch.distributed.all_gather(tensor_list, tensor, group=, async_op=False)[source]

torch.distributed.gather(tensor, gather_list=None, dst=0, group=, async_op=False)[source]

torch.distributed.scatter(tensor, scatter_list=None, src=0, group=, async_op=False)[source]

torch.distributed.reduce_scatter(output, input_list, op=ReduceOp.SUM, group=, async_op=False)[source]

torch.distributed.all_to_all(output_tensor_list, input_tensor_list, group=, async_op=False)[source]

torch.distributed.barrier(group=, async_op=False)[source]

class torch.distributed.ReduceOp

class torch.distributed.reduce_op[source]

多GPU收集函数

torch.distributed.broadcast_multigpu(tensor_list, src, group=, async_op=False, src_tensor=0)[source]

torch.distributed.all_reduce_multigpu(tensor_list, op=ReduceOp.SUM, group=, async_op=False)[source]

torch.distributed.reduce_multigpu(tensor_list, dst, op=ReduceOp.SUM, group=, async_op=False, dst_tensor=0)[source]

torch.distributed.all_gather_multigpu(output_tensor_lists, input_tensor_list, group=, async_op=False)[source]

torch.distributed.reduce_scatter_multigpu(output_tensor_list, input_tensor_lists, op=ReduceOp.SUM, group=, async_op=False)[source]


后端

torch.distributed支持三种后端,每个都有不同的能力,下表展示了那个函数对使用CPU/CUDA张量是可以得到的。MPI只有在构建PyTorch的实现支持CUDA时才支持它。

PyTorch自带的后端

Pytorch分布式现在仅仅支持Linux。默认地,用Gloo和NCLL后端用来构建,并且包含在Pytorch分布式中(NCCL仅仅使用CUDA时才构筑)。MPI是一个可选的后端,并且仅仅在如果你从Pytorch源中构建时才包含。(例如,在一个MPI已经安装的Host上构建Pytorch。)

使用哪个后端?

过去,我们经常问:“我应该使用哪个后端?”

经验法则

GPU的分布式训练使用NCCL后端

CPU分布式训练使用Gloo后端

GPU host使用无限制宽带互连:

  • 使用NCCL,因为它是目前唯一支持无限制宽带和GPUDirect的后端。

GPU hosts使用以太网互连:

  • 使用NCCL,因为它目前提供最佳分布式GPU训练性能,特别对于多进程单点或者多点分布式训练。如果你遇到任何NCCL的问题,使用Gloo作为应急计划选项。(注意对于GPU目前Gloo比NCCL运行的慢)

CPU hosts用无限制带宽连接:

  • 如果无限制带宽支持IB上的IP,使用Gloo,否则,使用MPI作为替代,我们计划在即将更新的版本中加入Gloo的无限制带宽支持。
  • CPU hosts with Ethernet interconnect

用以太网连接的GPU:

  • Use Gloo, unless you have specific reasons to use MPI.
  • 使用Gloo,除非你有特殊的原因需要使用MPI。

常见的环境变量

选择要使用的网络接口

默认的,NCCL和Gloo后端都会尝试尽力选择正确的网络接口来使用。如果自动检测到的接口不正确,你可以使用下面的环境变量来重写:

  • NCCL_SOCKET_IFNAME, for example export NCCL_SOCKET_IFNAME=eth0
  • GLOO_SOCKET_IFNAME, for example export GLOO_SOCKET_IFNAME=eth0

如果你使用Gloo后端,你可以通过用逗号分隔它们来指定一个多借口而,比如export GLOO_SOCKET_IFNAME=eth0,eth1,eth2,eth3。后端将会在这些接口上以循环的方式派遣操作。在这些变量中所有进程指定相同的接口号很重要。

Other NCCL environment variables

其他NCCL环境变量。

NCCL提供了大量的环境变量来微调这个目的。

通常使用下面用来debugging目的中的一个:

  • export NCCL_DEBUG=INFO
  • export NCCL_DEBUG_SUBSYS=ALL

对NCCL环境变量的全部列表,请参考NVIDIA NCCL’s official documentation

基础

torch.distributed包提供Pytorch支持和通信基元,对多进程并行,在一个或多个机器上运行的若干个计算阶段。类torch.nn.parallel.DistributedDataParallel() 基于此功能来提供同步式分布式训练,作为任何Pytorch模块的包裹器。这和Multiprocessing package - torch.multiprocessingtorch.nn.DataParallel()提供的并行式不同,它支持多网络连接的机器,对每个进程使用者必须明确的启动一个主训练脚本的一个分开的副本。

在单个机器同步的情况下,torch.distributed或者torch.nn.parallel.DistributedDataParallel()包裹器,相对于其他数据并行的方法包括torch.nn.DataParallel()依然有很大的优势:

  • 在每次迭代时每个进程保持自己的优化器并且执行一个完全的优化步骤。同时这也许会出现冗余,因为梯度已经聚合在一起,并且平均到进程上,因此对每个进程都是一样的,这意味着不需要无参数广播步骤,减少了张量和节点之间的时间花费。
  • 每个进程进程包含一个独立的Pytorch解释器,消除额外的解释器超出。来自执行若干执行线程的GIL-thrashing,模型复制或来自单个Python进程的GPUs。这对模型特别重要使得Python的运行时间能够大量使用,包括使用循环成的模型或者许多小的组件。

初始化

在调用任何方法之前,这个包需要使用torch.distributed.init_process_group()来进行初始化。这将阻塞,直到所有进程都已加入。

torch.distributed.is_available()[source]

如果分布式包可以获得的话就返回True。否则,torch.distributed对任何API都是不可见的。目前,torch.distributed在Linux和MacOS上都可以得到。设置USE_DISTRIBUTED=1来启动它,当从源中构建PyTorch时。目前,对Linux系统,默认值是USE_DISTRIBUTED=1,对MacOS系统,默认值是USE_DISTRIBUTED=0。

torch.distributed.init_process_group(backend, init_method=None, timeout=datetime.timedelta(0, 1800), world_size=-1, rank=-1, store=None, group_name='')[source]

初始化默认的分布式进程组,并且也会初始化分布式包。

There are 2 main ways to initialize a process group:

有两种主要的方式来进行初始化过程:

  1. 明确的指定store,rank和world_size
  2. 指定init_method (一个URL字符串),这指明在哪里和如何发现同类。选择性的指定rank和world_size,或者编码所有在URL中需要的参数,并且忽略它们。

如果两者都没有指定,init_method假定为"env://"。

参数:

  • backend(str或Backend):--要使用的backend依赖于构筑时间配置,mpi, gloo, nccl作为有效值。这个参数以小写字符串表示(例如,“gloo”),这也能通过Backend属性(例如,Backend.GLOO)来访问。如果利用nccl在每个机器上使用多进程,每个进程必须独占访问它使用的每个GPU,因为在进程间共享GPU将会导致停滞。
  • init_method(str,可选)--URL指定如何初始化进程组。默认是“env://”,如果init_method和store都没有指定的时候。和store是互斥的。
  • world_size (python:int, optional) – Number of processes participating in the job. Required if store is specified.
  • world_size(int,可选的)--在工作中参与的进程数,如果store指定时需要设置。
  • rank (python:int, optional) – Rank of the current process. Required if store is specified.
  • rank(int, 可选的)--当前进程的等级。如果store指定时就需要设置。
  • store(store,可选的)--所有工作可访问的键/值存储,用于交换连接/地址信息。与init_method互斥。
  • timeout(timedelta,可选的)--对流程组执行的操作的超时。默认值为30分钟。这适用于gloo后端。对于nccl,只有在环境变量NCCL_BLOCKING_WAIT被设置为1时才适用。
  • group_name(str,可选的,丢弃)--组名字。

为了使得backend == Backend.MPI,PyTorch需要在支持MPI的系统上从源代码构建。这对NCCL同样适用。

class torch.distributed.Backend

一个可获得后端的类似枚举的类:GLOO,NCLL和MPI。

这个类的值是小写字母,例如"gloo"。它们可以作为属性来访问,例如Backend,NCCL。

这个类能直接调用来解析字符串,例如Backend(backend_str),如果back_ste是空时将会检查。如果是这样的话,返回解析后的小写字母字符串。它也接受大写字符串,例如Backend("GLOO"),返回"gloo"。

注意

入口端。UNDEFINED存在,但仅用作某些字段的初始值。用户不应该直接使用它,也不应该假设它的存在。

torch.distributed.get_backend(group=<object object>)[source]

返回给定进程组的后端。

参数:

  • group (ProcessGroup, optional) – 要处理的过程组。默认是通用的主进程组。如果其他指定的组指定后,调用的过程必须是group的 一部分。

返回值:

  • 给定进程组的后端,作为一个小写字母的字符串。

torch.distributed.get_rank(group=<object object>)[source]

返回当前进程组的等级。在一个分布式进程组内,rank是一个独特的识别器分配到每个进程。它们通常是从0到world_size的连续的整数。

参数:

  • group (ProcessGroup, optional) – 要处理的过程组。

返回值:

  • 如果不是组的一部分,等级就是进程组-1。

torch.distributed.get_world_size(group=<object object>)[source]

返回当前进程组的进程数。

参数:

  • group (ProcessGroup, optional) – 要处理的过程组。

返回值:

  • 如果不是组的一部分,进程组的world_size就为-1。

torch.distributed.is_initialized()[source]

  • 检查默认的进程数是否已经被初始化

torch.distributed.is_mpi_available()[source]

  • 检查MPI后端是否可以得到

torch.distributed.is_nccl_available()[source]

  • 检查NCCL后端是否可以得到。

目前支持三种初始化方式:

TCP初始化

使用TCP时有两种初始化方法,两者都需要一个所有进程都可以访问的网络地址和一个想要的world_size。第一种方法需要指定一个属于rank 0集成的地址。这个初始化方法需要对所有进程手动指定等级。注意多路广播地址在最近的分布式包中已经不再支持。group_name也已经丢弃了。

import torch.distributed as dist

# Use address of one of the machines
dist.init_process_group(backend, init_method='tcp://10.1.1.20:23456',
                        rank=args.rank, world_size=4)

共享文件系统初始化

其他初始化方法使用一个文件系统,这个文件系统是共享的,并且在一个组内所有的机器都是能看见的,伴随着需要的world_size。URL应该以file://开始,并且包含共享文件系统中不存在文件的路径(在一个存在的目录中)。如果它不存在的话,文件系统初始化会自动创建一个文件,但是将会杉树文件。因此,你必须确定这个文件是否已在下一次init_process_group()调用相同文件路径名之前已经删除。注意多路广播地址在最近的分布式包中已经不再支持。group_name也已经丢弃了。

警告

这个方法假定文件系统支持用fant1锁定 - 大多数局部系统和NFS支持它。

警告

这个方法通常创建一个文件并且尽力去删除还在程序结束时移除这个文件。换句话说,用文件初始化方法初始的每个初始化将会需要一个需要一个全新的空文件,以便初始化成功。如果通过以前初始化后的文件再一次使用(没有清楚干净时将会发生),这是不希望发生的行为,并且进程会导致僵局和失败。因此,如果自动删除没有发生的话,尽管这个方法将会尽力清除这个文件,你必须保证文件在训练结束时被移除,来阻止相同的文件在下一次中再次使用。如果你计划在同样的文件系统中调用init_process_group()时,这非常重要。换句话说,如果文件没有移除和清楚,

  • 11
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wanderer001

ROIAlign原理

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值