onnxruntime 错误

使用onnxruntime可能会发生很多错误。本示例探讨了onnxruntime未返回模型预测而是引发异常的几种常见情况。它首先加载一个模型(参见 训练、转换和预测模型),该模型生成在Iris数据集上训练的逻辑回归。该模型接收一个维度为 2 的向量并返回三个类别中的一个。

import skl2onnx
import onnx
import sklearn
import onnxruntime as rt
import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression

try:
    from onnxruntime.capi.onnxruntime_pybind11_state import InvalidArgument
except ImportError:
    # onnxruntime <= 0.5
    InvalidArgument = RuntimeError

data = load_iris()
clr = LogisticRegression().fit(data.data[:, :2], data.target)
with open("logreg_iris.onnx", "wb") as f:
    f.write(
        skl2onnx.to_onnx(
            clr, data.data[:, :2].astype(np.float32), target_opset=12
        ).SerializeToString()
    )

example2 = "logreg_iris.onnx"
sess = rt.InferenceSession(example2, providers=["CPUExecutionProvider"])

input_name = sess.get_inputs()[0].name
output_name = sess.get_outputs()[0].name

第一个示例由于类型错误而失败。onnxruntime仅期望单精度浮点数(4 字节),无法处理任何其他类型的浮点数。

try:
    x = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]], dtype=np.float64)
    sess.run([output_name], {input_name: x})
except Exception as e:
    print("Unexpected type")
    print("{0}: {1}".format(type(e), e))
Unexpected type
<class 'onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument'>: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Unexpected input data type. Actual: (tensor(double)) , expected: (tensor(float))

如果名称拼写错误,则模型将无法返回输出。

try:
    x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
    sess.run(["misspelled"], {input_name: x})
except Exception as e:
    print("Misspelled output name")
    print("{0}: {1}".format(type(e), e))
Misspelled output name
<class 'onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument'>: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid Output Name:misspelled

输出名称是可选的,它可以替换为None,然后onnxruntime将返回所有输出。

x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
res = sess.run(None, {input_name: x})
print("All outputs")
print(res)
All outputs
[array([0, 0, 0], dtype=int64), [{0: 0.9999734163284302, 1: 2.656836477399338e-05, 2: 5.484377840758725e-09}, {0: 0.9999914169311523, 1: 8.446793799521402e-06, 2: 1.7366836857490853e-07}, {0: 0.9999918341636658, 1: 2.6854097541217925e-06, 2: 5.499288818100467e-06}]]

如果输入名称拼写错误,也是如此。

try:
    x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
    sess.run([output_name], {"misspelled": x})
except Exception as e:
    print("Misspelled input name")
    print("{0}: {1}".format(type(e), e))
Misspelled input name
<class 'ValueError'>: Required inputs (['X']) are missing from input feed (['misspelled']).

如果输入维度是预期输入维度的倍数,onnxruntime不一定会失败。

for x in [
    np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32),
    np.array([[1.0, 2.0, 3.0, 4.0]], dtype=np.float32),
    np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32),
    np.array([1.0, 2.0, 3.0], dtype=np.float32),
    np.array([[1.0, 2.0, 3.0]], dtype=np.float32),
]:
    try:
        r = sess.run([output_name], {input_name: x})
        print("Shape={0} and predicted labels={1}".format(x.shape, r))
    except (RuntimeError, InvalidArgument) as e:
        print("Shape={0} and error={1}".format(x.shape, e))

for x in [
    np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32),
    np.array([[1.0, 2.0, 3.0, 4.0]], dtype=np.float32),
    np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32),
    np.array([1.0, 2.0, 3.0], dtype=np.float32),
    np.array([[1.0, 2.0, 3.0]], dtype=np.float32),
]:
    try:
        r = sess.run(None, {input_name: x})
        print("Shape={0} and predicted probabilities={1}".format(x.shape, r[1]))
    except (RuntimeError, InvalidArgument) as e:
        print("Shape={0} and error={1}".format(x.shape, e))
Shape=(4,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 4) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
 index: 1 Got: 4 Expected: 2
 Please fix either the inputs or the model.
Shape=(2, 2) and predicted labels=[array([0, 0], dtype=int64)]
Shape=(3,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 3) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
 index: 1 Got: 3 Expected: 2
 Please fix either the inputs or the model.
Shape=(4,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 4) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
 index: 1 Got: 4 Expected: 2
 Please fix either the inputs or the model.
Shape=(2, 2) and predicted probabilities=[{0: 0.9999734163284302, 1: 2.656836477399338e-05, 2: 5.484377840758725e-09}, {0: 0.9999914169311523, 1: 8.446793799521402e-06, 2: 1.7366836857490853e-07}]
Shape=(3,) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 1 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 3) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Got invalid dimensions for input: X for the following indices
 index: 1 Got: 3 Expected: 2
 Please fix either the inputs or the model.

如果维度数高于预期,它也不会失败,但会产生警告。

for x in [
    np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=np.float32),
    np.array([[[1.0, 2.0, 3.0]]], dtype=np.float32),
    np.array([[[1.0, 2.0]], [[3.0, 4.0]]], dtype=np.float32),
]:
    try:
        r = sess.run([output_name], {input_name: x})
        print("Shape={0} and predicted labels={1}".format(x.shape, r))
    except (RuntimeError, InvalidArgument) as e:
        print("Shape={0} and error={1}".format(x.shape, e))
Shape=(1, 2, 2) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 3 Expected: 2 Please fix either the inputs or the model.
Shape=(1, 1, 3) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 3 Expected: 2 Please fix either the inputs or the model.
Shape=(2, 1, 2) and error=[ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: X Got: 3 Expected: 2 Please fix either the inputs or the model.

本示例使用的版本

print("numpy:", np.__version__)
print("scikit-learn:", sklearn.__version__)
print("onnx: ", onnx.__version__)
print("onnxruntime: ", rt.__version__)
print("skl2onnx: ", skl2onnx.__version__)
numpy: 1.23.5
scikit-learn: 1.4.dev0
onnx:  1.15.0
onnxruntime:  1.16.0+cu118
skl2onnx:  1.16.0

脚本总运行时间:(0 分钟 0.054 秒)

由 Sphinx-Gallery 生成的库