我可以将两个 ONNX 图组合在一起,将一个图的输出作为输入传递到另一个图吗?

Can I combine two ONNX graphs together, passing the output from one as input to another?

我有一个模型,从pytorch导出的,我会调用main_model.onnx。它有一个我称之为 main_input 的输入节点,它需要一个整数列表。我可以在 onnxruntime 中加载它并发送一个整数列表,效果很好。

我制作了另一个 ONNX 模型,我将使用输入 pre_input 和输出 pre_output 调用 pre_model.onnx。这会预处理一些文本,因此输入是文本,pre_output 是一个整数列表,完全符合 main_model.onnx 输入的需要。

我的目标是,使用 Python onnx.helper 工具,创建一个接受文本作为输入的超级模型,并运行我的 pre-model.onnx,可能是一些连接器节点( Identity 也许吧?),然后通过 main_model.onnx 一个大的 combined.onnx 模型。

我尝试使用 pre_model.graph.node+Identity connector+main_model.graph.node 作为新图中的节点,但是从 pytorch 导出的参数以这种方式丢失。有没有办法保留所有这些参数和周围的一切,并导出这个更大的组合 ONNX 模型?

虽然有点棘手,但这是可以实现的。您可以探索 ONNX (https://github.com/onnx/onnx/blob/master/docs/PythonAPIOverview.md) 提供的 Python API。这将允许您将模型加载到内存中,并且您必须使用公开的 API“组合”您的组合模型(将两个 GraphProto 消息组合成一个 - 这说起来容易做起来难 - 你必须确保你不'在执行此操作时违反了 onnx 规范)并最终将新的 Graphproto 存储在新的 ModelProto 中,并且您拥有了组合模型。我还会 运行 在完成时通过 onnx 检查器确保模型有效 post 它的创建。

如果您有静态尺寸输入,sclblonnx 包是合并 Onnx 模型的简单解决方案。但是,它不支持动态大小输入。

对于动态大小输入,一种解决方案是使用 ONNX API 编写您自己的代码,如前所述。

另一种解决方案是使用 onnx-tensorflow or onnx2pytorch 等工具将两个 ONNX 模型转换为一个框架(Tensorflow 或 PyTorch)。然后将一个网络的输出作为另一个网络的输入,并将整个网络导出为 Onnx 格式。