0x01 GPU如何加速深度学习

深度学习的实现似乎很复杂,但是其本质上还是一堆高等代数。

常用的运算还是比如矩阵加法和矩阵乘法。

比如,我们对一个向量套一个sigmoid函数:

python pytorch cuda什么作用 pytorch .cuda()_深度学习
python pytorch cuda什么作用 pytorch .cuda()_深度学习_02

如果只用CPU来做计算的话,它的计算过程是:逐个对python pytorch cuda什么作用 pytorch .cuda()_门延迟_03求sigmoid函数值,然后扔到向量里面。

有两种方法可以加快计算速度。

第一种是加快CPU的计算速度,这要求增加时钟频率。

能耗关系公式是: python pytorch cuda什么作用 pytorch .cuda()_门延迟_04 。其中 python pytorch cuda什么作用 pytorch .cuda()_深度学习_05 是常数, python pytorch cuda什么作用 pytorch .cuda()_CUDA_06 是电压, python pytorch cuda什么作用 pytorch .cuda()_CUDA_07 是频率。但是这并不意味着 python pytorch cuda什么作用 pytorch .cuda()_CUDA_07python pytorch cuda什么作用 pytorch .cuda()_CUDA_09

这块我们要引入门延迟(Gate Delay)的概念。简单来说,组成CPU的FET充放电需要一定时间,这个时间就是门延迟。只有在充放电完成后采样才能保证信号的完整性。而这个充放电时间和电压负相关,即电压高,则充放电时间就短。也和制程正相关,即制程越小,充放电时间就短。让我们去除制程的干扰因素,当我们不断提高频率后,过了某个节点,太快的翻转会造成门延迟跟不上,从而影响数字信号的完整性,从而造成错误。这也是为什么超频到某个阶段会不稳定,随机出错的原因。因此,可以通过提高电压来减小门延迟,让系统重新稳定下来。

因此,我们提高频率,同时为了保持运行稳定提高电压…这样做的后果就是闻到CPU的香气。

第二种方法就是并行地同时做计算。并行计算这些值不需要更快的处理器,只需要更多的处理器。这就是gpu的工作原理。

GPU是用来创建和处理图像的。由于每个像素的值都可以独立于其他像素进行计算,所以最好有很多较弱的处理器,而不是一个非常强大的处理器按顺序进行计算。

这与我们对深度学习模型的情况相同。大多数操作可以很容易地分解成可以独立完成的部分。

以往,在实际应用中,通用GPU编程长期不可用。GPU只能做图形,如果你想利用它们的处理能力,你需要学习OpenGL等图形编程语言。这不太实际,进入的门槛很高。

直到2007年,nVidia推出了CUDA框架,这是C的一个扩展,它为GPU计算提供了一个API。这显著地拉平了用户的学习曲线。

0x02 Pytorch对GPU(cuda)的调用

用GPU加速一共只需要干三件事:

  1. 声明自己要用GPU
  2. 把模型扔上去
  3. 把数据扔上去

对于1,我们可以简单粗暴地来一个:

device = "cuda" if CUDA_IS_AVAILABLE else "cpu"

2和3的话,只需要在模型和数据后面跟一个 to(device) 就行了。