onnx / onnx

Open standard for machine learning interoperability
https://onnx.ai/
Apache License 2.0
17.22k stars 3.62k forks source link

Discussion on the Correct Approach for Converting ONNX Models to Other Frameworks #6142

Open kumarutkarsh1248 opened 1 month ago

kumarutkarsh1248 commented 1 month ago

I am working on creating an ONNX converter for the mlpack(a machine learning library) framework. My current ONNX-MLPack converter is working fine for some simple linear and convolutional models(https://github.com/kumarutkarsh1248/onnx_mlpack_translator ). Basically, what my converter does is iterate through the nodes of the graph in topological order, extract the attributes of each node, and while doing so, the converter adds layers to the MLPack model one by one with all their attributes mapped.

This overall approach works fine for simple models with no side branching, but this converter fails when it comes to ONNX models with some side branches associated with nodes or complex closed connectivity of nodes.

There is also a significant difference in the graph for different versions of the ONNX model.

I don’t know how to deal with these issues, and I can’t find any documentation or reference on how machine learning frameworks should make their converters. If you could provide any such developer documentation or any other resources, it would help me a lot.

xadupre commented 1 month ago

You can read this https://onnx.ai/onnx/intro/converters.html to find some inspiration. Most of the converting libraries includes the three following components:

This page gives more details about a dummy exporter I made to convert torch model into onnx: https://sdpython.github.io/doc/experimental-experiment/dev/design/exporter.html. It follows this design.

About opsets, you have two choices. Either a converting function is producing different sequences of nodes depending on the opset or there are two functions for two opsets and the interpreter is calling the right one based on the opset.

cbourjau commented 1 month ago

We have built our own internal converter library based on Spox (which we have also built). It proved to be very well maintainable over ~2 years now. We build complex graphs with thousands of nodes across various projects. Spox does not have any explicit containers holding your state - instead, you simply describe your inference code using lazy objects that build up the required graph in the background. It ends up looking almost like regular NumPy code. I'd recommend taking a look at the respective section of the docs: https://spox.readthedocs.io/en/latest/guides/converter.html