Introduction
An ONNX tensor file holds a single tensor: an array of numbers, or of strings, with a
shape and an element type. It is one TensorProto message from the schema
of ONNX, the open format for neural networks, stored
as a Protocol Buffers message with no
header around it.
Most such files come from ONNX’s own test
data, where every test has files named input_0.pb,
output_0.pb and so on beside its model. Tensors saved from Python with
onnx.save_tensor, or with
numpy_helper.from_array(…).SerializeToString(), are the same format. Inside
an ONNX model the same message holds the weights.
The file follows the TensorProto of onnx.proto. Later ONNX versions have
only added data types and fields to it, so every version is one format; a change to
an existing field would make a separate one. A .pb file dropped on any
page of this site opens in the explorer, which shows the tensor’s shape, type and
every value, and draws the tensor as a picture when its shape looks like an
image.
Structure
The file is one TensorProto. Its fields can come in any order; ONNX’s writers put them in field-number order, as here.
0dims field 1, one varint field per dimension, outermost first2 bytes each, usually…data_type field 2, the element type2 bytes…name field 8, the tensor’s name, often the model input it feedsvaries…raw_data field 9, the values as little-endian bytes, or else one of the typed fieldsvaries
A whole file from ONNX’s test data, 254 bytes: a 3 × 4 × 5 tensor of floats named
x.
| Bytes | Field | Value |
|---|---|---|
08 03 | dims | 3 |
08 04 | dims | 4 |
08 05 | dims | 5 |
10 01 | data_type | 1, FLOAT |
42 01 78 | name | x |
4A F0 01 | raw_data | 240 bytes follow: 60 floats of 4 bytes |
78 CC E1 3F … | the first value, 1.764052 |
In the test files examined for this site, most tensors keep their values in
raw_data. int32_data appears for FLOAT16, 4-bit and float8
tests, string tensors use string_data, and a few use
float_data. Ranks from 0 (a scalar) to 6 occur.
Telling it apart
The file has no signature. The explorer takes it as Protocol Buffers when the name
ends .pb, .binpb or .onnx, the first field
reads cleanly and the first 512 bytes are not all printable text. Then the parser
for this format, tried first of the Protocol Buffers formats, checks:
- every field number is one of TensorProto’s (1 to 14, and 16), each with the wire type its type is stored with;
data_typeis present and from 1 to 28;- the dimensions make a valid shape;
- the values are in exactly one place:
raw_data, the typed field that matches the data type, or external data; - their size fits the shape exactly:
raw_datamust be ⌈elements × bits ÷ 8⌉ bytes, and a typed field must hold one value per element (two per element for the complex types, one per two elements for the 4-bit types, one per four for the 2-bit types). A tensor with a segment or external data skips this check; - strings declared
stringare valid UTF-8 (checked up to 4 KB).
A file that fails is turned down, and the explorer tries the next format: ONNX sequence, ONNX model, the TensorFlow formats, and last any Protocol Buffers message. The field numbers come from onnx 1.23. A later version of the schema that adds a field is still this format, but the parser turns such a file down until it learns the field, and the file is then shown as a message without a schema.
Variants
- ONNX tensor (TensorProto) – one tensor, as in ONNX’s test data
- ONNX sequence or optional value – a list of tensors, or a value that may be absent
- ONNX model (ModelProto) – a whole model: graph, operators and weights
- TensorFlow SavedModel (saved_model.pb) – meta graphs, signatures and functions
- TensorFlow GraphDef (frozen graph) – nodes, with the weights as constants
- Protocol Buffers message – any message, read without its schema
Links
Software
- protoc – with onnx.proto,
protoc --decode=onnx.TensorProto onnx.proto < input_0.pbprints the tensor as text (Windows, macOS, Linux) - Protoscope – prints the fields without the schema
Developers
- onnx –
onnx.load_tensor,onnx.save_tensorandnumpy_helperto turn tensors into NumPy arrays and back (Python)
Reference
- onnx.proto – the schema, with TensorProto and its data types
- ONNX versioning – the IR versions and the ONNX releases that brought them
- Encoding – the Protocol Buffers wire format