Bonky Zhu
If someone is able to show me that what I think or do is not right, I will happily change, for I seek the truth, by which no one was ever truly harmed. It is the person who continues in his self-deception and ignorance who is harmed.

Pytorch 使用 GPU

关于 GPU

GPU计算单元类似于CPU中的核,用来进行数值计算。衡量计算量的单位是flop: the number of floating-point multiplication-adds,浮点数先乘后加算一个flop。计算能力越强大,速度越快。衡量计算能力的单位是flops: 每秒能执行的flop数量

1*2+3                  1 flop
1*2 + 3*4 + 4*5        3 flop 


占用的显存的计算

主要转自:https://zhuanlan.zhihu.com/p/31558973

虽然说我们都知道一个 Float32浮点数占用的内存为 4 Byte,但不过平时写代码的时候都没有注意显存的计算这回事,这里说只是想要重视显存的估计。

神经网络模型占用的显存包括:

  • 模型自身的参数
  • 模型的输出
  • 梯度与动量的显存占用

模型的显存计算

让我们来看看下面这个全链接网络,Batch 大小为100,输入为32的时候,输出位为16的时候,所占用的显存为 4 * (100 * 32 + 32 * 16 + 100 *16) = 20.75M

v2-81063f1d5864c79bd422b7a42199a079_hd

梯度与动量的显存占用

举例来说, 优化器如果是SGD:

$$W_{t-1}=W_{t}-\alpha\nabla F(W_t)$$

可以看出来,除了保存W之外还要保存对应的梯度 $\nabla F(W)$,因此显存占用等于参数占用的显存x2,

如果是Adam优化器,动量占用的显存更多,显存x4

总结一下,模型中与输入无关的显存占用包括:

  • 参数 W
  • 梯度 dW(一般与参数一样)
  • 优化器的动量(普通SGD没有动量,momentum-SGD动量与梯度一样,Adam优化器动量的数量是梯度的两倍)

优化显存的方法

在深度学习中,一般占用显存最多的是卷积等层的输出,模型参数占用的显存相对较少,而且不太好优化。

节省显存一般有如下方法:

  • 降低batch-size
  • 下采样 (缩小输入维度)
  • 减少全连接层(一般只留最后一层分类用的全连接层)

减少训练时间的思路

  • 时间更宝贵,尽可能使模型变快(减少flop
  • 显存占用不是和batch size简单成正比,模型自身的参数及其延伸出来的数据也要占据显存
  • batch size越大,速度未必越快。在你充分利用计算资源的时候,加大batch size在速度上的提升很有限

尤其是batch-size,假定GPU处理单元已经充分利用的情况下:

  • 增大batch size能增大速度,但是很有限(主要是并行计算的优化)
  • 增大batch size能减缓梯度震荡,需要更少的迭代优化次数,收敛的更快,但是每次迭代耗时更长。
  • 增大batch size使得一个epoch所能进行的优化次数变少,收敛可能变慢,从而需要更多时间才能收敛(比如batch_size 变成全部样本数目)

torch.device

torch.device代表将torch.Tensor分配到的设备的对象。

torch.device包含一个设备类型('cpu''cuda'设备类型)和可选的设备的序号。如果设备序号不存在,则为当前设备; 例如,torch.Tensor用设备构建'cuda'的结果等同于'cuda:X',其中Xtorch.cuda.current_device()的结果。

torch.Tensor的设备可以通过Tensor.device访问属性。

构造torch.device可以通过字符串/字符串和设备编号。

关于 GPU 的一些操作

import torch
# 判断是否 cuda 能够使用,可以通过这个对变量是否执行 cuda()
print(torch.cuda.is_available())
# 判断可以使用的 GPU 数量
print(torch.cuda.device_count())
# 得到选定设备的名字
print(torch.cuda.get_device_name(0))
# 选择当前使用的设备
print(torch.cuda.current_device())

# 输出结果,
True
4
Tesla K80
0


使用指定的 GPU 的方法

原文链接:https://blog.csdn.net/u010454261/article/details/85274900

最近在使用pytorch写程序,想在指定的GPU设备上执行。

假设函数func()使用到了GPU设备:

则在func()函数内部或者调用func()的地方加上:

os.environ["CUDA_VISIBLE_DEVICES"] = str(gpu_id)

自动查找并使用空闲GPU

原文链接:https://blog.csdn.net/u011961856/article/details/77884946

查看GPU memory,并将结果保存在tmp中:

os.system('nvidia-smi -q -d Memory |grep -A4 GPU|grep Free >tmp')


读取gpu memory:

memory_gpu=[int(x.split()[2]) for x in open('tmp','r').readlines()]


求剩余memory最多的显卡号,并设置CUDA_VISIBLE_DEVICES为该显卡:

os.environ['CUDA_VISIBLE_DEVICES']=str(np.argmax(memory_gpu))
os.system('rm tmp')


这里显卡1剩余memory最多,因此CUDA_VISIBLE_DEVICES=1,即使用1号显卡.

运行代码,终端输入nvidia-smi,即可查看显卡使用信息.

屏幕快照 2019-08-26 下午8.31.30

Share

You may also like...

发表评论