Convert Figma logo to code with AI

onnx logoonnx-mlir

Representation and Reference Lowering of ONNX Models in MLIR Compiler Infrastructure

1,037
443
1,037
350

Top Related Projects

ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator

99,486

Tensors and Dynamic neural networks in Python with strong GPU acceleration

194,834

An Open Source Machine Learning Framework for Everyone

13,579

Open Machine Learning Compiler Framework

5,638

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

  1. 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");
}
  1. 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());
}
  1. 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:

  1. Clone the repository:

    git clone https://github.com/onnx/onnx-mlir.git
    
  2. Install dependencies (Ubuntu example):

    sudo apt-get install cmake ninja-build
    
  3. Build ONNX-MLIR:

    mkdir build && cd build
    cmake -G Ninja ..
    ninja
    
  4. 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]);
}
99,486

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.

194,834

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.

13,579

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.

5,638

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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.

SystemBuild StatusModel Zoo Status
s390x-LinuxBuild StatusModel Zoo Status
ppc64le-LinuxBuild StatusModel Zoo Status
amd64-LinuxBuild StatusModel Zoo Status
amd64-WindowsBuild Status
amd64-macOSBuild Status
CII Best Practices

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-mlir driver 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.