You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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()

问题分析

你的实现方式存在两个核心问题,是导致并行性能不佳的主要原因:

  1. 多进程重复加载模型,抢占GPU资源:每个Darknet实例都会启动一个独立的darknet detector test进程,每个进程都会把YOLO模型完整加载到GPU显存中。单GPU的计算资源是有限的,4个进程同时争抢GPU算力,会导致每个推理任务的实际运行时间被拉长,加上进程启动、上下文切换的额外开销,总耗时接近单张耗时的4倍。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:03:37