数据并行(选读)

Authors: Sung Kim and Jenny Kang

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

PyTorch非常容易就可以使用多GPU,用如下方式把一个模型放到GPU上:

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

GPU:
然后复制所有的张量到GPU上:

    mytensor = my_tensor.to(device)

请注意,只调用my_tensor.to(device)并没有复制张量到GPU上,而是返回了一个copy。所以你需要把它赋值给一个新的张量并在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 # Parameters and DataLoaders
input_size = 5
output_size = 2 batch_size = 30
data_size = 100

Device

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)

简单模型

作为演示,我们的模型只接受一个输入,执行一个线性操作,然后得到结果。
说明:DataParallel能在任何模型(CNN,RNN,Capsule Net等)上使用。

我们在模型内部放置了一条打印语句来打印输入和输出向量的大小。

请注意批次的秩为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)
Model(
(fc): Linear(in_features=5, out_features=2, bias=True)
)

运行模型

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

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([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
In Model: input size torch.Size([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
In Model: input size torch.Size([30, 5]) output size torch.Size([30, 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])
Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

结果

当没有或者只有一个GPU时,对30个输入和输出进行批处理,得到了期望的一样得到30个输入和输出,但是如果你有多个GPU,你得到如下的结果。

2 GPUs
~

If you have 2, you will see:

… code:: bash

# 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 GPUs
~

If you have 3 GPUs, you will see:

… code:: bash

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 GPUs
~~

If you have 8, you will see:

… code:: bash

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])

总结

DataParallel会自动的划分数据,并将作业发送到多个GPU上的多个模型。
并在每个模型完成作业后,收集合并结果并返回。

更多信息请看这里:
https://pytorch.org/tutorials/beginner/former_torchies/parallelism_tutorial.html.

[Pytorch框架] 1.7 数据并行的更多相关文章

  1. [源码解析] PyTorch分布式优化器(2)----数据并行优化器

    [源码解析] PyTorch分布式优化器(2)----数据并行优化器 目录 [源码解析] PyTorch分布式优化器(2)----数据并行优化器 0x00 摘要 0x01 前文回顾 0x02 DP 之 ...

  2. 深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用

    深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究热点,产生了广泛的应用.DNN具有深层结构.数千万参数需要学习,导致训练非常耗时.GPU有强大的计算能 ...

  3. 【深度学习系列2】Mariana DNN多GPU数据并行框架

    [深度学习系列2]Mariana DNN多GPU数据并行框架  本文是腾讯深度学习系列文章的第二篇,聚焦于腾讯深度学习平台Mariana中深度神经网络DNN的多GPU数据并行框架.   深度神经网络( ...

  4. PyTorch Tutorials 5 数据并行(选读)

    %matplotlib inline 数据并行(选读) Authors: Sung Kim and Jenny Kang 在这个教程里,我们将学习如何使用 DataParallel 来使用多GPU. ...

  5. PyTorch Data Parrallel数据并行

    PyTorch Data Parrallel数据并行 可选择:数据并行处理 本文将学习如何用 DataParallel 来使用多 GPU. 通过 PyTorch 使用多个 GPU 非常简单.可以将模型 ...

  6. C#并行编程-PLINQ:声明式数据并行

    目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-PLINQ:声明式数据并行 背景 通过LINQ可 ...

  7. C#并行编程--命令式数据并行(Parallel.Invoke)---与匿名函数一起理解(转载整理)

    命令式数据并行   Visual C# 2010和.NETFramework4.0提供了很多令人激动的新特性,这些特性是为应对多核处理器和多处理器的复杂性设计的.然而,因为他们包括了完整的新的特性,开 ...

  8. C#并行编程--命令式数据并行(Parallel.Invoke)

    命令式数据并行   Visual C# 2010和.NETFramework4.0提供了很多令人激动的新特性,这些特性是为应对多核处理器和多处理器的复杂性设计的.然而,因为他们包括了完整的新的特性,开 ...

  9. TensorFlow分布式计算机制解读:以数据并行为重

    Tensorflow 是一个为数值计算(最常见的是训练神经网络)设计的流行开源库.在这个框架中,计算流程通过数据流程图(data flow graph)设计,这为更改操作结构与安置提供了很大灵活性.T ...

  10. .NET 并行编程——数据并行

    本文内容 并行编程 数据并行 环境 计算 PI 矩阵相乘 把目录中的全部图片复制到另一个目录 列出指定目录中的所有文件,包括其子目录 最近,对多线程编程,并行编程,异步编程,这三个概念有点晕了,之前我 ...

随机推荐

  1. EL_获取域中存储的值_ List 集合&Map集合值和EL _ empty 运算符&隐式对象 pageContext

    3.获取对線. List 集合. Map 集合的值 1.对線:${域名称,键名.属性名}本质上会去调用对線的 getter 方法 2. List 集合:${域名称.键名[索引]} List list ...

  2. 编写简单的button配合input实现上传文件操作

    <template> <button> 导入文件 <input type="file" @change="fileChange" ...

  3. 记录一次MySQL主从同步

    主库配置 server-id=1log-bin=mysql-binbinlog_format=ROWbinlog_row_image=minimalbinlog-do-db=yjtb-cloud 解释 ...

  4. ImageUtils excel 中 emf 转图片(解决图片上部分显示不全问题)图片转文字

    excel 中ActiveX 工具 中的textbox  ,以及公式 解析后为emf 图片, emf 转图片(解决图片上部分显示不全问题) 图片转文字 /*********************** ...

  5. Python批量采集百度资讯文章,如何自定义采集日期范围

    01 引言 大家好!蜡笔小曦有个朋友是做能源相关工作的,她想要有一个工具以天为单位持续地采集百度资讯中能源相关的文章进行留存和使用. 其中有个需求点是说能够自定义采集的开始日期和结束日期,这样更加灵活 ...

  6. 【Jenkins】linux与windows环境下的安装步骤

    linux环境: <1>安装jdk: https://www.cnblogs.com/poloyy/p/12801792.htmljdk (参考) <2>环境清理 find / ...

  7. yhm的丘赛题解(其中的一些简单题)

    有选择地做了丘赛里的一些简单题,不定期更新     目录 [简单组合数学]2011丘赛个人[应数计算数学概统]第3题题解 [拉格朗日多项式插值]2011丘赛个人[应数计算数学概统]第2题题解 [概率] ...

  8. Go语言:利用 TDD 测试驱动开发帮助理解数组与动态数组(切片)的区别

    Array VS Slice 数组允许你以特定的顺序在变量中存储相同类型的多个元素. 对于数组来说,最常见的就是迭代数组中的元素. 我们创建一个 Sum 函数,它使用 for 来循环获取数组中的元素并 ...

  9. 分析document文档中script标签获取抖音无水印视频

    思路分析 使用 playwright 模拟浏览器打开分享链接 获取 播放页面 html 信息 解析 播放页面的 video标签,video标签的src属性就是视频的地址 这种模式会触发抖音的风控机制 ...

  10. Kafka 物理存储机制

    一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一.下面将从 Kafka文件存储机制和物理结构角度,分析 Kafka是如何实现高效文件存储,及实际应用效果. ...