Introduction

ONNX (Open Neural Network Exchange) is an open, framework-agnostic format for representing machine learning models, and ONNX Export is the process of converting a trained PyTorch model into this shared format so it can run on a much broader range of platforms, runtimes, and even other frameworks entirely. While TorchScript (covered in the previous topic) keeps a model within the PyTorch ecosystem — just freed from the Python dependency — ONNX takes portability a step further, enabling a model trained in PyTorch to potentially run in TensorFlow-based tools, specialized inference engines, or hardware-specific accelerators that never need to know PyTorch was involved at all.

ONNX has become a widely adopted standard precisely because it decouples where a model is trained from where it's deployed, letting teams use PyTorch's flexibility for development while deploying through whichever runtime best fits their specific production environment.

Why Does ONNX Export Matter?

ONNX Export helps to:

  • Enable a PyTorch model to run in non-PyTorch environments and runtimes
  • Provide a standard, shared format supported across many frameworks and tools
  • Unlock specialized, highly optimized inference engines (like ONNX Runtime) for faster serving
  • Support deployment on specialized hardware accelerators with ONNX-compatible drivers
  • Decouple model training decisions from deployment infrastructure decisions
  • Serve as a common interchange format between different parts of an ML pipeline or team

Exporting a PyTorch Model to ONNX

Similar to TorchScript's tracing method, ONNX export works by
running the model once with an example input and recording the
resulting computation graph — meaning ONNX export shares the
same important limitation covered in the TorchScript topic:
it can silently produce incorrect results for models containing
data-dependent control flow, since only the executed path gets
captured in the exported graph.

Understanding dynamic_axes

By default, an exported ONNX graph "bakes in" the exact shape
of the example input used during export — including the batch
size. Since real-world inference often needs to handle different
batch sizes (a single request vs. a large batch), dynamic_axes
tells the exporter which dimensions should remain flexible
rather than fixed, so the exported model can accept inputs
of varying batch size at inference time.

Verifying the Exported Model

Validating the exported model before deployment is an important step, since export issues — especially around dynamic shapes or unsupported operations — are often much easier to catch and debug immediately after export than after the model has already been deployed elsewhere.

Running an ONNX Model with ONNX Runtime

Notice that this code has no dependency on PyTorch at all —
onnxruntime is a separate, highly optimized inference engine
that can load and run the exported .onnx file directly, often
significantly faster than running the equivalent model through
PyTorch's own eager-mode execution, especially in production
serving scenarios.

Comparing the Original PyTorch Output to the ONNX Output

Comparing outputs between the original PyTorch model and the exported ONNX version is a critical validation step, catching any subtle discrepancies introduced during the export process before they cause problems in production.

What ONNX Enables Beyond PyTorch

Because ONNX is an open, shared standard (not PyTorch-specific),
an exported .onnx file can potentially be:

- Loaded and run using ONNX Runtime, a fast, cross-platform
  inference engine
- Converted for use with other frameworks that support
  importing ONNX models
- Deployed to specialized hardware accelerators with
  ONNX-compatible support
- Used within tools and platforms built around the ONNX
  standard, regardless of whether they have any native
  PyTorch integration at all

TorchScript vs ONNX Export

AspectTorchScriptONNX Export
EcosystemStays within the PyTorch/LibTorch ecosystemFramework-agnostic, open standard
Primary Use CaseRunning PyTorch models without Python, still via PyTorch's own runtimeRunning models via other runtimes, tools, or hardware
Control Flow HandlingScripting handles it correctly; tracing does notShares tracing's limitation — data-dependent control flow can be lost
Typical Deployment TargetC++ applications using LibTorch, PyTorch MobileONNX Runtime, specialized hardware, or other frameworks
Conversion MethodTracing or scriptingPrimarily tracing-based export

When to Choose ONNX vs TorchScript

ScenarioBetter Choice
Deploying with LibTorch in a C++ applicationTorchScript
Needing maximum cross-framework/tool compatibilityONNX Export
Model has significant data-dependent control flowTorchScript (via scripting)
Deploying to specialized hardware with ONNX supportONNX Export
Wanting to use ONNX Runtime's optimized inference engineONNX Export

Key Properties of ONNX Export

  • ONNX is an open, framework-agnostic format for representing machine learning models.
  • Exporting to ONNX, like tracing, captures the computation graph from one example run of the model.
  • dynamic_axes must be specified to allow the exported model to handle varying input shapes, like batch size.
  • ONNX Runtime provides a fast, PyTorch-independent way to run exported models in production.
  • Comparing PyTorch and ONNX outputs directly after export is an important validation step.

Where Is ONNX Export Used?

FieldApplication
Cross-Framework DeploymentRunning a PyTorch-trained model in a non-PyTorch serving environment
High-Performance Inference ServingLeveraging ONNX Runtime's optimizations for faster production inference
Hardware-Accelerated DeploymentRunning models on specialized chips with ONNX support
Multi-Team ML PipelinesProviding a standard interchange format between data science and deployment teams
Edge and Embedded DeploymentRunning optimized ONNX models on resource-constrained devices

Advantages

  • Enables deployment across a much broader range of platforms and tools than PyTorch alone
  • ONNX Runtime often provides significant inference speed improvements over eager-mode PyTorch
  • Decouples model training framework choice from deployment infrastructure choice
  • Widely adopted, open standard with strong industry and tooling support
  • Supports validation tools to check model correctness before deployment

Limitations

  • Shares tracing's limitation around data-dependent control flow, since export is trace-based
  • Not every custom PyTorch operation has a direct, supported ONNX equivalent
  • Requires careful configuration (like dynamic_axes) to handle real-world variable input shapes correctly
  • Adds an additional validation step to confirm exported behavior matches the original model
  • Debugging export failures can require understanding both PyTorch's and ONNX's internal representations

Real-World Examples

ApplicationONNX Export Use
Cross-Platform Model ServingDeploying a single exported model across multiple different runtime environments
High-Throughput Inference APIsUsing ONNX Runtime to serve predictions faster than native PyTorch
Hardware-Accelerated Edge DevicesRunning ONNX-optimized models on specialized inference chips
Multi-Framework ML TeamsSharing models between teams using different primary frameworks
Model Interoperability ResearchStudying how models transfer and perform across different runtime engines

Best Practices

  • Always set model.eval() before exporting to ensure correct layer behavior (e.g., Dropout, BatchNorm) is captured.
  • Use dynamic_axes to support realistic, variable input shapes like batch size at inference time.
  • Validate the exported model with onnx.checker.check_model() before deploying it anywhere.
  • Compare PyTorch and ONNX outputs directly on representative inputs to confirm the export preserved correct behavior.
  • Be aware of the same data-dependent control flow limitations that apply to tracing-based TorchScript export.

Interview Tip

A common interview question is:

"Why would you export a PyTorch model to ONNX instead of just using TorchScript, and what's a key limitation both approaches share?"

A strong answer is:

I'd export to ONNX specifically when I need to deploy a model outside the PyTorch ecosystem entirely — for example, running it through ONNX Runtime for optimized inference performance, deploying to specialized hardware with ONNX support, or integrating with tools and frameworks that have no native PyTorch dependency at all. TorchScript, by contrast, keeps the model within PyTorch's own runtime (LibTorch), which is the better choice for C++ deployment specifically using PyTorch's ecosystem. Both approaches share a key limitation, though: since ONNX export and TorchScript's tracing method both work by recording operations from a single example execution, they can silently produce incorrect results for models with data-dependent control flow, since only the branch actually taken during that example gets captured in the resulting graph.

Explaining the shared tracing limitation ties this topic directly back to the previous one, showing connected understanding.

Conclusion

ONNX Export provides a framework-agnostic path for deploying PyTorch models across a broad range of runtimes, tools, and hardware, trading some of tracing's control-flow limitations for significantly wider deployment flexibility than TorchScript alone. With both major deployment paths — TorchScript and ONNX Export — now covered, the final topic in this section, Save/Load Models, addresses the more everyday, general-purpose task of persisting and restoring PyTorch models for continued use within the PyTorch ecosystem itself.