onnx-mlir

Logo

MLIRコンパイラ基盤におけるONNXモデルの表現と参照低減

GitHubでプロジェクトを見る onnx/onnx-mlir

ハウツー

Pythonを使用した推論
C/C++を使用した推論
Javaを使用した推論

参考文献

ONNXダイアレクト
OMTensor C99ランタイムAPI
OMTensorList C99ランタイムAPI
OMTensor JavaランタイムAPI
OMTensorList JavaランタイムAPI
ONNXダイアレクトの生成
ドキュメントについて

開発

オペレーションの追加
テストガイドライン
エラー処理
コマンドラインオプション
インストルメンテーション
定数伝播
アクセラレータの追加

ツール

ツール

RunONNXModel.py
DocCheck

このプロジェクトはonnxによってメンテナンスされています

GitHub Pagesでホストされています — テーマはorderedlist

Pythonインターフェースの使用

Onnx-mlirには、PythonでONNXモデルをコンパイルして実行するためのランタイムユーティリティがあります。これらのユーティリティは、OnnxMlirCompilerコンパイラインターフェース(include/OnnxMlirCompiler.h)とExecutionSessionクラス(src/Runtime/ExecutionSession.hpp)によって実装されています。両方のユーティリティには、pybindライブラリによって生成された関連するPythonバインディングがあります。

Pythonインターフェースの設定

pybindを使用すると、C/C++バイナリをPythonインタープリターで直接インポートできます。onnx-mlirの場合、5つのライブラリがあり、1つはonnx-mlirモデルをコンパイルするため、2つはモデルを実行するため、残りの2つはモデルをコンパイルおよび実行するためのものです。

  1. onnx-mlirモデルをコンパイルするための共有ライブラリは、PyOMCompileSession(src/Compiler/PyOMCompileSession.hpp)によって生成され、build/Debug/lib/PyCompile.cpython-<target>.soとして共有ライブラリとしてビルドされます。
  2. onnx-mlirモデルを実行するための共有ライブラリは、PyExecutionSession(src/Runtime/PyExecutionSession.hpp)によって生成され、build/Debug/lib/PyRuntimeC.cpython-<target>.soとして共有ライブラリとしてビルドされます。
  3. onnx-mlirモデルを実行するためのPythonライブラリ(src/Runtime/python/PyRuntime.py)。
  4. onnx-mlirモデルをコンパイルおよび実行するための共有ライブラリは、PyOMCompileExecutionSessionC(src/Runtime/PyOMCompileExecutionSession.hpp)によって生成され、build/Debug/lib/PyCompileAndRuntimeC.cpython-<target>.soとして共有ライブラリとしてビルドされます。
  5. onnx-mlirモデルをコンパイルして実行するためのPythonライブラリ(src/Runtime/python/PyCompileAndRuntime.py)。このライブラリは、.onnxファイルとオプションを入力として受け取り、ロードしてからコンパイルして実行します。

モジュールは、PYTHONPATHにある限り、Pythonインタープリターで通常どおりインポートできます。別の方法は、作業ディレクトリにシンボリックリンクを作成することです。

cd <working directory>
ln -s <path to the shared library to copmpile onnx-mlir models>(e.g. `build/Debug/lib/PyCompile.cpython-<target>.so`) .
ln -s <path to the shared library to run onnx-mlir models>(e.g. `build/Debug/lib/PyRuntimeC.cpython-<target>.so`) .
ln -s <path to the Python library to run onnx-mlir models>(e.g. src/Runtime/python/PyRuntime.py) .
ln -s <path to the shared library to compile and run onnx-mlir models>(e.g. `build/Debug/lib/PyCompileAndRuntimeC.cpython-<target>.so`) .
ln -s <path to the Python library to compile and run onnx-mlir models>(e.g. src/Runtime/python/PyCompileAndRuntime.py) .
python3

モデルを実行するためのPythonインターフェース:PyRuntime

PyRuntimeインターフェースの実行

ONNXモデルは計算グラフであり、多くの場合、グラフには計算をトリガーするための単一のエントリーポイントがあります。以下は、単一のエントリーポイントを持つモデルの推論を実行する例です。

import numpy as np
from PyRuntime import OMExecutionSession

model = 'model.so' # LeNet from ONNX Zoo compiled with onnx-mlir

# Create a session for this model.
session = OMExecutionSession(shared_lib_path=model)
# Input and output signatures of the default entry point.
print("input signature in json", session.input_signature())
print("output signature in json",session.output_signature())
# Do inference using the default entry point.
a = np.full((1, 1, 28, 28), 1, np.dtype(np.float32))
outputs = session.run(input=[a])

for output in outputs:
    print(output.shape)

計算グラフに複数のエントリーポイントがある場合、ユーザーは推論を実行するために特定のエントリーポイントを設定する必要があります。以下は、複数のエントリーポイントを使用して推論を実行する例です。

import numpy as np
from PyRuntime import OMExecutionSession

model = 'multi-entry-points-model.so'

# Create a session for this model.
session = OMExecutionSession(shared_lib_path=model, use_default_entry_point=False) # False to manually set an entry point.

# Query entry points in the model.
entry_points = session.entry_points()

for entry_point in entry_points:
  # Set the entry point to do inference.
  session.set_entry_point(name=entry_point)
  # Input and output signatures of the current entry point.
  print("input signature in json", session.input_signature())
  print("output signature in json",session.output_signature())
  # Do inference using the current entry point.
  a = np.arange(10).astype('float32')
  b = np.arange(10).astype('float32')
  outputs = session.run(input=[a, b])
  for output in outputs:
    print(output.shape)

モデルタグの使用

モデルが--tagを使用してコンパイルされた場合、--tagの値はOMExecutionSessionに渡す必要があります。タグの使用は、同じPythonスクリプトに複数のモデルの複数のセッションがある場合に役立ちます。以下は、タグを使用して複数の推論を実行する例です。

import numpy as np
from PyRuntime import OMExecutionSession

encoder_model = 'encoder/model.so' # Assumed that the model was compiled using `--tag=encoder`
decoder_model = 'decoder/model.so' # Assumed that the model was compiled using `--tag=decoder`

# Create a session for the encoder model.
encoder_sess = OMExecutionSession(shared_lib_path=encoder_model, tag="encoder")
# Create a session for the decoder model.
decoder_sess = OMExecutionSession(shared_lib_path=decoder_model, tag="decoder")

2つのモデルが--tagを使用してコンパイルされなかった場合、同じプロセスで使用する場合は、異なる.soファイル名でコンパイルする必要があります。実際、タグが指定されていない場合は、ファイル名をデフォルトのタグとして使用します。以下は、タグを使用せずに複数の推論を実行する例です。

import numpy as np
from PyRuntime import OMExecutionSession

encoder_model = 'my_encoder.so'
decoder_model = 'my_decoder.so'

# Create a session for the encoder model.
encoder_sess = OMExecutionSession(shared_lib_path=encoder_model) # tag will be `my_encoder` by default.
# Create a session for the decoder model.
decoder_sess = OMExecutionSession(shared_lib_path=decoder_model) # tag will be `my_decoder` by default.

run_main_graphなどのタグなしで関数を使用するには、tag = "NONE"を設定します。

PyRuntimeモデルAPI

OMExecutionSessionへの完全なインターフェースは、前述のソースで確認できます。ただし、コンストラクターとrunメソッドを使用するだけで、推論を実行するのに十分です。

def __init__(self, shared_lib_path: str, tag: str, use_default_entry_point: bool):
    """
    Args:
        shared_lib_path: relative or absolute path to your .so model.
        tag: a string that was passed to `--tag` when compiling the .so model. By default, it is the output file name without its extension, namely, `filename` in `filename.so`
        use_default_entry_point: use the default entry point that is `run_main_graph_{tag}` or not. Set to True by default.
    """

def run(self, input: List[ndarray]) -> List[ndarray]:
    """
    Args:
        input: A list of NumPy arrays, the inputs of your model.

    Returns:
        A list of NumPy arrays, the outputs of your model.
    """

def input_signature(self) -> str:
    """
    Returns:
        A string containing a JSON representation of the model's input signature.
    """

def output_signature(self) -> str:
    """
    Returns:
        A string containing a JSON representation of the model's output signature.
    """

def entry_points(self) -> List[str]:
    """
    Returns:
        A list of entry point names.
    """

def set_entry_point(self, name: str):
    """
    Args:
        name: an entry point name.
    """

モデルをコンパイルするためのPythonインターフェース:PyCompile

PyCompileインターフェースの実行

ONNXモデルは、コマンドラインから直接コンパイルできます。結果として得られるライブラリは、前のセクションで示したように、Pythonを使用して実行できます。場合によっては、Pythonでモデルを直接コンパイルするのも便利な場合があります。このセクションでは、そうするためのPythonメソッドについて説明します。

OMCompileSessionオブジェクトは、構築中にファイル名を受け取ります。コンパイルの場合、compile()は、環境変数から設定されたデフォルトオプションを上書きするflags文字列を入力として受け取ります。

import numpy as np
from PyCompile import OMCompileSession

# Load onnx model and create OMCompileSession object.
file = './mnist.onnx'
compiler = OMCompileSession(file)
# Generate the library file. Success when rc == 0 while set the opt as "-O3"
rc = compiler.compile("-O3")
# Get the output file name
model = compiler.get_compiled_file_name()
if rc:
    print("Failed to compile with error code", rc)
    exit(1)
print("Compiled onnx file", file, "to", model, "with rc", rc)

PyCompileモジュールは、ONNXモデルを実行可能モデルにコンパイルするためのOMCompileSessionクラスをエクスポートします。通常、コンパイラオブジェクトは、ONNXモデルのファイル名を指定することで、特定のモデルに対して作成されます。次に、すべてのコンパイラオプションをstd::string全体として設定して、目的の実行可能ファイルを生成できます。最後に、コンパイル自体は、ユーザーがこの関数の入力としてオプション文字列を渡すcompile()コマンドを呼び出すことによって実行されます。

compile()コマンドは、コンパイルのステータスを反映するリターンコードを返します。ゼロ値は成功を示し、ゼロ以外の値はエラーコードを反映します。オペレーティングシステムによってライブラリのサフィックスが異なる場合があるため、出力ファイル名はget_compiled_file_name()メソッドを使用して取得できます。

PyCompileモデルAPI

OnnxMlirCompilerへの完全なインターフェースは、前述のソースで確認できます。ただし、コンストラクターと以下のメソッドを使用するだけで、モデルをコンパイルするのに十分です。

def __init__(self, file_name: str):
    """
    Constructor for an ONNX model contained in a file.
    Args:
        file_name: relative or absolute path to your ONNX model.
    """
def __init__(self, input_buffer: void *, buffer_size: int):
    """
    Constructor for an ONNX model contained in an input buffer.
    Args:
        input_buffer: buffer containing the protobuf representation of the model.
        buffer_size: byte size of the input buffer.
    """
def compile(self, flags: str):
    """
    Method to compile a model from a file.
    Args:
        flags: all the options users would like to set.
    Returns:
        Zero on success, error code on failure.
    """
def compile_from_array(self, output_base_name: str, target: OnnxMlirTarget):
    """
    Method to compile a model from an array.
    Args:
        output_base_name: base name (relative or absolute, without suffix)
        where the compiled model should be written into.
        target: target for the compiler's output. Typical values are
        OnnxMlirTarget.emit_lib or emit_jni.
    Returns:
        Zero on success, error code on failure.
    """
def get_compiled_file_name(self):
    """
    Method to provide the full (absolute or relative) output compiled file name, including
    its suffix.
    Returns:
        String containing the fle name after successful compilation; empty string on failure.
    """
def get_error_message(self):
    """
    Method to provide the compilation error message.
    Returns:
        String containing the error message; empty string on success.
    """

モデルをコンパイルおよび実行するためのPythonインターフェース:PyCompileAndRuntime

PyCompileAndRuntimeインターフェースの実行

import numpy as np
from PyCompileAndRuntime import OMCompileExecutionSession

# Load onnx model and create OMCompileExecutionSession object.
inputFileName = './mnist.onnx'
# Set the full name of compiled model
sharedLibPath = './mnist.so'
# Set the compile option as "-O3"
session = OMCompileExecutionSession(inputFileName,sharedLibPath,"-O3")

# Print the models input/output signature, for display.
# Signature functions for info only, commented out if they cause problems.
session.print_input_signature()
session.print_output_signature()

# Do inference using the default entry point.
a = np.full((1, 1, 28, 28), 1, np.dtype(np.float32))
outputs = session.run(input=[a])

for output in outputs:
    print(output.shape)

PyCompileAndRuntimeモデルAPI

PyCompileAndRuntimeは、コンパイルと実行を組み合わせた新しいクラスです。そのコンストラクターは.onnx入力ファイルを受け取り、ユーザーが指定したオプションでモデルをコンパイルしてから、入力を指定してモデルを実行します。

def __init__(self, input_model_path: str, compiled_file_path: str, flags: str, use_default_entry_point: bool):
    """
    Constructor for an ONNX model contained in a file.
    Args:
        input_model_path: relative or absolute path to your ONNX model.
        compiled_file_path: relative or absolute path to your compiled file.
        flags: all the options users would like to set.
        use_default_entry_point: use the default entry point that is `run_main_graph` or not. Set to True by default.
    """
def get_compiled_result(self):
    """
    Method to provide the results of the compilation.
    Returns:
        Int containing the results. 0 represents successful compilation; others on failure.
    """
def get_compiled_file_name(self):
    """
    Method to provide the full (absolute or relative) output file name, including
    its suffix.
    Returns:
        String containing the fle name after successful compilation; empty string on failure.
    """
def get_error_message(self):
    """
    Method to provide the compilation error message.
    Returns:
        String containing the error message; empty string on success.
    """
def entry_points(self) -> List[str]:
    """
    Returns:
        A list of entry point names.
    """
def set_entry_point(self, name: str):
    """
    Args:
        name: an entry point name.
    """
def run(self, input: List[ndarray]) -> List[ndarray]:
    """
    Args:
        input: A list of NumPy arrays, the inputs of your model.

    Returns:
        A list of NumPy arrays, the outputs of your model.
    """
def input_signature(self) -> str:
    """
    Returns:
        A string containing a JSON representation of the model's input signature.
    """

def output_signature(self) -> str:
    """
    Returns:
        A string containing a JSON representation of the model's output signature.
    """