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 (
init_method (
world_size (
rank (
store (
timeout (timedelta**, optional) – 对进程组执行的操作的超时时间。NCCL 的默认值为 10 分钟,其他后端的默认值为 30 分钟。这是集合操作将异步中止并导致进程崩溃的持续时间。这样做是因为 CUDA 执行是异步的,并且由于失败的异步 NCCL 操作可能导致后续的 CUDA 操作在损坏的数据上运行,继续执行用户代码已不再安全。设置 TORCH_NCCL_BLOCKING_WAIT 时,进程将阻塞并等待此超时。
group_name (
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-tdevice_id (
方法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的建议
-
单机训练:推荐
env://,简单且与启动工具集成。 -
多机训练:使用
tcp://指定主节点IP和端口,确保网络可达。 -
共享存储环境:可尝试
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?
-
灵活性:可以自定义存储后端(例如集成第三方分布式协调服务如 etcd、Redis)。
-
显式控制:直接管理存储对象的生命周期(如关闭端口或清理文件)。
-
多后端支持:支持 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()
注意事项
-
主节点标记:只有主节点(
rank=0)需要设置is_master=True,其他节点设为False。 -
端口占用:确保
TCPStore的端口未被防火墙阻止且未被占用。 -
同步问题:所有进程必须在初始化时访问同一个
store,否则会卡死。 -
后端兼容性:
-
NCCL后端通常与TCPStore配合使用。 -
Gloo后端支持FileStore和TCPStore。
-
总结
-
store参数提供了对分布式进程元数据同步的底层控制,适用于复杂场景(如多机训练)。 -
优先使用
TCPStore进行多机训练,FileStore适合有共享存储的环境,HashStore用于单机调试。 -
新版 PyTorch 推荐使用
store替代init_method,以获得更好的灵活性和兼容性。
浙公网安备 33010602011771号