Skip to main content

Diff your ONNXs

A powerful yet playful tool to compare and analyze ONNX models – whether you're hunting for hidden changes or debugging mysterious outputs. Think of it as a microscope for your pair of models, complete with structure analysis and runtime sanity checks.

🚀 Installation

pip install diffonnx        # CPU version
pip install "diffonnx[gpu]" # GPU version

Or if you’re the DIY type:

git clone https://github.com/yuxuan-z19/diffonnx.git
cd diffonnx && pip install -e .

🔍 X-ray vision for ONNX models

DiffONNX acts like an X-ray for your ONNX models — it pinpoints runtime hotspots with high precision, helping you quickly identify performance bottlenecks across different backends.

🧠 Static Analysis

  • Full ONNX graph comparison (nodes, edges, initializers, etc.)
  • Graph kernel similarity scores based on GraKel
  • Operator statistics and diff
  • Comparison after model simplification
❓ Why These Kernels?

We chose the following four kernels because they offer strong structural sensitivity, good scalability, and semantic insight, all critical for comparing ONNX models in optimization, verification, and architecture evolution.

Kernel Strengths Focus
Weisfeiler-Lehman Fast, captures subtle structural changes Global structure
Graphlet Highlights local connection patterns Local structure
Subgraph Matching Detects reused or rewritten modules Block-level changes
Propagation Combines topology with operator semantics Semantic differences

Together, they provide a balanced and interpretable toolkit for robust ONNX model analysis.

⚡ Runtime Analysis

  • Cosine / angular similarity of tensor outputs
  • Maximum absolute error inspection
  • Precision breakdowns
  • Operator performance microscopy (along with torch.fx IR)
  • Supports multiple execution providers (CPU, CUDA, anything ONNXRuntime speaks)

⚠️ Note on Using onnxsim.simplify

This tool is designed to compare ONNX models at both the structural and runtime levels. To ensure the analysis remains accurate and traceable, we strongly recommend against using onnxsim.simplify before comparison.

While onnxsim.simplify can be helpful for model deployment and optimization, it performs structural transformations leading to potential renaming or removing intermediate nodes. These changes may:

  • Break one-to-one correspondence between nodes in two models
  • Obscure the origin of certain operations
  • Distort static graph topology
  • Alter runtime profiling results

🛠 Usage

CLI: For Fast Hands-On Nerding

# Basic comparison
diffonnx ref_model.onnx usr_model.onnx

# Verbose mode – unleash the diff dragon
diffonnx ref_model.onnx usr_model.onnx -v

demo

Python API: For People Who Think in Code

import onnx
from diffonnx import MainDiff, StaticDiff, RuntimeDiff

ref = onnx.load("ref_model.onnx")
usr = onnx.load("usr_model.onnx")

# Full analysis, max drama
diff = MainDiff(ref, usr, verbose=True)
static_result, runtime_result = diff.summary(output=True)

# Just structure? Sure
static_only = StaticDiff(ref, usr)
static_result = static_only.summary(output=True)

# Runtime only, CUDA powered
runtime_only = RuntimeDiff(
    ref, usr, providers=["CUDAExecutionProvider"]
)
runtime_result = runtime_only.summary(output=True)

Quick Graph Kernel Scores

For users who want a simple, unified interface to compute multiple graph kernel similarities at once, we provide the handy GraphDiff class. It bundles the kernels and returns their scores in one call:

from grakel.graph import Graph
from diffonnx.static import GraphDiff

# graph_a = Graph()
# graph_b = Graph()

graph_diff = GraphDiff(verbose=True)
graph_diff.add_kernels(
    [
        ShortestPath(normalize=True, with_labels=False),
        RandomWalkLabeled(normalize=True),
    ]
)
graph_diff.remove_kernels([WeisfeilerLehman()])

scores = graph_diff.score(graph_a, graph_b)
print(scores.keys())
# Example output:
# {'GraphletSampling', 'SubgraphMatching', 'Propagation', 'ShortestPath', 'RandomWalkLabeled'}

This way, you can easily evaluate graph similarity across multiple kernels without manually instantiating each one.

📊 Output Breakdown

@dataclass
class StaticResult:
    # Is the structure identical?
    exact_match: bool
    
    # Similarity score (0 to 1, higher = happier)
    score: Score
    
    # Detailed matching info
    graph_matches: Dict[str, Matches] 

    # Model-level attribute differences
    root_matches: Dict[str, Matches]
@dataclass
class RuntimeResult:
    # Are the outputs exactly the same?
    exact_match: bool

    # Inputs that are invalid (shape/dtype mismatch).
    invalid: Dict[str, Accuracy]

    # Outputs that are exactly the same.
    equal: Dict[str, Accuracy]

    # Outputs that are not exactly the same but have the same shape and dtype.
    nonequal: Dict[str, Accuracy]

    # Outputs that have shape/dtype mismatch.
    mismatched: Dict[str, Accuracy]

Check diffonnx.structs for more about Matches and Accuracy.

👷 Development

If you're contributing or running tests, we recommend using uv — a faster, modern Python package manager.

git clone https://github.com/yuxuan-z19/diffonnx.git
cd diffonnx

# Install dev dependecies (CPU)
uv sync --locked --all-groups --extra torch-cpu
# Install dev dependencies (CUDA 12.4)
uv sync --locked --all-groups --extra torch-cu124

# Run tests
uv run pytest -n auto

⚠️ Known Issues

This section tracks known issues and their resolution status. Some are external, others have been patched (marked) in this repo.

GraKel related

We recommend using the built-from-source version of GraKeL rather than the latest PyPI release.

  • Import failure due to NumPy issue (GraKel#115)

    • Fixes have been merged, pending official release.

      pip install "grakel @ git+https://github.com/ysig/GraKeL"
      
  • Output shape issue in SubgraphMatching (GraKel#124)

onnxruntime related

  • CUDAExecutionProvider not available on some NVIDIA setups (onnxruntime#7748)

    • Uninstall both onnxruntime & "onnxruntime[cuda,cudnn]", and re-install in two steps:

      pip uninstall onnxruntime "onnxruntime[cuda,cudnn]"
      pip install onnxruntime
      pip install "onnxruntime[cuda,cudnn]"
      
  • Missing libcudnn.so.9 in LD_LIBRARY_PATH onnxruntime#25609

    • Fixed via utils::_patch_cudnn_ld_lib_path (applied in RuntimeDiff._prepare_providers)

      if "CUDAExecutionProvider" in providers:
          _patch_cudnn_ld_lib_path()
      self.providers = providers + default_provider
      

Metadata

Release files for diffonnx 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for diffonnx 1.0.2
File Size Uploaded
diffonnx-1.0.2.tar.gz 15.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for diffonnx 1.0.2
File Interpreter ABI Platform
diffonnx-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 31.9 kB

Release files / diffonnx-1.0.2.tar.gz

Download URL diffonnx-1.0.2.tar.gz
Size 15.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4ea8ac4b6fbbce3493cb118fd41ee01878fc0ec5af74f1f7714f36422981b385
BLAKE2b-256 checksum
How to use checksums
d88e3a0ef1f8fb42f1822a36ed1bb71d3b053cf7fa20f3f657b2ab981f25abeb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.4

Release files / diffonnx-1.0.2-py3-none-any.whl

Download URL diffonnx-1.0.2-py3-none-any.whl
Size 16.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c1c90a5509ed2bd4542dba5f123ac3dbadeaa971407a500783a73e9428f0d47
BLAKE2b-256 checksum
How to use checksums
22dd37fe035d435dbe8f157426b5034c81febac1ba4628ab99661aef79e45d0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.8.4

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page