Instructions to use CatSnowdrop/universal_onnxruntime with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- TensorRT
How to use CatSnowdrop/universal_onnxruntime with TensorRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
Download onnxruntime/tools/pytorch_export_contrib_ops.py from CatSnowdrop/universal_onnxruntime: direct link, hf CLI and curl.
- Browser
- Download file 5.21 kB
-
https://huggingface.co/CatSnowdrop/universal_onnxruntime/resolve/main/onnxruntime/tools/pytorch_export_contrib_ops.py
- Command line
-
hf download hf://CatSnowdrop/universal_onnxruntime/onnxruntime/tools/pytorch_export_contrib_ops.py
-
curl -L -o pytorch_export_contrib_ops.py https://huggingface.co/CatSnowdrop/universal_onnxruntime/resolve/main/onnxruntime/tools/pytorch_export_contrib_ops.py
5.21 kB
| # Copyright (c) Microsoft Corporation. All rights reserved. | |
| # Licensed under the MIT License. | |
| """ | |
| Support for registering ONNX Runtime's built-in contrib ops with | |
| PyTorch-ONNX exporter (torch.onnx.export). | |
| """ | |
| import contextlib | |
| import typing | |
| try: | |
| # TODO(justinchuby): Create a function to alert users when torch is not installed | |
| import torch | |
| except ModuleNotFoundError: | |
| raise ModuleNotFoundError( # noqa: B904 | |
| "This module is only useful in combination with PyTorch. To install PyTorch see https://pytorch.org/." | |
| ) | |
| from torch.onnx import symbolic_helper | |
| _OPSET_VERSION = 1 | |
| _registered_ops: typing.AbstractSet[str] = set() | |
| def _reg(symbolic_fn: typing.Callable, namespace: str = "aten"): | |
| name = f"{namespace}::{symbolic_fn.__name__}" | |
| torch.onnx.register_custom_op_symbolic(name, symbolic_fn, _OPSET_VERSION) | |
| _registered_ops.add(name) | |
| def register(): | |
| """Register ONNX Runtime's built-in contrib ops. | |
| Should be run before torch.onnx.export(). | |
| """ | |
| def grid_sampler(g, input, grid, mode, padding_mode, align_corners): | |
| # mode | |
| # 'bilinear' : onnx::Constant[value={0}] | |
| # 'nearest' : onnx::Constant[value={1}] | |
| # 'bicubic' : onnx::Constant[value={2}] | |
| # padding_mode | |
| # 'zeros' : onnx::Constant[value={0}] | |
| # 'border' : onnx::Constant[value={1}] | |
| # 'reflection' : onnx::Constant[value={2}] | |
| mode = symbolic_helper._maybe_get_const(mode, "i") | |
| padding_mode = symbolic_helper._maybe_get_const(padding_mode, "i") | |
| mode_str = ["bilinear", "nearest", "bicubic"][mode] | |
| padding_mode_str = ["zeros", "border", "reflection"][padding_mode] | |
| align_corners = int(symbolic_helper._maybe_get_const(align_corners, "b")) | |
| return g.op( | |
| "com.microsoft::GridSample", | |
| input, | |
| grid, | |
| mode_s=mode_str, | |
| padding_mode_s=padding_mode_str, | |
| align_corners_i=align_corners, | |
| ) | |
| _reg(grid_sampler) | |
| def inverse(g, self): | |
| return g.op("com.microsoft::Inverse", self).setType(self.type()) | |
| _reg(inverse) | |
| torch.onnx.register_custom_op_symbolic("aten::linalg_inv", inverse, _OPSET_VERSION) | |
| _registered_ops.add("aten::linalg_inv") | |
| def gelu(g, self: torch._C.Value, approximate="none"): | |
| # PyTorch can emit aten::gelu with or without the optional approximate arg. | |
| if not isinstance(approximate, str): | |
| approximate = symbolic_helper._maybe_get_const(approximate, "s") | |
| # Use microsoft::Gelu for performance if possible. It only supports approximate == "none". | |
| if approximate == "none": | |
| return g.op("com.microsoft::Gelu", self).setType(self.type()) | |
| return torch.onnx.symbolic_opset9.gelu(g, self, approximate) | |
| _reg(gelu) | |
| # Some PyTorch versions dispatch GELU symbolic lookup by exporter opset. | |
| # Registering across stable opsets keeps ORT Gelu fusion consistently enabled. | |
| for opset in range(9, 21): | |
| torch.onnx.register_custom_op_symbolic("aten::gelu", gelu, opset) | |
| def triu(g, self, diagonal): | |
| return g.op("com.microsoft::Trilu", self, diagonal, upper_i=1).setType(self.type()) | |
| _reg(triu) | |
| def tril(g, self, diagonal): | |
| return g.op("com.microsoft::Trilu", self, diagonal, upper_i=0).setType(self.type()) | |
| _reg(tril) | |
| def DynamicTimeWarping(g, self): # noqa: N802 | |
| return g.op("com.microsoft::DynamicTimeWarping", self) | |
| _reg(DynamicTimeWarping, namespace="onnxruntime") | |
| def UnfoldTensor(g, self, dim, size, step): # noqa: N802 | |
| dim = int(symbolic_helper._maybe_get_const(dim, "i")) | |
| size = int(symbolic_helper._maybe_get_const(size, "i")) | |
| step = int(symbolic_helper._maybe_get_const(step, "i")) | |
| return g.op( | |
| "com.microsoft::UnfoldTensor", | |
| self, | |
| dim_i=dim, | |
| size_i=size, | |
| step_i=step, | |
| ).setType(self.type().with_sizes([None, None, None, None, size])) | |
| _reg(UnfoldTensor, namespace="onnxruntime") | |
| def unregister(): | |
| """Unregister ONNX Runtime's built-in contrib ops.""" | |
| for name in _registered_ops: | |
| try: | |
| torch.onnx.unregister_custom_op_symbolic(name, _OPSET_VERSION) | |
| except AttributeError: | |
| # The symbolic_registry module was removed in PyTorch 1.13. | |
| # We are importing it here for backwards compatibility | |
| # because unregister_custom_op_symbolic is not available before PyTorch 1.12 | |
| from torch.onnx import symbolic_registry # noqa: PLC0415 | |
| namespace, kind = name.split("::") | |
| for version in symbolic_helper._onnx_stable_opsets: | |
| if version >= _OPSET_VERSION and symbolic_registry.is_registered_op(kind, namespace, version): | |
| del symbolic_registry._registry[(namespace, version)][kind] | |
| # Also clean up gelu's multi-opset registrations (see register()). | |
| for opset in range(9, 21): | |
| with contextlib.suppress(Exception): | |
| torch.onnx.unregister_custom_op_symbolic("aten::gelu", opset) | |