gradsnitch
it tells on your training run
A linter/diagnoser for ML training runs. Hook your loop with one line and get plain-language verdicts on why it broke — not just charts.
Tracking (W&B / TensorBoard) shows you the loss curve. Snitch reads it and tells you what went wrong and what to try. Every finding cites concrete evidence and stays silent unless the signature is unambiguous — a wrong diagnosis is worse than none.
[GS001] [ERROR] Loss became NaN/Inf
evidence: train_loss non-finite first at step 7 (lr=0.55)
likely: LR too high, fp16/bf16 overflow, or a bad batch.
try: Lower LR, add grad clipping, check inputs, or use bf16.
⚠️ Early project, not production-hardened. Thresholds are tuned on the bundled real-run rigs; weird curves (RL/GAN/restarts) may still surprise it. Found a false positive? That is the most useful issue you can file.
Install
pip install gradsnitch # core (numpy + pandas)
pip install "gradsnitch[torch]" # + torch, for watch()/framework adapters
Use
Raw PyTorch loop — one line:
import gradsnitch
mon = gradsnitch.watch(model, optimizer, check_every=50) # prints errors live
for step in range(steps):
loss = loss_fn(model(x), y)
loss.backward()
mon.log(step, loss.item(), val_loss=val) # grabs grad_norm + lr for you
optimizer.step(); optimizer.zero_grad()
mon.report() # verdicts at the end
Framework callbacks (verified against real transformers / lightning / keras):
from gradsnitch import integrations
Trainer(..., callbacks=[integrations.hf()]) # HuggingFace
Trainer(callbacks=[integrations.lightning()]) # PyTorch Lightning
model.fit(..., callbacks=[integrations.keras()]) # Keras
Already have a run? Lint any export — column names are auto-normalized
(train/loss, learning_rate, global_step, … all map):
for finding in gradsnitch.lint_csv("wandb_export.csv"):
print(finding)
Options: mute={"GS003"} suppresses a rule by id; on_alert=integrations.wandb_alert
pushes verdicts into W&B (Slack/email) on a live run.
What it catches today
| ID | Rule | Catches |
|---|---|---|
| GS001 | Loss NaN/Inf | overflow / bad batch / LR too high |
| GS002 | Gradient norm inf | exploding grads (before the loss shows it) |
| GS003 | Gradient-norm spike | unstable update, precursor to a loss spike |
| GS004 | Train/val overfitting | val rises (≥3%) while train keeps falling |
| GS005 | Loss plateau | no early progress (slope-significance t-test) |
| GS006 | Loss divergence | sustained rise above the run's best |
| GS007 | Vanishing gradients | grad_norm collapses while loss stays stuck |
| GS008 | Update/weight ratio off | LR too high/low (Karpathy's ~1e-3), via watch() |
| GS009 | Loss oscillation | growing-amplitude swings (GAN/RL constant osc stays silent) |
| GS010 | LR schedule collapsed early | scheduler length mismatch — LR hits ~0 mid-run and the rest trains at zero |
Rule IDs are stable — suppressions and config pin to them, so they are never renumbered.
How it's built
- One engine, thin adapters. Pure detector functions over a metrics
DataFrame;
Monitoris the only sink; each framework adapter is a ~10-line extractor over a shared_feed+normalize()alias table. Torch is optional (duck-typed); each framework imported lazily. - The harness is the moat.
tests/test_real_runs.pytrains tiny real torch models that break through real mechanisms (LR 1e4→NaN, 8-pt set→overfit, frozen→plateau, corrupted batch→spike, deep-sigmoid→vanishing, tiny/big LR→update ratio off, half-length LR schedule→dead second half) plus negative rigs that must stay silent (converged val, terminal spike, short noisy learner, momentum→decaying oscillation, a correct full-length decay). 25 rigs; correctness here is emergent across adapters, so this is where the value lives.
What could be added (roadmap, not done)
- More detectors: dead-ReLU / saturation from activation hooks (the metrics-only cousin — grad_norm collapse — already ships as GS007).
- v2 flagship — Cockpit's Alpha (α): a principled "LR too high/low" verdict from the loss curvature along the update direction. Needs per-sample grads, so it's intrusive (breaks log-only/torch-optional) — a separate opt-in mode.
- Gradient-noise / batch-size test (Cockpit/McCandlish).
- Rule-catalog docs page + richer
mute/config (Cleanlab-style). - Run history — compare a run to your last N (Aim-style store).
Adding a rule or an adapter: CONTRIBUTING.md. Design notes: PLAN.md.
Metadata
Release files for gradsnitch 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| gradsnitch-0.1.0.tar.gz | 25.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gradsnitch-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.8 kB
Release files / gradsnitch-0.1.0.tar.gz
| Download URL | gradsnitch-0.1.0.tar.gz |
|---|---|
| Size | 25.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6858bbd007b208fc5278be559356845ba5334907ede606c664fdec6c827728e4
|
|
BLAKE2b-256 checksum How to use checksums |
d6425c2f9f526a4e582eafe43641edd25bfb5205307f003dd79ead1af38479e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logRelease files / gradsnitch-0.1.0-py3-none-any.whl
| Download URL | gradsnitch-0.1.0-py3-none-any.whl |
|---|---|
| Size | 17.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
913af038d0e1677a13f89d3c59f8199b322b2c3f0ce9820e778e36ae17836f08
|
|
BLAKE2b-256 checksum How to use checksums |
53e184c4d45cbb48be4fcf4c89294089485f22498839d90d3d328899e6b82ef6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logSecurity for gradsnitch 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for gradsnitch-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.