Rust CLI for inspecting ML model artifacts without loading the framework
Project description
mod-trace
Inspect ML model artifacts without loading the framework.
mod-trace is a small Rust CLI for answering a practical question:
What is inside this model file?
It can inspect real artifacts such as CatBoost .cbm files, LightGBM .txt/.lgb text models, ONNX .onnx graphs, and PyTorch .pt/.pth checkpoints, then report structure, size, parameters, operator mix, rough inference cost, and changes between versions. All formats are read natively — no Python, framework, or runtime needed (CatBoost --deep is the one optional exception). The PyTorch reader is static: it sizes/names tensors and fingerprints weights without decoding exact shapes.
The most useful command is explain-diff, which says in plain English what changed between two model versions:
mod-trace explain-diff old_model.onnx new_model.onnx
(A secondary "tensor lab" for handcrafted JSON plans lives in docs/tensor-lab.md.)
Install
mod-trace is a single self-contained binary (written in Rust, published to PyPI as a wheel). The core commands need no Python and no ML framework at runtime.
pipx install mod-trace # recommended: isolated, puts `mod-trace` on your PATH
# or
pip install mod-trace
mod-trace doctor # shows which formats and helpers are available
- Prebuilt wheels for Apple Silicon macOS, Linux x86_64, and Windows x64 —
pipjust downloads the binary, no build step. - Intel macOS has no prebuilt wheel yet, so
pip installthere builds from source (needs a Rust toolchain). - Optional: CatBoost
--deep(decoded tree/leaf diffs) shells out to Pythoncatboost; pointMODELLENS_PYTHONat a Python that has it if needed. Everything else — including all of LightGBM, ONNX, and PyTorch — needs nothing extra.
Core Commands
mod-trace doctor # what formats/helpers are available
mod-trace inspect model.cbm # one model (also .lgb, .onnx, .pt)
mod-trace inspect --json model.onnx # machine-readable
mod-trace inspect --deep model.cbm # CatBoost: decoded splits (needs python catboost)
mod-trace diff old.cbm new.cbm # compare two versions
mod-trace explain-diff old.onnx new.onnx # plain-English what changed
mod-trace check --max-size-growth 20% --fail-on-feature-change old.lgb new.lgb # CI gate (exit != 0 = fail)
mod-trace convert model.pkl # un-pickle a model -> native (needs python)
Works on CatBoost .cbm, LightGBM .txt/.lgb, ONNX .onnx, and PyTorch .pt/.pth/.bin.
Why This Exists
Data and ML engineers often inherit model artifacts:
fraud_model.cbmranking_model.onnxmodel_v17.cbmcandidate_model.onnx
Before running them, it is useful to know:
- what type of model it is
- how large it is
- how many trees, parameters, nodes, or operators it contains
- what the rough per-row or per-forward-pass cost looks like
- what changed between two versions
mod-trace is not a model runtime. It is an artifact inspector.
Doctor
mod-trace doctor lists which inspectors and optional helpers are available (each built-in format, the Python/catboost helper for --deep/convert, and which commands are usable). Add --json for CI/setup scripts to check availability programmatically.
JSON Output
Use JSON when mod-trace is part of CI, release checks, or model registry automation:
mod-trace inspect --json path/to/model.cbm
mod-trace inspect --json path/to/model.onnx
mod-trace diff --json path/to/old_model.cbm path/to/new_model.cbm
mod-trace diff --json path/to/old_model.onnx path/to/new_model.onnx
The JSON diff is designed for checks such as:
- fail if file size, parameter memory, or estimated ops grows too much
- fail if CatBoost feature names, training config, or learned-state fingerprint changes unexpectedly
- fail if ONNX operator counts or initializer tensors change
--deep CatBoost reports are text-only for now because they are diagnostic dumps from CatBoost's native Python parser.
CI Checks
Use check when a model artifact should fail promotion if it changes too much:
mod-trace check path/to/old_model.cbm path/to/new_model.cbm \
--max-size-growth 20% \
--fail-on-feature-change \
--fail-on-training-config-change
mod-trace check path/to/old_model.onnx path/to/new_model.onnx \
--max-size-growth 20% \
--max-ops-growth 25% \
--max-parameter-growth 30% \
--fail-on-new-op
Check rules:
| Rule | Applies to | Fails when |
|---|---|---|
--max-size-growth <pct> |
all | file size grows more than <pct> |
--max-parameter-growth <pct> |
ONNX | parameter count grows more than <pct> |
--max-ops-growth <pct> |
ONNX | estimated op count grows more than <pct> |
--fail-on-new-op |
ONNX | a new operator type appears |
--fail-on-feature-change |
CatBoost, LightGBM | feature names change |
--fail-on-training-config-change |
CatBoost, LightGBM | objective/learning rate/etc. change |
check prints a short PASS/FAIL report and exits nonzero when a rule fails. Any number of rules can be combined; any one failing fails the whole check.
Explain Diff
explain-diff is the plain-English version of diff — it reports what actually changed between two model versions, not just raw numbers:
mod-trace explain-diff old_model.onnx new_model.onnx
Model Change Explanation
------------------------
Type: ONNX
Old: old_model.onnx
New: new_model.onnx
Architecture:
Attention layers: 12 -> 24
Hidden size: 768 -> 1024
Parameters: 110.0M -> 220.0M (+100%)
Nodes: 420 -> 820 (+95%)
Estimated inference cost (static op proxy): +94%
New operators introduced:
LayerNormalization
Summary:
Grew from ~12 to ~24 attention layers; parameters +100%, estimated cost +94%.
Works for ONNX, CatBoost, and LightGBM (tree models report trees / leaves / learned-state instead of attention layers).
Supported formats
| Format | Extensions | Commands | Native (no framework)? |
|---|---|---|---|
| CatBoost | .cbm |
inspect, diff, check, explain | yes (--deep uses Python catboost) |
| LightGBM | .txt, .lgb |
inspect, diff, check, explain-diff | yes |
| ONNX | .onnx |
inspect, diff, check, explain, explain-diff | yes |
| PyTorch | .pt, .pth, .bin, .ckpt |
inspect, diff, explain-diff, check | yes (no torch) |
Per-format commands and full example output live next to the sample models:
- CatBoost → examples/catboost/README.md (incl.
--deep) - LightGBM → examples/lightgbm/README.md
- ONNX → examples/onnx/README.md
- PyTorch → examples/pytorch/README.md
Notes per format
- CatBoost
--deepis optional and needs Pythoncatboost; it decodes exact splits, leaf values, feature typing, and float borders. Plaininspect/diffneed nothing. - PyTorch is read statically from the
torch.savezip (param counts, names, dtype, sampled weight fingerprint; ZIP64-safe). Shapes are not decoded. Legacy-pickle.pt/.bingive names-only;.safetensorsis not supported (export to ONNX instead). - PyTorch → ONNX: for graph-level detail or a
.safetensors/legacy file,torch.onnx.export(model, dummy, "model.onnx", opset_version=18)thenmod-trace inspect model.onnx. See examples/pytorch/README.md.
Convert (pickled / MLflow models)
mod-trace reads native model formats, but models are often stored as a pickle (model.pkl, e.g. logged by MLflow) — which is Python-only and can't be read without the framework. convert does the one-time translation:
mod-trace convert model.pkl # -> model.txt (LightGBM) or model.cbm (CatBoost)
mod-trace convert ./mlflow-model-dir --out /tmp/v3.txt
mod-trace inspect model.txt # now readable natively
This is the one command that needs Python (it loads the pickle with lightgbm/catboost, then re-saves natively). Point MODELLENS_PYTHON at an interpreter that has the model's library. Supported: LightGBM → .txt, CatBoost → .cbm. After converting, everything else is framework-free.
Tensor Lab
A secondary lab for explaining transformer internals on small handcrafted JSON
plans (trace, compare, why, validate, quiz, demo). It is not the
primary product surface. See docs/tensor-lab.md.
What It Does Not Do
mod-trace does not:
- run inference
- train models
- load PyTorch directly
- require CatBoost, PyTorch, or ONNX Runtime for inspection
- provide GPU kernels
- replace framework-native debugging tools
Privacy
Do not commit real model weights or private business artifacts. The repository ignores:
models/examples/*.onnxexamples/*.cbm
Use examples/make_sample_catboost.py when you need a shareable .cbm demo.
Architecture
mod-trace has small, native inspection paths per format:
- CatBoost
.cbmmetadata scanner - LightGBM
.txt/.lgbtext parser - ONNX protobuf graph scanner
- PyTorch
.pt/.pthzip/pickle scanner - JSON tensor-plan analyzer
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mod_trace-0.5.3.tar.gz.
File metadata
- Download URL: mod_trace-0.5.3.tar.gz
- Upload date:
- Size: 170.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
074884dcc2a9f1cfc04bd1c6bcebe0508216fc71ac655dafbbc93133efefbbe6
|
|
| MD5 |
3a1ed566d4d0419a08433a168f16c759
|
|
| BLAKE2b-256 |
66199b13a1a24e9de3451c23615703deb21880d59a71e35ff08c316cec77a30f
|
Provenance
The following attestation bundles were made for mod_trace-0.5.3.tar.gz:
Publisher:
release.yml on kraftaa/mod-trace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mod_trace-0.5.3.tar.gz -
Subject digest:
074884dcc2a9f1cfc04bd1c6bcebe0508216fc71ac655dafbbc93133efefbbe6 - Sigstore transparency entry: 1759178731
- Sigstore integration time:
-
Permalink:
kraftaa/mod-trace@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Branch / Tag:
refs/tags/v0.5.3 - Owner: https://github.com/kraftaa
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mod_trace-0.5.3-py3-none-win_amd64.whl.
File metadata
- Download URL: mod_trace-0.5.3-py3-none-win_amd64.whl
- Upload date:
- Size: 585.5 kB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25e725cf8df752caf5e7d1104bdde867d523164268ea4c242c2fed3ba4153811
|
|
| MD5 |
9ed1ae59765a5590b7f5861bc355a245
|
|
| BLAKE2b-256 |
03b33752b96d8c87b7fe00e71dbb3275760a1b6df62d9a7f3a5e54208c7d896c
|
Provenance
The following attestation bundles were made for mod_trace-0.5.3-py3-none-win_amd64.whl:
Publisher:
release.yml on kraftaa/mod-trace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mod_trace-0.5.3-py3-none-win_amd64.whl -
Subject digest:
25e725cf8df752caf5e7d1104bdde867d523164268ea4c242c2fed3ba4153811 - Sigstore transparency entry: 1759179069
- Sigstore integration time:
-
Permalink:
kraftaa/mod-trace@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Branch / Tag:
refs/tags/v0.5.3 - Owner: https://github.com/kraftaa
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mod_trace-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: mod_trace-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 646.0 kB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f36ddf66d9296035ecefbe1ab4b55554a8e2905b7392132e6fd8e0fa8965e03
|
|
| MD5 |
b5fa1b533fddfe4178138b09411e6c65
|
|
| BLAKE2b-256 |
679e7163d5c89e9de6897a61702b4b4ee33bfef935cc09dfa1337ddf6b7983cc
|
Provenance
The following attestation bundles were made for mod_trace-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on kraftaa/mod-trace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mod_trace-0.5.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
0f36ddf66d9296035ecefbe1ab4b55554a8e2905b7392132e6fd8e0fa8965e03 - Sigstore transparency entry: 1759178970
- Sigstore integration time:
-
Permalink:
kraftaa/mod-trace@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Branch / Tag:
refs/tags/v0.5.3 - Owner: https://github.com/kraftaa
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Trigger Event:
push
-
Statement type:
File details
Details for the file mod_trace-0.5.3-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: mod_trace-0.5.3-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 582.0 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6660254b1157f84f5b04acdd122e3262bedb484ecf8ccd1e3b8b4a6dcf0d44e2
|
|
| MD5 |
b34d191ac568e93bfbe8f864acb0f156
|
|
| BLAKE2b-256 |
21e22171ba5003c37807ef9849133eb7680a1827db9a65fc309e9b7bfbb12011
|
Provenance
The following attestation bundles were made for mod_trace-0.5.3-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on kraftaa/mod-trace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mod_trace-0.5.3-py3-none-macosx_11_0_arm64.whl -
Subject digest:
6660254b1157f84f5b04acdd122e3262bedb484ecf8ccd1e3b8b4a6dcf0d44e2 - Sigstore transparency entry: 1759178858
- Sigstore integration time:
-
Permalink:
kraftaa/mod-trace@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Branch / Tag:
refs/tags/v0.5.3 - Owner: https://github.com/kraftaa
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@073ad3ef290a0abe4470fec9002bfb69b6f5b130 -
Trigger Event:
push
-
Statement type: