## 34 多GPU训练实现

本讲内容为代码实现，这里整理QA，其余内容参考代码部分。

Q1: keras从tf分离，书籍会不会需要重新整理？

> 暂时不会有影响

Q2: 是否可以通过把resnet中的卷积层全替换成mlp来实现一个很深的网络？

> 可以，有这样做的paper，但是通过一维卷积（等价于全连接层）做的，如果直接换成全连接层很可能会过拟合。

Q3: 为什么batch norm是一种正则但只加快训练不提升精度？

> 老师也不太清楚并认为这是很好的问题，可以去查阅论文。

Q4: all_reduce, all_gather主要起什么作用？实际使用时发现pytorch的类似分布式op不能传导梯度，会破坏计算图不能自动求导，如何解决？

> all_reduce是把n个东西加在一起再把所有东西复制回去，all_gather则只是把来自不同地方东西合并但不相加。使用分布式的东西会破坏自动求导，跨GPU的自动求导并不好做，老师不确定pytorch能不能做到这一功能，如果不能就只能手写。

Q5: 两个GPU训练时最后的梯度是把两个GPU上的梯度相加吗？

> 是的。mini-batch的梯度就是每个样本的梯度求和，多GPU时同理，每个GPU向将自己算的那部分样本梯度求和，最后再将两个GPU的计算得的梯度求和。

Q6: 为什么参数大的模型不一定慢？flop数多的模型性能更好是什么原理？

> 性能取决于每算一个乘法需要访问多少个bit，计算量与内存访问的比值越高越好。通常CPU/GPU不会被卡在频率上而是访问数据/内存上，所以参数量小，算力高的模型性能较好（如卷积，矩阵乘法）。

Q7: 为什么分布到多GPU上测试精度会比单GPU抖动大？

> 抖动是因为学习率变大了，使用GPU数对测试精度没有影响，只会影响性能。但为了得到更好的速度需要把batchsize调大，使得收敛情况发生变化，把学习率上调就使得精度更抖。

Q8: batchsize太大会导致loss nan吗？

> 不会，batchsize中的loss是求均值的，理论上batchsize更大数值稳定性会更好，出现数值不稳定问题可能是学习率没有调好。

Q9: GPU显存如何优化？

> 显存手动优化很难，靠的是框架，pytorch的优化做的还不错。除非特别懂框架相关技术不然建议把batchsize调小或是把模型做简单一点。

Q10: 对于精度来说batchsize=1是一种最好的情况吗？

> 可能是。

Q11: parameter server可以和pytorch结合吗，具体如何实现？

> pytorch没有实现parameter server，但mxnet和tensorflow有。但是有第三方实现如byteps支持pytorch。

Q12: 用了nn.DataParallel()，是不是数据集也被自动分配到了多个GPU上？

> 是的。在算net.forward()的时候会分开。

Q13: 验证集准确率震荡大那个参数影响最大？

> 学习率。

Q14: 为了让网络前几层能够训练能否采用不同stage采用不同学习率的方法？

> 可以，主要的问题是麻烦，不好确定各部分学习率相差多少。

Q15: 在用torch的数据并行中将inputs和labels放到GPU0是否会导致性能问题，因为这些数据最终回被挪一次到其他GPU上。

> 数据相比梯度来说很少，不会对性能有太大影响。但这个操作看上去的确很多余，老师认为不需要做，但不这样做会报错。

Q16: 为什么batchsize较小精度会不怎么变化？

> 学习率太大了，batchsize小学习率就不能太大。

Q17: 使用两块不同型号GPU影响深度学习性能吗？

> 需要算好两块GPU的性能差。如一块GPU的性能是另一块的2倍，那么在分配任务时也应该分得2倍的任务量。保证各GPU在同样时间内算完同一部分。

Q18: 课内竞赛直接用教材的VGG11但不收敛，同样的dataloader用resnet可以收敛，如何解决这一问题？

> 可能是学习率太大，也可考虑加入batch normalization。

