一直使用 onnxruntime 作为 CPU 上的推理引擎, 也一直知道 Intel 平台上还可以用 OpenVINO, 速度可能会更快. 由于没有使用过 OpenVINO, 不敢轻言哪个是更好的选择, 遂写了一份测试代码比较两者的速度 (随便也测试了 OpenCV DNN).
首先利用下面的代码获取待测试模型 (ResNet50):
import onnx
import openvino as ov
onnx_filename = 'resnet50.onnx'
model_xml = 'resnet50.xml'
model = onnx.hub.load("resnet50")
onnx.save(model, onnx_filename)
ov_model = ov.convert_model(onnx_filename)
ov.save_model(ov_model, model_xml)
速度测试代码如下, 其中 onnxruntime 的版本为 1.16.3, openvino 的版本为 2023.2.0, opencv 的版本为 4.5.2:
import time
import cv2
import numpy as np
import onnxruntime as rt
import openvino as ov
from openvino.runtime import Core
import openvino.properties as props
import openvino.properties.hint as hints
if __name__ == '__main__':
onnx_filename = 'resnet50.onnx'
model_xml = 'resnet50.xml'
batch_size = 1
ort_session = rt.InferenceSession(onnx_filename)
input_names = [item.name for item in ort_session.get_inputs()]
output_names = [item.name for item in ort_session.get_outputs()]
ie = Core()
ov_model = ie.read_model(model=model_xml)
compiled_model = ie.compile_model(ov_model, "CPU")
net = cv2.dnn.readNetFromONNX(onnx_filename)
for _ in range(10):
input_data = np.random.uniform(-1, 1, (batch_size, 3, 224, 224)).astype(np.float32)
start_time = time.time()
result_ort = ort_session.run(output_names, {input_names[0]: input_data})[0]
print(f'onnxruntime: {time.time() - start_time:.6f}')
start_time = time.time()
result_ov = compiled_model(input_data)[0]
print(f'openvino: {time.time() - start_time:.6f}')
start_time = time.time()
net.setInput(input_data)
result_cv = net.forward()
print(f'opencv: {time.time() - start_time:.6f}')
print('===================')
print(result_ov.shape, result_ov.dtype)
print(result_ort.shape, result_ort.dtype)
print(result_cv.shape, result_cv.dtype)
print(np.allclose(result_ort, result_ov, atol=0.1))
print(np.allclose(result_ort, result_cv, atol=0.1))
print(result_ov[0, :10])
print(result_ort[0, :10])
print(result_cv[0, :10])
测试结果为:
- 当 batch_size 为 1 时, 速度大小关系为 onnxruntime > opencv > openvino.
- 当 batch_size 为 10 时, opencv 的速度明显不如其他两个, onnxruntime 和 openvino 不分伯仲.
- 当 batch_size 为 100 时, openvino 速度最快, 其次是 onnxruntime, 最后是 opencv.
结论是: 在 Intel 平台上选择推理引擎, 当 batch_size 较小时, 推荐使用 onnxruntime, 当 batch_size 较大时, 推荐使用 openvino.
附: 由于硬件架构, 推理引擎版本, 待测模型, 推理配置等差异, 上面的现象及相应的结论可能会有不同, 建议在选择之前自测一下.