0704-使用GPU加速_cuda
0704-使用GPU加速_cuda
pytorch完整教程目录:https://www.cnblogs.com/nickchen121/p/14662511.html
一、CPU 和 GPU 数据相互转换
在 torch 中以下数据结构分为 CPU 和 GPU 两个版本:
- Tensor
- Variable(包括 Parameter)
- nn.Module(包括常用的 layer、loss function,以及容器 Sequential 等)
它们都带有一个 .cuda 方法,通过这个方法可以把它们转换对应的 GPU 对象。
但是在把 cpu 上的数据转化成 gpu 上的数据时,需要注意以下两点:
tensor.cuda和variable.cuda都会返回一个新对象,这个新对象存放在 GPU 中,而之前的数据则依然还会在 CPU 上。module.cuda会将所有的数据都迁移到 GPU,并且返回自己,也就是说module=module.cuda()和module.cuda()的效果是一样的
其实 variable 和 nn.Module 在 cpu 和 gpu 之间的转换,本质上还是利用了 tensor 在 cpu 和 gpu 之间的转换。比如 variable.cuda 实际上是把 variable.data 转移到指定的 gpu 上。而 nn.Module 的 cuda 方法是把 nn.Module 下的所有 parameter(包括子 module 的 parameter)都转移到 gpu 上,而 Parameter 的本质其实又是 variable。
下面举例说明,但是需要有两块 gpu 设备。
注:为什么把数据转移到 gpu 的方法叫做 .cuda 而不是 .gpu 呢?这是因为 gpu 的编程接口采用 cuda,而目前并不是所有的 gpu 都支持 cuda,只有部分 NVIDIA 的 gpu 才支持。torch 未来可能还会支持 AMD 的 gpu,而 AMD GPU 的编程接口采用 OpenCL,因此 torch 还预留着 .cl 方法,用于以后支持 AMD 等的 GPU。
import torch as t
# tensor 测试
tensor = t.Tensor(3, 4)
tensor.cuda(0) # 返回一个新的 tensor,保存在第 1 块 GPU 上,但原来的 tensor 并没有改变
tensor.is_cuda # False # 原来的 tensor 依然再 cpu 上
tensor = tensor.cuda() # 不指定所使用的 GPU 设备,将默认使用第 1 块 GPU
tensor.is_cuda # False
# variable 测试
variable = t.autograd.Variable(tensor)
variable.cuda()
variable.is_cuda() # False # 原来的 variable 依然再 cpu 上
# nn.module 测试
module = nn.Linear(3, 4)
module.cuda(device_id=1)
module.weight.is_cuda # True
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
在 VeryBigModule 类中,两个 Parameter 所占用的内存非常大,大概是 8GB,如果两者放在一块 GPU 上,可能会把显存占满,因此把这两个 Parameter 放在两块 GPU 上。
二、使用 GPU 的注意事项
关于使用 GPU 有一些小小的建议:
- gpu 运算很快,但是运算量小时,不能体现出它的优势,因此一些简单的操作可以使用 cpu 完成
- 数据在 cpu 和 gpu 之间的传递会比较耗时,应当尽量避免
- 在进行低精度的计算时,可以考虑使用 HalfTensor 时,相比较 FloatTensor 能节省一半的显存,但需要注意数值溢出的情况
注:大部分的损失函数也都属于 nn.Module,但在使用 gpu 时,很多时候我们都忘记使用它的 .cuda 方法,在大多数情况下不会保存,因为损失函数没有可学习的参数。但在某些情况下会出错,为了保险起见也为了代码更规范,也应该记得调用 criterion.cuda,下面举例说明:
# 交叉熵损失函数,带权重
criterion = t.nn.CrossEntropyLoss(weight=t.Tensor([1, 3]))
inp = t.autograd.Variable(t.randn(4, 2)).cuda()
target = t.autograd.Variable(t.Tensor([1, 0, 0, 1])).long().cuda()
# 下面这行会报错,因为 weight 没有被转移到 GPU 上
# loss = criterion(inp, target)
# 这行则不会报错
criterion.cuda()
loss = criterion(inp, target)
criterion._buffers
三、设置默认 GPU
除了调用 .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 1
with t.cuda.device(1):
# 在 GPU 1 上构建 tensor
a = t.cuda.FloatTensor(2, 3)
# 把 tensor 转移到 GPU 1
b = t.FloatTensor(2, 3).cuda()
print(a.get_device() == b.get_device() == 1)
c = a + b
print(c.get_device() == 1)
z = x + y
print(z.get_device() == 0)
# 手动指定使用 GPU 0
d = t.randn(2, 3).cuda(0)
print(d.get_device() == 2)
# t.set_default_tensor_type('torch.cuda.FloatTensor') # 指定默认 tensor 的类型为 GPU 上的 FloatTensor
a = t.ones(2, 3)
a.is_cuda()
四、GPU 之间的切换
如果服务器有多个 gpu,tensor.cuda() 方法将会把 tensor 保存到第一快 gpu 上,这等价于 tensor.cuda(0),这个时候如果想使用第二块 gpu,需要手动指定 tensor.cuda(1),但是这需要修改大量代码,因此很繁琐。这里有两种代替的方法:
- 第一种方法是先调用
t.cuda.set_device(1)指定使用第二块 gpu,后序的.cuda()都不需要改变。 - 另外一种方法是设置环境变量
CUDA_VISIBLE_DEVICES,例如当export CUDA_VISIBLE_DEVICES=1时,只使用 物理上的第二块 GPU,但在程序中这块 cpu 会被看成是第一块逻辑 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"
上述一般都是自己使用的情况,在实际工程中,可能还会用到分布式 GPU,由于一般人员使用不到这种方法,这里不做赘述,想详细了解的可以看官方文档——GPU 分布式通信
0704-使用GPU加速_cuda的更多相关文章
- Theano在windows下的安装及GPU加速
安装环境:wondows 64bit Teano安装测试 1. Anaconda 安装 Anaconda是一个科学计算环境,自带的包管理器conda很强大.之所以选择它是因为它内置了python,以及 ...
- GPU 加速NLP任务(Theano+CUDA)
之前学习了CNN的相关知识,提到Yoon Kim(2014)的论文,利用CNN进行文本分类,虽然该CNN网络结构简单效果可观,但论文没有给出具体训练时间,这便值得进一步探讨. Yoon Kim代码:h ...
- 开启gpu加速的高性能移动端相框组件!
通过设置新的css3新属性translateX来代替传统的绝对定位改变left值的动画原理,新属性translateX会开启浏览器自带的gpu硬件加速动画性能,提高流畅度从而提高用户体验, 代码有很详 ...
- ubuntu 15 安装cuda,开启GPU加速
1 首先要开启GPU加速就要安装cuda.安装cuda,首先要安装英伟达的驱动.ubuntu有自带的开源驱动,首先要禁用nouveau.这儿要注意,虚拟机不能安装ubuntu驱动.VMWare下显卡只 ...
- Silverlight - GPU加速
1. 在Silverlight plug-in上设置 <param name="enableGPUAcceleration" value="true" / ...
- 用cudamat做矩阵运算的GPU加速
1. cudamat简介 cudamat是一个python语言下,利用NVIDIA的cuda sdk 进行矩阵运算加速的库.对于不熟悉cuda编程的程序员来说,这是一个非常方便的GPU加速方案.很多工 ...
- 深度学习“引擎”之争:GPU加速还是专属神经网络芯片?
深度学习“引擎”之争:GPU加速还是专属神经网络芯片? 深度学习(Deep Learning)在这两年风靡全球,大数据和高性能计算平台的推动作用功不可没,可谓深度学习的“燃料”和“引擎”,GPU则是引 ...
- GPU加速有坑?
大多数人都知道有动画的地方可以使用GPU来加速页面渲染. 例如,做优化的时候,将使用left和top属性的动画修改成使用transform属性的CSS动画.或者听到别人教你使用transform:tr ...
- Keras学习环境配置-GPU加速版(Ubuntu 16.04 + CUDA8.0 + cuDNN6.0 + Tensorflow)
本文是个人对Keras深度学习框架配置的总结,不周之处请指出,谢谢! 1. 首先,我们需要安装Ubuntu操作系统(Windows下也行),这里使用Ubuntu16.04版本: 2. 安装好Ubunt ...
随机推荐
- 卧槽,好强大的魔法,竟能让Python支持方法重载
1. 你真的了解方法重载吗? 方法重载是面向对象中一个非常重要的概念,在类中包含了成员方法和构造方法.如果类中存在多个同名,且参数(个数和类型)不同的成员方法或构造方法,那么这些成员方法或构造方法就被 ...
- 安鸾渗透实战平台-PHP代码练习
0x00 前言 --工欲善其事,必先利其器 0x01 代码理解 (1)linux命令 pwd 查看当前工作目录的完整路径 cd / 切换到根目录 ls / 查看根目录下的所有目录和文件 cat /[f ...
- 实现 Abp Vnext Pro
Abp Vnext Pro 的 Vue 实现版本 开箱即用的中后台前端/设计解决方案 知识点 .Net Core5.0 Abp Vnext 4.x , Ant Design, Vue2.x Mysql ...
- android上实现0.5px线条
转: android上实现0.5px线条 由于安卓手机无法识别border: 0.5px,因此我们要用0.5px的话必须要借助css3中的-webkit-transform:scale缩放来实现. 原 ...
- 9.Vue之webpack打包基础---模块化思维
主要内容: 1. 什么是模块化思维? 2. ES6包的封装思想 一.什么是模块化思维呢? 现实工作中, 一个项目可能会有多个人同时开发. 然后, 将所有人开发的内容, 合并到一个文件中. 比如: 1 ...
- BERT 服务化 bert-as-service
bert-as-service 用 BERT 作为句子编码器, 并通过 ZeroMQ 服务托管, 只需两行代码就可以将句子映射成固定长度的向量表示; 准备 windows10 + python3.5 ...
- Mybatis系列全解(二):Mybatis简介与环境搭建
封面:洛小汐 作者:潘潘 Mybatis 是一套持久层框架,灵活易用,特别流行. 前言 Mybatis系列全解,我们预计准备10+篇文章,让我们了解到 Mybatis 的基本全貌,真正从入门到上手,从 ...
- 【粉丝问答10】C语言关键字static的使用详解
视频地址:https://www.ixigua.com/6935761378816819748 粉丝提问 粉丝问题,总结一下: 关键字static的使用方法. 要想搞清楚关键字static的使用方法, ...
- [数据结构与算法-15]单源最短路径(Dijkstra+SPFA)
单源最短路径 问题描述 分别求出从起点到其他所有点的最短路径,这次主要介绍两种算法,Dijkstra和SPFA.若无负权优先Dijkstra算法,存在负权选择SPFA算法. Dijkstra算法 非负 ...
- requirejs的用法
requirejs的用法 2014年11月6日 17164次浏览 之前我的一片文章介绍过requirejs,具体地址是:http://www.haorooms.com/post/RequireJS_m ...