YOLOv5提高检测速度:使用detect.py进行多进程推理
需求
我们的项目有一个需求,就是10s之内得检测完一张图片。但实际上程序可能需要的时间接近40s,所以就有了一个多线程的需求。所以下面测试我将通过跑3次相同路径下图片的耗时进行比较。使用的GPU设备是RTX3060。
原始推理
我先对他的main函数做了一些简单的修改。
def main(path):
opt = parse_opt(path)
check_requirements(ROOT / 'requirements.txt', exclude=('tensorboard', 'thop'))
return run(**vars(opt))
if __name__ == '__main__':
s_t = time.time()
path1 = "data/PCBDatasets/images"
path2 = "data/PCBDatasets/images"
path3 = "data/PCBDatasets/images"
# 原始推理
main(path1)
main(path2)
main(path3)
print("Tatal Cost Time:", time.time() - s_t)
通过上述的方式连续跑三次,耗时23s-29s。
多进程推理
同样的,对代码进行一些小修改。
import multiprocessing as mp
def main(path):
opt = parse_opt(path)
check_requirements(ROOT / 'requirements.txt', exclude=('tensorboard', 'thop'))
return run(**vars(opt))
if __name__ == '__main__':
s_t = time.time()
path1 = "data/PCBDatasets/images"
path2 = "data/PCBDatasets/images"
path3 = "data/PCBDatasets/images"
# 多进程推理
p1 = mp.Process(target=main, args=(path1,))
p2 = mp.Process(target=main, args=(path2,))
p3 = mp.Process(target=main, args=(path3,))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print("Tatal Cost Time:", time.time() - s_t)
多进程的耗时为11.1s。
根据这种对比方式,得到的结果确实和网站上的一致,多进程均在不同程度上提高了速度。
多进程结合实际应用进行验证
但是我觉得这一个对比方式有一个错误。原始推理实际上一次检测只需要加载一次模型就可以了,但是这个比较方式原始推理加载了5次模型,明显比实际上消耗了更多的时间。所以我在下面做了额外的实验。
我进行了实际应用的对比。即将多进程融入到一整张大图的检测过程中。原始推理的实验还是按照正常的流程,对大图进行切割,然后加载模型检测检测。多进程的实验我就对过程进行了一下修改。对大图进行切割,然后将切割后的小图分到n个不同的文件夹中,然后加载n个模型,分别检测n个文件夹。根据结果发现,双进程的单张耗时约等于原始推理的两倍,四进程的单张耗时约等于原始推理的四倍,然后开n进程又会多出额外的加载模型的时间,导致开进程并没有提高速度反而降低了速度。
我暂时是没有明白问题出在了哪里。如果后续还有添加实验验证会继续补充。