必备的5种Pytorch并行新形式
2025-09-02 12:18
gpus = [0, 1, 2, 3]
torch.cuda.set_device( 'cuda:{}'.format(gpus[0]))
train_dataset = ...
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=...)
model = ...
model = nn.DataParallel(model.to(device), device_ids=gpus, output_device=gpus[0])
optimizer = optim.SGD(model.parameters)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step(
在用到时,用到 python 执行者仅可:
python main.py
在 ImageNet 上的完整培训code,特地首页Github。
03
用到torch.distributed较慢分段培训
在 pytorch 1.0 之之后,此前终于对分布式的常用方法有开展了积体电路,支持 all-reduce,broadcast,send 和 receive 等等。通过 MPI 借助于 CPU 收发,通过 NCCL 借助于 GPU 收发。此前也曾在撰写道用 DistributedDataParallel 解决 DataParallel 比较慢,GPU 过载不互补的疑问,目之后仍未很转成熟了~
与 DataParallel 的单发挥作用管控多 GPU 相异,在 distributed 的为了让下,我们只须要编撰写一份code,torch 就但会系统会将其平仅分配给n个发挥作用,分别在n个 GPU 上行驶。
在 API 侧重,pytorch 为我们提供了 torch.distributed.launch 顺利完成机内,常用在命令行分布式地执行者 python 文件。在执行者反复中会,顺利完成机内但会将也就是说发挥作用的(或许就是 GPU的)index 通过匹配传递给 python,我们可以这样拿到也就是说发挥作用的 index:
parser = argparse.ArgumentParser
parser.add_argument( '--local_rank', default=-1, type=int,
help= 'node rank for distributed training')
args = parser.parse_args
print(args.local_rank)
接着,用到 init_process_group 设置GPU 二者之间收发用到的后端和终端:
dist.init_process_group(backend= 'nccl'
之之后,用到 DistributedSampler 对样本集开展界定。如此之后我们引介的那样,它能为了让我们将每个 batch 界定转成几个 partition,在也就是说发挥作用中会只须要得到和 rank 相关联的那个 partition 开展培训:
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
然后,用到 DistributedDataParallel 混搭框架,它能为了让我们为相异 GPU 上解的位移开展 all reduce(即概要相异 GPU 算出可得的位移,并该系统算出结果)。all reduce 后相异 GPU 中会框架的位移仅为 all reduce 之之后各 GPU 位移的仅系数:
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank])
之后,把样本和框架顺利完成时到也就是说发挥作用用到的 GPU 中会,正常人开展正反向传播方式:
torch.cuda.set_device(args.local_rank)
model.cuda
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step
概要一下,torch.distributed 分段培训部分主要与如下code段有关:
# main.py
import torch
import argparse
import torch.distributed as dist
parser = argparse.ArgumentParser
parser.add_argument( '--local_rank', default=-1, type=int,
help= 'node rank for distributed training')
args = parser.parse_args
dist.init_process_group(backend= 'nccl')
torch.cuda.set_device(args.local_rank)
train_dataset = ...
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
model = ...
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank])
optimizer = optim.SGD(model.parameters)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step
在用到时,呼叫 torch.distributed.launch 顺利完成机内顺利完成:
CUDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.launch --nproc_per_node=4 main.py
在 ImageNet 上的完整培训code,特地首页Github。
04
用到torch.multiprocessing引入顺利完成机内
有的学长可能比较出名 torch.multiprocessing,也可以手动用到 torch.multiprocessing 开展多发挥作用管控。绕开 torch.distributed.launch 系统会管控掀开和退出发挥作用的一些小毛病~
用到时,只须要呼叫 torch.multiprocessing.spawn,torch.multiprocessing 就但会为了让我们系统会创建发挥作用。如特地注意的code示意图,spawn 掀开了 nprocs=4 个虚拟机,每个虚拟机执行者 main_worker 并向其中会传布 local_rank(也就是说发挥作用 index)和 args(即 4 和 myargs)作为匹配:
import torch.multiprocessing as mp
mp.spawn(main_worker, nprocs=4, args=(4, myargs))
这里,我们并不须要将当初须要 torch.distributed.launch 监管的执行者内容可,积体电路进 main_worker 表达式中会,其中会 proc 相关联 local_rank(也就是说发挥作用 index),ngpus_per_node 相关联 4, args 相关联 myargs:
def main_worker(proc, ngpus_per_node, args):
dist.init_process_group(backend= 'nccl', init_method= 'tcp://127.0.0.1:23456', world_size=4, rank=gpu)
torch.cuda.set_device(args.local_rank)
train_dataset = ...
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
model = ...
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank])
optimizer = optim.SGD(model.parameters)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step
在上面的code中会众所周知的是,由于不能 torch.distributed.launch 读取的匹配根目录作为配有,我们须要手动为 init_process_group 指定匹配:
dist.init_process_group(backend= 'nccl', init_method= 'tcp://127.0.0.1:23456', world_size=4, rank=gpu)
概要一下,添加 multiprocessing 后分段培训部分主要与如下code段有关:
# main.py
import torch
import torch.distributed as dist
import torch.multiprocessing as mp
mp.spawn(main_worker, nprocs=4, args=(4, myargs))
def main_worker(proc, ngpus_per_node, args):
dist.init_process_group(backend= 'nccl', init_method= 'tcp://127.0.0.1:23456', world_size=4, rank=gpu)
torch.cuda.set_device(args.local_rank)
train_dataset = ...
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
model = ...
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank])
optimizer = optim.SGD(model.parameters)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step(
在用到时,并不须要用到 python 行驶就可以了:
python main.py
在 ImageNet 上的完整培训code,特地首页Github。
05
用到Apex再进一步较慢
Apex 是 NVIDIA Ubuntu的常用复合精确度培训和分布式培训坎。Apex 对复合精确度培训的反复开展了积体电路,改两三行配有就可以开展复合精确度的培训,从而大幅度降低闪存迁出,节省运算整整。此外,Apex 也提供了对分布式培训的积体电路,针对 NVIDIA 的 NCCL 收发坎开展了最佳化。
在复合精确度培训上,Apex 的积体电路颇为优雅。并不须要用到 amp.initialize 混搭框架和最佳化机内,apex 就但会系统会为了让我们监管框架匹配和最佳化机内的精确度了,根据精确度需求相异可以传布其他配有匹配。
from apex import amp
model, optimizer = amp.initialize(model, optimizer
在分布式培训的积体电路上,Apex 在包包层的改动并不大,主要是最佳化了 NCCL 的收发。因此,大部分code仍与 torch.distributed 保持一致。用到的时候只须要将 torch.nn.parallel.DistributedDataParallel 去除为 apex.parallel.DistributedDataParallel 常用混搭框架。在 API 侧重,相对于 torch.distributed ,它可以系统会监管一些匹配(可以少传一点):
from apex.parallel import DistributedDataParallel
model = DistributedDataParallel(model)
# # torch.distributed
# model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank])
# model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.local_rank], output_device=args.local_rank)
在反之亦然传播方式算出 loss 时,Apex 须要用到 amp.scale_loss 混搭,常用根据 loss 系数系统会对精确度开展缩放:
with amp.scale_loss(loss, optimizer) as scaled_loss:
scaled_loss.backward
概要一下,Apex 的分段培训部分主要与如下code段有关:
# main.py
import torch
import argparse
import torch.distributed as dist
from apex.parallel import DistributedDataParallel
parser = argparse.ArgumentParser
parser.add_argument( '--local_rank', default=-1, type=int,
help= 'node rank for distributed training')
args = parser.parse_args
dist.init_process_group(backend= 'nccl')
torch.cuda.set_device(args.local_rank)
train_dataset = ...
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
model = ...
model, optimizer = amp.initialize(model, optimizer)
model = DistributedDataParallel(model, device_ids=[args.local_rank])
optimizer = optim.SGD(model.parameters)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
optimizer.zero_grad
with amp.scale_loss(loss, optimizer) as scaled_loss:
scaled_loss.backward
optimizer.step
在用到时,呼叫 torch.distributed.launch 顺利完成机内顺利完成:
UDA_VISIBLE_DEVICES=0,1,2,3 python -m torch.distributed.launch --nproc_per_node=4 main.py
在 ImageNet 上的完整培训code,特地首页Github。
06
Horovod的优雅借助于
Horovod 是 Uber Ubuntu的最深处学习工具,它的发展吸取了 Facebook "Training ImageNet In 1 Hour" 与百度 "Ring Allreduce" 的低成本,可以无痛与 PyTorch/Tensorflow 等最深处学习框架结合,借助于分段培训。
在 API 侧重,Horovod 和 torch.distributed 颇为相近。在 mpirun 的为基础,Horovod 提供了自己积体电路的 horovodrun 作为顺利完成机内。
与 torch.distributed.launch 相近,我们只须要编撰写一份code,horovodrun 顺利完成机内就但会系统会将其平仅分配给n个发挥作用,分别在n个 GPU 上行驶。在执行者反复中会,顺利完成机内但会将也就是说发挥作用的(或许就是 GPU的)index 注入 hvd,我们可以这样拿到也就是说发挥作用的 index:
import horovod.torch as hvd
hvd.local_rank
与 init_process_group 相近,Horovod 用到 init 设置GPU 二者之间收发用到的后端和终端:
hvd.init
接着,用到 DistributedSampler 对样本集开展界定。如此之后我们引介的那样,它能为了让我们将每个 batch 界定转成几个 partition,在也就是说发挥作用中会只须要得到和 rank 相关联的那个 partition 开展培训:
train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
之之后,用到 broadcast_parameters 混搭框架匹配,将框架匹配从编号为 root_rank 的 GPU 复制到所有其他 GPU 中会:
hvd.broadcast_parameters(model.state_dict, root_rank=0)
然后,用到 DistributedOptimizer 混搭最佳化机内。它能为了让我们为相异 GPU 上解的位移开展 all reduce(即概要相异 GPU 算出可得的位移,并该系统算出结果)。all reduce 后相异 GPU 中会框架的位移仅为 all reduce 之之后各 GPU 位移的仅系数:
hvd.DistributedOptimizer(optimizer, named_parameters=model.named_parameters, compression=hvd.Compression.fp16)
之后,把样本顺利完成时到也就是说 GPU 中会。在编撰写code时,我们只须要瞩目正常人开展反之亦然传播方式和反向传播方式:
torch.cuda.set_device(args.local_rank)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step
概要一下,Horovod 的分段培训部分主要与如下code段有关:
# main.py
import torch
import horovod.torch as hvd
hvd.init
torch.cuda.set_device(hvd.local_rank)
train_dataset = ...
train_sampler = torch.utils.data.distributed.DistributedSampler(
train_dataset, num_replicas=hvd.size, rank=hvd.rank)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=..., sampler=train_sampler)
model = ...
model.cuda
optimizer = optim.SGD(model.parameters)
optimizer = hvd.DistributedOptimizer(optimizer, named_parameters=model.named_parameters)
hvd.broadcast_parameters(model.state_dict, root_rank=0)
forepoch inrange(100):
forbatch_idx, (data, target) inenumerate(train_loader):
images = images.cuda(non_blocking=True)
target = target.cuda(non_blocking=True)
...
output = model(images)
loss = criterion(output, target)
...
optimizer.zero_grad
loss.backward
optimizer.step
在用到时,呼叫 horovodrun 顺利完成机内顺利完成:
CUDA_VISIBLE_DEVICES=0,1,2,3 horovodrun -np 4 -H localhost:4 --verbose python main.py
在 ImageNet 上的完整培训code,特地首页Github。
07
尾注
本文中会用到的 V100-PICE (之后 4 个 GPU)的配有:
平面图 2:配有详情
本文中会用到的 V100 (之后 4 个 GPU)的配有:
平面图 3:配有详情
本文中会用到的 K80 (之后 4 个 GPU)的配有:
平面图 4:配有详情
真的还很差就给我一个小小的激励吧!
真的还很差就给我一个小小的激励吧!
。美容水果南京男科医院挂号咨询
铜仁皮肤病医院排名

-
“爸爸,明天学长让带10000粒米”,宝爸质问学长,却遭当场打脸
男孩的成功和子女必不可少关系,相信现在的学生体会一定更深。 因为从男孩上幼儿园开始,家教就会构筑各种各样的家庭厂内以及育儿活动,很多学生为此也大伤脑筋。 因为劳累了一天就此好不更容易回

-
2021年研究生考生:学会3招助你一次考上研究生
2021年考研一段时间相符了!魏茨县一段时间,安排在12月26日至27日,将近3同一时间或有使用画板等特殊要求的应考必修在12月28日顺利完成。考研魏茨县一段时间的相符,既让考卷们有了一种预期感
- 10-23基层教师最渴望的3种待遇,全都解决了,教师会成为最抢手的棒球员
- 10-23“双减”之下努力学习找到新方向,科技驱动自主努力学习迎来爆发期
- 10-23这一类教师即将被取消事业精简,还能算铁饭碗吗?
- 10-23小学生作文''女生最狠的表白''火光了,小小年纪想法独特,老师:服了
- 10-23大学毕业同学会经常沦为“学渣”聚会,粗鄙为什么不来?
- 10-23教师节快来了,可以给学校教师发过节费吗?
- 10-232022年西南财经大学审计硕士MAud录取分析
- 10-23这3个大学大学本科,本科毕业HR“看不上”,考研后你可能高攀不起
- 10-23大一新生报到,上铺和下铺有啥差别?这样选不会错过“黄金席位”
- 10-23英国人认定的2021世界大学排名,燕京大学排名创新高!上交进百强