openvino的文档实在太少了,写的也是相当含糊,包括它的例子,谷歌搜索了半天找不到和我类似的问题,于是我在此记录一下,用来帮助后来人,如何用openvino推断多输入多输出的模型。
本文将使用openvino runtime的python binding,先把模型转换为正确的格式,再进行推断。
首先先科普一些基本知识,openvino目前是支持onnx模型直接加载的,也可以将onnx模型通过openvino的模型优化器转化成xml再加载,如果你是pytorch的模型的话,请先转为onnx。另外,在推断时,openvino的gpu推断目前是不支持动态加载的,只有cpu支持,也就是说你的向量尺寸必须固定下来,不能变化。不巧的是,本例中的模型还真就是动态加载的。
用netron软件打开我们的onnx模型看下输入输出:
输入有6个向量,src,r1i,r2i,r3i,r4i,r5i,downsample_ration。
输出也有六个向量,fgr,pha,r1o,r2o,r3o,r4o。本例中模型特殊的地方在于r1-r4是循环记忆向量,这个是在变化的,也就是说不能固定尺寸。
本文假定你已经安装好了openvino的工具包。然后在命令行里输入:
mo --input_model 你的模型.onnx
--input src,r1i,r2i,r3i,r4i,downsample_ratio
--input_shape (1,3,720,1280),(1,?,?,?),(1,?,?,?),(1,?,?,?),(1,?,?,?),(1)
--output fgr,pha,r1o,r2o,r3o,r4o
--data_type FP32
这里注意input和output里面的写法。多个输入输出要用逗号隔开并正确指定名称,同时input_shape里的向量形状需要你固定好,本例中由于r1-r4没法固定,所以就只固定了第一个和最后一个向量,其他都以问号填充。data_type指定模型的精度,本例中指定了FP32,一般对于cpu而言FP32会跑的更快。
没有报错后顺利转换完毕。多出了几个文件。只需要xml就行。
本例假定你已经安装了openvino runtime。
from openvino.runtime import Core
ie = Core()
model_openvino = "xxxxx.xml"
model = ie.read_model(model=model_openvino)
compiled_model = ie.compile_model(model=model, device_name="CPU")
x = iter(compiled_model.inputs)
for i in x:
print(i)
y = iter(compiled_model.outputs)
for i in y:
print(i)
前三行代码读取模型,第四行代码加载模型,其中device_name指定cpu或者gpu跑,本例中因为动态尺寸,所以必须用cpu,不然加载报错。
后面几行代码会打印出所有的输入层和输出层,是用来检查的。
输出如下:
接下来正式推断:
infer_request = compiled_model({
'src': src,
'r1i': rec[0],
'r2i': rec[1],
'r3i': rec[2],
'r4i': rec[3],
'downsample_ratio': downsample_ratio
})
fgr,pha,*rec= infer_request.values()
输入的时候注意把向量尺寸都对应好,其中的infer_request是一个字典,因为有多个输出,取值的时候只需要按照字典的顺序用values()方法直接取值即可。
另外这里的*rec是指把剩下的四个循环记忆向量都存进了rec数组里,当成输入再进行推断,所以说是动态尺寸,因为在初始化时,这四个向量是空的,推断一次后就有固定形状了,这玩意目前在openvino的gpu推断里不支持。反正本例最重要的是多输入多输出如何推断的方法,我自行摸索了好久才明白过来。