博主电脑配置是AMD R5 3600,Nvidia RTX3060 12G,16G 3200MHz内存,训练数据集是自建数据集,大约1200张图片,3个检测目标。
训练YOLOv5-5.0版本的模型参数设置,模型是yolov5s,epoch 150(如果想要更好的mAP@0.5:0.95指标可以设置的更大,博主这个收敛的太快了就没设太多),batchsize 32或者64,imgsize 640,640,其他均为默认。
在最初训练模型的时候训练一次epoch大约需要3分钟,而且不管怎么设置参数,训练时间都不会改变太多,都在3分钟左右,博主期初是因为自己没用GPU跑,但是显存是实实在在的吃满了,但利率用始终在0%和4%之间波动,大多数还是在0%,博主百思不得其解,百度了许多方法都没有用,看了大部分博主的文章,然后看了看运行时候的内存,CPU和GPU,发现CPU使用率不高,但是内存和显存占用很高,那么也就排除了在用CPU跑模型的情况,思来想去大概是出在数据读取上。下面来介绍一些训练模型速度慢可能的原因和解决方法:
1.GPU太差
博主之前用的自己的GTX960m的确跑不起来,如果自己显卡太老,显存太低,要么降低batchsize和worker,还有imgsize,要么就换一张显卡。三个参数的设置在train.py的设置代码如图
2.没用到GPU,完全是CPU在跑
这种情况也很好发现,只需要看看显存是否被占用或者有没有安装pytorch和cuda,可以用如下代码来查看是否装了pytorch和cuda,怎么安装很多博主已经介绍过了,随便一查一大堆。
import torchprint(torch.__version__)torch.cuda.is_available()
上面代码结果如下图,说明正确安装CUDA和pytorch(记得要版本对应,不然会报错),最好把cudnn也装上。
如果是CPU在训练,可以设置下面的代码来更换GPU训练模型,default设置成你GPU的编号就行,单显卡就是0。
3.训练瓶颈
3.1 CPU瓶颈
CPU瓶颈很好判断,那就是CPU占用率很高,同时GPU也在使用,这说明电脑CPU太差了。设置参数,尽量不让CPU占用率超过85%。
3.2 内存瓶颈
简单来说就是内存爆了,基本上不存在内存频率跟不上的,同样设置参数,内存占用也尽量不要超过85%-90%。
3.3 IO瓶颈
这种情况会复杂很多,这个IO可能是硬盘读到内存导致的,也有可能是从内存到GPU导致的,也有可能是读写记录的时候导致的,反正杂七杂八的,最难看出哪里出了问题。
对于以上三种瓶颈可以通过瓶颈测试工具来测试出来,具体方法下面的博客说的很清楚。
(24条消息) PyTorch消除训练瓶颈 提速技巧_*pprp*的博客-CSDN博客
对于前两种瓶颈,都可以通过设置batchsize,workers和imgsize来尝试解决,或者更换yolov5的模型,使用最小的yolov5s来训练,如果以上方法解决不了,建议更换硬件或者租用云服务器。对于第三种情况基本只能通过预读取数据和更换硬件来实现。
4.性能过剩
对,你没有看错,性能过剩也会导致Yolov5训练速度过慢,原因也很让人无语,在train.py中有这样一行代码,这行代码旨在将数据读到内存中进行缓存,这样就可以更快的存取数据。
这样读取数据就可以让正在工作的GPU计算完数据后不会因为硬盘读写太慢而等待数据读入,所以硬盘的读取很重要,训练过程中,数据首先从硬盘读入到内存,然后再从内存读取到CPU或者GPU,所以一块好的硬盘可以有效的加速模型的训练,特别是笔记本硬盘,笔记本硬盘读取速度很慢,建议把数据放入SSD中。那么问题来了,如果GPU计算速度超过了从硬盘读入内存,再从内存读入GPU的速度,并且硬盘的读取速度够快,会发生什么,这也是导致博主训练速度太慢的原因。
对于小批量数据(很多自建数据都是小批量数据),一两千张,检测目标数不多,模型不复杂的情况下,对于高端显卡或者专业图形卡都是小case,基本都用不到多少算力,GPU很快就计算完了一个batch的数据,这时候就要等待数据读入,如果硬盘读写够快,数据从硬盘读入内存,GPU再从内存读出,相较于直接从硬盘读入GPU,本来用作缓存的内存反而成了额外的开销,数据绕了远路,IO读取时间反而增大了。其实说白了还是IO问题造成的,只不过原因不是硬件太差。当然,以上内容是博主的猜测,仅供参考。
所以,对于拥有一个好的SSD,好显卡,内存和CPU性能好的计算机而言,在训练数据量小,模型不大的情况下,建议将cacheimages关掉,直接从硬盘读入GPU,将action=’store_true’替换为action=’store_false’即可,关掉之后博主一次epoch从3分钟变成了20s,提升巨大,而且训练结果没有改变。
总结
大多数情况来说都是性能不足,存在瓶颈的情况,从而导致模型训练时间长,这也是深度学习中常有的事,但是在自己硬件条件好,数据量不大的情况下,模型训练仍然慢,就该考虑下是不是因为性能过剩,在数据存取上花了过多的时间造成的,这表现为内存和显存使用很大,但是CPU和GPU却不怎么占用。经过博主一些测试,博主发现不管有没有用缓存,内存和显存使用都很大,这应该是pytorch底层逻辑的关系,在用GPU跑模型的时候pytorch会自动把数据缓存到显存里,内存使用大小仅仅和batch_size有关。
值得一提的是,虽然训练速度大大增加,但是依然没有解决GPU占用率低的问题,虽然GPU占用率很低,但是不会存在一段时间为0的情况,博主推测,可能是因为数据量太小,所需要检测目标数不多造成计算量太小的原因。博主之前在用VOC2012数据集进行训练时,GPU占用率就不低,但是仍然只占用了30%-60%,不知道使用这种方法有没有效,因为学业问题只能先跑自己数据集,如果有时间博主会更新相关结论。
最后,博主计算机功底不算扎实,如果有问题,希望各位读者指正。