当前位置: 首页 > news >正文

Pytorch分布式训练/多卡训练(三) —— Model Parallel 并行

 Model Parallel

        数据并行是指,多张 GPUs 使用相同的模型副本,但采用不同 batch 的数据进行训练.

        模型并行是指,多张 GPUs 使用同一 batch 的数据,分别训练模型的不同部分.

Part of the model on CPU and part on the GPU


class DistributedModel(nn.Module):

    def __init__(self):
        super().__init__(
            embedding=nn.Embedding(1000, 10),
            rnn=nn.Linear(10, 10).to(device),
        )

    def forward(self, x):
        # Compute embedding on CPU
        x = self.embedding(x)

        # Transfer to GPU
        x = x.to(device)

        # Compute RNN on GPU
        x = self.rnn(x)
        return x

Basic Usage

首先从包含两个线性层的toy model开始。 要在两个GPU上运行此模型,只需将每个线性层放在不同的GPU上,然后移动输入和中间输出以匹配设备。

import torch
import torch.nn as nn
import torch.optim as optim

class ToyModel(nn.Module):
    def __init__(self):
        super(ToyModel, self).__init__()
        self.net1 = torch.nn.Linear(10, 10).to('cuda:0')
        self.relu = torch.nn.ReLU()
        self.net2 = torch.nn.Linear(10, 5).to('cuda:1')

    def forward(self, x):
        x = self.relu(self.net1(x.to('cuda:0')))
        return self.net2(x.to('cuda:1'))


model = ToyModel()
loss_fn = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.001)

optimizer.zero_grad()
outputs = model(torch.randn(20, 10))
labels = torch.randn(20, 5).to('cuda:1')
loss_fn(outputs, labels).backward()
optimizer.step()

      除了5个 to(device) 调用将线性层和张量放置在适当的设备上之外,上面的ToyModel看起来非常类似于在单个GPU上实现它的方式。 to(device)是模型中唯一需要更改的地方。多GPU训练时 backward() 和torch.optim将自动处理梯度,就和模型在一个GPU上一样。 只需要注意在调用损失函数时,确保label与output位于同一设备上。

另一个例子

from torchvision.models.resnet import ResNet, Bottleneck

num_classes = 1000


class ModelParallelResNet50(ResNet):
    def __init__(self, *args, **kwargs):
        super(ModelParallelResNet50, self).__init__(
            Bottleneck, [3, 4, 6, 3], num_classes=num_classes, *args, **kwargs)

        self.seq1 = nn.Sequential(
            self.conv1,
            self.bn1,
            self.relu,
            self.maxpool,

            self.layer1,
            self.layer2
        ).to('cuda:0')

        self.seq2 = nn.Sequential(
            self.layer3,
            self.layer4,
            self.avgpool,
        ).to('cuda:1')

        self.fc.to('cuda:1')

    def forward(self, x):
        x = self.seq2(self.seq1(x).to('cuda:1'))
        return self.fc(x.view(x.size(0), -1))

      这就显示了如何将torchvision.models.resnet50()分解为两个GPU。 这个想法是继承现有的ResNet模块,并在构建过程中将层拆分为两个GPU。 然后,通过相应地移动中间输出,覆盖前向方法来连接两个子模块。

      对于模型太大而无法放入单个GPU的情况,上述实现解决了该问题。 但是要注意到,它将比在单个GPU上运行要慢。 这是因为在任何时间点,两个GPU中只有一个在工作,而另一个在那儿什么也没做。 由于中间输出需要在第2层和第3层之间从cuda:0复制到cuda:1,因此性能进一步下降

      我们可以对此改进,因为我们知道两个GPU之一在整个执行过程中都处于闲置状态。 一种选择是将每个批次进一步划分为拆分流水线,以便当一个拆分到达第二个卡时,可以将下一个拆分馈入第一张卡。 这样,两个连续的拆分可以在两个GPU上同时运行。

Speed Up by Pipelining Inputs

Single-Machine Model Parallel Best Practices — PyTorch Tutorials 1.11.0+cu102 documentation

相关文章:

  • Pytorch backend 通信后端
  • PyTorch多卡/多GPU/分布式DPP的基本概念(noderanklocal_ranknnodesnode_ranknproc_per_nodeworld_size)
  • Pytorch函数keepdim=True
  • Python opencv putText()中文乱码问题
  • Python类的__call__方法
  • Python处理XML(ElementTree)
  • Pytorch为不同层设置不同的学习率(全局微调)
  • PIL Image和opencv读入图片相互转化
  • Python 星号表达式*(starred expression / unpack / 解包)
  • Pytorch/Python计算交并比IOU(IU)代码(批量算IOU)
  • Pytorch apply() 函数
  • Python namedtuple数据结构(命名元组)(collections)
  • numpy/pytorch 高级索引(整数数组索引 布尔索引)
  • Python Type Hint(类型标注/类型提示) (箭头 ->)(type annotation)
  • Pytorch清空显存缓冲区(torch.cuda.empty_cache)
  • (三)从jvm层面了解线程的启动和停止
  • 【翻译】babel对TC39装饰器草案的实现
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Apache Spark Streaming 使用实例
  • Apache的80端口被占用以及访问时报错403
  • crontab执行失败的多种原因
  • Electron入门介绍
  • Fundebug计费标准解释:事件数是如何定义的?
  • HashMap剖析之内部结构
  • jquery ajax学习笔记
  • LeetCode29.两数相除 JavaScript
  • Magento 1.x 中文订单打印乱码
  • MySQL几个简单SQL的优化
  • Promise面试题,控制异步流程
  • python大佬养成计划----difflib模块
  • Spark RDD学习: aggregate函数
  • SpiderData 2019年2月23日 DApp数据排行榜
  • swift基础之_对象 实例方法 对象方法。
  • Travix是如何部署应用程序到Kubernetes上的
  • VuePress 静态网站生成
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • webgl (原生)基础入门指南【一】
  • 百度地图API标注+时间轴组件
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 机器学习 vs. 深度学习
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 前端js -- this指向总结。
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 在Unity中实现一个简单的消息管理器
  • 智能合约开发环境搭建及Hello World合约
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​2020 年大前端技术趋势解读
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #git 撤消对文件的更改
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (13):Silverlight 2 数据与通信之WebRequest
  • (vue)页面文件上传获取:action地址