A forensic trace console for PyTorch models.
Project description
A forensic trace console for PyTorch models.
Features
- Zero-code tracing -- wraps any
nn.Modulevia context manager, no hook scattering - Per-layer capture -- name, type, shape, dtype, device, params, latency
- Activation statistics -- mean, std, min, max, NaN count, Inf count per tensor
- Backward gradient tracing -- grad norm, mean, NaN detection, zero-gradient detection
- Anomaly detection -- 8 built-in checks: NaN, Inf, dead layers, exploding variance, variance spikes, zero gradients, NaN gradients, empty outputs
- JSON export -- structured, flat format designed for dashboards and CI pipelines
- Rich CLI inspector -- nested layer tree, anomaly warnings, model summary in the terminal
- Accurate latency -- pre-hook to post-hook timing, not just stat-computation overhead
Install
pip install tracetorch-ml
Requires Python 3.11+. Runtime dependencies: PyTorch 2.0+, Rich 13.0+.
Quick start
import torch
import torch.nn as nn
from tracetorch import TraceSession
model = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10),
)
session = TraceSession(model)
with session:
x = torch.randn(32, 784)
y = model(x)
print(session.summary())
session.export("trace.json")
Inspect the saved trace:
tracetorch inspect trace.json
What gets captured
For each child module reached through model.named_modules():
- module name, full name, type, and nesting depth
- direct parameter count (
recurse=False) - input and output tensor shape, dtype, and device
- floating tensor statistics: mean, std, min, max, NaN count, Inf count
- forward latency measured from pre-hook to post-hook
- backward gradient norm, mean, NaN flag, zero-gradient flag
Root model is not traced; only its children are.
Backward tracing
Run backward inside the session to capture gradient data:
session = TraceSession(model)
with session:
x = torch.randn(4, 10, requires_grad=True)
out = model(x)
loss = out.sum()
loss.backward()
for layer in session.record.layers:
print(layer.full_name, layer.grad_norm, layer.has_zero_grad)
Gradient fields stay None / False if no backward pass runs.
Anomaly checks
| Type | Trigger |
|---|---|
nan_activation |
Output tensor contains NaN |
inf_activation |
Output tensor contains Inf |
dead_layer |
Output mean and std both near zero |
exploding_variance |
Std > 100, or >10x spike from previous layer |
high_variance |
Std between 10 and 100 |
empty_output |
No tensor output captured |
zero_gradient |
Backward gradient is all zeros |
nan_gradient |
Backward gradient contains NaN |
JSON format
{
"metadata": {
"model_name": "Sequential",
"pytorch_version": "2.x",
"python_version": "3.11.x",
"cuda_available": false,
"active_device": "cpu",
"total_time_ms": 1.23
},
"layers": [
{
"name": "0",
"type": "Linear",
"full_name": "0",
"depth": 1,
"params": 200960,
"inputs": [
{
"shape": [32, 784],
"dtype": "torch.float32",
"device": "cpu",
"mean": 0.0,
"std": 1.0,
"min": -3.0,
"max": 3.0,
"nan_count": 0,
"inf_count": 0
}
],
"outputs": [
{
"shape": [32, 256],
"dtype": "torch.float32",
"device": "cpu",
"mean": 0.01,
"std": 0.58,
"min": -2.1,
"max": 2.4,
"nan_count": 0,
"inf_count": 0
}
],
"latency_ms": 0.25,
"grad_norm": null,
"grad_mean": null,
"grad_has_nan": false,
"has_zero_grad": false
}
],
"warnings": []
}
Load a saved trace in Python:
from tracetorch.storage import load_json
record = load_json("trace.json")
print(record.metadata)
print(record.layers[0].outputs)
API Reference
TraceSession
session = TraceSession(model, capture_stats=True, model_name=None)
Context manager for one traced execution window.
| Property / Method | Description |
|---|---|
record |
Collected TraceRecord |
anomalies |
list[Anomaly] populated after exit |
export(path) |
Write JSON, return Path |
summary() |
Compact text summary |
Data structures
from tracetorch import TraceRecord, LayerTrace, TensorStats, Anomaly
All dataclasses serialize via .to_dict(). JSON format is flat for dashboard consumption.
CLI
tracetorch inspect trace.json
Prints model summary, nested layer tree with tensor shapes/params/latency/std, and anomaly warnings.
Architecture
PyTorch Model
│
PyTorch Hooks
(forward_pre, forward, backward)
│
Trace Collector
capture shapes, stats, grads
│
Anomaly Detector
8 built-in checks
│
Storage Layer
JSON export / import
│
CLI Inspector
rich terminal output
Development
git clone https://github.com/phraakture/tracetorch.git
cd tracetorch
pip install -e ".[dev]"
pytest # tests
ruff check tracetorch tests # lint
mypy tracetorch # types
Run the example:
python example.py
tracetorch inspect trace.json
License
MIT
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 Distribution
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 tracetorch_ml-0.1.1.tar.gz.
File metadata
- Download URL: tracetorch_ml-0.1.1.tar.gz
- Upload date:
- Size: 184.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c1894c3dc51aff7a90db7a482ee0229b8348e55ad046b88a32f05324f7b7669
|
|
| MD5 |
7a1a64cde507b8b8806793354af97399
|
|
| BLAKE2b-256 |
0d244cf01ffc8802d1edb58c9e82f80bb33ef02df7ae172932404535c1ae4972
|
File details
Details for the file tracetorch_ml-0.1.1-py3-none-any.whl.
File metadata
- Download URL: tracetorch_ml-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cde31f0c34ed32074ed51636b110436ffeb0f9ac9a4941a8db74ba6b3c6f824
|
|
| MD5 |
b90b384d61283aca7ed3bc86ced2f4c0
|
|
| BLAKE2b-256 |
dfcbdad15379d9b1907265a6d038d070494a6e20ab89e5b862ef4e7359297b52
|