Skip to main content

ModelMRI

Chrome DevTools for AI models and agents. Load any local model — LLM, VLM, or robot policy — and see inside it while it runs: what it attended to, which concepts fired, what happens when you turn one off, and exactly where your agent went wrong.

Local-first. No cloud, no account, no telemetry. MIT.

▶ Try the live demo — no install, no GPU, real recorded output. 📖 Docs

Hovering tokens; attention arcs follow the cursor across the strip

Hover any token — arcs show what it attended to. Every layer, every head.

pip install modelmri
modelmri serve          # open http://localhost:5900

The model picker listing models already on disk

It finds the models you already have — HF cache, plain folders, GGUF — before asking you to type anything.


What you can actually do with it

1. See what a token attended to

Type a prompt, watch it stream, then hover any token — arcs show which earlier tokens it looked at, scaled by attention weight, for any layer and head.

On GPT-2, the generated token " Paris" attends back to " capital" and " France". The information was always there. Nobody was looking.

2. Find a concept and turn it off

Load a sparse autoencoder and ModelMRI shows the human-interpretable features firing on every token. Click one, drag the slider, and run a deterministic A/B:

prompt   The Eiffel Tower is located in the city of
baseline  Paris, France.
feature #974 @ -40   San Diego, and is located in the San Diego State University

Same prompt, greedy decoding, no prompt tricks. We reached into layer 8 and turned the concept down. Clearing the steer restores the baseline byte-for-byte.

3. Find the step where your agent died

Two lines of modelmri.record around any agent run gives you a timeline: LLM calls, tool calls, subagents, each as a block. The failure glows. Click it for the exact input, output, tokens, and error.

from modelmri.record import trace, step

with trace("fix-failing-tests"):
    step("llm_call", name="plan", input=prompt, output=answer, tokens_in=912)
    with step("subagent", name="auth-fixer"):
        step("tool_call", name="pytest", output="17 passed")

Or instrument automatically: modelmri.record.instrument_anthropic().

4. Look inside a robot policy

This is the part nobody else ships. ModelMRI loads the vision tower of the real SmolVLA checkpoint and runs actual robot-camera frames through it, painting each image patch's attention back onto the frame. Scrub an episode, run the policy, drag the layer slider.

Measured on PushT frames — share of attention mass in the top 5% of patches:

vision layer concentration
0 27%
6 56%
11 60%

Early layers look everywhere; deep layers lock on. No robot hardware required — it reads public LeRobot datasets straight from disk.

5. Debug a model you trained yourself

Everything above is transformer-shaped. This isn't. Point ModelMRI at your own nn.Module — an MLP, a small CNN, whatever you're training — and get a layer-by-layer map of one real forward pass.

# my_net_adapter.py — the whole contract
def load():
    model = MyNet()
    model.load_state_dict(torch.load("checkpoints/best.pt", map_location="cpu"))
    return model
layer type output activation
fc1 Linear 8×64 −31.20 ± 24.21
act1 ReLU 8×64 0.10 ± 0.26 80% dead
fc2 Linear 8×32 −1.02 ± 4.74
act2 Tanh 8×32 −0.12 ± 0.90 55% saturated
head Linear 8×3 −0.13 ± 0.44

Dead units, saturated activations, and the first layer where a nan appears — statistics exclude non-finite values on purpose, so one bad number can't turn every row below it into nan and hide where it started.

A state_dict alone is refused, with the reason: it's weights without an architecture, and guessing one would produce a map that looks authoritative and describes a network you never trained.


Install

pip install modelmri              # core: playground, attention, features, steering, agents
pip install "modelmri[vla-lite]"  # + robot datasets (av, pyarrow, pillow)
pip install modelmri-record       # just the agent recorder — stdlib only, 7 KiB
modelmri serve

From source:

git clone https://github.com/muhammadmahadazher/ModelMRI && cd ModelMRI
cd frontend && npm ci && npm run build && cd ..
uv sync && uv run modelmri serve

Models. Type any HuggingFace id, pick from what's already cached on your machine, or switch to Ollama to run any open model you've pulled. (Ollama gives you text only — internals need a HuggingFace model, and ModelMRI says so rather than pretending.)

Everything runs on CPU. A 0.5B model streams in a couple of seconds on a laptop.

API

The UI is a client of a plain HTTP API — script against it directly.

POST /api/model/load {hf_id, source}"hf" or "ollama"
WS /ws/generate stream tokens
GET /api/attention ?layer=&head= → tokens + attention matrix
POST /api/sae/load · GET /api/features/summary SAE features per token
POST /api/steer {feature_id, scale} — clamp a concept during generation
POST /api/traces/import · GET /api/traces/{id} agent traces
POST /api/vla/analyse · GET /api/vla/attention robot-policy attention
POST /api/custom/load · POST /api/custom/run inspect a model you trained yourself

Status

Playground · streaming · any local model · Ollama
Attention inspector
SAE feature browser + activation steering
Agent trace timeline + step inspector
Robot policy (VLA) attention over real episodes ✅ perception
Custom models — adapters, TorchScript, layer map
VLA action expert (needs lerobot, separate env) 🏗️
Hosted zero-install demo

Honest limits

  • Attention needs eager attention. SDPA and FlashAttention never materialize the weights, so ModelMRI loads models with attn_implementation="eager". Slower, but it's the only way to see anything.
  • SAE features need a matching SAE. Ships pointed at the public GPT-2 SAEs; other models need their own.
  • Custom models get a layer map, not attention. Attention and SAE features need a transformer; for an arbitrary nn.Module ModelMRI shows shapes, activation statistics and pathologies. Loading an adapter runs your Python — see SECURITY.md.
  • VLA mode is the perception half. SmolVLA's vision tower is real and loaded from the real checkpoint; the action expert needs lerobot, whose torch/numpy pins conflict with the core runtime, so it lives behind an opt-in extra rather than degrading everyone's install.

Contributing

Issues and pull requests are welcome. One rule runs the whole repository: don't ship a measurement you haven't verified. A visualization that looks plausible and is wrong is worse than none, because interpretability is exactly the domain where nobody has an independent way to notice.

Built in public

Notes, mistakes, and what broke: modelmri.substack.com

MIT © Muhammad Mahad Azher

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

modelmri-0.5.0.tar.gz (4.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

modelmri-0.5.0-py3-none-any.whl (181.8 kB view details)

Uploaded Python 3

File details

Details for the file modelmri-0.5.0.tar.gz.

File metadata

  • Download URL: modelmri-0.5.0.tar.gz
  • Upload date:
  • Size: 4.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for modelmri-0.5.0.tar.gz
Algorithm Hash digest
SHA256 15c91f5ab22a99ed996e8ab1dc133b5a6c27738dd644651309bb99506c100ee8
MD5 a356ed55b5f281c248b6ae1f42d1a769
BLAKE2b-256 d47eed7aec7d9430a1634adfe43bae4fa64c3e9a59661c53dcf5df93f3deb3de

See more details on using hashes here.

File details

Details for the file modelmri-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: modelmri-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 181.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for modelmri-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a1742b23c1004a20c199e74cd40514628f94d8c0ba152b17cda99f0304d179ac
MD5 804559b841a21cafdf538c7a9d09a281
BLAKE2b-256 92337631a20eb426481d1f12ff70693ed3ef62678d8ccce01d8bab5fd8385393

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page