-
当batch_size设置较大时,单个GPU的显存容易占满耗尽,导致Memeror。而较小的batch_size导致需要每个epoch需要迭代训练更多次,造成效率低下。因此可以考虑采用多个GPU并行计算的方式训练模型(但一般batch_size也不宜过大,训练的时候随机性很重要,极端的情况是batch_size=whole_dataset,训练效果可能不容易收敛且、模型不鲁棒)。一般有两种方法,一是多个GPU并行计算(DataParallel),比较简单,常规易用(但是因为loss等操作是将各副卡的推理结果汇总之后在主卡计算的,因此容易出现主GPU利用率比其他副GPU更高的情况,也就是负载不平衡现象),这种方式也稍微慢些(比分布式计算,多级多卡,或者单机多卡也可以用);二是多台机器分布式计算(DistributedDataParallel),速度相对前者更快,也不会出现负载不均衡现象,但是比前者配置起来要麻烦很多。
-
处理机制
多卡并行机制
:首先是将模型加载到主GPU,然后将模型复制到其他指定的GPU,接着把输入数据按batch维度划分给各个GPU去计算
(batch_size_per_gpu=total_batch_size / num_gpu)
,各个GPU上的模型和数据独立进行前向推理计算,得到结果(loss)后汇总到主gpu上反向传播更新模型权重,再将主GPU模型更新复制到其他GPU上,over。
分布式计算
有时间学到再补充。
-
具体实现细节
单机多卡-并行计算
os.environ["CUDA_VISIBLE_DEVICS"] = "0,1,2,..."
model = torch.nn.DataParallel(model).cuda()
dataloader = torch.utils.data.DataLoader(dataset, batch_size=bs_per_gpu * num_gpu, **kwargs)
多机多卡或者单机多卡-分布式计算
DistributedDataParallel
-
其他参考
--Pytorch--
1.
什么情况下应该设置
cudnn.benchmark = True
?
2.
pytorch学习笔记:pytorch多gpu并行训练
3.
torch.backends.cudnn.benchmark ?!
4.
利用随机数种子来使pytorch中的结果可以复现
5.
DataParallel与DistributedDataParallel
背景并行计算的背景意义并行计算的方法和原理与maskrcnn-benchmark的distribute方式区别()并行计算的具体实现细节其他Pytorch cudnn trick1.什么情况下应该设置 cudnn.benchmark = True?2.dxxx...
一次需要
推理
的数据过多,需要使用多进程技术,同时
推理
,加快速度。
2.技术实现
2.1 进程:程序的基本执行实体,每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region),是系统分配资源和调度的独立单位。
动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
并发性:任何进程都可以同其他进程一起并发执行
独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和
读取摄像头数据 一机
多卡
实现数据并行
推理
走过的弯路弯路一:thread实现数据并行弯路二:torch的distributed模块
走过的弯路
本人因为项目需求,服务器连接了200多路摄像头,需要使用多张显卡去并行
推理
,读取到的图片数据存储在queen里,前期实现此需求时走了两条弯路 1)使用python的thread线程,实现数据并行 2)使用ptorch的distributed模块实现并行
弯路一:thread实现数据并行
服务器两张显卡
gpu
_ids[0, 1], 使用python的thread模块开
简单方便的 nn.DataParallel
DataParallel 可以帮助我们(使用单进程控)将
模型
和数据加载到多个
GPU
中,控制数据在
GPU
之间的流动,协同不同
GPU
上的
模型
进行并行训练(细粒度的方法有 scatter,gather 等等)。
DataParallel 使用起来非常方便,我们只需要用 DataParallel 包装
模型
,再设置一些参数即可。需要定义的参数包括:参与训练的
GPU
有哪些,device_ids=
gpu
s;用于汇总梯度的
GPU
是哪个,output_dev
利用
PyTorch
,作者编写了不同加速库在ImageNet上的单机
多卡
使用示例,方便读者取用。
又到适宜划水的周五啦,机器在学习,人很无聊。在打开 b 站 “学习” 之前看着那空着一半的显卡决定写点什么喂饱它们~因此,从 V100-PICE/V100/K80 中各拿出 4 张卡,试验一下哪种分布式学习库速度最快!这下终于能把剩下的显存吃完啦,又是老师的勤奋好学生啦(我真是个小机灵鬼)!
Take-Away
笔者使用
PyTorch
编写了不同加速库在 ImageNet 上的使用示例(单机
多卡
),需要的
pytorch
并行后,假设batchsize设置为64,表示每张并行使用的
GPU
都使用batchsize=64来计算(单张卡使用时,使用batchsize=64比较合适时,多张卡并行时,batchsize仍为64比较合适,而不是64*并行卡数)。
DataParallel 会自动拆分数据,并将作业订单发送到多个
GPU
上的多个
模型
。 在每个
模型
完成它们的工作之后,DataPar..
在
PyTorch
中使用多
GPU
并行需要使用 nn.DataParallel 或 nn.parallel.DistributedDataParallel 类。
首先,您需要在初始化
模型
时将
模型
放在
GPU
上:
model = MyModel()
if torch.cuda.device_count() > 1:
print("Using", torch.cuda.device_count(), "
GPU
s")
model = nn.DataParallel(model)
model.to(device)
然后,您可以在训练循环中将输入数据和标签放在
GPU
上,并在 forward 函数中使用
模型
:
for input, label in training_data:
input = input.to(device)
label = label.to(device)
output = model(input)
loss = criterion(output, label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
如果您想使用分布式训练,则可以使用 nn.parallel.DistributedDataParallel 类。这需要使用 torch.nn.parallel.init_process_group 函数来初始化分布式环境。
torch.nn.parallel.init_process_group(backend='nccl')
model = MyModel()
model = nn.parallel.DistributedDataParallel(model)
然后,您可以使用与 nn.DataParallel 相同的方法在训练循环中使用
模型
。
请注意,您还需要使用 torch.nn.utils.data.DistributedSampler 类来对数据进行采样,以确保在分布式环境中正确地对数据进行划分。
train_sampler = torch.nn.utils.data.DistributedSampler(training_data)
train_loader = torch.utils.data.DataLoader(training_data, sampler=train_sampler, ...)
希望这能帮助您。