OnnxRuntime vs OnnxRuntime+OpenVinoEP 推理时间差异

OnnxRuntime vs OnnxRuntime+OpenVinoEP inference time difference

我试图通过将模型转换为 OnnxRuntime 来加速模型的性能。但是,在尝试测量推理时间时,我得到了奇怪的结果。

虽然 运行仅 1 次迭代 OnnxRuntime 的 CPUExecutionProvider 大大优于 OpenVINOExecutionProvider:

但是如果我 运行 假设 5 次迭代,结果是不同的:

如果我 运行 100 次迭代,结果将大不相同:

在我看来,OpenVinoEP 的推理时间不是线性的,但我不明白为什么。 所以我的问题是:

代码非常基础:

import onnxruntime as rt
import numpy as np
import time 
from tqdm import tqdm

limit = 5
# MODEL
device = 'CPU_FP32'
model_file_path = 'road.onnx'

image = np.random.rand(1, 3, 512, 512).astype(np.float32)

# OnnxRuntime
sess = rt.InferenceSession(model_file_path, providers=['CPUExecutionProvider'], provider_options=[{'device_type' : device}])
input_name = sess.get_inputs()[0].name

start = time.time()
for i in tqdm(range(limit)):
    out = sess.run(None, {input_name: image})
end = time.time()
inference_time = end - start
print(inference_time)

# OnnxRuntime + OpenVinoEP
sess = rt.InferenceSession(model_file_path, providers=['OpenVINOExecutionProvider'], provider_options=[{'device_type' : device}])
input_name = sess.get_inputs()[0].name

start = time.time()
for i in tqdm(range(limit)):
    out = sess.run(None, {input_name: image})
end = time.time()
inference_time = end - start
print(inference_time)

将 ONNX Runtime 与 OpenVINO Execution Provider 结合使用可以在 OpenVINO 工具包在后端运行时使用 ONNX Runtime API 推断 ONNX 模型。 与 Intel® CPU、GPU、VPU 和 FPGA 上的通用加速相比,这可以加速 ONNX 模型在相同硬件上的性能。

一般来说,CPU Execution Provider 最适合小迭代,因为它的目的是保持二进制文件的大小。同时,OpenVINO Execution Provider 旨在用于英特尔 CPUs、英特尔集成 GPU 和英特尔® MovidiusTM 视觉处理单元 (VPU) 上的深度学习推理。

这就是 OpenVINO 执行提供程序在较大迭代期间优于 CPU 执行提供程序的原因。

您应该选择能够满足您自己要求的执行提供商。如果您要通过大量迭代执行复杂的 DL,请选择 OpenVINO Execution Provider。对于更简单的用例,您需要使用较小的迭代来减小二进制大小,您可以选择 CPU Execution Provider。

更多信息可以参考这个ONNX Runtime Performance Tuning

关于 non-linear 时间,当您第一次 运行 使用 OpenVINO 的模型时,可能会发生一些准备工作 - 也许当您第一次调用时,模型首先被编译为 OpenVINO sess.run。我在使用 TFLite 时观察到类似的效果。对于这些场景,在进行基准测试时丢弃第一次迭代的时间是有意义的。也往往会有相当大的差异,因此 运行宁 >10 次或理想情况下 >100 次迭代是个好主意。