已经证实了我的猜想“从batch_size角度考虑”的正确性。详细解释在后面更新。
GPU利用率低而显存占用率高的思考
问题描述:在深度学习training中,可以看到cpu利用率很高、内存占用率很高、显存占用率很 高,但GPU利用率很低,train比较耗时。
本文对这个问题进行了思考。
(仅仅是自己遇到问题思考的一些内容,也不一定正确,期待和大家交流探讨)
1.先了解下深度学习中数据的加载问题
先将硬盘中的数据读取到内存中,然后CPU从内存中读取数据,再将数据传输到显存中,等待GPU处理,处理完成之后会传递一部分参数数据到CPU。同时CPU还会将网络和损失函数等传递给GPU。详细可以看这里:。
2.遇到的问题描述
性能可以在任务管理中查看,也可以通过终端查看。不多过阐述。
内存占用率很高(27G/63G);CPU利用率很高70%-90%;显存占用率很高,GPU利用率不高。可以看下图,我用的dataset是Cityscapes精细标注的版本。
3.问题分析
1)从CPU传输数据角度来考虑
GPU处理的数据是从CPU拿过来的,是否存在io传输瓶颈的问题?针对我的情况来看,我的理解是cpu、显存占用率都这么高,可以理解为GPU要从显存拿数据做处理,如果传输受到了限制,那首先显存占用率会降下来,所以这一点可以排除。
2)从batch_size角度考虑
可以从bs传输数据的的角度考虑,先假设GPU处理数据时间小于数据传输时间(具体计算是又模型来决定,而且确实是小于的,因为没看到显卡的数据一直是满的),当传一个bs的数据就非常大的时候(足以占满显存),那GPU利用率低的主要原因是由于显存大小限制的,因为GPU一直在空闲等待数据中。
但是这个角度我还不能验证,等我训练完之后抽空试试看,但是这个思路可以和大家分享。
以上两点是我的思考,以下是两点有关调参的小tips。
Num_works和pin memory这两个参数的作用,第一个是开辟多少个CPU线程来处理数据,可以根据CPU核数设置,一般用4,8,16等。但是这个参数也不能太大。当这个参数太大是,在分发数据的时候可能会消耗一定的时间,极端点可以理解为CPU处理数据很快只要1s,但是因为线程数太多而分发数据的时候花了5s。pin memory的介绍可以参考这里:pin_memory - 知乎。简单讲就是该参数开启时,可以减少数据传递到显存中的时间。
更新2022.5.31
解释:这段时间对代码有进行了修改,对细节也把握更多了。我跑的代码是GSCNN的代码,看到作者传进模型的feature map 是[b,3,720,720],进过wideresnet七层处理之后最后得到m7为[b,4096,90,90],然后传入到ASPP做卷积操作。当时跑代码的时候,模型只有cnn的计算,可以看到设备使用情况,在上面可以看到。当时设置的训练集和验证集的bs都为6,num_works设置好像为5.
后面这段时间我将transformers加入到GSCNN中,计划是将在不同的cnn层之后加入TF,但是在实际操作过程中由于太吃显存了,硬件条件有限(48G 2*3090),最后只加了一层TF,但是就这一层TF加进去之后,GPU的利用率马上就上来了。很明显大家都知道TF的计算量是非常大的。所以基于这一点我们可以得出结论,之前显存里面全是加载进来的数据,GPU计算性能没被拉满,是因为受到显存的限制。假设GPU的计算能力为十个单位。传入同样大小的数据,以占满显存为准(48G),纯CNN的时候计算需求为1个单位,那加入TF之后计算需求为4个单位。(举个例子)
性能利用率对比
内存 | cpu利用率 | 显存 | GPU利用率 | |
CNN | 27 | 89% | 23.8/24 | 9% |
CNN+TF | 21.6 | 40% | 23.3/24 | 40% |
关于内存和CPU利用率变化的原因是bs和num_works设置的时候不一样引起的,这个不是重点讨论对象,根据这个现象我们可以得出结论:1、显存会限制GPU性能的发挥,2、利用率(可以理解为计算需求)和模型中计算量有关。
思考到这里我又有了疑问了:之前也跑过同样数据集,好像是deeplabv3+模型,其中一个模型跑起来速度超级快的,(当时已经意识到了GPU利用率的问题,所以特地有关注GPU利用率)GPU利用率也很高,好想达到了百分之八九十的样子。对比这个模型(纯CNN的),同样都是一些卷积操作,为什么dpV3+ 跑起来GPU利用率那么高,训练耗时少 ,而gscnn就不行。
结合我上面的思路我考虑到了是不是传给模型的数据问题,我测试了gscnn中传给模型的数据为
[b,3,720,720],但是我没有测试dpV3+的数据是多大,所以疑问就是不同大小分辨率的图片传给模型会对性能有影响吗?为什么有的代码传给模型的分辨率较高,有的较低,这一差异的出发点在哪?
待我探索完成后来更新这个问题的答案。
参考: