MMDetection性能优化

MMDetection性能优化
xiuqhouMMDetection性能优化
使用MMDetection训练时发现速度特别慢,使用nvidia-smi -l 1
命令,发现训练时GPU利用率大部分时间是0,说明GPU处于空闲状态在等待数据的到来,内存带宽和数据加载速度已经成为模型训练的瓶颈了,需要想办法提升加载速度。
设置PyTorch可以使用的最大线程数
PyTorch默认使用一半的CPU核心运行,而MMDetection在运行时为防止机器过载可能会限制可利用的核心数为1,导致速度慢,可以在训练的语句前面加上环境变量来修改这一限制。
1 | 原始命令 |
也可以在python程序的起始位置使用os库设置环境变量:
1 | import os |
实验发现并非数值越大越好,我设置为2的时候训练时间最短。
增大workers_per_gpu和samples_per_gpu
workers_per_gpu
表示读取数据时每个gpu分配的线程数,samples_per_gpu
表示每个GPU的样本数目。增大这两项会使GPU同时处理更多的数据,因此会增大显存占用,对速度的提升效果也并非越大越好。源码显示batch_size=workers_per_gpu * samples_per_gpu
,因此设置这两项会改变训练时的batch_size
,而测试时batch_size=1
。
根据线性缩放原则,增大batch_size
时也需要对学习率lr
按比例缩放,mmdetection默认的学习率缩放策略如下:
1 | auto_scale_lr = dict(enable=False, base_batch_size=16) |
其中base_batch_size
是一个缩放基准,任何情况下都不能修改。如果要进行学习率缩放,可以设置enable=True
,或手动按调整优化策略:
1 | optimizer = dict(type='SGD', lr=0.025, momentum=0.9, weight_decay=0.0001) # 调整这里的`lr`参数 |
设置锁页内存
CUDA有分页内存Peageable Memory和锁页内存Pinned Memory的概念,GPU访问分页内存数据时需要首先开辟临时缓冲区(Pinned Memory),然后将数据从分页内存复制到锁页内存上才能读取,而Pytorch框架中DataLoader可以设置pin_memory=True
,这会默认打开锁页内存,使硬件外设直接访问CPU内存,避免过多的复制操作,提高数据读取速度。mmdetection默认关闭锁页内存,可以在数据集配置的data
环节增加如下设置打开:
1 | data = dict( |