基于Darknet与pexpect的4张图片并行检测性能问题咨询
Darknet+pexpect并行检测性能疑问:单张70ms,4张并行耗时300ms
我尝试用Darknet结合pexpect对4张图片做并行检测处理,单张图片检测耗时70ms,但4张并行检测总耗时300ms。想请教是我的实现方式有误,还是必须依赖多GPU支持?
测试代码
class Darknet: def __init__(self): self.instance = pexpect.spawn(f'darknet detector test {config.OBJ_DATA} {config.YOLOV3} {config.WEIGHTS} -ext_output -dont_show') self.instance.delaybeforesend = None self.instance.delayafterread = None self.instance.expect('Enter Image Path:') self.available = True def process(self, image_name): self.instance.sendline(image_name) self.instance.expect('milli-seconds.', timeout=600) self.instance.expect('Enter Image Path:', timeout=600) output = self.instance.before logging.info(output) return output class PexpectPerformanceTest(unittest.TestCase): def test_pexpect_speed(self): image_path = "/app/tmp/training_set/125_20231113_100730_609_3.jpg" darknet_instance_1 = SimpleDarknetThread(Darknet(), image_path) darknet_instance_2 = SimpleDarknetThread(Darknet(), image_path) darknet_instance_3 = SimpleDarknetThread(Darknet(), image_path) darknet_instance_4 = SimpleDarknetThread(Darknet(), image_path) darknet_instance_1.start() darknet_instance_2.start() darknet_instance_3.start() darknet_instance_4.start() darknet_instance_1.join() darknet_instance_2.join() darknet_instance_3.join() darknet_instance_4.join() print(f"Darknet 1 output: {darknet_instance_1.output}") print(f"Darknet 2 output: {darknet_instance_2.output}") print(f"Darknet 3 output: {darknet_instance_3.output}") print(f"Darknet 4 output: {darknet_instance_4.output}") class SimpleDarknetThread(threading.Thread): def __init__(self, darknet, image_path): super().__init__() self.darknet = darknet self.image_path = image_path self.output = None def run(self): start_time = time.time() self.output = self.darknet.process(self.image_path) print(f"Required time: {(time.time() - start_time):.2f} s") if __name__ == "main": unittest.main()
问题分析
你的实现方式存在两个核心问题,是导致并行性能不佳的主要原因:
- 多进程重复加载模型,抢占GPU资源:每个
Darknet实例都会启动一个独立的darknet detector test进程,每个进程都会把YOLO模型完整加载到GPU显存中。单GPU的计算资源是有限的,4个进程同时争抢GPU算力,会导致每个推理任务的实际运行时间被拉长,加上进程启动、上下文切换的额外开销,总耗时接近单张耗时的4倍。 - pexpect子进程交互的额外开销:pexpect通过命令行交互的方式传递图片路径,每个子进程的IO交互都有延迟,并行多个子进程会放大这种开销。
优化方案
不需要立刻升级多GPU,通过调整实现方式就能大幅提升并行效率:
- 复用单个Darknet进程处理多张图片:
darknet detector test模式支持连续输入图片路径,不需要为每张图片启动新进程。可以启动一个Darknet进程,用线程安全的任务队列分发图片,让单个进程串行处理(或结合Darknet的批处理能力),避免重复加载模型和资源争抢。 - 使用批处理推理:Darknet支持一次性传入多张图片做批处理检测,GPU对批处理任务的并行利用率更高。修改命令行参数为
darknet detector test ... -batch 4,一次性传入4张图片,总耗时会远低于单张耗时的4倍。 - 改用Darknet Python绑定:直接调用Darknet的Python API(比如官方提供的
darknet.py),在Python中一次性加载模型,再用多线程/多进程处理图片。这种方式避免了命令行交互的开销,且模型只加载一次,显存占用更低,GPU利用率更高。 - 控制并行进程数:如果必须保留多进程模式,单GPU下建议并行进程数控制在2-3个,避免过度抢占资源导致效率下降。
总结
当前的性能问题主要是实现方式不合理导致的,单GPU环境下通过优化就能提升并行效率;如果需要进一步处理更多图片的并行检测,多GPU可以提供额外的算力支持,但不是解决当前问题的必要条件。
内容的提问来源于stack exchange,提问作者stefansingularity99
相关产品推荐
相关产品推荐

