Model transformations without brittle graph scripts.
Rune is a powerful graph rewrite system for ONNX, TFLite and torch.export models.
With simple, auditable rules, Rune finds every match site in the model, applies replacements, verifies the result against the original and provides evidence.
$ pip install byteinfer-rune
$ uv tool install byteinfer-rune
$ git clone https://github.com/ByteInfer-Labs/rune && cd rune && pip install -e .
The problem
How it works
Find → Check → Apply → Verify
You describe a pattern. Rune finds every place it appears in the graph.
Each match is simulated on a copy first. If it would break the graph, the gate refuses it.
Only the changes that passed get applied, all at once.
The rewritten model is run and its outputs compared with the original.
the ruleMul#m -> Add#a -> Relu#r + FusedMulAddRelu#f > m.input[0] -> f.input[0] ...
swipe to pan →
Case studies
Measured
Each number is a paired A/B measurement on the real model. Every rewrite passed an equivalence gate before it ran.
In the wild
Issues from the runtimes' own trackers. We re-checked each one on current releases: some were closed without a fix, and one fix no longer matches today's exports.
Verified on ORT 1.23 · transformers 5.13 · PyTorch 2.13
TFLite
An old TFLite converter pass replaced batched matmuls with per-head Split, FullyConnected, Pack stacks. Both reports were closed stale, and models built with that converter still ship: MediaPipe's BERT classifier has 48 of these stacks. One rule replaces each with BATCH_MATMUL.
48 sites · within 1e-3 · 1.54× on LiteRT
ONNX Runtime
ORT's attention fuser is patched one export layout at a time. The CLIP report was fixed in 2024; we re-ran it with transformers 5.13 and ORT 1.23 and the attention comes out unfused again — the export layout changed. MiniLM's eager export was never covered. One rule maps the layout to MultiHeadAttention directly.
6 of 6 layers fused · exact · 1.05× on CUDA
PyTorch
GQA models repeat K/V heads before sdpa, materialising copies that grow with the cache. PyTorch's fix is enable_gqa — we verified it bit-identical and 2× faster at a 2048-token decode shape. Exported models still carry the repeat chain, so one rule removes it and sets enable_gqa on the same call.
bit-identical · Llama 1.33× · Qwen 1.42× at 2048 tokens
Rune finds every matching instance and checks each candidate before committing the rewrite.
Workflow
Just run it. One command picks rules, applies them, verifies the output.
rune-cli run model.onnx --target ort-cpu --output model_optimized.onnx
Review first. Generate a plan, inspect it, then apply.
rune-cli plan model.onnx --target ort-cpu rune-cli apply model.onnx model.plan
Full control. optimize, validate, query, analyze, discover are individual commands for when you need them.
Every run leaves a receipt: which rules ran, tagged and versioned. rune-cli versions, reproduce, diff.
swipe to pan →
Automation
Rune ships with skills for inspecting models, writing rules, validating them and running rewrites.
The agent writes the transformation. Rune decides whether it is safe to apply.
Research
experimental
.rune rules automatically.rune-cli discover model.onnx --out rules/
swipe to pan →
Before you start
ONNX and torch.export are the most mature targets. TFLite has the same safety gates but narrower operator coverage.