Skip to main content

Naturally author ONNX functions and models using a subset of Python

Project description

ONNX Script

CI Dev Release PyPI - Version PyPI - Python Version Ruff Black

ONNX Script enables developers to naturally author ONNX functions and models using a subset of Python. ONNX Script is:

  • Expressive: enables the authoring of all ONNX functions.
  • Simple and concise: function code is natural and simple.
  • Debuggable: allows for eager-mode evaluation that provides for a more delightful ONNX model debugging experience.

Note however that ONNX Script does not intend to support the entirety of the Python language.

Design Overview

ONNX Script provides a few major capabilities for authoring and debugging ONNX models and functions:

  • A converter which translates a Python ONNX Script function into an ONNX graph, accomplished by traversing the Python Abstract Syntax Tree to build an ONNX graph equivalent of the function.

  • A converter that operates inversely, translating ONNX models and functions into ONNX Script. This capability can be used to fully round-trip ONNX Script ↔ ONNX graph.

  • A runtime shim that allows such functions to be evaluated (in an "eager mode"). This functionality currently relies on ONNX Runtime for executing every ONNX Operator, and there is a Python-only reference runtime for ONNX underway that will also be supported.

    Note that the runtime is intended to help understand and debug function definitions. Performance is not a goal here.

Installing ONNX Script

pip install --upgrade onnxscript

Install for Development

pip install onnx onnxruntime pytest
git clone https://github.com/microsoft/onnxscript
cd onnxscript
pip install -e .

Run Unit Tests

pytest onnxscript

Example

import onnx

# We use ONNX opset 15 to define the function below.
from onnxscript import FLOAT, script
from onnxscript import opset15 as op


# We use the script decorator to indicate that
# this is meant to be translated to ONNX.
@script()
def onnx_hardmax(X, axis: int):
    """Hardmax is similar to ArgMax, with the result being encoded OneHot style."""

    # The type annotation on X indicates that it is a float tensor of
    # unknown rank. The type annotation on axis indicates that it will
    # be treated as an int attribute in ONNX.
    #
    # Invoke ONNX opset 15 op ArgMax.
    # Use unnamed arguments for ONNX input parameters, and named
    # arguments for ONNX attribute parameters.
    argmax = op.ArgMax(X, axis=axis, keepdims=False)
    xshape = op.Shape(X, start=axis)
    # use the Constant operator to create constant tensors
    zero = op.Constant(value_ints=[0])
    depth = op.GatherElements(xshape, zero)
    empty_shape = op.Constant(value_ints=[0])
    depth = op.Reshape(depth, empty_shape)
    values = op.Constant(value_ints=[0, 1])
    cast_values = op.CastLike(values, X)
    return op.OneHot(argmax, depth, cast_values, axis=axis)


# We use the script decorator to indicate that
# this is meant to be translated to ONNX.
@script()
def sample_model(X: FLOAT[64, 128], Wt: FLOAT[128, 10], Bias: FLOAT[10]) -> FLOAT[64, 10]:
    matmul = op.MatMul(X, Wt) + Bias
    return onnx_hardmax(matmul, axis=1)


# onnx_model is an in-memory ModelProto
onnx_model = sample_model.to_model_proto()

# Save the ONNX model at a given path
onnx.save(onnx_model, "sample_model.onnx")

# Check the model
try:
    onnx.checker.check_model(onnx_model)
except onnx.checker.ValidationError as e:
    print(f"The model is invalid: {e}")
else:
    print("The model is valid!")

The decorator parses the code of the function, converting it into an intermediate representation. If it fails, it produces an error message indicating the line where the error was detected. If it succeeds, the intermediate representation can be converted into an ONNX graph structure of type FunctionProto:

  • Hardmax.to_function_proto() returns a FunctionProto

Eager Mode Evaluation

Eager mode is mostly used to debug and validate that intermediate results are as expected. The function defined above can be called as below, executing in an eager-evaluation mode:

import numpy as np

v = np.array([[0, 1], [2, 3]], dtype=np.float32)
result = Hardmax(v)

More examples can be found in the docs/examples directory.

Development Guidelines

Every change impacting the converter or the eager evaluation must be unit tested with class OnnxScriptTestCase to ensure both systems do return the same results with the same inputs.

Coding Style

We use ruff, black, isort, and mypy etc. to check code formatting and use lintrunner to run all linters. You can install the dependencies and initialize with

pip install lintrunner lintrunner-adapters
lintrunner init

This will install lintrunner on your system and download all the necessary dependencies to run linters locally. If you want to see what lintrunner init will install, run lintrunner init --dry-run.

To lint local changes:

lintrunner

To format files:

lintrunner f

To lint all files:

lintrunner --all-files

Use --output oneline to produce a compact list of lint errors, useful when there are many errors to fix.

See all available options with lintrunner -h.

To read more about lintrunner, see wiki. To update an existing linting rule or create a new one, modify .lintrunner.toml or create a new adapter following examples in https://github.com/justinchuby/lintrunner-adapters.

Contributing

We're always looking for your help to improve the product (bug fixes, new features, documentation, etc). Currently ONNX Script is under early and heavy development, so we encourage proposing any major changes by filing an issue to discuss your idea with the team first.

Report a Security Issue

Please do not report security vulnerabilities through public GitHub issues.

Please refer to our guidance on filing Security Issues.

Licensing Guidelines

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos is subject to those third-party's policies.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

onnxscript-0.1.0.dev20240425.tar.gz (499.4 kB view details)

Uploaded Source

Built Distribution

onnxscript-0.1.0.dev20240425-py3-none-any.whl (593.1 kB view details)

Uploaded Python 3

File details

Details for the file onnxscript-0.1.0.dev20240425.tar.gz.

File metadata

File hashes

Hashes for onnxscript-0.1.0.dev20240425.tar.gz
Algorithm Hash digest
SHA256 a096305f74b3dfd77d8dffec045bcf6ae8ecaeaf800e5600c28d10e1f40ab53f
MD5 bc6f7475eb893158235bbec1d5a19204
BLAKE2b-256 44d4b78e6561c6b7bb8598af55e4c9dbd1a52686937ebf3c09e75fe7d45a6a35

See more details on using hashes here.

File details

Details for the file onnxscript-0.1.0.dev20240425-py3-none-any.whl.

File metadata

File hashes

Hashes for onnxscript-0.1.0.dev20240425-py3-none-any.whl
Algorithm Hash digest
SHA256 56707932642b75b91d6467ca09bf27a9e8e42f99dd9fd454e47e061573c3e4be
MD5 ec3de1adc7f23e83950e6d2a8a57d47b
BLAKE2b-256 c7c696fd225771870a9cc310987fef3acbad56e5637f935eb68001093e512fb0

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page