• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Gesündeste
博客园    首页    新随笔    联系   管理    订阅  订阅
torch.distributed.init_process_group()参数解析

函数声明

torch.distributed.init_process_group(backend=None, 
                                  init_method=None,
                                  timeout=None,
                                  world_size=-1,
                                  rank=-1,
                                  store=None,
                                  group_name='',
                                  pg_options=None,
                                  device_id=None)

初始化默认分布式进程组,同时也会初始化分布式包。

  • 初始化进程组主要有两种方式

    显式指定 store, rank, 和 world_size。指定 init_method (一个 URL 字符串),指明在哪里/如何发现对等方。可以选择指定 rank 和 world_size,或将所有必需参数编码在 URL 中并省略它们。

如果两者都未指定,则假定 init_method 为“env://”。

  • 参数

    backend (str or Backend, optional) – 要使用的后端。根据构建时配置,有效值包括 mpi、gloo、nccl、ucc 或第三方插件注册的后端。自 2.6 版本起,如果未提供 backend,c10d 将使用 device_id kwarg(如果提供)指示的设备类型注册的后端。目前已知的默认注册是:cuda 使用 nccl,cpu 使用 gloo。如果既未提供 backend 也未提供 device_id,c10d 将检测运行时机器上的加速器并使用为该检测到的加速器(或 cpu)注册的后端。此字段可以作为小写字符串(例如,“gloo”)给出,也可以通过 Backend 属性(例如,Backend.GLOO)访问。如果在使用 nccl 后端时每台机器使用多个进程,则每个进程必须对其使用的每个 GPU 拥有独占访问权,因为在进程之间共享 GPU 可能导致死锁或 NCCL 无效使用。ucc 后端是实验性的。

    init_method (str, optional) – 指定如何初始化进程组的 URL。如果未指定 init_method 或 store,则默认为“env://”。与 store 互斥。

    world_size (int, optional) – 参与作业的进程数。如果指定了 store,则必需。

    rank (int, optional) – 当前进程的排名(应为 0 到 world_size-1 之间的数字)。如果指定了 store,则必需。

    store (Store, optional) – 所有工作进程可访问的键/值存储,用于交换连接/地址信息。与 init_method 互斥。

    timeout (timedelta**, optional) – 对进程组执行的操作的超时时间。NCCL 的默认值为 10 分钟,其他后端的默认值为 30 分钟。这是集合操作将异步中止并导致进程崩溃的持续时间。这样做是因为 CUDA 执行是异步的,并且由于失败的异步 NCCL 操作可能导致后续的 CUDA 操作在损坏的数据上运行,继续执行用户代码已不再安全。设置 TORCH_NCCL_BLOCKING_WAIT 时,进程将阻塞并等待此超时。

    group_name (str, optional**, deprecated) – 组名。此参数被忽略

    pg_options (ProcessGroupOptions**, optional) – 进程组选项,指定在构建特定进程组时需要传入的额外选项。目前,我们唯一支持的选项是针对 nccl 后端的 ProcessGroupNCCL.Options,可以指定 is_high_priority_stream,以便 nccl 后端在有计算内核等待时能够选择高优先级 CUDA 流。有关配置 nccl 的其他可用选项,请参阅 https://docs.nvda.net.cn/deeplearning/nccl/user-guide/docs/api/types.html#ncclconfig-t

    device_id (torch.device, optional) – 用于将此进程“绑定”到单个特定设备,从而实现后端特定优化。目前,这仅在 NCCL 下有两个影响:通信器会立即形成(立即调用 ncclCommInit* 而不是正常的延迟调用),并且子组在可能的情况下会使用 ncclCommSplit 以避免不必要的组创建开销。如果想尽早了解 NCCL 初始化错误,也可以使用此字段。

 

方法1:指定 init_method

我现在要解释一下PyTorch中torch.distributed.init_process_group()函数的init_method参数。这个参数看起来是用来初始化分布式进程组的,但我得先理解它的具体作用和不同的选项。

首先,我记得在分布式训练中,不同的进程需要相互通信,所以必须有一种方法来协调它们的启动和通信方式。init_method参数应该就是用来指定这种协调方法的。可能的选项包括环境变量、共享文件或者TCP地址之类的。

PyTorch文档里提到过几种初始化方法,比如使用环境变量(env://),或者一个共享的文件系统(file://path),还有通过TCP连接到一个主进程(比如tcp://IP:port)。不同的初始化方法适用于不同的场景,比如在单机多卡的情况下可能用环境变量更方便,而多机训练可能需要TCP或者共享文件。

让我再仔细想想。当使用init_method='env://'时,进程会从环境变量中获取MASTER_ADDR和MASTER_PORT等信息,这样每个进程只需要正确设置这些环境变量,就能找到主节点并建立通信。这可能是在使用像torch.distributed.launch或者torchrun这样的启动脚本时自动处理的,因为它们会设置这些环境变量。

另一种情况是使用文件系统,比如init_method='file:///path/to/file'。这时,所有进程都会访问同一个文件,通过文件来同步信息。这种方法可能适用于共享存储环境,但需要注意文件锁的问题,避免竞争条件。如果文件被删除或者无法访问,可能会导致初始化失败。

然后是TCP方式,比如init_method='tcp://10.1.1.20:23456'。这里需要指定一个主进程的IP地址和端口,其他进程通过这个地址连接到主进程进行协调。这种方法适合多台机器之间的通信,但需要确保网络通畅,端口开放,并且所有机器都能访问指定的IP和端口。

另外,可能还有其他初始化方法,比如使用NCCL或者Gloo后端时的不同设置,但init_method主要处理的是如何找到和协调进程之间的通信参数,而后端(backend参数)则处理实际的通信协议,比如Gloo用于CPU,NCCL用于GPU。

需要注意的是,不同的初始化方法可能对不同的后端支持程度不同。例如,文件初始化方法可能在Gloo后端下工作良好,但在NCCL中可能有问题。或者TCP方法在跨机器时更可靠。因此,选择合适的init_method需要结合训练的环境和后端类型。

还有一个要点是,当使用多台机器时,每个进程的RANK和WORLD_SIZE需要正确设置,无论是通过环境变量还是通过启动参数手动传递。而init_method则是告诉进程如何找到主节点或者共享的协调点,以便交换这些信息。

例如,当使用TCP方式时,主节点的IP地址必须是所有机器都能访问的,端口要开放,并且所有进程在初始化时都连接到这个地址。主节点负责协调各个进程的rank和world_size,确保它们正确同步。

而使用环境变量方式时,每个进程可能已经通过启动脚本设置了RANK、WORLD_SIZE、MASTER_ADDR和MASTER_PORT,这样在调用init_process_group时,只需要指定env://,就会自动读取这些变量。

不过,可能还有其他参数需要配合,比如backend、rank和world_size,这些是否需要在init_process_group中显式传递,还是通过环境变量自动获取?例如,如果使用env://,是否还需要在函数参数中指定rank和world_size?可能需要看具体的文档说明。比如,当使用env://时,PyTorch会从环境变量中获取RANK和WORLD_SIZE,所以可能不需要在函数中传递,但如果显式传递了,可能会覆盖环境变量。这点需要注意。

总结一下,init_method参数用于指定进程组初始化的方法,不同的方法对应不同的协调机制。常见的有env://(环境变量)、file://(共享文件)、tcp://(TCP连接)。选择哪种方法取决于运行环境和需求,比如单机用env或file,多机用tcp,共享存储用file等。同时需要配合正确设置相关参数,如MASTER_ADDR、MASTER_PORT、RANK、WORLD_SIZE等,无论是通过环境变量还是直接传递参数。

可能还需要注意一些细节,例如使用文件方法时,所有进程需要有权限读写该文件;使用TCP时防火墙设置等。另外,不同后端对初始化方法的支持可能不同,例如NCCL可能更倾向于使用TCP而不是文件,尤其是在多GPU情况下。

此外,初始化进程组是分布式训练的第一步,必须正确执行,否则进程会挂起或报错。例如,如果某个进程无法连接到指定的TCP地址,或者无法访问共享文件,初始化就会失败,导致整个训练无法开始。

最后,可能还需要考虑不同初始化方法的性能和可靠性。例如,TCP可能在多机情况下更高效,而文件系统方法可能在特定存储系统中存在延迟或锁竞争问题。因此,根据实际环境选择最合适的初始化方法很重要。

在PyTorch的分布式训练中,torch.distributed.init_process_group()函数的init_method参数用于指定进程组初始化的方法,确保不同进程能够协调通信。以下是该参数的详细说明及常见选项:


init_method参数的作用

  • 协调通信:分布式训练需要多个进程(可能跨机器)同步彼此的地址、端口和配置信息。init_method定义了进程间如何交换这些信息。

  • 初始化后端:与backend参数配合使用(如NCCL、Gloo),确定通信协议,而init_method则决定进程如何发现彼此。


常见的init_method选项

1. env://(环境变量)

  • 机制:从环境变量中读取配置,如MASTER_ADDR(主节点IP)、MASTER_PORT(端口)、RANK(进程编号)、WORLD_SIZE(总进程数)。

  • 适用场景:单机或多机训练,配合启动工具(如torchrun或torch.distributed.launch)自动设置环境变量。

  • 示例:

  • import os
    os.environ["MASTER_ADDR"] = "localhost"
    os.environ["MASTER_PORT"] = "12355"
    os.environ["RANK"] = "0"
    os.environ["WORLD_SIZE"] = "2"
    torch.distributed.init_process_group(backend="gloo", init_method="env://")

2. file://(共享文件)

  • 机制:所有进程通过读写共享文件同步信息。文件路径需对所有进程可见(如NFS)。

  • 适用场景:共享存储环境,但需注意文件锁和并发问题。

  • 示例:

  • # 所有进程使用同一文件路径
    torch.distributed.init_process_group(
       backend="gloo",
       init_method="file:///path/to/shared/file",
       rank=0,  # 必须显式指定rank和world_size
       world_size=2
    )

3. tcp://(TCP协议)

  • 机制:所有进程连接到指定的主节点(通过IP和端口)交换信息。

  • 适用场景:多机训练,需确保网络互通且防火墙开放端口。

  • 示例:

  • # 主节点(rank=0)的IP为10.1.1.20,端口23456
    torch.distributed.init_process_group(
       backend="nccl",
       init_method="tcp://10.1.1.20:23456",
       rank=0,  # 必须显式指定rank和world_size
       world_size=2
    )

选择init_method的建议

  1. 单机训练:推荐env://,简单且与启动工具集成。

  2. 多机训练:使用tcp://指定主节点IP和端口,确保网络可达。

  3. 共享存储环境:可尝试file://,但需注意文件权限和锁机制。


注意事项

  • 显式参数 vs 环境变量:若在init_process_group()中显式传递rank和world_size,会覆盖环境变量。

  • 后端兼容性:

    • NCCL后端多用于GPU,对tcp://和env://支持较好。

    • Gloo后端支持CPU,兼容所有init_method。

  • 端口冲突:使用tcp://时,确保端口未被占用且防火墙允许。


完整示例(多机TCP初始化)

import torch
import argparse
​
parser = argparse.ArgumentParser()
parser.add_argument("--rank", type=int)
parser.add_argument("--world_size", type=int)
parser.add_argument("--master_addr", type=str, default="10.1.1.20")
parser.add_argument("--master_port", type=str, default="23456")
args = parser.parse_args()
​
torch.distributed.init_process_group(
   backend="nccl",
   init_method=f"tcp://{args.master_addr}:{args.master_port}",
   rank=args.rank,
   world_size=args.world_size
)

运行命令:

# 机器1(主节点)
python script.py --rank 0 --world_size 2 --master_addr 10.1.1.20
​
# 机器2
python script.py --rank 1 --world_size 2 --master_addr 10.1.1.20

通过合理配置init_method,可以确保分布式训练正确初始化进程组,为后续的跨进程通信(如all_reduce)奠定基础。

 

方法2:显式指定 store, rank, 和 world_size。

store 参数的作用

store 是一个实现了键值存储(Key-Value Store)接口的对象,核心功能是同步所有进程的元数据(如地址、端口、rank、world_size 等)。所有进程通过访问同一个 store 来交换必要的信息,从而完成进程组的初始化。

在 PyTorch 的分布式训练中,torch.distributed.init_process_group() 的 store 参数是用于定义进程间通信的底层存储机制的。它替代了早期版本中通过 init_method 直接指定初始化方式的做法,提供了更灵活、更底层的方式控制分布式进程的协调和通信。

store参数是在PyTorch的后续版本中引入的,补充了init_method的功能。用户可能在使用较新的PyTorch版本使用store参数,store参数的具体作用用于存储分布式训练中进程间的通信信息,比如地址和端口。与init_method不同,store提供了更灵活的配置方式,支持多种后端存储,如HashStore、TCPStore、FileStore等。这可能让用户更容易在不同环境下配置分布式训练。

在较新的版本中,推荐使用store来替代init_method,因为store提供了更多的选项和更好的扩展性。同时,需要明确如何正确初始化store对象,并将其传递给init_process_group。

需要注意,当同时指定store和init_method时,可能会出现冲突,因此需要建议用户只使用其中一种方式。

 

下面提供具体的代码示例更好地理解如何使用store参数,比如如何创建TCPStore实例并传递给初始化函数。

PyTorch 提供了多种内置的 store 类型,适用于不同的场景:


常见的 store 类型

1. HashStore(默认)

  • 机制:基于内存的简单键值存储,仅适用于单机多进程(同一台机器上的多个进程)。

  • 用途:本地调试或单机训练。

  • 示例:

    python

     

  • import torch.distributed as dist
    ​
    # 默认使用 HashStore
    dist.init_process_group(backend="gloo")

2. TCPStore

  • 机制:基于 TCP 协议的键值存储,需要一个中心化的主节点(通过 IP 和端口访问)。

  • 用途:多机训练(跨机器的分布式训练)。

  • 示例:

    python

     

  • import torch.distributed as dist
    ​
    # 主节点(rank=0)的配置
    if rank == 0:
      store = dist.TCPStore(
          host_name="10.1.1.20", # 主节点 IP
          port=12345,             # 主节点端口
          world_size=4,           # 总进程数
          is_master=True         # 主节点标记
      )
    else:
      store = dist.TCPStore(
          host_name="10.1.1.20", # 主节点 IP
          port=12345,             # 主节点端口
          world_size=4,           # 总进程数
          is_master=False         # 非主节点
      )
    ​
    dist.init_process_group(backend="nccl", store=store, rank=rank, world_size=4)

3. FileStore

  • 机制:通过共享文件系统(如 NFS)同步元数据。所有进程读写同一个文件。

  • 用途:有共享存储的多机环境,但需注意文件锁问题。

  • 示例:

    python

     

  • store = dist.FileStore("/path/to/shared/file", world_size=4)
    dist.init_process_group(backend="gloo", store=store, rank=rank, world_size=4)

4. C10dStore

  • 机制:PyTorch 内部的默认存储实现,兼容多种后端(如 env:// 的初始化方式)。

  • 用途:通过环境变量自动配置(如 MASTER_ADDR 和 MASTER_PORT)。

  • 示例:

    python

     

  • # 隐式使用 C10dStore(等价于 init_method="env://")
    dist.init_process_group(backend="nccl")

store vs init_method

  • init_method 是旧版参数,通过字符串直接指定初始化方式(如 tcp:// 或 file://)。

  • store 是新版参数,通过显式传递存储对象(如 TCPStore)实现更精细的控制。

  • 兼容性:

    • 如果同时指定 store 和 init_method,PyTorch 会优先使用 store。

    • 新版代码推荐优先使用 store,因为它的接口更清晰且支持更多功能。


为什么需要 store?

  1. 灵活性:可以自定义存储后端(例如集成第三方分布式协调服务如 etcd、Redis)。

  2. 显式控制:直接管理存储对象的生命周期(如关闭端口或清理文件)。

  3. 多后端支持:支持 TCP、文件、内存等多种同步机制,适应不同环境。


使用 store 的完整流程

以下是一个多机训练中使用 TCPStore 的示例:

import torch
import torch.distributed as dist

def main():
# 假设通过命令行参数传入 rank 和 world_size
parser = argparse.ArgumentParser()
parser.add_argument("--rank", type=int)
parser.add_argument("--world_size", type=int)
parser.add_argument("--master_addr", type=str, default="10.1.1.20")
parser.add_argument("--master_port", type=int, default=12345)
args = parser.parse_args()

# 创建 TCPStore
store = dist.TCPStore(
args.master_addr, # 主节点 IP
args.master_port, # 主节点端口
args.world_size, # 总进程数
is_master=(args.rank == 0) # 主节点标记
)

# 初始化进程组
dist.init_process_group(
backend="nccl",
store=store,
rank=args.rank,
world_size=args.world_size
)

# 后续分布式训练代码...

if __name__ == "__main__":
main()

注意事项

  1. 主节点标记:只有主节点(rank=0)需要设置 is_master=True,其他节点设为 False。

  2. 端口占用:确保 TCPStore 的端口未被防火墙阻止且未被占用。

  3. 同步问题:所有进程必须在初始化时访问同一个 store,否则会卡死。

  4. 后端兼容性:

    • NCCL 后端通常与 TCPStore 配合使用。

    • Gloo 后端支持 FileStore 和 TCPStore。


总结

  • store 参数提供了对分布式进程元数据同步的底层控制,适用于复杂场景(如多机训练)。

  • 优先使用 TCPStore 进行多机训练,FileStore 适合有共享存储的环境,HashStore 用于单机调试。

  • 新版 PyTorch 推荐使用 store 替代 init_method,以获得更好的灵活性和兼容性。

posted on 2025-05-14 20:05  Gesündeste  阅读(586)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3