Skip to main content

One-line circuit breaker for PyTorch training — catches NaN gradients, logs spikes, prevents model corruption.

Project description

⚡ StabilityGuard

One-line circuit breaker for PyTorch training.
Add one line. See exactly which layer is about to explode.

License: MIT Python 3.9+ PyTorch 2.0+


The Problem

Training large models? Gradient spikes and NaN explosions silently corrupt your model weights. You lose hours of GPU time, and the error message tells you nothing about which layer caused it.

The Fix

pip install stabilityguard

Before StabilityGuard (standard PyTorch):

from torch.optim import AdamW

optimizer = AdamW(model.parameters(), lr=2e-4)

for batch in dataloader:
    loss = model(batch)
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()

After StabilityGuard (one-line change):

from torch.optim import AdamW
from stabilityguard import GuardedOptimizer  # ← the only change

base_opt = AdamW(model.parameters(), lr=2e-4)
optimizer = GuardedOptimizer(base_opt, model,
    spike_threshold=10.0,      # gradient norm ratio to trigger alert
    nan_action="skip",         # "skip" | "rollback" | "raise"
    log_every=50               # steps between diagnostic summaries
)

for batch in dataloader:
    loss = model(batch)
    loss.backward()
    optimizer.step()           # GuardedOptimizer intercepts here
    optimizer.zero_grad()

What You See

When a spike hits at step 847:

╔══════════════════════════════════════════════════════════════╗
║  ⚠ STABILITYGUARD — SPIKE DETECTED @ step 847                ║
╠══════════════════════════════════════════════════════════════╣
║  Trigger layer  : transformer.h.11.mlp.c_proj                ║
║  Grad norm      : 847.3  (baseline: 1.2, ratio: 706.1x)      ║
║  Action taken   : optimizer.step() SKIPPED                   ║
║  Loss (pre-skip): 14.71                                      ║
╚══════════════════════════════════════════════════════════════╝
stabilityguard.log written → ./sg_logs/spike_step847.json

Your model weights are untouched. Training continues.

How It Works

  1. Backward hooks on every nn.Module capture per-layer gradient L2 norms
  2. EMA baselines track normal gradient behavior (α=0.01, ~100 step lookback)
  3. Spike detection fires when current_norm / ema_baseline > threshold
  4. NaN/Inf short-circuit catches corrupted gradients via torch.isfinite
  5. Actions execute automatically: skip the step, rollback to checkpoint, or raise

Configuration

Parameter Default Description
spike_threshold 10.0 Ratio of current norm to EMA baseline that triggers a spike
nan_action "skip" Action on spike: "skip", "rollback", or "raise"
log_every 50 Steps between periodic diagnostic summaries
log_dir "./sg_logs" Directory for JSON spike reports
ema_alpha 0.01 EMA smoothing factor (smaller = slower adaptation)
warmup_steps 10 Steps before spike detection activates
verbose True Print diagnostic summaries to stdout

Actions

Action Behavior
skip Skip optimizer.step() — corrupted gradients discarded, weights unchanged
rollback Restore model + optimizer to the last clean checkpoint
raise Throw GradientSpikeError for interactive debugging

Integrations

Weights & Biases

from stabilityguard.integrations.wandb import WandBBridge
bridge = WandBBridge()
# Metrics logged under sg/ namespace automatically

MLflow

from stabilityguard.integrations.mlflow import MLflowBridge
bridge = MLflowBridge()

HuggingFace Transformers

from stabilityguard.integrations.huggingface import StabilityGuardCallback

trainer = Trainer(
    model=model,
    args=training_args,
    callbacks=[StabilityGuardCallback(spike_threshold=10.0)],
)

Performance

Metric Value
Per-step overhead (no spike) < 0.2ms on A100
Per-step overhead (spike detected) ~3ms (includes JSON write)
External dependencies 0 (only PyTorch)
License MIT

Install from source

git clone https://github.com/stabilityguard/stabilityguard.git
cd stabilityguard
pip install -e ".[test]"
pytest tests/ -v

License

MIT — use it anywhere, no restrictions.

Project details


Download files

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

Source Distribution

stabilityguard-0.1.0.tar.gz (21.6 kB view details)

Uploaded Source

Built Distribution

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

stabilityguard-0.1.0-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file stabilityguard-0.1.0.tar.gz.

File metadata

  • Download URL: stabilityguard-0.1.0.tar.gz
  • Upload date:
  • Size: 21.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for stabilityguard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1d19dcbbe9f77d7afe8f88bd70327220de2eba785d859a2f7e91d13718d546e8
MD5 0bc3eb47cf79a36b4dd488286c6206b4
BLAKE2b-256 32cb0d5efd28d2859418026e43c24c8528cdf540344351d052009cac77267a07

See more details on using hashes here.

File details

Details for the file stabilityguard-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: stabilityguard-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for stabilityguard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 783d1950c2a4bdd6c77b59c9ee89171d9f4d27afa606e28433a99aebdc3b7af1
MD5 33d3e63433704a36a36bbab260c809f1
BLAKE2b-256 1eb7ccd09b885fd3cfe1a6d70f3a16b4220f04418a1aae1d952a6209e0a5a1a2

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