相关文章推荐

使用pytorch DDP(DistributedDataParallel,分布式数据并行)可以进行多卡训练,涉及到模型保存与加载问题时,一般会涉及到以下两种需求:

  1. 将多卡训练的模型保存到磁盘。
  2. 从磁盘加载模型,在多卡上继续训练。

如何无bug且高效的解决以上需求 ?(假设训练设备为“单机4卡”)

对于需求1,由于DDP在多卡中维护了相同的模型参数(通过在4张GPU上确保模型初始化以及广播相同的梯度来保证4张卡中的模型参数是完全相同的),因此只需要在其中一张卡保存模型即可:

def save_checkpoint(local_rank, ddp_model, path):
    #只在GPU 0 上保存模型
    if local_rank== 0:
        state = {
            'model': ddp_model.module.state_dict(),
            'optimizer': optimizer.state_dict(),
        torch.save(state, path)

对于需求2,一般会使用torch.load()方法从磁盘加载文件:

def load_checkpoint(path):
    checkpoint = torch.load(path)
    model = Net()
    model.load_state_dict(checkpoint['model'])
    model = DDP(model, device_ids=[gpu])
    return model

但是此时往往会遇到多进程在GPU0上占用过多显存的问题:

使用nvidia-smi命令:

上图中,在所有使用GPU0的进程中,除了PID为62250的进程外,还存在其他三个进程,而这三个进程还分别使用GPU1\2\3。这三个额外进程在GPU0占用了725MB*3的显存空间,这可能会导致GPU0在训练时出现爆显存的问题。

在DDP中,会为每张卡单独创建一个进程:

上图的情况是正常的,每个进程只会使用与其对应的一张显卡。

该问题出现的原因是:torch.load()的不正确使用。

在pytorch对 torch. load() 方法的 官方文档 中,有以下说明:

If map_location is missing, torch.load will first load the module to CPU and then copy each parameter to where it was saved

意思是,如果map_location参数是空的,则torch.load方法会先把模型加载到CPU,然后把模型参数复制到 保存它的地方 (根据上文,保存模型的位置恰好是GPU 0)。

跑在GPU1上的进程在执行到torch.load方法后,会先加载模型到CPU,之后该进程顺理成章地调用GPU0,把一部分数据复制到GPU0,也就出现了前面图中的问题。

与其说是bug,倒不如说没仔细阅读文档。

两种解决方法方法。

一,将map_location指定为CPU:

def load_checkpoint(path):
    #加载到CPU
    checkpoint = torch.load(path,map_location='cpu')
    model = Net()
    model.load_state_dict(checkpoint['model'])
    model = DDP(model, device_ids=[gpu])
    return model

二,将map_location指定为local_rank对应的GPU:

def load_checkpoint(path):
    #加载到CPU
    checkpoint = torch.load(path,map_location='cuda:{}'.format(local_rank))
    model = Net()
    model.load_state_dict(checkpoint['model'])
    model = DDP(model, device_ids=[gpu])
    return model
本文主要解决 pytorch 在进行 模型 训练 时 出现 GPU 的0卡 占用 显存 比其他卡要多的 问题 。 如下图所示:本机 GPU 卡为TITAN RTX, 显存 24220M,batch_size = 9,用了三张卡。第0卡 显存 占用 24207M,这 时 仅仅是刚开始运行,数据只是少量的移到显卡上,如果数据在多点,0卡的 显存 肯定撑爆。 出现 0卡 显存 更高的原因:网络在反向传播的 时 候,计算loss的梯度默认都在0卡上计算。因此会比其他显卡多用一些 显存 ,具体多用多少,主要还要看网络的结构。 因此,为了防止训练由于 out of memory
某次训练 深度学习 模型 时 , 使用 *** roberta-large 模型 作为基础模块,起初 使用 DataParallel *** 的方式,进行单机多卡训练,卡数为2,每张卡 显存 为10G。 训练期间发现,无法 使用 较大的batch_size,batch_size最大为4。同 时 ,训练 时 间增加到3个小 时 一个epoch, 时 间开销太大。 观察 GPU 利用 显存 率,0卡 占用 显存 明显比1卡 占用 的要多,这也是*** DataParallel *** 这种模式的弊端。 *** DataParallel *** 数据传输过程包括: 模型 并行 模型 并行主要应用于 模型 相比 显存 来说更大,一块 device 无法 加载 的场景,通过把 模型 切割为几个部分,分别 加载 到不同的 device 上。比如早期的 AlexNet,当 时 限于显卡, 模型 就是分别 加载 在两块显卡上的。 这个是日常会应用的比较多的情况。每一个 device 上会 加载 一份 模型 ,然后把数据分发到每个 device 并行进行计算,加快训练速度。 如果要再细分,又可以分
感谢知乎作者 https://www.zhihu.com/question/67209417/answer/866488638 在 使用 DDP 进行单机多卡分布式训练 时 , 出现 了在 加载 预训练权重 时 显存 不够的现象,但是相同的代码单机单卡运行并不会 出现 问题 ,后来发现是在多卡训练 时 ,额外 出现 了3个进程同 时 占用 了0卡的部分 显存 导致的,而这3个进程正是另外3张卡load进来的数据,默认这些数据被放在了0卡上。解决的方法是把load进来的数据放在cpu(也就是内存)里。 # 原来代码,load进的数据放在 gpu 里 # pre
1. 搭建自己的简单二分类网络, 使用 pytorch 训练和测试; 2. 将 pytorch 训练的pth 模型 转换成ONNX,并编码测试; 3. 含训练和测试数据,含训练ok的pth 模型 和ONNX 模型 ,含完整python和C++实现; 4. 使用 方法:首先运行“TrainTestConvertOnnx.py”执行“训练数据读入、 模型 训练、 模型 测试、导出onnx”,再运行“TestOnnx.cpp”测试onnx(需要配置OpenCV);
在公司用多卡训练 模型 ,得到权值文件后保存,然后回到实验室,没有多卡的环境,用单卡训练, 加载 模型 时 出错,因为单卡机器上,没有 使用 DataParallel来 加载 模型 ,所以会 出现 加载 错误。 DataParallel包装的 模型 在保存 时 ,权值参数前面会带有module字符,然而自己在单卡环境下,没有用DataParallel包装的 模型 权值参数不带module。本质上保存的权值文件是一个有序字典。 1.在单卡环境下,用DataParallel包装 模型 。 2.自己重写Load函数,灵活。 from collections import OrderedDict def myOwnLoa
如果在python内调用 pytorch 有可能 显存 和 GPU 占用 不会被自动释放,此 时 需要加入如下代码 torch.cuda.empty_cache() 我们来看一下官方文档的说明 Releases all unoccupied cached memory currently held by the caching allocator so that those can be used in other GPU application and visible in nvidia-smi. empty_cache() doesn’t increase the amount of GPU me
问题 描述 首先说明: 由于我的测试集很大, 因此需要对测试集进行分批次推理. 在写代码的 时 候发现进行训练的 时 候大概 显存 只 占用 了2GB左右, 而且训练过程中 显存 占用 量也基本上是不变的. 而在测试的 时 候, 发现 显存 在每个batch数据推理后逐渐增加, 直至最后导致爆 显存 , 程序fail. 这里放一下我测试的代码: y, y_ = torch.Tensor(), torch.Tensor() for batch in tqdm(loader): x, batch_y =
PyTorch 是一个流行的 深度学习 框架,支持 使用 单个 GPU 或多个 GPU s进行训练和测试。在 使用 单个 GPU 时 ,需要将 模型 和数据 加载 到 GPU 上。 使用 单个 GPU 进行训练和测试的示例代码如下: 示例代码如下: ```python #将 模型 加载 到 GPU device = torch.device('cuda:0') #选择第一个 GPU model.to(device) #将数据 加载 到 GPU x = x.to(device) y = y.to(device) #在 GPU 上进行前向传播 y_pred = model(x) #计算损失 loss = criterion(y_pred, y) #在 GPU 上进行反向传播 loss.backward() #更新权重 optimizer.step() 使用 多个 GPU 可以加快训练和测试的速度。 PyTorch 提供了两种多 GPU 的方法:DataParallel和DistributedDataParallel( DDP )。其中,DataParallel是在单台机器上 使用 多个 GPU 的方法,而 DDP 是在多台机器上 使用 多个 GPU 的方法。 使用 DataParallel 时 ,可以将 模型 和数据 加载 到单个 GPU 上,然后 使用 torch.nn.DataParallel将 模型 复制到其他 GPU 上。 使用 DataParallel进行训练和测试的示例代码如下: 示例代码如下: ```python #将 模型 加载 到 GPU device = torch.device('cuda:0') #选择第一个 GPU model.to(device) # 使用 DataParallel将 模型 复制到其他 GPU 上 if torch.cuda.device_count() > 1: model = nn.DataParallel(model) #将数据 加载 到 GPU x = x.to(device) y = y.to(device) #在 GPU 上进行前向传播 y_pred = model(x) #计算损失 loss = criterion(y_pred, y) #在 GPU 上进行反向传播 loss.backward() #更新权重 optimizer.step() 使用 DDP 时 ,需要在多台机器上安装 PyTorch 和NCCL库,并按照官方文档中的说明进行配置。 使用 DDP 进行训练和测试的示例代码如下: ```python #在每个进程中选择一个 GPU device = torch.device('cuda', rank % torch.cuda.device_count()) # 使用 DistributedDataParallel初始化 模型 model = nn.parallel.DistributedDataParallel(model, device_ids=[device]) #在 GPU 上进行前向传播 y_pred = model(x) #计算损失 loss = criterion(y_pred, y) #在 GPU 上进行反向传播 loss.backward() #更新权重 optimizer.step() 以上就是 PyTorch 使用 单个 GPU 和多个 GPU 进行训练和测试的方法。具体 使用 哪种方法,需要根据硬件和应用场景的要求进行选择。
玩转CIFAR10—Pytorch复现LeNet,AlexNet,VGG,GoogLeNet,MobileNet,ResNet,DenseNet,Vision Transformer等模型(持续更新) 在VS Code中使用jupyter notebook,输出过多时show more显示不正常,出现乱码问题的解决方案
 
推荐文章