ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.5 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://cloud.tencent.com/developer/article/1582972 |
| Last Crawled | 2026-03-29 07:00:10 (15 days ago) |
| First Indexed | 2020-04-05 18:37:16 (6 years ago) |
| HTTP Status Code | 200 |
| Meta Title | PyTorch分布式训练简介-腾讯云开发者社区-腾讯云 |
| Meta Description | PyTorch分布式训练指南:详解单机多卡与多机多卡实现方法,包括DataParallel和DistributedDataParallel两种方式,提供环境配置、代码修改及启动命令详解,帮助开发者高效利用GPU资源加速深度学习模型训练。 |
| Meta Canonical | null |
| Boilerpipe Text | PyTorch分布式训练
分布式训练已经成为如今训练深度学习模型的一个必备工具,但pytorch默认使用单个GPU进行训练,如果想用使用多个GPU乃至多个含有多块GPU的节点进行分布式训练的时候,需要在代码当中进行修改,这里总结一下几种使用pytorch进行分布式训练的方式。
环境
本文使用的环境为:
python =3.7
pytorch = 1.0
CUDA = 8.0
使用单个GPU
pytorch中pytorch.cuda用于设置和运行CUDA操作,它会跟踪当前选定的GPU,并且您分配的所有CUDA张量将默认在该设备上创建。所选设备可以使用 torch.cuda.device 环境管理器进行更改。
pytorch中想要使用GPU进行模型训练非常简单,首先需要使用代码torch.cuda.is_available()判断当前环境是否可以使用GPU,如果返回False那么证明GPU不可用,需要检查软件包或驱动等是否安装正确。
当GPU可用时,可以使用torch.device()创建一个torch.device对象,例如torch.device('cuda')或使用torch.device('cuda:0')指定GPU,该对象可以将张量移动至GPU上。假设有一个张量x,我们可以使用x.cuda()或x.to(device)的方式将其移动至GPU上,这两种方式可以视作是等价的,并没有太大的区别,Variable与模型同理,也可以使用这样的方式进行移动。接下来按照征程的操作即可以进行训练。
单机使用多个GPU
单机使用多个GPU有两种方式,torch.nn.DataParallel()与torch.nn.parallel.DistributedDataParallel
其中torch.nn.DataParallel()只能实现在单机多卡中进行分布式训练,而torch.nn.parallel.DistributedDataParallel则是新方法,在单机多卡和多机多卡都可以训练。官方建议使用最新的torch.nn.parallel.DistributedDataParallel,因为即使在单机多卡上,新的方法在效率上也要比旧的表现好。
代码语言:
javascript
复制
torch.nn.DataParallel()
使用该方法的方式很简单,假设我们已经构建了一个模型NET,则只需要:
代码语言:
javascript
复制
model = NET()
model = torch.nn.DataParallel()
mode.cuda()
将模型分发到各个GPU上,接下来既可以使用多个GPU同时进行训练。
值得注意的是,这里torch是把模型输入的batch_size按照GPU的个数进行均分,因此如果希望保持与单个GPU训练时同样的batch_sizze则需要按照GPU的个数n对batch_size进行扩展到batch_size *n。
还有一点是torch默认输入的第一维是batch_size的大小,因此会直接在第一维上进行分割,因此构造batch数据时需要注意。
代码语言:
javascript
复制
torch.nn.parallel.DistributedDataParallel()
torch.nn.parallel.DistributedDataParallel是pytorch1.0新提供的方法。该计算模型并没有采用主流的Parameter Server结构,而是直接用了Uber Horovod的形式,也是百度开源的RingAllReduce算法。算法细节此处不表。
使用该方法首先需要进行初始化torch.distributed.init_process_group(backend, init_method='env://', **kwargs),其中的参数有:
代码语言:
javascript
复制
backend(str): 后端选择,包括 gloo,nccl,mpi
init_method(str,optional): 用来初始化包的URL, 我理解是一个用来做并发控制的共享方式
world_size(int, optional): 参与这个工作的进程数
rank(int,optional): 当前进程的rank
group_name(str,optional): 用来标记这组进程名的
其中初始化方式有三种:
TCP initialization
tcp:// IP组播(要求所有进程都在同一个网络中)比较好理解, 以TCP协议的方式进行不同分布式进程之间的数据交流,需要设置一个端口,不同进程之间公用这一个端口,并且设置host的级别和host的数量。设计两个参数rank和world_size。其中rank为host的编号,默认0为主机,端口应该位于该主机上。world_size为分布式主机的个数。
具体的可以初始化为:tcp://127.0.0.1:12345
Shared file-system initialization
file:// 共享文件系统(要求所有进程可以访问单个文件系统)有共享文件系统可以选择
提供的第二种方式是文件共享,机器有共享的文件系统,故可以采用这种方式,也避免了基于TCP的网络传输。这里使用方式是使用绝对路径在指定一个共享文件系统下不存在的文件。
具体的:file://PathToShareFile/MultiNode
Environment variable initialization
env:// 环境变量(需要您手动分配等级并知道所有进程可访问节点的地址)默认是这个
代码语言:
javascript
复制
MASTER_PORT - required; has to be a free port on machine with rank 0
MASTER_ADDR - required (except for rank 0); address of rank 0 node
WORLD_SIZE - required; can be set either here, or in a call to init function
RANK - required; can be set either here, or in a call to init function
官方示例:
代码语言:
javascript
复制
Node 1: (IP: 192.168.1.1, and has a free port: 1234)
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=0 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
Node 2:
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=1 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
在代码中进行初始化时,需要注意的一点是由于需要创建N个进程分别运行在0到N-1号GPU上,因此需要在代码中手动进行指定代码运行的GPU号,使用如下代码:
代码语言:
javascript
复制
torch.cuda.set_device(i)
其中i是0到N-1中的一个。同时在代码中也应该做如下的指定操作:
代码语言:
javascript
复制
torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...')
model = DistributedDataParallel(model, device_ids=[i], output_device=i)
在torch.distributed.init_process_group()中word_size与rank参数是必需的。代表了工作的进程数与当前进程的rank。接下来可以启动进行分布式训练,官方也提供了相应的启动方式。
启动方式
在torch.distributed当中提供了一个用于启动的程序torch.distributed.launch,此帮助程序可用于为每个节点启动多个进程以进行分布式训练,它在每个训练节点上产生多个分布式训练进程。这个工具可以用作CPU或者GPU,如果被用于GPU,每个GPU产生一个进程进行训练。
该工具既可以用来做单节点多GPU训练,也可用于多节点多GPU训练。如果是单节点多GPU,将会在单个GPU上运行一个分布式进程,据称可以非常好地改进单节点训练性能。如果用于多节点分布式训练,则通过在每个节点上产生多个进程来获得更好的多节点分布式训练性能。如果有Infiniband接口则加速比会更高。
在单节点分布式训练或多节点分布式训练的两种情况下,该工具将为每个节点启动给定数量的进程(–nproc_per_node)。如果用于GPU培训,则此数字需要小于或等于当前系统上的GPU数量(nproc_per_node),并且每个进程将在从GPU 0到GPU(nproc_per_node - 1)的单个GPU上运行。
启动的命令为:
代码语言:
javascript
复制
python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
YOUR_TRAINING_SCRIPT.py (–arg1 --arg2 --arg3 and all other
arguments of your training script
注意 使用启动工具进行启动时,会产生--local_rank参数,需要在代码中使用如下类似代码处理:
代码语言:
javascript
复制
import argparser
parser = argparse.ArgumentParser()
parser.add_argument('--local_rank', type=int, ...)
args = parser..parse_args()
这一参数的作用是为各个进程分配rank号,因此可以直接使用这个local_rank参数作为torch.distributed.init_process_group()当中的参数rank,同时也可以作为
代码语言:
javascript
复制
torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...')
model = DistributedDataParallel(model, device_ids=[i], output_device=i)
多机使用多个GPU
相比于单机使用多个GPu,最大的区别在于启动方式的不同,假设有两个节点时:
Node 1: (IP: 192.168.1.1, and has a free port: 1234)
代码语言:
javascript
复制
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=0 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
代码语言:
javascript
复制
Node 2:
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=1 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
增加的参数有nnodes代表机器即节点的个数,node_rank代表节点的rank,master-addr,master_port代表主节点的地址与端口号用于通信。至此就介绍完了pytorch的分布式训练的基础内容。
本文参与
腾讯云自媒体同步曝光计划
,分享自作者个人站点/博客。
原始发表:2020/01/14 ,如有侵权请联系
cloudcommunity@tencent.com
删除 |
| Markdown | [狼啸风云](https://cloud.tencent.com/developer/user/4464657)
## PyTorch分布式训练简介
关注作者
[*腾讯云*](https://cloud.tencent.com/?from=20060&from_column=20060)
[*开发者社区*](https://cloud.tencent.com/developer)
[文档](https://cloud.tencent.com/document/product?from=20702&from_column=20702)[建议反馈](https://cloud.tencent.com/voc/?from=20703&from_column=20703)[控制台](https://console.cloud.tencent.com/?from=20063&from_column=20063)
登录/注册
[首页](https://cloud.tencent.com/developer)
学习
活动
专区
圈层
工具
[MCP广场](https://cloud.tencent.com/developer/mcp)
文章/答案/技术大牛
搜索
搜索
关闭
发布
狼啸风云
[社区首页](https://cloud.tencent.com/developer) \>[专栏](https://cloud.tencent.com/developer/column) \>PyTorch分布式训练简介
# PyTorch分布式训练简介

狼啸风云
关注
修改于 2022-09-03 19:12:28
修改于 2022-09-03 19:12:28
5\.3K
0
举报
文章被收录于专栏:[计算机视觉理论及其实现](https://cloud.tencent.com/developer/column/74199)[计算机视觉理论及其实现]()
#### PyTorch分布式训练
分布式训练已经成为如今训练深度学习模型的一个必备工具,但pytorch默认使用单个GPU进行训练,如果想用使用多个GPU乃至多个含有多块GPU的节点进行分布式训练的时候,需要在代码当中进行修改,这里总结一下几种使用pytorch进行分布式训练的方式。
#### 环境
本文使用的环境为:
- python =3.7
- pytorch = 1.0
- CUDA = 8.0
#### 使用单个GPU
pytorch中pytorch.cuda用于设置和运行CUDA操作,它会跟踪当前选定的GPU,并且您分配的所有CUDA张量将默认在该设备上创建。所选设备可以使用 torch.cuda.device 环境管理器进行更改。 pytorch中想要使用GPU进行模型训练非常简单,首先需要使用代码torch.cuda.is\_available()判断当前环境是否可以使用GPU,如果返回False那么证明GPU不可用,需要检查软件包或驱动等是否安装正确。 当GPU可用时,可以使用torch.device()创建一个torch.device对象,例如torch.device('cuda')或使用torch.device('cuda:0')指定GPU,该对象可以将张量移动至GPU上。假设有一个张量x,我们可以使用x.cuda()或x.to(device)的方式将其移动至GPU上,这两种方式可以视作是等价的,并没有太大的区别,Variable与模型同理,也可以使用这样的方式进行移动。接下来按照征程的操作即可以进行训练。
#### 单机使用多个GPU
单机使用多个GPU有两种方式,torch.nn.DataParallel()与torch.nn.parallel.DistributedDataParallel 其中torch.nn.DataParallel()只能实现在单机多卡中进行分布式训练,而torch.nn.parallel.DistributedDataParallel则是新方法,在单机多卡和多机多卡都可以训练。官方建议使用最新的torch.nn.parallel.DistributedDataParallel,因为即使在单机多卡上,新的方法在效率上也要比旧的表现好。
代码语言:javascript
复制
```
torch.nn.DataParallel()
```
使用该方法的方式很简单,假设我们已经构建了一个模型NET,则只需要:
代码语言:javascript
复制
```
model = NET()
model = torch.nn.DataParallel()
mode.cuda()
```
将模型分发到各个GPU上,接下来既可以使用多个GPU同时进行训练。
值得注意的是,这里torch是把模型输入的batch\_size按照GPU的个数进行均分,因此如果希望保持与单个GPU训练时同样的batch\_sizze则需要按照GPU的个数n对batch\_size进行扩展到batch\_size \*n。
还有一点是torch默认输入的第一维是batch\_size的大小,因此会直接在第一维上进行分割,因此构造batch数据时需要注意。
代码语言:javascript
复制
```
torch.nn.parallel.DistributedDataParallel()
```
torch.nn.parallel.DistributedDataParallel是pytorch1.0新提供的方法。该计算模型并没有采用主流的Parameter Server结构,而是直接用了Uber Horovod的形式,也是百度开源的RingAllReduce算法。算法细节此处不表。 使用该方法首先需要进行初始化torch.distributed.init\_process\_group(backend, init\_method='env://', \*\*kwargs),其中的参数有:
代码语言:javascript
复制
```
backend(str): 后端选择,包括 gloo,nccl,mpi
init_method(str,optional): 用来初始化包的URL, 我理解是一个用来做并发控制的共享方式
world_size(int, optional): 参与这个工作的进程数
rank(int,optional): 当前进程的rank
group_name(str,optional): 用来标记这组进程名的
```
其中初始化方式有三种:
- TCP initialization
tcp:// IP组播(要求所有进程都在同一个网络中)比较好理解, 以TCP协议的方式进行不同分布式进程之间的数据交流,需要设置一个端口,不同进程之间公用这一个端口,并且设置host的级别和host的数量。设计两个参数rank和world\_size。其中rank为host的编号,默认0为主机,端口应该位于该主机上。world\_size为分布式主机的个数。 具体的可以初始化为:tcp://127.0.0.1:12345
- Shared file-system initialization
file:// 共享文件系统(要求所有进程可以访问单个文件系统)有共享文件系统可以选择 提供的第二种方式是文件共享,机器有共享的文件系统,故可以采用这种方式,也避免了基于TCP的网络传输。这里使用方式是使用绝对路径在指定一个共享文件系统下不存在的文件。 具体的:file://PathToShareFile/MultiNode
- Environment variable initialization
env:// 环境变量(需要您手动分配等级并知道所有进程可访问节点的地址)默认是这个
代码语言:javascript
复制
```
MASTER_PORT - required; has to be a free port on machine with rank 0
MASTER_ADDR - required (except for rank 0); address of rank 0 node
WORLD_SIZE - required; can be set either here, or in a call to init function
RANK - required; can be set either here, or in a call to init function
```
官方示例:
代码语言:javascript
复制
```
Node 1: (IP: 192.168.1.1, and has a free port: 1234)
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=0 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
Node 2:
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=1 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
```
在代码中进行初始化时,需要注意的一点是由于需要创建N个进程分别运行在0到N-1号GPU上,因此需要在代码中手动进行指定代码运行的GPU号,使用如下代码:
代码语言:javascript
复制
```
torch.cuda.set_device(i)
```
其中i是0到N-1中的一个。同时在代码中也应该做如下的指定操作:
代码语言:javascript
复制
```
torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...')
model = DistributedDataParallel(model, device_ids=[i], output_device=i)
```
在torch.distributed.init\_process\_group()中word\_size与rank参数是必需的。代表了工作的进程数与当前进程的rank。接下来可以启动进行分布式训练,官方也提供了相应的启动方式。
#### 启动方式
在torch.distributed当中提供了一个用于启动的程序torch.distributed.launch,此帮助程序可用于为每个节点启动多个进程以进行分布式训练,它在每个训练节点上产生多个分布式训练进程。这个工具可以用作CPU或者GPU,如果被用于GPU,每个GPU产生一个进程进行训练。
该工具既可以用来做单节点多GPU训练,也可用于多节点多GPU训练。如果是单节点多GPU,将会在单个GPU上运行一个分布式进程,据称可以非常好地改进单节点训练性能。如果用于多节点分布式训练,则通过在每个节点上产生多个进程来获得更好的多节点分布式训练性能。如果有Infiniband接口则加速比会更高。
在单节点分布式训练或多节点分布式训练的两种情况下,该工具将为每个节点启动给定数量的进程(–nproc\_per\_node)。如果用于GPU培训,则此数字需要小于或等于当前系统上的GPU数量(nproc\_per\_node),并且每个进程将在从GPU 0到GPU(nproc\_per\_node - 1)的单个GPU上运行。 启动的命令为:
代码语言:javascript
复制
```
python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
YOUR_TRAINING_SCRIPT.py (–arg1 --arg2 --arg3 and all other
arguments of your training script
```
注意 使用启动工具进行启动时,会产生--local\_rank参数,需要在代码中使用如下类似代码处理:
代码语言:javascript
复制
```
import argparser
parser = argparse.ArgumentParser()
parser.add_argument('--local_rank', type=int, ...)
args = parser..parse_args()
```
这一参数的作用是为各个进程分配rank号,因此可以直接使用这个local\_rank参数作为torch.distributed.init\_process\_group()当中的参数rank,同时也可以作为
代码语言:javascript
复制
```
torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...')
model = DistributedDataParallel(model, device_ids=[i], output_device=i)
```
#### 多机使用多个GPU
相比于单机使用多个GPu,最大的区别在于启动方式的不同,假设有两个节点时: Node 1: (IP: 192.168.1.1, and has a free port: 1234)
代码语言:javascript
复制
```
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=0 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
```
代码语言:javascript
复制
```
Node 2:
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=1 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
```
增加的参数有nnodes代表机器即节点的个数,node\_rank代表节点的rank,master-addr,master\_port代表主节点的地址与端口号用于通信。至此就介绍完了pytorch的分布式训练的基础内容。
本文参与 [腾讯云自媒体同步曝光计划](https://cloud.tencent.com/developer/support-plan),分享自作者个人站点/博客。
原始发表:2020/01/14 ,如有侵权请联系 [cloudcommunity@tencent.com](mailto:cloudcommunity@tencent.com) 删除
前往查看
[分布式](https://cloud.tencent.com/developer/tag/10668)
[pytorch](https://cloud.tencent.com/developer/tag/10735)
[node.js](https://cloud.tencent.com/developer/tag/10200)
本文分享自 作者个人站点/博客 前往查看
如有侵权,请联系 [cloudcommunity@tencent.com](mailto:cloudcommunity@tencent.com) 删除。
本文参与 [腾讯云自媒体同步曝光计划](https://cloud.tencent.com/developer/support-plan) ,欢迎热爱写作的你一起参与!
[分布式](https://cloud.tencent.com/developer/tag/10668)
[pytorch](https://cloud.tencent.com/developer/tag/10735)
[node.js](https://cloud.tencent.com/developer/tag/10200)
评论
登录后参与评论
0 条评论
热度
最新
登录 后参与评论
推荐阅读
目录
- PyTorch分布式训练
- 环境
- 使用单个GPU
- 单机使用多个GPU
- 启动方式
- 多机使用多个GPU
领券
- ### 社区
- [技术文章](https://cloud.tencent.com/developer/column)
- [技术问答](https://cloud.tencent.com/developer/ask)
- [技术沙龙](https://cloud.tencent.com/developer/salon)
- [技术视频](https://cloud.tencent.com/developer/video)
- [学习中心](https://cloud.tencent.com/developer/learning)
- [技术百科](https://cloud.tencent.com/developer/techpedia)
- [技术专区](https://cloud.tencent.com/developer/zone/list)
- ### 活动
- [自媒体同步曝光计划](https://cloud.tencent.com/developer/support-plan)
- [邀请作者入驻](https://cloud.tencent.com/developer/support-plan-invitation)
- [自荐上首页](https://cloud.tencent.com/developer/article/1535830)
- [技术竞赛](https://cloud.tencent.com/developer/competition)
- ### 圈层
- [腾讯云最具价值专家](https://cloud.tencent.com/tvp)
- [腾讯云架构师技术同盟](https://cloud.tencent.com/developer/program/tm)
- [腾讯云创作之星](https://cloud.tencent.com/developer/program/tci)
- [腾讯云TDP](https://cloud.tencent.com/developer/program/tdp)
- ### 关于
- [社区规范](https://cloud.tencent.com/developer/article/1006434)
- [免责声明](https://cloud.tencent.com/developer/article/1006435)
- [联系我们](mailto:cloudcommunity@tencent.com)
- [友情链接](https://cloud.tencent.com/developer/friendlink)
- [MCP广场开源版权声明](https://cloud.tencent.com/developer/article/2537547)
### 腾讯云开发者

扫码关注腾讯云开发者
领取腾讯云代金券
### 热门产品
- [域名注册](https://cloud.tencent.com/product/domain?from=20064&from_column=20064)
- [云服务器](https://cloud.tencent.com/product/cvm?from=20064&from_column=20064)
- [区块链服务](https://cloud.tencent.com/product/tbaas?from=20064&from_column=20064)
- [消息队列](https://cloud.tencent.com/product/message-queue-catalog?from=20064&from_column=20064)
- [网络加速](https://cloud.tencent.com/product/ecdn?from=20064&from_column=20064)
- [云数据库](https://cloud.tencent.com/product/tencentdb-catalog?from=20064&from_column=20064)
- [域名解析](https://cloud.tencent.com/product/dns?from=20064&from_column=20064)
- [云存储](https://cloud.tencent.com/product/cos?from=20064&from_column=20064)
- [视频直播](https://cloud.tencent.com/product/css?from=20064&from_column=20064)
### 热门推荐
- [人脸识别](https://cloud.tencent.com/product/facerecognition?from=20064&from_column=20064)
- [腾讯会议](https://cloud.tencent.com/product/tm?from=20064&from_column=20064)
- [企业云](https://cloud.tencent.com/act/pro/enterprise2022?from=20064&from_column=20064)
- [CDN加速](https://cloud.tencent.com/product/cdn?from=20064&from_column=20064)
- [视频通话](https://cloud.tencent.com/product/trtc?from=20064&from_column=20064)
- [图像分析](https://cloud.tencent.com/product/imagerecognition?from=20064&from_column=20064)
- [MySQL 数据库](https://cloud.tencent.com/product/cdb?from=20064&from_column=20064)
- [SSL 证书](https://cloud.tencent.com/product/ssl?from=20064&from_column=20064)
- [语音识别](https://cloud.tencent.com/product/asr?from=20064&from_column=20064)
### 更多推荐
- [数据安全](https://cloud.tencent.com/solution/data_protection?from=20064&from_column=20064)
- [负载均衡](https://cloud.tencent.com/product/clb?from=20064&from_column=20064)
- [短信](https://cloud.tencent.com/product/sms?from=20064&from_column=20064)
- [文字识别](https://cloud.tencent.com/product/ocr?from=20064&from_column=20064)
- [云点播](https://cloud.tencent.com/product/vod?from=20064&from_column=20064)
- [大数据](https://cloud.tencent.com/product/bigdata-class?from=20064&from_column=20064)
- [小程序开发](https://cloud.tencent.com/solution/la?from=20064&from_column=20064)
- [网站监控](https://cloud.tencent.com/product/tcop?from=20064&from_column=20064)
- [数据迁移](https://cloud.tencent.com/product/cdm?from=20064&from_column=20064)
Copyright © 2013 - 2026 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
[深圳市腾讯计算机系统有限公司](https://qcloudimg.tencent-cloud.cn/raw/986376a919726e0c35e96b311f54184d.jpg) ICP备案/许可证号:[粤B2-20090059](https://beian.miit.gov.cn/#/Integrated/index) [粤公网安备44030502008569号](https://beian.mps.gov.cn/#/query/webSearch?code=44030502008569)
[腾讯云计算(北京)有限责任公司](https://qcloudimg.tencent-cloud.cn/raw/a2390663ee4a95ceeead8fdc34d4b207.jpg) 京ICP证150476号 \| [京ICP备11018762号](https://beian.miit.gov.cn/#/Integrated/index)
[问题归档](https://cloud.tencent.com/developer/ask/archives.html)[专栏文章](https://cloud.tencent.com/developer/column/archives.html)[快讯文章归档](https://cloud.tencent.com/developer/news/archives.html)[关键词归档](https://cloud.tencent.com/developer/information/all.html)[开发者手册归档](https://cloud.tencent.com/developer/devdocs/archives.html)[开发者手册 Section 归档](https://cloud.tencent.com/developer/devdocs/sections_p1.html)
Copyright © 2013 - 2026 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有
登录 后参与评论
0
0
0
推荐 |
| Readable Markdown | #### PyTorch分布式训练
分布式训练已经成为如今训练深度学习模型的一个必备工具,但pytorch默认使用单个GPU进行训练,如果想用使用多个GPU乃至多个含有多块GPU的节点进行分布式训练的时候,需要在代码当中进行修改,这里总结一下几种使用pytorch进行分布式训练的方式。
#### 环境
本文使用的环境为:
- python =3.7
- pytorch = 1.0
- CUDA = 8.0
#### 使用单个GPU
pytorch中pytorch.cuda用于设置和运行CUDA操作,它会跟踪当前选定的GPU,并且您分配的所有CUDA张量将默认在该设备上创建。所选设备可以使用 torch.cuda.device 环境管理器进行更改。 pytorch中想要使用GPU进行模型训练非常简单,首先需要使用代码torch.cuda.is\_available()判断当前环境是否可以使用GPU,如果返回False那么证明GPU不可用,需要检查软件包或驱动等是否安装正确。 当GPU可用时,可以使用torch.device()创建一个torch.device对象,例如torch.device('cuda')或使用torch.device('cuda:0')指定GPU,该对象可以将张量移动至GPU上。假设有一个张量x,我们可以使用x.cuda()或x.to(device)的方式将其移动至GPU上,这两种方式可以视作是等价的,并没有太大的区别,Variable与模型同理,也可以使用这样的方式进行移动。接下来按照征程的操作即可以进行训练。
#### 单机使用多个GPU
单机使用多个GPU有两种方式,torch.nn.DataParallel()与torch.nn.parallel.DistributedDataParallel 其中torch.nn.DataParallel()只能实现在单机多卡中进行分布式训练,而torch.nn.parallel.DistributedDataParallel则是新方法,在单机多卡和多机多卡都可以训练。官方建议使用最新的torch.nn.parallel.DistributedDataParallel,因为即使在单机多卡上,新的方法在效率上也要比旧的表现好。
代码语言:javascript
复制
```
torch.nn.DataParallel()
```
使用该方法的方式很简单,假设我们已经构建了一个模型NET,则只需要:
代码语言:javascript
复制
```
model = NET()
model = torch.nn.DataParallel()
mode.cuda()
```
将模型分发到各个GPU上,接下来既可以使用多个GPU同时进行训练。
值得注意的是,这里torch是把模型输入的batch\_size按照GPU的个数进行均分,因此如果希望保持与单个GPU训练时同样的batch\_sizze则需要按照GPU的个数n对batch\_size进行扩展到batch\_size \*n。
还有一点是torch默认输入的第一维是batch\_size的大小,因此会直接在第一维上进行分割,因此构造batch数据时需要注意。
代码语言:javascript
复制
```
torch.nn.parallel.DistributedDataParallel()
```
torch.nn.parallel.DistributedDataParallel是pytorch1.0新提供的方法。该计算模型并没有采用主流的Parameter Server结构,而是直接用了Uber Horovod的形式,也是百度开源的RingAllReduce算法。算法细节此处不表。 使用该方法首先需要进行初始化torch.distributed.init\_process\_group(backend, init\_method='env://', \*\*kwargs),其中的参数有:
代码语言:javascript
复制
```
backend(str): 后端选择,包括 gloo,nccl,mpi
init_method(str,optional): 用来初始化包的URL, 我理解是一个用来做并发控制的共享方式
world_size(int, optional): 参与这个工作的进程数
rank(int,optional): 当前进程的rank
group_name(str,optional): 用来标记这组进程名的
```
其中初始化方式有三种:
- TCP initialization
tcp:// IP组播(要求所有进程都在同一个网络中)比较好理解, 以TCP协议的方式进行不同分布式进程之间的数据交流,需要设置一个端口,不同进程之间公用这一个端口,并且设置host的级别和host的数量。设计两个参数rank和world\_size。其中rank为host的编号,默认0为主机,端口应该位于该主机上。world\_size为分布式主机的个数。 具体的可以初始化为:tcp://127.0.0.1:12345
- Shared file-system initialization
file:// 共享文件系统(要求所有进程可以访问单个文件系统)有共享文件系统可以选择 提供的第二种方式是文件共享,机器有共享的文件系统,故可以采用这种方式,也避免了基于TCP的网络传输。这里使用方式是使用绝对路径在指定一个共享文件系统下不存在的文件。 具体的:file://PathToShareFile/MultiNode
- Environment variable initialization
env:// 环境变量(需要您手动分配等级并知道所有进程可访问节点的地址)默认是这个
代码语言:javascript
复制
```
MASTER_PORT - required; has to be a free port on machine with rank 0
MASTER_ADDR - required (except for rank 0); address of rank 0 node
WORLD_SIZE - required; can be set either here, or in a call to init function
RANK - required; can be set either here, or in a call to init function
```
官方示例:
代码语言:javascript
复制
```
Node 1: (IP: 192.168.1.1, and has a free port: 1234)
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=0 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
Node 2:
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=1 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
```
在代码中进行初始化时,需要注意的一点是由于需要创建N个进程分别运行在0到N-1号GPU上,因此需要在代码中手动进行指定代码运行的GPU号,使用如下代码:
代码语言:javascript
复制
```
torch.cuda.set_device(i)
```
其中i是0到N-1中的一个。同时在代码中也应该做如下的指定操作:
代码语言:javascript
复制
```
torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...')
model = DistributedDataParallel(model, device_ids=[i], output_device=i)
```
在torch.distributed.init\_process\_group()中word\_size与rank参数是必需的。代表了工作的进程数与当前进程的rank。接下来可以启动进行分布式训练,官方也提供了相应的启动方式。
#### 启动方式
在torch.distributed当中提供了一个用于启动的程序torch.distributed.launch,此帮助程序可用于为每个节点启动多个进程以进行分布式训练,它在每个训练节点上产生多个分布式训练进程。这个工具可以用作CPU或者GPU,如果被用于GPU,每个GPU产生一个进程进行训练。
该工具既可以用来做单节点多GPU训练,也可用于多节点多GPU训练。如果是单节点多GPU,将会在单个GPU上运行一个分布式进程,据称可以非常好地改进单节点训练性能。如果用于多节点分布式训练,则通过在每个节点上产生多个进程来获得更好的多节点分布式训练性能。如果有Infiniband接口则加速比会更高。
在单节点分布式训练或多节点分布式训练的两种情况下,该工具将为每个节点启动给定数量的进程(–nproc\_per\_node)。如果用于GPU培训,则此数字需要小于或等于当前系统上的GPU数量(nproc\_per\_node),并且每个进程将在从GPU 0到GPU(nproc\_per\_node - 1)的单个GPU上运行。 启动的命令为:
代码语言:javascript
复制
```
python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
YOUR_TRAINING_SCRIPT.py (–arg1 --arg2 --arg3 and all other
arguments of your training script
```
注意 使用启动工具进行启动时,会产生--local\_rank参数,需要在代码中使用如下类似代码处理:
代码语言:javascript
复制
```
import argparser
parser = argparse.ArgumentParser()
parser.add_argument('--local_rank', type=int, ...)
args = parser..parse_args()
```
这一参数的作用是为各个进程分配rank号,因此可以直接使用这个local\_rank参数作为torch.distributed.init\_process\_group()当中的参数rank,同时也可以作为
代码语言:javascript
复制
```
torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...')
model = DistributedDataParallel(model, device_ids=[i], output_device=i)
```
#### 多机使用多个GPU
相比于单机使用多个GPu,最大的区别在于启动方式的不同,假设有两个节点时: Node 1: (IP: 192.168.1.1, and has a free port: 1234)
代码语言:javascript
复制
```
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=0 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
```
代码语言:javascript
复制
```
Node 2:
>>> python -m torch.distributed.launch --nproc_per_node=NUM_GPUS_YOU_HAVE
--nnodes=2 --node_rank=1 --master_addr="192.168.1.1"
--master_port=1234 YOUR_TRAINING_SCRIPT.py (--arg1 --arg2 --arg3
and all other arguments of your training script)
```
增加的参数有nnodes代表机器即节点的个数,node\_rank代表节点的rank,master-addr,master\_port代表主节点的地址与端口号用于通信。至此就介绍完了pytorch的分布式训练的基础内容。
本文参与 [腾讯云自媒体同步曝光计划](https://cloud.tencent.com/developer/support-plan),分享自作者个人站点/博客。
原始发表:2020/01/14 ,如有侵权请联系 [cloudcommunity@tencent.com](mailto:cloudcommunity@tencent.com) 删除 |
| Shard | 50 (laksa) |
| Root Hash | 6417570461941030050 |
| Unparsed URL | com,tencent!cloud,/developer/article/1582972 s443 |