如何使用 ONNX.js 加载 onnx 模型

How to load an onnx model using ONNX.js

我正在尝试使用 onnxjs 导入 ONNX 模型,但出现以下错误:

Uncaught (in promise) TypeError: cannot resolve operator 'Cast' with opsets: ai.onnx v11

下面显示了我的 html 文件中的代码片段。

<html>
  <head> </head>
  <body>
    <!-- Load ONNX.js -->
    <script src="https://cdn.jsdelivr.net/npm/onnxjs/dist/onnx.min.js"></script>
    <!-- Code that consume ONNX.js -->
    <script>
        async function test(){
            const sess = new onnx.InferenceSession()
            await sess.loadModel('./onnx_model.onnx')
            }
        test()
    </script>
  </body>
</html>

如何解决?

这将加载 Resnet 50 model

const sess = new onnx.InferenceSession()
async function test(){
  console.time("loading model")
  await sess.loadModel('https://microsoft.github.io/onnxjs-demo/resnet50v2.onnx')
  console.timeEnd("loading model")

  console.log("model loaded");
}
document.querySelector('#load').addEventListener('click', test);
<script src="https://cdn.jsdelivr.net/npm/onnxjs/dist/onnx.min.js"></script>

<button id="load">load model</button>

该消息建议与 Cast operator opset 11 不支持,也许您想使用 Cast-9。也许你必须生成一个新模型。

编辑

您的模型使用 onnxruntime 加载 python

sess = onnxruntime.InferenceSession('../../Downloads/onnx_model.onnx');
{i.name: i.shape for i in sess.get_inputs()}
{o.name: o.shape for o in sess.get_outputs()}
{'input_ids': ['batch', 'sequence'],
 'attention_mask': ['batch', 'sequence'],
 'token_type_ids': ['batch', 'sequence']}

{'output_0': ['batch', 2]}

一个想法

您可能需要自己调试它,希望唯一的问题是转换运算符。

您开始寻找 here 对 onnxjs 的运算符支持,并重写出现运算符的模型部分。

比如Cast运算符只出现一次,您可以按如下方式定位

import onnx
model = onnx.load('../../Downloads/onnx_model.onnx')
for node in model.graph.node:
    if 'cast' in node.op_type.lower():
        print(node.name, node.op_type)

那将打印

Cast_2 Cast

使用https://netron.app/(或者桌面版)可以看到是

所以你应该简单地重写你的注意力掩码在模型中的处理方式,一个可能的解决方案是让 unsqueezecast 操作在模型之外。