onnx-mlir
Representation and Reference Lowering of ONNX Models in MLIR Compiler Infrastructure
Top Related Projects
ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator
Tensors and Dynamic neural networks in Python with strong GPU acceleration
An Open Source Machine Learning Framework for Everyone
Open Machine Learning Compiler Framework
mlpack: a fast, header-only C++ machine learning library
Core ML tools contain supporting tools for Core ML model conversion, editing, and validation.
Quick Overview
ONNX-MLIR is an open-source project that provides a compiler for the Open Neural Network Exchange (ONNX) using MLIR. It aims to enable the compilation of ONNX models to various hardware targets, leveraging the MLIR infrastructure for optimizations and code generation.
Pros
- Enables compilation of ONNX models to different hardware targets
- Leverages MLIR for powerful optimizations and transformations
- Supports a wide range of ONNX operators and models
- Actively maintained and developed by a community of contributors
Cons
- Relatively complex setup and build process
- Limited documentation for advanced use cases
- May have performance overhead compared to specialized frameworks
- Requires understanding of both ONNX and MLIR concepts
Code Examples
- Loading and compiling an ONNX model:
#include "src/Compiler/CompilerUtils.hpp"
#include "src/Runtime/ExecutionSession.hpp"
int main() {
onnx_mlir::setExecPath(argv[0]);
auto module = onnx_mlir::parseSourceFile("model.onnx");
onnx_mlir::compileToBinary(module, "compiled_model");
}
- Running an inference using the compiled model:
#include "src/Runtime/ExecutionSession.hpp"
int main() {
onnx_mlir::ExecutionSession session;
session.loadExecutable("compiled_model");
std::vector<float> input = {1.0, 2.0, 3.0, 4.0};
std::vector<float> output(10);
session.run(input.data(), output.data());
}
- Applying MLIR optimizations:
#include "src/Compiler/CompilerUtils.hpp"
#include "mlir/Pass/PassManager.h"
int main() {
auto module = onnx_mlir::parseSourceFile("model.onnx");
mlir::PassManager pm(module->getContext());
pm.addPass(mlir::createCanonicalizerPass());
pm.addPass(mlir::createCSEPass());
pm.run(*module);
}
Getting Started
To get started with ONNX-MLIR:
-
Clone the repository:
git clone https://github.com/onnx/onnx-mlir.git -
Install dependencies (Ubuntu example):
sudo apt-get install cmake ninja-build -
Build ONNX-MLIR:
mkdir build && cd build cmake -G Ninja .. ninja -
Run tests:
ninja check-onnx-lit
For more detailed instructions and usage examples, refer to the project's documentation and README file.
Competitor Comparisons
ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator
Pros of ONNX Runtime
- More comprehensive and production-ready solution for ONNX model inference
- Supports a wider range of hardware accelerators and platforms
- Offers better performance optimization and runtime efficiency
Cons of ONNX Runtime
- Larger codebase and potentially more complex to contribute to or customize
- May have a steeper learning curve for developers new to the project
Code Comparison
ONNX-MLIR (Lowering an ONNX operation):
void ONNXReluOp::ONNXToKrnl(ONNXReluOp op, KrnlBuilder &rewriter) {
auto loc = op.getLoc();
Value input = op.getX();
Value output = op.getY();
rewriter.create<KrnlReluOp>(loc, input, output);
}
ONNX Runtime (Implementing a custom operator):
Ort::CustomOpApi::KernelInfo info = ...;
auto output = info.GetOutputTensor(0);
const float* input = reinterpret_cast<const float*>(info.GetInputTensor(0)->GetTensorData<float>());
float* out = output->GetTensorMutableData<float>();
for (int64_t i = 0; i < output->Shape().Size(); i++) {
out[i] = std::max(0.0f, input[i]);
}
Tensors and Dynamic neural networks in Python with strong GPU acceleration
Pros of PyTorch
- Larger community and ecosystem, with more resources and third-party libraries
- More flexible and dynamic computational graph, allowing for easier debugging
- Pythonic interface and easier learning curve for beginners
Cons of PyTorch
- Slower inference speed compared to ONNX-MLIR's optimized runtime
- Less focus on model portability and deployment across different hardware
Code Comparison
PyTorch:
import torch
x = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
z = x + y
print(z)
ONNX-MLIR:
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Builders.h"
mlir::MLIRContext ctx;
mlir::OpBuilder builder(&ctx);
auto x = builder.create<ONNXConstantOp>(loc, ...);
auto y = builder.create<ONNXConstantOp>(loc, ...);
auto z = builder.create<ONNXAddOp>(loc, x, y);
The PyTorch example shows its simplicity and Python-based approach, while the ONNX-MLIR example demonstrates its lower-level MLIR-based representation, which allows for more fine-grained optimizations but requires more verbose code.
An Open Source Machine Learning Framework for Everyone
Pros of TensorFlow
- Larger ecosystem with more tools, libraries, and community support
- Comprehensive platform for machine learning, including deployment options
- Better documentation and learning resources
Cons of TensorFlow
- Steeper learning curve, especially for beginners
- Can be slower and more resource-intensive than ONNX-MLIR
- Less flexible for cross-platform model deployment
Code Comparison
ONNX-MLIR (using MLIR dialect):
func @simple_add(%arg0: tensor<*xf32>, %arg1: tensor<*xf32>) -> tensor<*xf32> {
%0 = "onnx.Add"(%arg0, %arg1) : (tensor<*xf32>, tensor<*xf32>) -> tensor<*xf32>
return %0 : tensor<*xf32>
}
TensorFlow:
import tensorflow as tf
@tf.function
def simple_add(a, b):
return tf.add(a, b)
ONNX-MLIR focuses on providing a compiler infrastructure for ONNX models using MLIR, while TensorFlow offers a complete ecosystem for building and deploying machine learning models. ONNX-MLIR is more specialized and potentially more efficient for certain use cases, whereas TensorFlow provides a broader range of features and better support for end-to-end machine learning workflows.
Open Machine Learning Compiler Framework
Pros of TVM
- Broader support for hardware targets, including CPUs, GPUs, and specialized AI accelerators
- More extensive optimization capabilities, including auto-tuning and graph-level optimizations
- Larger and more active community, with contributions from major tech companies
Cons of TVM
- Steeper learning curve due to its more complex architecture and broader scope
- Potentially slower compilation times for simpler models compared to ONNX-MLIR
Code Comparison
ONNX-MLIR (using MLIR dialect):
func @test_relu(%arg0: tensor<10x10xf32>) -> tensor<10x10xf32> {
%0 = "onnx.Relu"(%arg0) : (tensor<10x10xf32>) -> tensor<10x10xf32>
return %0 : tensor<10x10xf32>
}
TVM (using Relay IR):
def @main(%x: Tensor[(10, 10), float32]) -> Tensor[(10, 10), float32] {
nn.relu(%x)
}
Both ONNX-MLIR and TVM aim to optimize and deploy machine learning models, but they have different focuses. ONNX-MLIR specializes in ONNX model compilation using MLIR, while TVM provides a more comprehensive end-to-end deep learning compilation framework with broader hardware support and optimization capabilities.
mlpack: a fast, header-only C++ machine learning library
Pros of mlpack
- Extensive collection of machine learning algorithms implemented in C++
- Highly optimized for performance and efficiency
- Flexible API with bindings for multiple languages (C++, Python, R, Julia)
Cons of mlpack
- Steeper learning curve compared to ONNX-MLIR
- Less focus on interoperability with other ML frameworks
- Smaller community and ecosystem compared to ONNX-MLIR
Code Comparison
mlpack example (C++):
#include <mlpack/core.hpp>
#include <mlpack/methods/linear_regression/linear_regression.hpp>
arma::mat X, y;
mlpack::regression::LinearRegression lr(X, y);
arma::vec predictions;
lr.Predict(X, predictions);
ONNX-MLIR example (MLIR):
func @main(%arg0: tensor<1x3xf32>) -> tensor<1x1xf32> {
%0 = "onnx.LinearRegression"(%arg0) {coefficients = dense<[1.0, 2.0, 3.0]> : tensor<3xf32>, intercepts = dense<0.5> : tensor<1xf32>} : (tensor<1x3xf32>) -> tensor<1x1xf32>
return %0 : tensor<1x1xf32>
}
Note: The code examples showcase basic linear regression implementations in both frameworks, highlighting their different approaches and syntax.
Core ML tools contain supporting tools for Core ML model conversion, editing, and validation.
Pros of coremltools
- Specifically designed for Apple platforms, offering seamless integration with iOS, macOS, and other Apple devices
- Provides tools for quantization and optimization of models for Apple's Neural Engine
- Supports conversion from a wider range of frameworks, including TensorFlow, Keras, and scikit-learn
Cons of coremltools
- Limited to Apple ecosystem, lacking cross-platform compatibility
- May have less frequent updates compared to the more community-driven onnx-mlir project
- Potentially steeper learning curve for developers not familiar with Apple's ML ecosystem
Code Comparison
coremltools:
import coremltools as ct
model = ct.convert('model.h5', source='keras')
model.save('model.mlmodel')
onnx-mlir:
onnx-mlir --EmitMLIR --InputONNX model.onnx
onnx-mlir --EmitLLVMIR model.onnx
Note: The code examples demonstrate different aspects of each tool's functionality and may not be directly comparable.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME

ONNX-MLIR
This project (https://onnx.ai/onnx-mlir/) provides compiler technology to transform a valid Open Neural Network Exchange (ONNX) graph into code that implements the graph with minimum runtime support. It implements the ONNX standard and is based on the underlying LLVM/MLIR compiler technology.
| System | Build Status | Model Zoo Status |
|---|---|---|
| s390x-Linux | ||
| ppc64le-Linux | ||
| amd64-Linux | ||
| amd64-Windows | ||
| amd64-macOS | ||
This project contributes:
- an ONNX Dialect that can be integrated in other projects,
- a compiler interfaces that lower ONNX graphs into MLIR files/LLVM bytecodes/C & Java libraries,
- an
onnx-mlirdriver to perform these lowering, - and a python/C/C++/Java runtime environment.
Current levels of support for the code generation of ONNX operations are listed here for a generic CPU and IBM's Telum integrated AI accelerator.
Interacting with the community.
For ongoing discussions, we use an #onnx-mlir-discussion slack channel established under the Linux Foundation AI and Data Workspace.
Join this workspace using this link.
We use GitHub Issues for request for comments, questions, or bug reports. Security-related issues are reported using the channels listed in the SECURITY page.
We hold informal weekly meetings on Tuesdays where we discuss current issues and progress. Meeting agenda, notes, and links (to participate) are found here. Please email alexe@us.ibm.com to request a 15-30 min time slot to discuss a specific topic of interest.
Setting up ONNX-MLIR using Prebuilt Containers
The preferred approach to using and developing ONNX-MLIR is to use Docker Images and Containers, as getting the proper code dependences may be tricky on some systems. Our instructions on using ONNX-MLIR with Dockers are here.
If you intend to develop code, you should look at our workflow document which help you setup your Docker environment in a way that let you contribute code easily.
Setting up ONNX-MLIR directly
ONNX-MLIR runs natively on Linux, OSX, and Windows. Detailed instructions are provided below.
Prerequisites
python >= 3.8
gcc >= 6.4
protobuf >= 4.21.12
cmake >= 3.13.4
make >= 4.2.1 or ninja >= 1.10.2
java >= 1.11 (optional)
All the PyPi package dependencies and their appropriate versions are captured in requirements.txt.
Look here for help to set up the prerequisite software.
At any point in time, ONNX-MLIR depends on a specific commit of the LLVM project that has been shown to work with the project. Periodically the maintainers need to move to a more recent LLVM level. Among other things, this requires to update the LLVM commit string in clone-mlir.sh. When updating ONNX-MLIR, it is good practice to check that the commit string of the MLIR/LLVM is the same as the one listed in that file. See instructions here when third-party ONNX also need to be updated.
Build
Directions to install MLIR and ONNX-MLIR are dependent on your OS.
After installation, an onnx-mlir executable should appear in the build/Debug/bin or build/Release/bin directory.
If you have difficulties building, rebuilding, or testing onnx-mlir, check this page for helpful hints.
Using ONNX-MLIR
The usage of onnx-mlir is as such:
OVERVIEW: ONNX-MLIR modular optimizer driver
USAGE: onnx-mlir [options] <input file>
OPTIONS:
Generic Options:
--help - Display available options (--help-hidden for more)
--help-list - Display list of available options (--help-list-hidden for more)
--version - Display the version of this program
ONNX-MLIR Options:
These are frontend options.
Choose target to emit:
--EmitONNXBasic - Ingest ONNX and emit the basic ONNX operations without inferred shapes.
--EmitONNXIR - Ingest ONNX and emit corresponding ONNX dialect.
--EmitMLIR - Lower the input to MLIR built-in transformation dialect.
--EmitLLVMIR - Lower the input to LLVM IR (LLVM MLIR dialect).
--EmitObj - Compile the input to an object file.
--EmitLib - Compile and link the input into a shared library (default).
--EmitJNI - Compile the input to a jar file.
Optimization levels:
--O0 - Optimization level 0 (default).
--O1 - Optimization level 1.
--O2 - Optimization level 2.
--O3 - Optimization level 3.
The full list of options is given by the -help option.
The - and the -- prefix for flags can be used interchangeably.
Note that just as most compilers, the default optimization level is -O0.
We recommend using -O3 for most applications.
Options are also read from the ONNX_MLIR_FLAGS environment variable. For example, ONNX_MLIR_FLAGS="-O3" will ensure -O3 for all compilations.
Simple Example
For example, use the following command to lower an ONNX model (e.g., add.onnx) to ONNX dialect:
./onnx-mlir --EmitONNXIR add.onnx
The output should look like:
module {
func.func @main_graph(%arg0: tensor<10x10x10xf32>, %arg1: tensor<10x10x10xf32>) -> tensor<10x10x10xf32> {
%0 = "onnx.Add"(%arg0, %arg1) : (tensor<10x10x10xf32>, tensor<10x10x10xf32>) -> tensor<10x10x10xf32>
return %0 : tensor<10x10x10xf32>
}
}
An example based on the add operation is found here, which build an ONNX model using a python script, and then provide a main program to load the model's value, compute, and print the models output.
Writing a driver to perform inferences: end to end example
An end to end example is provided here, which train, compile, and execute a simple MNIST example using our C/C++, Python, or Java interface.
Documentation
Documentation is provided in the docs sub-directory; the DocumentList page provides an organized list of documents. Information is also provided on our public facing
onnx.ai/onnx-mlir pages.
Contributing
We are welcoming contributions from the community. Please consult the CONTRIBUTING page for help on how to proceed.
ONNX-MLIR requires committers to sign their code using the Developer Certificate of Origin (DCO).
Practically, each git commit needs to be signed, see here for specific instructions.
Code of Conduct
The ONNX-MLIR code of conduct is described at https://onnx.ai/codeofconduct.html.
Projects related/using onnx-mlir
- The onnx-mlir-serving project implements a GRPC server written with C++ to serve onnx-mlir compiled models. Benefiting from C++ implementation, ONNX Serving has very low latency overhead and high throughput.
Top Related Projects
ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator
Tensors and Dynamic neural networks in Python with strong GPU acceleration
An Open Source Machine Learning Framework for Everyone
Open Machine Learning Compiler Framework
mlpack: a fast, header-only C++ machine learning library
Core ML tools contain supporting tools for Core ML model conversion, editing, and validation.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot