数据并行(选读)

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. 使用 Transformers 在你自己的数据集上训练文本分类模型

    最近实在是有点忙,没啥时间写博客了.趁着周末水一文,把最近用 huggingface transformers 训练文本分类模型时遇到的一个小问题说下. 背景 之前只闻 transformers 超厉 ...

  2. PT的常用命令

    归纳常用的PT命令,便于工作中应用. 1. 报时序的命令 report_timing -from A -to  [get_clocks {clkA}]  -delay_type min report_ ...

  3. java 线程池 带返回值

    import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import ja ...

  4. maven插件实现项目一键“run maven、debug maven”等命令 => 插件名:“maven helper”

    1.在IDEA中下载插件 2.使用 总结:通过 "maven helper" 插件即可通过命令实现对项目的一键管理

  5. 手写 Java HashMap 核心源码

    手写 Java HashMap 核心源码 手写 Java HashMap 核心源码 上一章手写 LinkedList 核心源码,本章我们来手写 Java HashMap 的核心源码. 我们来先了解一下 ...

  6. IDEA下Maven项目中通过JDBC连接MySQL数据库

    ### 1. 在当前Maven项目的pom.xml文件中导入数据库依赖: ```<dependency> <groupId>mysql</groupId> < ...

  7. 量子图形加密算法的MATLAB代码实现

    一.概述 目前主流的量子图形加密算法有量子像素编码算法(Quantum Image Pixel Encoding,QIPE).量子像素置乱算法(Quantum Image Pixel Scrambli ...

  8. windows下使用route添加路由

    1,首先在"运行"窗口输入cmd(按WIN+R打开运行窗口),然后回车进入命令行. 2,在命令行下输入route命令,会有对应的提示信息. ROUTE [-f] [-p] [-4| ...

  9. SpringBoot笔记--文件配置加载顺序+整合其他框架

    内部文件配置加载顺序 外部文件配置加载顺序 jar包配置 整合Junit 若是业务管理类和测试类在同一个包下面,那么这句话, 可以不加括号,只写注解名称 否则,就必须指定到包下面,不然会报错 整合Re ...

  10. day02-容器功能

    容器功能 1.Spring注入组件的注解 Spring中的传统注解@Component.@Controller.@Service.@Repository,在SpringBoot中仍然有效. 2.@Co ...