3 Multi-GPU

Multi-GPU原理

torch单机多卡基本原理:使用多张卡的GPU单元来加速运算(实例如下):

假设我们一次性读入一个batch的数据, 其大小为[16, 10, 5],我们有四张卡可以使用。那么计算过程遵循以下步骤:

1、pytorch先把初始模型同步放到4个GPU中

2、将数据分为4份,按照次序放置到四个GPU的模型中,每一份大小为[4, 10, 5]

3、每个GPU分别进行前项计算过程

4、前向过程计算完后,pytorch再从四个GPU中收集计算后的结果假设[4, 10, 5],然后再按照次序将其拼接起来[16, 10, 5],计算 Loss

整个过程其实就是: 同步模型参数→分别前向计算→计算损失→梯度反传

注:模型要求所有的数据和初始网络被放置到GPU0(即多GPU中的第一块)。

Muti-GPU使用

https://blog.csdn.net/qq_34243930/article/details/106695877

nn.DataParallel():

torch.nn.DataParallel(
	module, 					# 即模型,此处注意,虽然输入数据被均分到不同gpu上,但每个gpu上都要拷贝一份模型。
	device_ids=None, 				# 即参与训练的gpu列表,例如三块卡, device_ids = [0,1,2]。
	output_device=None, 				# 指定输出gpu,一般省略。在省略的情况下,默认为第一块卡,即索引为0的卡。此处有一个问题,输入计算是被几块卡均分的,但输出loss的计算是由这一张卡独自承担的,这就造成这张卡所承受的计算量要大于其他参与训练的卡。
	dim=0)						# 不懂?

注:在同一台机器上要运行多个程序时,我们需要在程序中重新指定其可见的 devices

os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"		 
os.environ["CUDA_VISIBLE_DEVICES"] = "2, 3"		# 假设我们要使用第三第四张卡

注:当添加这两行代码后,那么 device_ids[0] 默认的就是第 2 号卡,模型也会初始化在第 2 号卡上了,而不会占用第 0 号卡了。

注:多GPU计算减少了程序运行的时间?

很多人发现在进行多GPU运算时,程序花费的时间反而更多了,这其实是因为batch_size太小了,因为torch.nn.DataParallel()这个函数是将每个batch的数据平均拆开分配到多个GPU上进行计算,计算完再返回来合并。这导致GPU之间的开关和通讯过程占了大部分的时间开销。

可以使用 watch -n 1 nvidia-smi 这个命令来查看每1s各个GPU的运行情况,如果发现每个GPU的占用率均低于50%,则使用多GPU计算所花的时间要比单GPU计算花的时间更长。

posted @ 2021-10-03 18:00  SethDeng  阅读(155)  评论(0编辑  收藏  举报