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.
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 gradsnitch-0.1.0.tar.gz.
File metadata
- Download URL: gradsnitch-0.1.0.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6858bbd007b208fc5278be559356845ba5334907ede606c664fdec6c827728e4
|
|
| MD5 |
c1b4949408ea29363d56259e7a817b98
|
|
| BLAKE2b-256 |
d6425c2f9f526a4e582eafe43641edd25bfb5205307f003dd79ead1af38479e2
|
Provenance
The following attestation bundles were made for gradsnitch-0.1.0.tar.gz:
Publisher:
publish.yml on devangpratap/gradsnitch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gradsnitch-0.1.0.tar.gz -
Subject digest:
6858bbd007b208fc5278be559356845ba5334907ede606c664fdec6c827728e4 - Sigstore transparency entry: 2703045200
- Sigstore integration time:
-
Permalink:
devangpratap/gradsnitch@4a7a40d4dd7d36b51338628999dca6912dbe0aa7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/devangpratap
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a7a40d4dd7d36b51338628999dca6912dbe0aa7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file gradsnitch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gradsnitch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
913af038d0e1677a13f89d3c59f8199b322b2c3f0ce9820e778e36ae17836f08
|
|
| MD5 |
ab730ff855debf8f96f7cf3acc0e570b
|
|
| BLAKE2b-256 |
53e184c4d45cbb48be4fcf4c89294089485f22498839d90d3d328899e6b82ef6
|
Provenance
The following attestation bundles were made for gradsnitch-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on devangpratap/gradsnitch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gradsnitch-0.1.0-py3-none-any.whl -
Subject digest:
913af038d0e1677a13f89d3c59f8199b322b2c3f0ce9820e778e36ae17836f08 - Sigstore transparency entry: 2703045252
- Sigstore integration time:
-
Permalink:
devangpratap/gradsnitch@4a7a40d4dd7d36b51338628999dca6912dbe0aa7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/devangpratap
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a7a40d4dd7d36b51338628999dca6912dbe0aa7 -
Trigger Event:
release
-
Statement type: