本文采用的方法为作者独自设计,未参考其他框架的思路。如有雷同纯属巧合。
注意事项
神经网络的多卡并行训练通常有两个思路,一是数据并行,二是网络并行。数据并行即多张显卡上使用的是同一个网络和权重,将训练集拆分为两个部分,各自计算之后,将权重变化取平均值并同时更新。网络并行即考虑网络本身规模很大,因此需要将网络分成多个部分存在多张显卡上。因为这个并行设计与网络结构相关,需要针对具体问题,通用性不高,本文只分析数据并行的情况。
本文也不讨论多机并行,因为多机并行通常延迟较高,提速效果有限。
线程的分配来说,按Nvidia的推荐,一个线程控制一个显卡比较适合。因此线程设计采取1+N的模式,即主线程+N个副线程,其中N为显卡的个数。主线程负责调度和处理数据集,每个副线程对应一个显卡,控制GPU的运行。
多显卡的程序在调试过程中相对比较困难,因为一旦跨显卡调用错误,可能导致整个系统卡死,后续的调试异常困难。因此,有几个cuda设备相关的函数在这里非常关键,例如:cudaSetDevice,cudaMemcpyPeer等。它们用于设置本线程使用的显卡和跨显卡复制数据,使用时必须非常谨慎!
Nvidia旧版的驱动还存在一个诡异的问题。驱动附带的nvml可以得到显卡的更多信息,但