Pytorch 用.cuda()的时机
0x01 GPU如何加速深度学习深度学习的实现似乎很复杂,但是其本质上还是一堆高等代数。常用的运算还是比如矩阵加法和矩阵乘法。比如,我们对一个向量套一个sigmoid函数:x=[x1,...,xn]x = [x_1, ... , x_n]x=[x1,...,xn]sigmoid(x)=[sigmoid(x1),...,sigmoid(xn)]sigmoid(x) = [sigmoid(x_1)
0x01 GPU如何加速深度学习
深度学习的实现似乎很复杂,但是其本质上还是一堆高等代数。
常用的运算还是比如矩阵加法和矩阵乘法。
比如,我们对一个向量套一个sigmoid函数:
x
=
[
x
1
,
.
.
.
,
x
n
]
x = [x_1, ... , x_n]
x=[x1,...,xn]
s
i
g
m
o
i
d
(
x
)
=
[
s
i
g
m
o
i
d
(
x
1
)
,
.
.
.
,
s
i
g
m
o
i
d
(
x
n
)
]
sigmoid(x) = [sigmoid(x_1), ... , sigmoid(x_n)]
sigmoid(x)=[sigmoid(x1),...,sigmoid(xn)]
如果只用CPU来做计算的话,它的计算过程是:逐个对 x i x_i xi求sigmoid函数值,然后扔到向量里面。
有两种方法可以加快计算速度。
第一种是加快CPU的计算速度,这要求增加时钟频率。
能耗关系公式是: P = C V 2 f P = CV^2f P=CV2f 。其中 C C C 是常数, V V V 是电压, f f f 是频率。但是这并不意味着 f f f 和 P P P 是线性关系。
这块我们要引入门延迟(Gate Delay)的概念。简单来说,组成CPU的FET充放电需要一定时间,这个时间就是门延迟。只有在充放电完成后采样才能保证信号的完整性。而这个充放电时间和电压负相关,即电压高,则充放电时间就短。也和制程正相关,即制程越小,充放电时间就短。让我们去除制程的干扰因素,当我们不断提高频率后,过了某个节点,太快的翻转会造成门延迟跟不上,从而影响数字信号的完整性,从而造成错误。这也是为什么超频到某个阶段会不稳定,随机出错的原因。因此,可以通过提高电压来减小门延迟,让系统重新稳定下来。
因此,我们提高频率,同时为了保持运行稳定提高电压…这样做的后果就是闻到CPU的香气。
第二种方法就是并行地同时做计算。并行计算这些值不需要更快的处理器,只需要更多的处理器。这就是gpu的工作原理。
GPU是用来创建和处理图像的。由于每个像素的值都可以独立于其他像素进行计算,所以最好有很多较弱的处理器,而不是一个非常强大的处理器按顺序进行计算。
这与我们对深度学习模型的情况相同。大多数操作可以很容易地分解成可以独立完成的部分。
以往,在实际应用中,通用GPU编程长期不可用。GPU只能做图形,如果你想利用它们的处理能力,你需要学习OpenGL等图形编程语言。这不太实际,进入的门槛很高。
直到2007年,nVidia推出了CUDA框架,这是C的一个扩展,它为GPU计算提供了一个API。这显著地拉平了用户的学习曲线。
0x02 Pytorch对GPU(cuda)的调用
用GPU加速一共只需要干三件事:
- 声明自己要用GPU
- 把模型扔上去
- 把数据扔上去
对于1,我们可以简单粗暴地来一个:
device = "cuda" if CUDA_IS_AVAILABLE else "cpu"
2和3的话,只需要在模型和数据后面跟一个 to(device)
就行了。
更多推荐
所有评论(0)