From spml
Systematically diagnoses ML training failures: convergence issues, anomalous behavior, and performance bottlenecks. Uses structured evidence gathering before proposing fixes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/spml:diagnosticsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Systematic diagnosis for ML training problems. Replaces random "try this" debugging with structured evidence gathering and hypothesis testing.
Systematic diagnosis for ML training problems. Replaces random "try this" debugging with structured evidence gathering and hypothesis testing.
Core principle: In ML, "not working" is normal. The question is WHY it's not working — implementation bug or strategy limitation? Misdiagnosing this wastes entire research directions.
Do NOT propose fixes without completing Phase 1 (evidence gathering). The temptation to "just try lowering the learning rate" is the #1 cause of wasted GPU hours.Every ML diagnostic starts by identifying which question you're answering:
You MUST complete each phase before proceeding to the next.
BEFORE proposing ANY fix:
# Quick diagnostic snapshot
def diagnostic_snapshot(model, loss_history, step):
snapshot = {}
# Gradient health
for name, param in model.named_parameters():
if param.grad is not None:
g = param.grad
snapshot[f"grad/{name}/norm"] = g.norm().item()
snapshot[f"grad/{name}/has_nan"] = torch.isnan(g).any().item()
snapshot[f"grad/{name}/has_inf"] = torch.isinf(g).any().item()
# Loss trend
if len(loss_history) >= 10:
recent = loss_history[-10:]
snapshot["loss/recent_mean"] = sum(recent) / len(recent)
snapshot["loss/recent_std"] = (sum((x - snapshot["loss/recent_mean"])**2 for x in recent) / len(recent)) ** 0.5
snapshot["loss/trend"] = "decreasing" if recent[-1] < recent[0] else "flat_or_increasing"
# Parameter norms
for name, param in model.named_parameters():
snapshot[f"param/{name}/norm"] = param.data.norm().item()
return snapshot
Find the pattern:
Compare against expected behavior:
Localize the problem:
Hierarchical decomposition (when needed):
Overall problem
-> Which substructure? (attention / FFN / embedding / MoE routing)
-> Within that substructure, which operation?
-> Is it forward, backward, or both?
Use toolkit/profiling/layer_profiler.py for per-layer timing decomposition.
Use gradient hooks for per-layer gradient analysis.
Scientific method — one variable at a time:
| Evidence | Likely Cause | First Action |
|---|---|---|
| All gradients near 0 | Vanishing gradients | Check init, residual connections, gradient clipping |
| Some gradients exploding | Exploding gradients | Lower LR, add gradient clipping |
| Gradients normal but loss flat | LR too low, or loss function wrong | Check LR schedule, verify loss function |
| Loss oscillating wildly | LR too high | Reduce LR by 10x, check batch size |
| Loss goes to NaN | Numerical instability | Check for log(0), division by 0, overflow |
| Loss decreases then plateaus high | Underfitting | Check model capacity, data quality |
| Evidence | Likely Cause | First Action |
|---|---|---|
| MFU < 20% | I/O bottleneck or wrong backend | Check data loading speed, verify FA enabled |
| MFU 20-40% | Memory bound or poor overlap | Check memory profiler, verify comm/compute overlap |
| MFU > 40% but slow | Expected — model is memory-bound | This may be normal for your architecture |
| One layer dominates time | Bottleneck layer | Profile that layer specifically, check for inefficient ops |
| Evidence | Likely Cause | First Action |
|---|---|---|
| Attention entropy < 0.1 | Attention collapse | Check attention init, temperature, positional encoding |
| MoE balance < 0.5 | Expert collapse | Check auxiliary loss, router init |
| Residual write ratio > 1.0 | Layer output overwhelming residual | Check layer norm placement, init scale |
| Embedding norms exploding | Embedding learning rate too high | Separate LR for embeddings |
If 3 hypotheses fail, STOP fixing and question fundamentals:
Discuss with the human before attempting more fixes. Three failures usually mean the problem is architectural, not a parameter tweak.
Validation Pyramid check fails
-> Identify which check failed (L0/L1)
-> Map to core question (Q1/Q2/Q3)
-> Enter Phase 1 with relevant metrics already collected
-> After fix: re-run the failed Validation Pyramid check
-> Pass: return to pyramid (continue to next layer)
-> Fail again: continue diagnosis
npx claudepluginhub qqhard/superpowers-ml --plugin spmlSystematic approach to debugging ML training failures: divergence, NaNs, memory issues, inconsistent metrics.
Diagnoses failing ML experiments by probing system state, GPU stats, logs, and checkpoints before forming hypotheses. Enforces evidence-before-action protocol.
Diagnoses ML/AI failures like OOM, NaN, divergence, crashes, bad throughput, wrong outputs, and dependency conflicts using grounded framework docs and citations.