aidos-echo-onxx
A byte-level echo (identity) "model" in ONNX. It is a smoke-test fixture, not a trained network: the only weight is a hand-built 256×256 identity matrix, so the correct output is known exactly for every possible input — the input itself. Any wrong byte is a runtime bug, never model drift.
Built for Aidos, a local-first AI agent project, as a fixture for testing its model-loading and inference runtime against a model whose correct output is known in advance for every input.
| File | echo.onnx (258 KB) |
| Opset / IR | 13 / 8 — the floor mobile ONNX Runtime builds still accept |
| Inputs | input_ids — int64[batch, seq], byte values 0..255 |
| Outputs | output_ids — int64[batch, seq]; logits — float32[batch, seq, 256] |
| Contract | output_ids[b][i] == input_ids[b][i] |
batch and seq are dynamic. Both dimensions may be any size ≥ 1.
Why echo
A smoke test needs a model whose correct output is known in advance, for every possible input. Real models do not offer that: their outputs shift with quantization, sampling, threading, and version bumps, so a test can only assert something vague and ends up passing on broken runtimes.
The identity function over bytes gives a total, exactly-specified function on all 256 inputs: the answer is always the input itself. This fixture computes it through genuine model machinery — a float32 GEMM instead of a lookup table — so loading the file exercises what a real model exercises: dynamic shapes, float matmul, argmax, and the int64 ↔ float boundary, while staying small enough to check into git.
The model is not trained. The only weight is a hand-built identity matrix; see
below. This is the same construction as
aidos-rot13-onxx, with
the permutation matrix set to the identity instead of ROT13's.
Why it is shaped this way
input_ids ──OneHot(depth=256)──▶ float32[batch, seq, 256]
──MatMul(I)─────────▶ logits
──ArgMax(axis=-1)───▶ output_ids
I[t] is the one-hot row for t itself, so logits is a clean one-hot:
exactly one 1.0 per position and 0.0 elsewhere. A smoke test can assert on
that directly when it wants to check float tensor plumbing rather than just
the decoded bytes.
Properties worth asserting
- Total. Defined for all 256 byte values, not just ASCII letters.
- Trivially its own inverse. Feeding
output_idsback in returns the same input again — a round-trip check needs no expected-value table. - Position- and batch-independent. Each position is computed on its own, so a row's result must not change with sequence length or batch composition. A batched result that differs from the same row run alone is a bug.
- Exact. The logit gap is
1.0vs0.0; no tolerance tuning is needed.
Inputs outside 0..255 are a contract violation. ONNX defines OneHot to emit
an all-zero row for an out-of-range index, so the model returns 0 rather than
raising — callers must range-check.
Use
import numpy as np, onnxruntime as ort
session = ort.InferenceSession("echo.onnx", providers=["CPUExecutionProvider"])
ids = np.frombuffer(b"Hello, World!", dtype=np.uint8).astype(np.int64)[None, :]
output_ids, logits = session.run(None, {"input_ids": ids})
print(bytes(output_ids[0].astype(np.uint8))) # b'Hello, World!'
Regenerate and verify
Source, build.py, and verify.py live in the
Aidos monorepo:
pip install onnx onnxruntime numpy
python3 build.py # rewrites echo.onnx
python3 verify.py # exits non-zero on any mismatch
verify.py checks all 256 byte values individually and as one batch, several
text fixtures, the round-trip, batch independence, and the shape and one-hot
structure of logits.
See also: aidos-echo-gguf,
the same fixture as a full autoregressive llama-architecture transformer, and
aidos-rot13-onxx, the
ROT13 sibling of this fixture.