Simplify, optimize, and inspect ONNX models with onnxsim and onnx-optimizer, compiled to WebAssembly. Everything runs locally in your browser — models are never uploaded.
Paste an ONNX model or graph in the
textual representation
— the form onnx.parser.parse_graph / parse_model accept.
It is parsed into a model by the WebAssembly module (a bare graph is
wrapped into a model with a default-domain opset import) and shown in
the Before Netron pane. Local function definitions
(<domain: "..."> name (...) => (...) {...} blocks after
the graph) are parsed too, and the wrapped model gains an opset import
for each function's domain so it validates. With convert after
parsing on, it is also run straight through the currently selected
convert mode below (Simplify / Optimize / Inline functions, or a single
debug pass).
onnxmodelzoo org; any owner/repo
or direct .onnx URL works too. Picking a model (or
entering a repo id / URL) shows its download size first, so you
can see how big it is before fetching. When a repo holds more than
one .onnx, the largest is auto-detected; use the
file selector to convert a different one.
?model=onnxmodelzoo/resnet18d_Opset18 or
?model=https://…/foo.onnx&optimizer=optimize&cf=0.
It loads and converts automatically (add &autoload=0
to only prefill). Keys: model
(hf/url), graph (an ONNX text
graph to parse), optimizer (a.k.a. mode/processor; the
convert mode —
simplify/optimize/optimize_fixed/inline/infer_shapes/data_propagation/fold_constant),
constant_fold/cf,
shape_inference/si,
inline_functions/inline,
tensor_size_threshold/tst,
target_opset/opset,
autorun/autoinfer (auto-run inference
after each conversion),
backend (prefills the backend-test URL). Setting an
input updates this URL so it stays shareable (uploads excepted).
@huggingface/hub, reconstructing the
file from content-addressed chunks and caching them in
IndexedDB so repeated / overlapping loads reuse them. On by
default; falls back to a direct download automatically if the
Xet path isn't available (e.g. a non-Xet repo or a CORS block).
XetBlob)
fetches a file serially, so parallel shards reads
it in that many concurrent byte-range slices to saturate your
link — this is what makes Xet fast enough to be the default
(~10 or fewer is usually best; 1 disables
sharding). Xet also gives chunk dedup / cache reuse across
repeated or overlapping loads.
model.onnx and the test data
(test_data_set_N/ of input_*.pb /
output_*.pb) from GitHub, runs the model through
onnxruntime-web with the test inputs, and checks each output
against the expected tensor within tolerance. Pick a preset above or
paste a GitHub tree / raw.githubusercontent.com
URL; listing uses GitHub's public (rate-limited) API. With
convert the model on, the fetched model is also run through the
selected convert mode below (and shown in the Netron panes).
Renders the model graph with a self-hosted Netron: the original model on the left and the simplified/optimized result on the right, so you can compare them side by side. Nothing is uploaded — the model bytes are posted straight into the embedded Netron in your browser, so there is no model-size limit. Use export SVG to save the rendered graph as an SVG image.
Netron is driven here purely as an embeddable model-preview component
over a postMessage protocol; that idea and protocol are
being discussed upstream in
lutzroeder/netron#1591.
Lists the model's symbolic axis names (ONNX
dim_params) on its graph inputs and outputs —
before and after simplify/optimize — so you can see how
the conversion changed the dynamic axes: a batch /
sequence axis kept symbolic, or a symbolic dimension
folded to a fixed size. Read straight from the model bytes in your
browser (nothing is uploaded); symbolic axes are shown
highlighted.
Try it:
load
Xenova/all-MiniLM-L6-v2
(a ~21 MB quantized MiniLM sentence-transformer) — its inputs
and output carry the named dynamic axes batch_size and
sequence_length, so they show up here on both the
before and after sides. Most image models (e.g. the
onnxmodelzoo ResNets in the dropdown) are fully static
and list no dim_params.
.log file. Report an issue opens a pre-filled
GitHub issue
with the selected options, browser info, and the tail of the
console output. Please also attach your model (and the downloaded
log) so the problem can be reproduced.
Profiling is on by default (“profile simplification” above): convert a model with Simplify and the fixed-point transforms (shape inference, onnx-optimizer, constant folding) — with ONNX Runtime's own per-operator constant-folding spans merged in — render below as a flame graph. Download the JSON, or click Embed in Perfetto to open the full Perfetto timeline inline on this page.
Runs a model for a few iterations to check it executes, using dummy inputs generated from the model's input shapes. The model picker chooses what to run: compare (before vs after conversion) — the default — runs both the original upload and the converted result on the same deterministic input and reports how far their outputs diverge (max |Δ|) plus the speed difference, so you can confirm the simplify/optimize step preserved the model's numerics and see how much faster it got. You can also run just the converted result or the original upload on their own. The batch control sizes the model's dynamic batch (first) axis; it has no effect on inputs whose first dimension is fixed. The warmup control runs that many untimed passes before the timed iterations, so one-time costs (kernel/program compilation, buffer allocation) don't add noise to the reported latency; set it to 0 to time every run. WebGPU falls back to WebAssembly when unavailable. Tick auto-run after each conversion to run this panel automatically whenever a conversion finishes (with the options selected here), instead of clicking Run inference each time.
The execution-provider picker also offers
WebNN
(GPU / NPU / CPU), which runs the model through the browser's own
ML stack. WebNN is experimental and ships behind a flag
(Chrome/Edge: chrome://flags/#web-machine-learning-neural-network),
with the broadest support on Windows — the WebNN status line
below the controls reports whether it is usable in your browser, and
any WebNN run falls back to WebAssembly when the chosen device or an
operator is unsupported.
If the model carries onnxsim's MAC/FLOP metrics in its
metadata_props (onnxsim
PR #527,
e.g. annotated via onnxsim.model_info.annotate_metadata),
they are shown below with the achieved throughput (GFLOP/s = model
FLOPs ÷ average latency). With annotate model info on (the
default), the converter bakes these metrics into both the
converted result and the original upload, so you can run each
and compare their MACs alongside the measured inference speed.
With profiling on (default), the run captures an onnxruntime-web
trace: on WebGPU, one span per GPU kernel invocation; on WASM (or as
a fallback), one span per session.run iteration. It
renders below in the same viewer, with an Embed in Perfetto
button to open the full timeline inline.