可选择:数据并行处理(文末有完整代码下载)

作者:Sung Kim 和 Jenny Kang

在这个教程中,我们将学习如何用 DataParallel 来使用多 GPU。

通过 PyTorch 使用多个 GPU 非常简单。你可以将模型放在一个 GPU:

device = torch.device("cuda:0")

model.to(device)

然后,你可以复制所有的张量到 GPU:

mytensor = my_tensor.to(device)

请注意,只是调用 my_tensor.to(device) 返回一个 my_tensor 新的复制在GPU上,而不是重写 my_tensor。你需要分配给他一个新的张量并且在 GPU 上使用这个张量。

在多 GPU 中执行前馈,后馈操作是非常自然的。尽管如此,PyTorch 默认只会使用一个 GPU。通过使用 DataParallel 让你的模型并行运行,你可以很容易的在多 GPU 上运行你的操作。

model = nn.DataParallel(model)

这是整个教程的核心,我们接下来将会详细讲解。

引用和参数

引入 PyTorch 模块和定义参数

import torch

import torch.nn as nn

from torch.utils.data import Dataset, DataLoader

参数

input_size = 5

output_size = 2

batch_size = 30

data_size = 100

设备

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

实验(玩具)数据

生成一个玩具数据。你只需要实现 getitem.

class RandomDataset(Dataset):

def __init__(self, size, length):
self.len = length
self.data = torch.randn(length, size) def __getitem__(self, index):
return self.data[index] def __len__(self):
return self.len

rand_loader = DataLoader(dataset=RandomDataset(input_size, data_size),batch_size=batch_size, shuffle=True)

简单模型

为了做一个小 demo,我们的模型只是获得一个输入,执行一个线性操作,然后给一个输出。尽管如此,你可以使用 DataParallel   在任何模型(CNN, RNN, Capsule Net 等等.)

我们放置了一个输出声明在模型中来检测输出和输入张量的大小。请注意在 batch rank 0 中的输出。

class Model(nn.Module):

# Our model

def __init__(self, input_size, output_size):
super(Model, self).__init__()
self.fc = nn.Linear(input_size, output_size) def forward(self, input):
output = self.fc(input)
print("\tIn Model: input size", input.size(),
"output size", output.size()) return output

创建模型并且数据并行处理

这是整个教程的核心。首先我们需要一个模型的实例,然后验证我们是否有多个 GPU。如果我们有多个 GPU,我们可以用 nn.DataParallel 来   包裹 我们的模型。然后我们使用 model.to(device) 把模型放到多 GPU 中。

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)

输出:

Let's use 2 GPUs!

 运行模型:

现在我们可以看到输入和输出张量的大小了。

 

for data in rand_loader:

input = data.to(device)

output = model(input)

print("Outside: input size", input.size(),

"output_size", output.size())

输出:

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])

In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])

Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

结果:

如果你没有 GPU 或者只有一个 GPU,当我们获取 30 个输入和 30 个输出,模型将期望获得 30 个输入和 30 个输出。但是如果你有多个 GPU ,你会获得这样的结果。

多 GPU

如果你有 2 个GPU,你会看到:

on 2 GPUs

Let's use 2 GPUs!

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])

In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])

Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

如果你有 3个GPU,你会看到:

Let's use 3 GPUs!

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

如果你有 8个GPU,你会看到:

Let's use 8 GPUs!

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([4, 5]) output size torch.Size([4, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

In Model: input size torch.Size([2, 5]) output size torch.Size([2, 2])

Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

总结

数据并行自动拆分了你的数据并且将任务单发送到多个 GPU 上。当每一个模型都完成自己的任务之后,DataParallel 收集并且合并这些结果,然后再返回给你。

更多信息,请访问:

https://pytorch.org/tutorials/beginner/former_torchies/parallelism_tutorial.html

下载 Python 版本完整代码:

http://pytorchchina.com/2018/12/11/optional-data-parallelism/

PyTorch 60 分钟入门教程:数据并行处理的更多相关文章

  1. PyTorch 60 分钟入门教程

    PyTorch 60 分钟入门教程:PyTorch 深度学习官方入门中文教程 http://pytorchchina.com/2018/06/25/what-is-pytorch/ PyTorch 6 ...

  2. PyTorch 60 分钟入门教程:PyTorch 深度学习官方入门中文教程

    什么是 PyTorch? PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群: NumPy 的替代品,可以利用 GPU 的性能进行计算. 深度学习研究平台拥有足够的灵活性和速度 ...

  3. [PyTorch入门之60分钟入门闪击战]之入门

    深度学习60分钟入门 来源于这里. 本文目标: 在高层次上理解PyTorch的Tensor库和神经网络 训练一个小型的图形分类神经网络 本文示例运行在ipython中. 什么是PyTorch PyTo ...

  4. Objective-C 30分钟入门教程

    Objective-C 30分钟入门教程 我第一次看OC觉得这个语言的语法有些怪异,为什么充满了@符号,[]符号,函数调用没有()这个,但是面向对象的高级语言也不外乎类,接口,多态,封装,继承等概念. ...

  5. 正则表达式30分钟入门教程<转载>

    来园子之前写的一篇正则表达式教程,部分翻译自codeproject的The 30 Minute Regex Tutorial. 由于评论里有过长的URL,所以本页排版比较混乱,推荐你到原处查看,看完了 ...

  6. PHP正则表达式30分钟入门教程

    正则表达式30分钟入门教程 三个常用的知识点: 1.惰性匹配:正则引擎默认是贪婪的,若要最少重复的话,需要用到惰性匹配符 “?” 懒惰限定符 代码/语法 说明 *? 重复任意次,但尽可能少重复 +? ...

  7. iOS开发60分钟入门

    原文:https://github.com/qinjx/30min_guides/blob/master/ios.md 本文面向已有其它语言(如Java,C,PHP,Javascript)编程经验的i ...

  8. AngularJs 基础(60分钟入门)

    AngularJS 是一个创建富客户端应用的JavaScript MVC框架.你仍然需要具有服务端后台,但大多数的用户交互逻辑将放到客户端上处理.它可以创建单页的应用程序,一个页面的应用仅仅需要HTM ...

  9. AngularJs 基础(60分钟入门) (转)

    AngularJs是一个不错的用于开发SPA应用(单页Web应用)的框架.单页Web应用(single page web application,SPA),就是只有一张Web页面的应用.浏览器一开始会 ...

随机推荐

  1. python基础知识12-异常

    几个命令: sudo apt install tree tree 当前目录以树形结构展示出来. tree a 查看a内的所有目录.也可以跟绝对路径. a = input('请输入您的密码') 将用户输 ...

  2. Java 关于循环的练习--和为n的正数序列

    要求:输入一个正数n,输出所有和为n的连续正数序列. 分析可以从1开始连续加,若到i的和等于n则输出1到i之间的连续正数,若到i的和大于n,则改为从2开始连续加,再判断到i的和是否等于n,等于则输出2 ...

  3. JavaScript 的类型

    var a ="111"; console.log(a.constructor);//function String() { [native code]} var b= Strin ...

  4. 什么是Kubernetes?

    刚刚进学校实验室,第一次开会导师和小组同学说了n次Kubernetes,从来没听过,一脸懵逼. Kubernetes也有很多人把它叫K8S, 原文链接:http://omerio.com/2015/1 ...

  5. c++之析构函数

    #include<iostream>using namespace std;class A{   public:    A(){cout<<"A constructi ...

  6. 解决Genymotion运行Android 5.0一直卡在开机界面

    在一些机器,启动genymotion 的android5.0版模拟器时,会卡在启动界面,一直启动不了. 这是因为要求的开启虚拟选项没有打开,在第一次启动时,会有提示,但可能大家没有注意(我也没注意到, ...

  7. msp430项目编程23

    msp430中项目---风扇控制系统 1.比较器工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  8. msp430入门编程12

    msp430中C语言的模块化头文件及库文件12 msp430入门学习 msp430入门编程

  9. 用 Gearman 分发 PHP 应用程序的工作负载【转载】

    通过本文,了解工作分发系统 Gearman 并分发用 PHP.C.Ruby 及其他受支持语言编写的应用程序的工作负载. 尽管一个 Web 应用程序的大部分内容都与表示有关,但它的价值与竞争优势却可能体 ...

  10. Swift--字典的了解

    字典存储时,key和value值的类型都是固定的,且都是无序的. 1.字典类型的缩写语法 在swift中,字典的完整格式如下: Dictionary<Key, Value> 注意:字典的k ...