我如何在 OpenVino 上进行异步推理

How do I do async inference on OpenVino

我写了一个 python 服务器,它使用 OpenVino 网络 运行 推断传入的请求。为了加快速度,我在多个线程中接收请求,我想 运行 同时进行推理。 似乎无论我做什么,我得到的时间都与非并发解决方案相同 - 这让我觉得我错过了一些东西。

我正在 Python 中使用 openvino 2019.1.144 编写它。我正在对同一个插件和网络使用多个请求,以便尝试同时进行推断 运行。

def __init__(self, num_of_requests: int = 4):
   self._plugin = IEPlugin("CPU", plugin_dirs=None)
   model_path = './Det/'
   model_xml = os.path.join(model_path, "ssh_graph.xml")
   model_bin = os.path.join(model_path, "ssh_graph.bin")
   net = IENetwork(model=model_xml, weights=model_bin)
   self._input_blob = next(iter(net.inputs))

   # Load network to the plugin
   self._exec_net = self._plugin.load(network=net, num_requests=num_of_requests)
   del net

def _async_runner(detect, images_subset, idx):
    for img in images_subset:
        request_handle = self._exec_net.start_async(request_id=idx, inputs={self._input_blob: img})
        request_handle.wait()


def run_async(images):  # These are the images to infer
    det = Detector(num_of_requests=4)
    multiplier = int(len(images)/4)
    with ThreadPoolExecutor(4) as pool:
        futures = []
        for idx in range(0,3):
            images_subset = images[idx*multiplier:(idx+1)*multiplier-1]
            futures.append(pool.submit(_async_runner, det.detect, images_subset, idx))

当我 运行 在同步模式下进行 800 次推理时,我得到了一个平均值。 运行 290ms的时间 当我 运行 处于异步模式时,我得到 280 毫秒的平均 运行 时间。 这些都不是实质性的改进。我做错了什么?

您可以参考 C:\Program Files (x86)\IntelSWTools\openvino_2019.1.144\inference_engine\samples\python_samples\object_detection_demo_ssd_async\object_detection_demo_ssd_async.py 中的示例代码或 python_samples 目录中的类似示例来检查解决异步模式的方式。

如果使用 wait(),执行线程会阻塞,直到结果可用。如果您想使用真正的异步模式,您将需要 wait(0) ,它不会阻止执行。只需在需要时启动推理并存储 request_id。然后,你可以检查结果是否可用,检查 wait(0) 的返回值是否为 0。注意不要在 IE 进行推理时使用相同的 request_id,这会导致冲突并且它将引发异常。

但是,在您提供的代码中,您不能这样做,因为您正在创建一个线程池,每个线程在其中执行将图像子集推断为唯一 request_id。事实上,这是一个并行执行,会给你一个很好的性能,但它不是 "async" 模式。

真正的异步模式应该是这样的:

while still_items_to_infer():
    get_item_to_infer()
    get_unused_request_id()
    launch_infer()
    do_someting()
    if results_available():
        get_inference_results()
        free_request_id()
        #This may be in a new thread
        process_inference_results()

这样,您可以在等待推理完成的同时分派连续推理。