Skip to main content

TorchInstruments

Record per-layer activation and output-gradient statistics without changing your training loop.

from datetime import timedelta
from torchinstruments import inject_observer, remove_observer

inject_observer(model, interval=timedelta(minutes=1), output_dir="stats")
try:
    train(model)
finally:
    remove_observer(model)

The first forward is sampled immediately, then once per interval. The default interval is one minute. Evaluation works too, including torch.no_grad() and torch.inference_mode().

Calling a child directly, such as model.encoder(x) inside a Lightning step, also works. When the observed root is bypassed, selected layers sample independently at the given interval. Each selected module's forward() is intercepted once, so both module(x) and module.forward(x) are captured. Removal restores the original methods.

Output

Everything is created automatically:

Artifact Purpose
history.parquet Full sampled scalar history
result.json Indented history summary for each layer
index.md Reading guide for an LLM, including schema and history queries
tensorboard/ Histogram history for selected layers

history.parquet, result.json, index.md, and TensorBoard update after each sampled forward or backward. They are readable without calling remove_observer(). Removal detaches hooks, closes resources, and cleans up intermediate history.parts/ chunks. Interrupted runs retain the last published files and completed chunks. Each refresh rewrites the Parquet snapshot and aggregates collected history, so its cost grows with run length.

Statistics

Each sampled tensor reports mean, population standard deviation, min, max, p25, p50, p75, zero fraction, and nonfinite fraction. Gradients are recorded separately. Train/eval context is captured automatically, and missing measurements carry reasons.

JSON aggregates each metric's history, including previous/recent window means. These summarize sampled statistics, not pooled tensor entries. Exact observations stay in Parquet. There are no scores or diagnoses. Give index.md to an LLM as the starting point.

Layer selection

All modules, including composite blocks and the root, contribute scalar history when called. The root has the empty layer name "". Histograms cover the first eight selected modules. To focus the dashboard, use histogram_selector:

inject_observer(
    model,
    histogram_selector=lambda name, module: name.startswith("encoder.blocks.7."),
)

Use selector similarly to restrict all collection. Histogram focus must match an observed module. Use selector=leaf_modules() (imported from torchinstruments) for leaf-only coverage. Other existing extension arguments remain available; ordinary usage needs none of them.

Examples and limits

  • Examples: ordinary training, Lightning, and controlled model problems.
  • LLM guide: how to interpret measurements and query history.
  • Benchmarks: interval-based usage and separate stress tests.
  • Changelog: version changes and schema migration.

CPU, native MPS, in-place activations, and non-reentrant checkpointing are tested. Reentrant checkpoint internals lack gradient coverage. Only the first backward is recorded, with the caller's loss scaling. CUDA performance and torch.compile compatibility are unverified. The interval amortizes collection cost; sampled forwards still scan their tensors.

MIT licensed. Author: Vadym Stupakov vadim.stupakov@gmail.com.

Release files for torchinstruments 0.10.0

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

Built distribution (wheel)

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

Release files / torchinstruments-0.10.0-py3-none-any.whl

Download URL torchinstruments-0.10.0-py3-none-any.whl
Size 50.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a8bdb0d18c8e9af5549193ebfb60831e481bbe7d69b547511fecc9598f082a38
BLAKE2b-256 checksum
How to use checksums
0184590d79c89ec7f993f15cf1ec99df9b1532924e3966253773aaa893bfa8aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.10.1

1 release file

This release

0.10.0 This release

1 release file

0.9.2

1 release file

0.9.1

1 release file

0.9.0

1 release file

0.8.0

1 release file

0.7.0

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.0

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.0

1 release file

0.1.1

1 release file

0.1.0

1 release file

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