pytorch指定用多张显卡训练_pytorch多gpu并行训练

本文详细介绍了如何在PyTorch中使用多GPU进行并行训练,包括单机多卡的DataParallel用法、显存平衡问题以及DistributedDataParallel的实现。此外,还探讨了多机多GPU训练的初始化、数据处理、模型处理和保存加载策略。通过示例代码,阐述了如何解决DataParallel导致的显存使用不平衡问题,并对比了DataParallel与DistributedDataParallel的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录目录

pytorch多gpu并行训练1.单机多卡并行训练1.1.torch.nn.DataParallel

1.2.如何平衡DataParallel带来的显存使用不平衡的问题

1.3.torch.nn.parallel.DistributedDataParallel

2.多机多gpu训练2.1.初始化2.1.1.初始化backend

2.1.2.初始化init_method2.1.2.1.使用TCP初始化

2.1.2.2.使用共享文件系统初始化

2.1.3.初始化rank和world_size

2.1.4.初始化中一些需要注意的地方

2.2.数据的处理-DataLoader

2.3.模型的处理

2.4.模型的保存与加载

pytorch多gpu并行训练

注: 以下都在Ubuntu上面进行的调试, 使用的Ubuntu版本包括14, 18LST

参考文档:

1.单机多卡并行训练

1.1.torch.nn.DataParallel

我一般在使用多GPU的时候, 会喜欢使用os.environ['CUDA_VISIBLE_DEVICES']来限制使用的GPU个数, 例如我要使用第0和第3编号的GPU, 那么只需要在程序中设置:

os.environ['CUDA_VISIBLE_DEVICES'] = '0,3'

但是要注意的是, 这个参数的设定要保证在模型加载到gpu上之前, 我一般都是在程序开始的时候就设定好这个参数, 之后如何将模型加载到多GPU上面呢?

如果是模型, 那么需要执行下面的这几句代码:

model = nn.DataParallel(model)

model = model.cuda()

如果是数据, 那么直接执行下面这几句代码就可以了:

inputs = inputs.cuda()

labels = labels.cuda()

其实如果看pytorch官网给的示例代码,我们可以看到下面这样的代码

model = Model(input_size, output_size)

if torch.cuda.device_count() > 1:

print("Let's use", torch.cuda.device_count(), "GPUs!")

# dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs

model = nn.DataParallel(model)

model.to(device)

这个和我上面写的好像有点不太一样, 但是如果看一下DataParallel的内部代码, 我们就可以发现, 其实是一样的:

class DataParallel(Module):

def __init__(self, module, device_ids=None, output_device=None, dim=0):

super(DataParallel, self).__init__()

if not torch.cuda.is_available():

self.module = module

self.device_ids = []

return

if device_ids is None:

device_ids = list(range(torch.cuda.device_count()))

if output_device is None:

output_device = device_ids[0]

我截取了其中一部分代码, 我们可以看到如果我们不设定好要使用的device_ids的话, 程序会自动找到这个机器上面可以用的所有的显卡, 然后用于训练. 但是因为我们前面使用os.environ['CUDA_VISIBLE_DEVICES']限定了这个程序可以使用的显卡, 所以这个地方程序如果自己获取的话, 获取到的其实就是我们上面设定的那几个显卡.

我没有进行深入得到考究, 但是我感觉使用os.environ['CUDA_VISIBLE_DEVICES']对可以使用的显卡进行限定之后, 显卡的实际编号和程序看到的编号应该是不一样的, 例如上面我们设定的是os.environ['CUDA_VISIBLE_DEVICES']="0,2", 但是程序看到的显卡编号应该被改成了'0,1', 也就是说程序所使用的显卡编号实际上是经过了一次映射之后才会映射到真正的显卡编号上面的, 例如这里的程序看到的1对应实际的2

1.2.如何平衡DataParallel带来的显存使用不平衡的问题

这个问题其实讨论的也比较多了, 官方给的解决方案就是使用 DistributedDataParallel来代替 DataParallel(实际上DistributedDataParallel显存分配的也不是很平衡), 但是从某些角度来说, DataParallel使用起来确实比较方便, 而且最近使用 Distrib

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值