PyTorch 笔记(19)— Tensor 用 GPU 加速
在 PyTorch
中以下数据结构分为 CPU
和 GPU
两个版本:
Tensor
nn.Module
(包括常用的layer
、loss function
,以及容器Sequential
等)
它们都带有一个 .cuda
方法,调用此方法即可将其转为对应的 GPU
对象。
注意,tensor.cuda
会返回一个新对象,这个新对象的数据已转移至GPU,而之前的 tensor
还在原来的设备上(CPU
)。而 module.cuda
则会将所有的数据都迁移至 GPU
,并返回自己。所以 module = module.cuda()
和 module.cuda()
所起的作用一致。
tensor = t.Tensor(3, 4)
# 返回一个新的tensor,但原来的tensor并没有改变
tensor.cuda(0)
tensor.is_cuda # False
重新赋给自己,tensor
指向 cuda
上的数据,不再执行原数据。不指定使用的 GPU
设备,将默认使用第 1 块 GPU
。
tensor = tensor.cuda()
tensor.is_cuda # True
nn.Module
在 GPU
与 CPU
之间的转换,本质上还是利用了 Tensor
在 GPU
和 CPU
之间的转换。nn.Module
的 cuda
方法是将 nn.Module
下的所有 parameter
(包括子 module
的 parameter
)都转移至GPU
,而 Parameter
本质上也是 tensor
( Tensor
的子类)。
# 将nn.Module模型放到cuda上,其子模型也都自动放到cuda上
from torch import nn
module = nn.Linear(3, 4)
module.cuda(device = 0)
module.weight.is_cuda # True
注意: 为什么将数据转移至 GPU
的方法叫做 .cuda
而不是 .gpu
,就像将数据转移至 CPU
调用的方法是 .cpu
?
这是因为 GPU
的编程接口采用 CUDA
,而目前并不是所有的 GPU
都支持 CUDA
,只有部分 Nvidia
的GPU
才支持。PyTorch
未来可能会支持 AMD
的 GPU
,而 AMD GPU
的编程接口采用 OpenCL
,因此PyTorch
还预留着 .cl
方法,用于以后支持 AMD
等的 GPU
。
下面将举例说明,这部分代码需要你具有两块GPU设备。
class VeryBigModule(nn.Module):def __init__(self):super(VeryBigModule, self).__init__()self.GiantParameter1 = t.nn.Parameter(t.randn(100000, 20000)).cuda(0)self.GiantParameter2 = t.nn.Parameter(t.randn(20000, 100000)).cuda(1)def forward(self, x):x = self.GiantParameter1.mm(x.cuda(0))x = self.GiantParameter2.mm(x.cuda(1))return x
上面最后一部分中,两个 Parameter
所占用的内存空间都非常大,大概是 8 个 G,如果将这两个都同时放在一块 GPU
上几乎会将显存占满,无法再进行任何其它运算。此时可通过这种方式将不同的计算分布到不同的 GPU
中。
关于使用 GPU
的一些建议:
GPU
运算很快,但对于很小的运算量来说,并不能体现出它的优势,因此对于一些简单的操作可直接利用CPU
完成;- 数据在
CPU
和GPU
之间,以及GPU
与GPU
之间的传递会比较耗时,应当尽量避免; - 在进行低精度的计算时,可以考虑
HalfTensor
,它相比于FloatTensor
能节省一半的显存,但需千万注意数值溢出的情况;
而除了调用对象的 .cuda
方法之外,还可以使用 torch.cuda.device
,来指定默认使用哪一块 GPU
,或使用torch.set_default_tensor_type
使程序默认使用 GPU
,不需要手动调用 cuda
。
# 如果未指定使用哪块GPU,默认使用GPU 0
x = t.cuda.FloatTensor(2, 3)
# x.get_device() == 0
y = t.FloatTensor(2, 3).cuda()
# y.get_device() == 0# 指定默认使用GPU 0
with t.cuda.device(0): # 在GPU 0上构建tensora = t.cuda.FloatTensor(2, 3)# 将tensor转移至GPU 0b = t.FloatTensor(2, 3).cuda()print(a.get_device() == b.get_device() == 0 ) # Truec = a + bprint(c.get_device() == 0) # Truez = x + yprint(z.get_device() == 0) # True# 手动指定使用GPU 0d = t.randn(2, 3).cuda(0)print(d.get_device() == 2) # False
# 指定默认tensor的类型为GPU上的FloatTensor
t.set_default_tensor_type('torch.cuda.FloatTensor')
a = t.ones(2, 3)
a.is_cuda # True
如果服务器具有多个 GPU
,tensor.cuda()
方法会将 tensor
保存到第一块 GPU
上,等价于tensor.cuda(0)
。此时如果想使用第二块 GPU
,需手动指定 tensor.cuda(1)
,而这需要修改大量代码,很是繁琐。这里有两种替代方法:
- 一种是先调用
t.cuda.set_device(1)
指定使用第二块GPU
,后续的.cuda()
都无需更改,切换GPU
只需修改这一行代码。 - 更推荐的方法是设置环境变量
CUDA_VISIBLE_DEVICES
,例如当export CUDA_VISIBLE_DEVICE=1
(下标是从 0 开始,1 代表第二块GPU
),只使用第二块物理GPU
,但在程序中这块GPU
会被看成是第一块逻辑GPU
,因此此时调用tensor.cuda()
会将Tensor
转移至第二块物理GPU
。CUDA_VISIBLE_DEVICES
还可以指定多个GPU
,如export CUDA_VISIBLE_DEVICES=0,2,3
,那么第一、三、四块物理GPU
会被映射成第一、二、三块逻辑GPU
,tensor.cuda(1)
会将Tensor
转移到第三块物理GPU
上。
设置 CUDA_VISIBLE_DEVICES
有两种方法:
- 一种是在命令行中
CUDA_VISIBLE_DEVICES=0,1 python main.py
; - 一种是在程序中
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
如果使用 IPython
或者 Jupyter notebook
,还可以使用 %env CUDA_VISIBLE_DEVICES=1,2
来设置环境变量。
从 0.4 版本开始,PyTorch
新增了 tensor.to(device)
方法,能够实现设备透明,便于实现 CPU/GPU
兼容。
x = torch.randn(1)
if torch.cuda.is_available():device = torch.device("cuda") y = torch.ones_like(x, device=device) # directly create a tensor on GPUx = x.to(device) z = x + yprint(z)print(z.to("cpu", torch.double))
输出:
tensor([ 2.0718], device='cuda:0')
tensor([ 2.0718], dtype=torch.float64)
PyTorch
支持分布式 GPU
。分布式是指有多个 GPU
在多台服务器上,而并行一般指的是一台服务器上的多个 GPU
。分布式涉及到了服务器之间的通信,因此比较复杂,PyTorch
封装了相应的接口,可以用几句简单的代码实现分布式训练。分布式对普通用户来说比较遥远,因为搭建一个分布式集群的代价十分大,使用也比较复杂。相比之下一机多卡更加现实。
PyTorch 笔记(19)— Tensor 用 GPU 加速相关推荐
- Windows10安装Anaconda和Pytorch(CPU版,无GPU加速)
1.Anaconda安装 Anaconda的安装网上的教程非常非常多,很简单,下面这篇博客写的很详细,看我写的也可以. 地址:https://blog.csdn.net/u014546828/arti ...
- Pytorch框架之tensor的gpu状态查看以及设备号
tensor的gpu相关的属性 is_cuda device QQ:3020889729 小蔡 is_cuda 查看当前数据(tensor)是否存放在GPU上 '''当前tensor未放在gpu上存放 ...
- 04_Pytorch生态、PyTorch能做什么、PyTorch之Autograd、autograd案例、GPU加速案例
1.4.初见PyTorch 1.4.1.PyTorch生态 1.4.2.PyTorch能做什么? GPU加速 自动求导 常用网络层 nn.Linear nn.Conv2d nn.LSTMnn.R ...
- 8月2日Pytorch笔记——梯度、全连接层、GPU加速、Visdom
文章目录 前言 一.常见函数的梯度 二.激活函数及其梯度 1.Sigmoid 2.Tanh 3.ReLU 三.Loss 函数及其梯度 1.Mean Squared Error(MSE) 2.Softm ...
- PyTorch 笔记(03)— Tensor 数据类型分类(默认数据类型、CPU tensor、GPU tensor、CPU 和 GPU 之间的转换、数据类型之间转换)
1. Tensor 数据类型 Tensor 有不同的数据类型,如下表所示,每种类型都有 CPU 和 GPU 版本(HalfTensor)除外,默认的 tensor 是数据类型是 FloatTensor ...
- PyTorch 笔记(02)— 常用创建 Tensor 方法(torch.Tensor、ones、zeros、eye、arange、linspace、rand、randn、new)
1. Tensor 概念分类 PyTorch 中的张量(Tensor)类似 NumPy 中的 ndarrays,之所以称之为 Tensor 的另一个原因是它可以运行在 GPU 中,以加速运算. 1.1 ...
- (最新最全)windows使用anaconda安装pytorch进行深度学习并使用GPU加速
本篇文章记录下自己安装pytorch的过程,由于我装过3~4次了,所以还算是比较有经验了. 文章目录 1.检查电脑配置 2.Anaconda的准备工作-添加国内镜像源 3.下载 3.测试 1.检查电脑 ...
- pytorch tensor 初始化_PyTorch简明笔记[1]-Tensor的初始化和基本操作
听麻麻说,偷偷收藏而不感谢是不礼貌的,至少应该点个赞~我觉得麻麻说的对! 不断地被人安利PyTorch,终于忍不住诱惑决定入坑了. 当初学习TensorFlow的时候,没有系统性地学习.之前TF的英文 ...
- PyTorch学习笔记(19) ——NIPS2019 PyTorch: An Imperative Style, High-Performance Deep Learning Library
0. 前言 波兰小哥Adam Paszke从15年的Torch开始,到现在发表了关于PyTorch的Neurips2019论文(令我惊讶的是只中了Poster?而不是Spotlight?).中间经历了 ...
最新文章
- 如何用python数据挖掘_Python数据挖掘-文本挖掘
- 用c语言描述单链表的数据类型,数据结构—单链表(类C语言描述)
- 为什么你今年的去哪儿产品经理面试挂了?
- JS的parseFloat
- Azure Lambda Function创建失败 - 400 bad request和成功 - 201 Created
- sqlserver操作geography方法
- 设计模式在项目中的应用案例_设计模式在项目中的应用(初学者版)
- linux下mqm添加用户,Linux 下MQ的安装和配置亲测
- 多进程鱼多线程的权衡选择
- 新书速递 | 《知识图谱:方法、实践与应用》
- Oracle复杂查询
- 【Apple苹果设备刷机】ipad已停用,iTunes无法联系网络等问题
- linux如何扫描文件格式,Linux系统如何使用扫描仪
- jQuery学习基础理论(二)
- 车牌识别关键技术-车牌定位
- 美国加州大学河滨分校陈雪梅教授北大招聘Co-PI
- vue3 provide inject用法
- casella pdf 统计推断_统计推断_PDF图书下载_George Casella,Roger L. Berger_免费PDF电子书下载_第一图书网...
- 基于机器学习的电影票房分析与预测系统
- python flask项目结构_Flask项目结构
热门文章
- Alibaba Cloud Linux 2.1903 LTS 64位服务器yum源下载404,Alibaba Cloud Linux 2实例中使用docker-ce、epel等YUM源安装软件失败
- 2022-2028年中国环保设备行业投资分析及前景预测报告
- 实现SSTab单个选项卡代码
- tf.variance_scaling_initializer() tensorflow学习:参数初始化
- 机器学习——标准化/归一化的目的、作用和场景
- LeetCode简单题之检查是否区域内所有整数都被覆盖
- 大三Java后端暑期实习面经总结——Java容器篇
- 最新Spring整合MyBatis详解教程
- centos7 安装Git
- Android setMovementMethod() 方法