§ ONNX Runtime for Engineers
9 lessons · every lesson has a Colab notebook

The ONNX format

Nine lessons on running trained models with ONNX Runtime. Each lesson links to a Colab notebook for hands-on practice. The core exercises use a CPU; GPU work is optional.

Before you begin

You should be comfortable with Python functions and arrays. Inference means using a trained model to calculate an answer. A graph describes the operations used in that calculation. An operator is one kind of operation, such as addition or matrix multiplication.

Read the plain-language introduction, try its question, then open the notebook. Keep your measured results separate from the illustrative simulations on this page.

Technical references: ONNX Runtime Python API and quantization guidance.

02 · The ONNX Format Up Close

Introduction

An ONNX file is more than a list of operations. Its model stores nodes, learned initializers, input and output contracts, plus separate IR and opset versions that can fail for different reasons.

Learning goal

Inspect an ONNX model graph and diagnose shape, operator, IR-version, and opset-version compatibility problems accurately.

Before you start

Tensors, shapes, data types, computation graphs, and basic Python object inspection.

Lesson plan

  1. Open the model structure and locate graph nodes, initializers, inputs, and outputs.
  2. Distinguish graph shape information from the model's IR and operator-set versions.
  3. Match common runtime errors to the contract or version that caused them.

Read the graph as data. Each node names an operation and connects named tensors. Initializers store learned constants such as weights. Opset and IR versions describe different compatibility layers, so matching one does not guarantee matching the other.

Anatomy of a graph

An .onnx file is protobuf. A GraphProto holds:

FieldWhat it isWhy you care
node[]Operators with named inputs/outputsFusion opportunities and fallback risk live here
initializer[]Weights, inline as tensorsThe file is self-contained; size = params × dtype bytes
input[] / output[]Exposed tensors with types and shapesThe session's contract: names, dtypes, symbolic axes
value_info[]Intermediate shapesPopulated by shape inference; the debugging ground truth
opset_import[]Operator-set versionSemantics of every op; must be supported by the runtime
metadata_props[]Key/value metadataCarry build info, git SHA, calibration data references
Definition · IR version vs. opset

The IR version versions the protobuf container (fields available in the file). The opset version versions the semantics of operators. They move independently: a runtime can understand the container but not your opset, or vice versa. Pin both.

Real error we hit while building this guide

The onnx Python package releases faster than onnxruntime. At the time of writing, onnx stamps new models with IR version 14 while ORT supports up to 13, so a freshly built model fails to load with:

Fail: [ONNXRuntimeError] : 1 : FAIL : Unsupported model IR version: 14, max supported IR version: 13

The one-line fix — and a habit worth keeping — is model.ir_version = 8 right after helper.make_model(...). Notebook 02 demonstrates the failure and the fix side by side.

import onnx
from onnx import shape_inference

inferred = shape_inference.infer_shapes(model)     # propagate shapes through the graph
json_like = onnx.printer.to_text(model)            # read the protobuf as text
total_params = sum(t.dims == t.dims and int(np.prod(t.dims)) for t in model.graph.initializer)
▶ Run notebook 02 in Colab 02-onnx-format-up-close.ipynb CPU runtime · ~25 seconds

The errors you will actually see

What you didWhat you getWhere it surfaces
Used an op newer than the declared opsetNo Op registered for X with domain_version ...Export time — onnx.checker
Declared an opset the runtime doesn't knowONNX Runtime only *guarantees* support for models stamped with official released onnx opset versionsSession creation
Fed int64 where float32 was declaredUnexpected input data type. Actual: (tensor(int64)) , expected: (tensor(float))First run
Fed the wrong tensor nameRequired inputs (['X']) are missing from input feed (['x'])First run