Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
d2l-zh
提交
437f1fff
D
d2l-zh
项目概览
OpenDocCN
/
d2l-zh
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
d2l-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
437f1fff
编写于
9月 13, 2018
作者:
A
Aston Zhang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
2pass gpu
上级
f731a01e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
20 addition
and
16 deletion
+20
-16
chapter_deep-learning-computation/use-gpu.md
chapter_deep-learning-computation/use-gpu.md
+20
-16
未找到文件。
chapter_deep-learning-computation/use-gpu.md
浏览文件 @
437f1fff
# GPU计算
目前为止我们一直在使用CPU计算。对于复杂的神经网络和大规模的数据来说,使用CPU来计算可能不够高效。本节中,我们将介绍如何使用单块Nvidia GPU来计算。首先,需要确保
至少有一块Nvidia GPU已经安装好了。然后,下载
[
CUDA
](
https://developer.nvidia.com/cuda-downloads
)
并按照提示设置好相应的路径。这些准备工作都完成后,下面就可以通过
`nvidia-smi`
来查看显卡信息了。
目前为止我们一直在使用CPU计算。对于复杂的神经网络和大规模的数据来说,使用CPU来计算可能不够高效。本节中,我们将介绍如何使用单块Nvidia GPU来计算。首先,需要确保
已经安装好了至少一块Nvidia GPU。然后,下载CUDA并按照提示设置好相应的路径 [1]。这些准备工作都完成后,下面就可以通过
`nvidia-smi`
命令
来查看显卡信息了。
```
{.python .input n=1}
!nvidia-smi
```
接下来,我们需要确认安装了MXNet的GPU版本。如果装了MXNet的CPU版本,我们需要先卸载它
。例如我们可以使用
`pip uninstall mxnet`
。然后根据CUDA的版本安装对应的MXNet版本。假设你安装了CUDA 9.1,那么我们可以通过
`pip install --pre mxnet-cu91`
来安装支持CUDA 9.1的MXNet版本
。
接下来,我们需要确认安装了MXNet的GPU版本。如果装了MXNet的CPU版本,我们需要先卸载它
,例如使用
`pip uninstall mxnet`
命令,然后根据CUDA的版本安装相应的MXNet版本。假设你安装了CUDA 9.0,可以通过
`pip install mxnet-cu90`
来安装支持CUDA 9.0的MXNet版本。运行本节中的程序需要至少两块GPU
。
## 计算设备
MXNet
使用
`context`
来指定用来存储和计算的设备,例如可以是CPU或者GPU。默认情况下,MXNet会将数据创建在主内存,然后利用CPU来计算。在MXNet中,CPU和GPU可分别由
`cpu()`
和
`gpu()`
来表示。需要注意的是,
`mx.cpu()`
(或者在括号里填任意整数)表示所有的物理CPU和内存。这意味着计算上
会尽量使用所有的CPU核。但
`mx.gpu()`
只代表一块显卡和相应的显卡内存。如果有多块GPU,我们用
`mx.gpu(i)`
来表示第$i$块GPU($i$从0开始)且
`mx.gpu(0)`
和
`mx.gpu()`
等价。
MXNet
可以指定用来存储和计算的设备,例如CPU或者GPU。默认情况下,MXNet会将数据创建在主内存,然后利用CPU来计算。在MXNet中,CPU和GPU可分别由
`cpu()`
和
`gpu()`
来表示。需要注意的是,
`mx.cpu()`
(或者在括号里填任意整数)表示所有的物理CPU和内存。这意味着MXNet的计算
会尽量使用所有的CPU核。但
`mx.gpu()`
只代表一块显卡和相应的显卡内存。如果有多块GPU,我们用
`mx.gpu(i)`
来表示第$i$块GPU($i$从0开始)且
`mx.gpu(0)`
和
`mx.gpu()`
等价。
```
{.python .input}
import mxnet as mx
...
...
@@ -29,7 +29,7 @@ x = nd.array([1, 2, 3])
x
```
我们可以通过NDArray的
`context`
属性来查看
其
所在的设备。
我们可以通过NDArray的
`context`
属性来查看
该NDArray
所在的设备。
```
{.python .input}
x.context
...
...
@@ -37,21 +37,21 @@ x.context
### GPU上的存储
我们有多种方法将NDArray
放置在GPU上。例如我们可以在创建NDArray的时候通过
`ctx`
指定存储设备。下面我们将
`a`
创建在GPU 0上。注意到在打印
`a`
时,设备信息变成了
`@gpu(0)`
。创建在GPU上时我们会只用GPU内存,你可以通过
`nvidia-smi`
查看GPU内存使用情况。通常你需要确保不要
创建超过GPU内存上限的数据。
我们有多种方法将NDArray
存储在GPU上。例如我们可以在创建NDArray的时候通过
`ctx`
参数指定存储设备。下面我们将NDArray变量
`a`
创建在
`gpu(0)`
上。注意到在打印
`a`
时,设备信息变成了
`@gpu(0)`
。创建在GPU上的NDArray只消耗相同GPU的内存。我们可以通过
`nvidia-smi`
命令查看GPU内存的使用情况。通常,我们需要确保不
创建超过GPU内存上限的数据。
```
{.python .input n=5}
a = nd.array([1, 2, 3], ctx=mx.gpu())
a
```
假设你至少有两块GPU,下面代码将会在
GPU 1上创建随机数组
假设你至少有两块GPU,下面代码将会在
`gpu(1)`
上创建随机数组。
```
{.python .input}
b = nd.random.uniform(shape=(2, 3), ctx=mx.gpu(1))
b
```
除了在创建时指定,我们也可以通过
`copyto`
和
`as_in_context`
函数在设备之间传输数据。下面我们将CPU上的
`x`
复制到GPU 0
上。
除了在创建时指定,我们也可以通过
`copyto`
和
`as_in_context`
函数在设备之间传输数据。下面我们将CPU上的
NDArray变量
`x`
复制到
`gpu(0)`
上。
```
{.python .input n=7}
y = x.copyto(mx.gpu())
...
...
@@ -63,13 +63,13 @@ z = x.as_in_context(mx.gpu())
z
```
需要区分的是,如果源变量和目标变量的
`context`
一致,
`as_in_context`
使目标变量和源变量共享源变量的内存,
需要区分的是,如果源变量和目标变量的
`context`
一致,
`as_in_context`
函数
使目标变量和源变量共享源变量的内存,
```
{.python .input n=8}
y.as_in_context(mx.gpu()) is y
```
而
`copyto`
总是为目标变量新创建
内存。
而
`copyto`
函数总是为目标变量创建新的
内存。
```
{.python .input}
y.copyto(mx.gpu()) is y
...
...
@@ -77,19 +77,17 @@ y.copyto(mx.gpu()) is y
### GPU上的计算
MXNet的计算会在数据的
`context`
上执行。为了使用GPU计算,我们只需要事先将数据放在GPU上面。而
计算结果会自动保存在相同的GPU上。
MXNet的计算会在数据的
`context`
所指定的设备上执行。为了使用GPU计算,我们只需要事先将数据存储在GPU上。
计算结果会自动保存在相同的GPU上。
```
{.python .input n=9}
(z + 2).exp() * y
```
注意,MXNet要求计算的所有输入数据都在同一个CPU/GPU上。这个设计的原因是不同CPU/GPU之间的数据交互通常比较耗时。因此,MXNet希望用户确切地指明计算的输入数据都在同一个CPU/GPU上。例如,如果将CPU上的
`x`
和GPU上的
`y`
做运算,会出现错误信息。
当我们打印NDArray或将NDArray转换成NumPy格式时,如果数据不在主内存里,MXNet会自动将其先复制到主内存,从而带来隐形的传输开销。
注意,MXNet要求计算的所有输入数据都在CPU或同一个GPU上。这个设计的原因是CPU和不同的GPU之间的数据交互通常比较耗时。因此,MXNet希望用户确切地指明计算的输入数据都在CPU或同一个GPU上。例如,如果将CPU上的NDArray变量
`x`
和GPU上的NDArray变量
`y`
做运算,会出现错误信息。当我们打印NDArray或将NDArray转换成NumPy格式时,如果数据不在主内存里,MXNet会将它先复制到主内存,从而造成额外的传输开销。
## Gluon的GPU计算
同NDArray类似,Gluon的模型可以在初始化时通过
`ctx`
指定设备。下面代码将模型参数初始化在GPU上。
同NDArray类似,Gluon的模型可以在初始化时通过
`ctx`
参数
指定设备。下面代码将模型参数初始化在GPU上。
```
{.python .input n=12}
net = nn.Sequential()
...
...
@@ -103,7 +101,7 @@ net.initialize(ctx=mx.gpu())
net(y)
```
确认一下模型参数存储在相同的GPU上。
下面我们
确认一下模型参数存储在相同的GPU上。
```
{.python .input n=14}
net[0].weight.data()
...
...
@@ -111,7 +109,8 @@ net[0].weight.data()
## 小结
*
通过
`context`
,我们可以在不同的CPU/GPU上存储数据和计算。
*
MXNet可以指定用来存储和计算的设备,例如CPU或者GPU。默认情况下,MXNet会将数据创建在主内存,然后利用CPU来计算。
*
MXNet要求计算的所有输入数据都在CPU或同一个GPU上。
## 练习
...
...
@@ -121,3 +120,8 @@ net[0].weight.data()
## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/988)
![](
../img/qr_use-gpu.svg
)
## 参考文献
[1] CUDA下载地址。 https://developer.nvidia.com/cuda-downloads
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录