{"id":94585,"date":"2023-08-01T08:00:00","date_gmt":"2023-08-01T15:00:00","guid":{"rendered":""},"modified":"2025-06-02T07:33:40","modified_gmt":"2025-06-02T14:33:40","slug":"introducing-onnx-script-authoring-onnx-with-the-ease-of-python","status":"publish","type":"post","link":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/","title":{"rendered":"Introducing ONNX Script: Authoring ONNX with the ease of Python"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"an-onnx-refresher\">An ONNX refresher&nbsp;<\/h2>\n\n\n\n<p>ONNX models are flexible, standardized representations of machine learning that allow them to be executed across a gamut of hardware platforms and runtime environments from large-scale cloud-based supercomputers to resource-constrained edge devices such as your web browser and phone.&nbsp;<\/p>\n\n\n\n<p>Beyond its graph format, canonically <a href=\"https:\/\/onnx.ai\/onnx\/api\/classes.html#protos\" target=\"_blank\" rel=\"noreferrer noopener\">represented using\u202fProtobuf<\/a>, ONNX consists of a standard set of primitive operators which are implemented by runtimes and hardware vendors alike. With this broad ecosystem in mind, ONNX aims to keep the number of these operators low, encouraging composability through ONNX functions. This is important to reduce the overhead of supporting ONNX.&nbsp;<\/p>\n\n\n\n<p>Typically, machine learning models are developed using higher-level frameworks such as\u202f<a href=\"https:\/\/pytorch.org\/docs\/stable\/onnx.html\" target=\"_blank\" rel=\"noreferrer noopener\">PyTorch<\/a>\u202fand\u202f<a href=\"https:\/\/github.com\/onnx\/tensorflow-onnx\" target=\"_blank\" rel=\"noreferrer noopener\">TensorFlow<\/a>. While these frameworks tend to be productive for iterating on the development of models, the models are not typically deployed to production in this fashion. Instead, they are exported to ONNX by facilities provided by the frameworks, and then optimized for a particular target by <a href=\"https:\/\/onnxruntime.ai\/docs\/performance\/olive.html\" target=\"_blank\" rel=\"noreferrer noopener\">tools such as\u202fOlive<\/a>.&nbsp;<\/p>\n\n\n\n<p>Want to dive right into ONNX Script? <a href=\"https:\/\/github.com\/microsoft\/onnxscript\/\">Check it out on GitHub<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"announcing-onnx-script\">Announcing ONNX Script&nbsp;<\/h2>\n\n\n\n<p>ONNX Script is a new open-source library for directly authoring ONNX models in Python with a focus on\u202fclean, idiomatic Python\u202fsyntax and composability through ONNX-native functions. Critically, it is also the foundation upon which we are building the new PyTorch ONNX exporter to <a href=\"https:\/\/pytorch.org\/docs\/stable\/dynamo\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">support\u202fTorchDynamo<\/a>\u2014the future of PyTorch.&nbsp;<\/p>\n\n\n\n<p>Prior to ONNX Script, authoring ONNX models required deep knowledge of the specification and serialization format itself. While eventually a more convenient\u202f<a href=\"https:\/\/onnx.ai\/onnx\/api\/helper.html\" target=\"_blank\" rel=\"noreferrer noopener\">helper API<\/a>\u202fwas introduced that largely abstracted the serialization format, it still required deep familiarity with ONNX constructs.&nbsp;<\/p>\n\n\n\n<p>ONNX Script takes a new approach by integrating deeply with Python on two fronts:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>It provides a strongly typed API for all operators in ONNX (all 186 as of opset 19).<sup>1<\/sup> This allows existing Python tooling, linters, and integrated development environments (IDEs) to provide valuable feedback and enforce correctness.<\/li>\n\n\n\n<li>ONNX Script supports idiomatic Python language constructs to make authoring ONNX more natural, including support for conditionals and loops, binary and unary operators, subscripting, slicing, and more. For example, the expression\u202f<code>a\u202f+\u202fb<\/code>\u202fin Python would translate to the ONNX operator\u202fas <code>Add(a,\u202fb)<\/code>.<\/li>\n<\/ol>\n\n\n\n<p>Let\u2019s look at how we might implement GELU using ONNX Script and compare it with\u202fonnx.helper\u202fAPI\u2014and to be clear\u2014the examples below produce the same ONNX model. For reference, we\u2019ll use this definition of GELU to guide the ONNX implementations:&nbsp;<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/gelu_onnxscript_onnxhelper.webp\" alt=\"GELU formula and implementation in ONNX Script and using helper API\" class=\"wp-image-94712 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/gelu_onnxscript_onnxhelper.webp\"><\/figure>\n\n\n\n<p>As you can see, ONNX Script emphasizes the familiar readability and productivity of Python while expressing an ONNX model that can be statically reasoned about by existing Python and ONNX tooling.&nbsp;<\/p>\n\n\n\n<p>This also means ONNX comes alive within the context of your existing tooling and development environments, be it debugging in Visual Studio Code or demonstrating concepts in a Jupyter Notebook\u2014ONNX Script integrates naturally.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-are-we-investing-in-onnx-script\">Why are we investing in ONNX Script?&nbsp;<\/h2>\n\n\n\n<p>Much has changed since ONNX support for PyTorch was originally introduced over five years ago in PyTorch 0.3.0. For PyTorch 2.0, TorchDynamo represents the eventual deprecation of TorchScript, which implies a major overhaul of the ONNX exporter is necessary. We are fully embracing this as an opportunity to revisit the fundamentals upon which the exporter is built, and ONNX Script is its new foundation. We began this effort in November 2022 and have worked closely with PyTorch engineers to ensure TorchDynamo is a fully capable starting point for exporting high-fidelity ONNX for years to come.&nbsp;<\/p>\n\n\n\n<p>One of the first streams of work we started was the development of what we call Torchlib, a pure ONNX implementation of the operators in PyTorch\u2014namely\u202f<a href=\"https:\/\/pytorch.org\/docs\/stable\/ir.html\" target=\"_blank\" rel=\"noreferrer noopener\">Core ATen IR and Prims IR<\/a>\u2014and of course, these operators are implemented in ONNX Script. This approach greatly simplifies the central responsibility of the exporter as it \u201cjust\u201d needs to project FX graph nodes produced by TorchDynamo into ONNX graph nodes, without concerning itself with the implementation details of individual operators.&nbsp;<\/p>\n\n\n\n<p>We will cover the new PyTorch ONNX exporter in a separate post with more depth as PyTorch 2.1 approaches, but for now, the key takeaway is that ONNX Script is pervasive throughout our renewed approach. For those willing to try bold new things, the new exporter is available as a preview in PyTorch nightly via the\u202f<a href=\"https:\/\/pytorch.org\/docs\/main\/onnx.html#preview-torch-onnx-torchdynamo-exporter\" target=\"_blank\" rel=\"noreferrer noopener\">torch.onnx.dynamo_export<\/a>\u202fAPI.&nbsp;<\/p>\n\n\n\n<p>By deeply weaving ONNX Script support into the PyTorch ONNX exporter, we have also made it possible to augment PyTorch model code with specialized ONNX functions as custom operators. We introduced initial support for this in the TorchScript exporter <a href=\"https:\/\/pytorch.org\/docs\/stable\/onnx.html#onnx-script-functions\" target=\"_blank\" rel=\"noreferrer noopener\">starting with\u202fPyTorch 1.13<\/a>\u202fand continue to refine this capability in the new exporter.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"an-end-to-end-example\">An end-to-end example&nbsp;&nbsp;<\/h2>\n\n\n\n<p>Let\u2019s look at an example slightly more complicated than GELU. In fact, the following example is adapted directly from the new PyTorch ONNX exporter, implementing <a href=\"https:\/\/pytorch.org\/docs\/stable\/generated\/torch.chunk.html\" target=\"_blank\" rel=\"noreferrer noopener\">support for\u202ftorch.chunk<\/a>, which attempts to split a tensor into the number of specified chunks.&nbsp;<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/aten_chunk.webp\" alt=\"The aten_chunk() function\" class=\"wp-image-94713 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/aten_chunk.webp\"><\/figure>\n\n\n\n<p>We start by importing from onnxscript the ONNX opset we wish to use (version 18 in this case), the\u202f<code>@script<\/code>\u202fdecorator, and the tensor types of\u202f<code>FLOAT<\/code>\u202fand\u202f<code>INT64<\/code>. In ONNX Script, tensor shapes are denoted by subscripting the type, such as <code>FLOAT[2, 10]<\/code>, symbolically such as <code>FLOAT[\"M\", \"N\"]<\/code>, or <code>FLOAT[...]<\/code> incase the tensor shape is unknown. Without subscripting (just <code>FLOAT<\/code>), the type is intended to indicate a scalar (a tensor of rank 0).<\/p>\n\n\n\n<p>Next, we define the\u202f<code>aten_chunk<\/code>\u202ffunction with type annotations and implement the body of the function using both built-in Python syntax and explicit invocations of ONNX operators. The example uses various binary expressions and an\u202fif\u202fstatement, but many other idiomatic Python constructs are also supported.&nbsp;<\/p>\n\n\n\n<p>We also need to define a simple model that calls our ONNX Script function so we can export and verify an end-to-end example:&nbsp;<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model.webp\" alt=\"ten_chunks_model() function, calling the ONNX Script function\" class=\"wp-image-94714 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model.webp\"><\/figure>\n\n\n\n<p>This model will simply split the provided tensor into ten tensors, but it also demonstrates that ONNX functions can of course call other ONNX functions, not just built-in ONNX operators.&nbsp;<\/p>\n\n\n\n<p>We\u2019ll now export our ONNX Script model to ONNX and explore it in Netron. Functions decorated with <code>@script<\/code> allow them to be exported using the <code>to_model_proto<\/code> function.<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model_to_onnx.webp\" alt=\"saving the ONNX model\" class=\"wp-image-94715 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model_to_onnx.webp\"><\/figure>\n\n\n\n<p>If we open\u202f<em>ten_chunks_model.onnx<\/em>\u202fin Netron, we can observe the composability of ONNX functions and how the Python code was translated into an ONNX model.&nbsp;<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture1-1.webp\" alt=\"a netron graph of the ten_chunks_model and its connected function, aten_chunk\" class=\"wp-image-94586 webp-format\" style=\"width:900px;height:883px\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture1-1.webp\"><\/figure>\n\n\n\n<p>The graphs depict our two ONNX functions. We can observe the original\u202f<strong>input tensor<\/strong>\u202fflowing from\u202f<code>ten_chunks_model<\/code>\u202finto\u202f<code>aten_chunk<\/code>\u202falong with the\u202f<strong>attribute chunks=10<\/strong>. A\u202fsequence of <strong>\u2264 10 tensors<\/strong>\u202fis returned. As one might expect, functions in ONNX can be defined once and invoked any number of times within a model.\u202fRead more about <a href=\"https:\/\/onnx.ai\/onnx\/intro\/concepts.html#input-output-node-initializer-attributes\" target=\"_blank\" rel=\"noreferrer noopener\">core ONNX concepts<\/a><em>.<\/em>&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"iterating-and-debugging\">Iterating and debugging&nbsp;<\/h2>\n\n\n\n<p>Finally, we should test our model. ONNX Script makes this easy since it provides a mechanism for eagerly evaluating the model through either\u202f<a href=\"https:\/\/onnxruntime.ai\/\" target=\"_blank\" rel=\"noreferrer noopener\">ONNX Runtime<\/a>\u202for the new\u202f<a href=\"https:\/\/onnx.ai\/onnx\/api\/reference.html\" target=\"_blank\" rel=\"noreferrer noopener\">ONNX Reference Evaluator<\/a>. Of note, ONNX Script has <a href=\"https:\/\/numpy.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">built-in support for\u202fNumPy<\/a>\u202ffor input and output values to ease the overhead of creating and filling tensors in ONNX. &nbsp;<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model_eager_eval.webp\" alt=\"setting up testing tensors and chunked_tensors arrays\" class=\"wp-image-94717 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model_eager_eval.webp\"><\/figure>\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model_eager_eval_output.webp\" alt=\"Output arrays, as expected\" class=\"wp-image-94716 webp-format\" srcset=\"\" data-orig-src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/07\/ten_chunks_model_eager_eval_output.webp\"><\/figure>\n\n\n\n<p>Because ONNX Script\u2019s eager mode evaluates the model on an op-by-op basis, it is conducive to debugging ONNX using standard Python tooling <a href=\"https:\/\/docs.python.org\/3\/library\/pdb.html\" target=\"_blank\" rel=\"noreferrer noopener\">such as\u202fpdb<\/a>\u202fdirectly or through richer IDE and editor integrations provided by Visual Studio and Visual Studio Code.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"512\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1.png\" alt=\"A screenshot of Visual Studio Code debugging the model while stopped on a breakpoint to inspect the\u202fdim_size\u202fvariable and call stack.\" class=\"wp-image-94587\" style=\"width:900px;height:512px\" srcset=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1.webp 900w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1-300x171.png 300w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1-768x437.png 768w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1-800x455.png 800w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1-400x228.png 400w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1-450x256.png 450w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture2-1-650x370.webp 650w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><figcaption class=\"wp-element-caption\"><em>A screenshot of Visual Studio Code debugging the model while stopped on a breakpoint to inspect the\u202f<code>dim_size<\/code>\u202fvariable and call stack.<\/em><\/figcaption><\/figure>\n\n\n\n<p>Along with debuggability, IntelliSense support is front-and-center with ONNX Script. We rely heavily on Python type annotations to enforce the correctness of ONNX and to make ONNX more discoverable, including inline documentation on hover tooltips and code completion suggestions. A single click will take you to expanded online documentation in your browser as well.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"574\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2.png\" alt=\"A screenshot of Visual Studio Code displaying a hover tooltip for the ONNX\u202fExpand operator\u202fwith inline documentation linking to full online documentation. \" class=\"wp-image-94588\" style=\"width:900px;height:574px\" srcset=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2.webp 900w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2-300x191.png 300w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2-768x490.png 768w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2-800x510.png 800w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2-400x255.png 400w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2-450x287.png 450w, https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2023\/06\/Picture3-2-650x415.webp 650w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><figcaption class=\"wp-element-caption\"><em>A screenshot of Visual Studio Code displaying a hover tooltip for the ONNX\u202f<\/em><a href=\"https:\/\/onnx.ai\/onnx\/operators\/onnx__Expand.html#expand-13\" target=\"_blank\" rel=\"noreferrer noopener\"><em>Expand operator<\/em><\/a><em>\u202fwith inline documentation linking to full online documentation.<\/em>&nbsp;<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-s-next-for-onnx-script\">What\u2019s next for ONNX Script?&nbsp;<\/h2>\n\n\n\n<p>In summary, ONNX Script offers a new Python-first programming model for authoring ONNX models that integrates with the existing rich ecosystem of Python tooling and environments.&nbsp;<\/p>\n\n\n\n<p>Going forward, we envision ONNX Script as a means for defining and extending ONNX itself. New core operators and higher-order functions that are intended to become part of the ONNX standard could be authored in ONNX Script as well, reducing the time and effort it takes for the standard to evolve. We have proven this is a viable strategy by developing Torchlib, upon which the upcoming PyTorch Dynamo-based ONNX exporter is built.&nbsp;<\/p>\n\n\n\n<p>Over the coming months, we will also support converting ONNX into ONNX Script to enable seamless editing of existing models, which can play a key role in optimization passes, but also allow for maintaining and evolving ONNX models more naturally. We also intend to propose ONNX Script for inclusion directly within the ONNX GitHub organization soon, under the Linux Foundation umbrella.&nbsp;<\/p>\n\n\n\n<p>Check out ONNX Script today <a href=\"https:\/\/github.com\/microsoft\/onnxscript\">on GitHub<\/a>!<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p>A\u202f<em>huge thank you<\/em>\u202fto the wonderful engineering team at Microsoft that has brought us to this point so far:\u202f<em>Bowen Bao, Aaron Bockover, Shubham Bhokare, Jacky Chen, Wei-Sheng Chin, Justin Chu, Thiago Crepaldi, Xavier Dupre, Liqun Fu, Xaiowu Hu, Ganesan Ramalingam, Ti-Tai Wang, Jay Zhang<\/em>.&nbsp;<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p><sup>1<\/sup> <a href=\"https:\/\/onnx.ai\/onnx\/operators\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">ONNX Operators\u2014ONNX 1.15.0 documentation<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ONNX Script is a new open-source library for directly authoring ONNX models in Python.<\/p>\n","protected":false},"author":6191,"featured_media":95470,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"msxcm_post_with_no_image":false,"ep_exclude_from_search":false,"_classifai_error":"","_classifai_text_to_speech_error":"","footnotes":""},"post_tag":[663,223,224],"content-type":[346],"topic":[],"programming-languages":[2264,2265],"coauthors":[2040,2041,2042,2043],"class_list":["post-94585","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-onnx","tag-visual-studio","tag-visual-studio-code","content-type-news","programming-languages-python","programming-languages-pytorch","review-flag-1593580362-584","review-flag-1593580419-521","review-flag-1-1593580432-963","review-flag-2-1593580437-411","review-flag-3-1593580442-169","review-flag-machi-1680214156-53","review-flag-new-1593580248-669"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Introducing ONNX Script: Authoring ONNX with the ease of Python | Microsoft Open Source Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing ONNX Script: Authoring ONNX with the ease of Python | Microsoft Open Source Blog\" \/>\n<meta property=\"og:description\" content=\"ONNX Script is a new open-source library for directly authoring ONNX models in Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\" \/>\n<meta property=\"og:site_name\" content=\"Microsoft Open Source Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-01T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-02T14:33:40+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1170\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Aaron Bockover, Maanav Dalal, Ganesan Ramalingam, Justin Chu\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:site\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Aaron Bockover, Maanav Dalal, Ganesan Ramalingam, Justin Chu\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 min read\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\"},\"author\":[{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/aaron-bockover\/\",\"@type\":\"Person\",\"@name\":\"Aaron Bockover\"},{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/maanav-dalal\/\",\"@type\":\"Person\",\"@name\":\"Maanav Dalal\"},{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/ganesan-ramalingam\/\",\"@type\":\"Person\",\"@name\":\"Ganesan Ramalingam\"},{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/justin-chu\/\",\"@type\":\"Person\",\"@name\":\"Justin Chu\"}],\"headline\":\"Introducing ONNX Script: Authoring ONNX with the ease of Python\",\"datePublished\":\"2023-08-01T15:00:00+00:00\",\"dateModified\":\"2025-06-02T14:33:40+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\"},\"wordCount\":1532,\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp\",\"keywords\":[\"ONNX\",\"Visual Studio\",\"Visual Studio Code\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\",\"name\":\"Introducing ONNX Script: Authoring ONNX with the ease of Python | Microsoft Open Source Blog\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp\",\"datePublished\":\"2023-08-01T15:00:00+00:00\",\"dateModified\":\"2025-06-02T14:33:40+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp\",\"width\":1170,\"height\":640},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/opensource.microsoft.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing ONNX Script: Authoring ONNX with the ease of Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"name\":\"Microsoft Open Source Blog\",\"description\":\"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability\",\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\",\"name\":\"Microsoft Open Source Blog\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"width\":259,\"height\":194,\"caption\":\"Microsoft Open Source Blog\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/OpenAtMicrosoft\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Introducing ONNX Script: Authoring ONNX with the ease of Python | Microsoft Open Source Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/","og_locale":"en_US","og_type":"article","og_title":"Introducing ONNX Script: Authoring ONNX with the ease of Python | Microsoft Open Source Blog","og_description":"ONNX Script is a new open-source library for directly authoring ONNX models in Python.","og_url":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/","og_site_name":"Microsoft Open Source Blog","article_published_time":"2023-08-01T15:00:00+00:00","article_modified_time":"2025-06-02T14:33:40+00:00","og_image":[{"width":1170,"height":640,"url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.png","type":"image\/png"}],"author":"Aaron Bockover, Maanav Dalal, Ganesan Ramalingam, Justin Chu","twitter_card":"summary_large_image","twitter_creator":"@OpenAtMicrosoft","twitter_site":"@OpenAtMicrosoft","twitter_misc":{"Written by":"Aaron Bockover, Maanav Dalal, Ganesan Ramalingam, Justin Chu","Est. reading time":"6 min read"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#article","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/"},"author":[{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/aaron-bockover\/","@type":"Person","@name":"Aaron Bockover"},{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/maanav-dalal\/","@type":"Person","@name":"Maanav Dalal"},{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/ganesan-ramalingam\/","@type":"Person","@name":"Ganesan Ramalingam"},{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/justin-chu\/","@type":"Person","@name":"Justin Chu"}],"headline":"Introducing ONNX Script: Authoring ONNX with the ease of Python","datePublished":"2023-08-01T15:00:00+00:00","dateModified":"2025-06-02T14:33:40+00:00","mainEntityOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/"},"wordCount":1532,"publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp","keywords":["ONNX","Visual Studio","Visual Studio Code"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/","url":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/","name":"Introducing ONNX Script: Authoring ONNX with the ease of Python | Microsoft Open Source Blog","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp","datePublished":"2023-08-01T15:00:00+00:00","dateModified":"2025-06-02T14:33:40+00:00","breadcrumb":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#primaryimage","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO22_Coworking_015.webp","width":1170,"height":640},{"@type":"BreadcrumbList","@id":"https:\/\/opensource.microsoft.com\/blog\/2023\/08\/01\/introducing-onnx-script-authoring-onnx-with-the-ease-of-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/opensource.microsoft.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Introducing ONNX Script: Authoring ONNX with the ease of Python"}]},{"@type":"WebSite","@id":"https:\/\/opensource.microsoft.com\/blog\/#website","url":"https:\/\/opensource.microsoft.com\/blog\/","name":"Microsoft Open Source Blog","description":"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability","publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/opensource.microsoft.com\/blog\/#organization","name":"Microsoft Open Source Blog","url":"https:\/\/opensource.microsoft.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","width":259,"height":194,"caption":"Microsoft Open Source Blog"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/OpenAtMicrosoft"]}]}},"msxcm_display_generated_audio":false,"msxcm_animated_featured_image":null,"distributor_meta":false,"distributor_terms":false,"distributor_media":false,"distributor_original_site_name":"Microsoft Open Source Blog","distributor_original_site_url":"https:\/\/opensource.microsoft.com\/blog","push-errors":false,"_links":{"self":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/94585","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/users\/6191"}],"replies":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=94585"}],"version-history":[{"count":2,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/94585\/revisions"}],"predecessor-version":[{"id":96348,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/94585\/revisions\/96348"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media\/95470"}],"wp:attachment":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=94585"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/post_tag?post=94585"},{"taxonomy":"content-type","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/content-type?post=94585"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/topic?post=94585"},{"taxonomy":"programming-languages","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/programming-languages?post=94585"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/coauthors?post=94585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}