Benchmarks

Every number on this page comes from a script in the experiments/ directory of the ARC repository, so you can re-run it. Results measured on ARC 5.2.0 come first. Older results come from ARC 5.1 code and are marked as such until they are re-run.

Scope

Most recovery results use programmatically injected failures, the standard method in the fault-tolerance literature (ReCycle, SWIFT, Oobleck, Bamboo, JIT-Checkpointing). An organic-failure harness also tests failures caused by real training conditions. Long organic runs at scale are still future work.

70/70
Transient faults recovered (20/70 without ARC)
0
Rollbacks on clean control runs
10/10
Models kept intact under persistent bad data
2.2%
GPU overhead, GPT-2 124M
2.65B
Params in a rollback run (H200, 5.1)

Fault-Injection Recovery (ARC 5.2.0)

Protocol: 5 seeds, CPU. Each trial trains the same MLP on the same data twice, once unprotected and once with arc.Controller, and injects the same fault at step 60 of 150. Both runs are judged by the same checks at the end: no exception, every weight finite, and held-out loss no more than 2× its pre-fault value.
Script: experiments/recovery_benchmark.py

Fault classTrialsHealthy without ARCHealthy with ARCARC rollbacks
No fault (control)5550
Transient: 14 types (NaN/Inf loss, ×1e10 spikes, NaN weights or optimizer state, LR set to 1e6, Inf and adversarial gradients, repeated bursts)702070173
Persistent bad data (NaN in every batch; ×1e15 loss every 10th step)10510305
Reading the table

Under persistent NaN data, rollback can't fix the input. In all 5 of those trials ARC kept the model intact and flagged the run unrecoverable instead of looping. In 20 transient trials ARC rolled back for a fault that unprotected Adam would have absorbed, for example a ×1e10 loss spike. That cost a few steps but never left a worse model. The control group is small, and false-positive rates on full-size training recipes have not been measured yet.

GPU Overhead (ARC 5.2.0)

Protocol: GPT-2 (124M, random init), batch 4, sequence 128, AdamW. 400 steps in interleaved blocks of 50, with and without ARC, after 20 warm-up steps each. The figure is the median step time.
Script: python experiments/controller_overhead.py --steps 400 --batch 4 --seq 128

GPUBaseline (ms/step)With ARC (ms/step)Overhead
RTX 3050 6GB Laptop255.86261.492.2%

Snapshots are copied to host memory on a background thread right after optimizer.step(), so the copy overlaps the next forward and backward pass. Gradient and weight checks use one host sync per step. ARC 5.1 measured 40.7% (GPT-2) and 33.4% (GPT-2 Medium) on a Tesla T4 with a different engine and settings, so those numbers aren't directly comparable. A100, H100, and multi-billion-parameter runs have not been profiled yet.

Results from ARC 5.1 (pending re-measurement)

Why these are marked

An October 2026 audit found that the 5.1 stress suites (Nightmare, Comprehensive, Silent Failure) never applied their crash checks to the ARC-protected run, so their "100% recovered" figures meant "didn't raise an exception". Those suites are superseded by the symmetric benchmark above and are no longer reported. The results below come from 5.1 code, some from legacy APIs, and are kept for reference until they are re-run on 5.2.

Baseline Comparison

Protocol: 4 methods × 5 failure types × 5 seeds = 25 scenarios per method.
Script: experiments/baseline_comparison.py

MethodDetectionRecoveryFalse Pos.Avg. Time
No Protection52.0%0.0%0926ms
Gradient Clipping20.0%0.0%01297ms
Loss-Only Monitor80.0%80.0%01359ms
Full ARC100%100%01722ms

Detection Rate

No Protection
52%
Gradient Clipping
20%
Loss-Only Monitor
80%
Full ARC
100%

Billion-Scale Rollback (H200)

Protocol: NVIDIA H200, PyTorch 2.12. A 40 to 50 step fine-tune with one NaN loss injected at step 30, using the legacy WeightRollback. Each model is run healthy, unprotected with the failure, and ARC-protected with the failure.
Script: experiments/billion_scale_benchmark.py

ModelParamsNo ProtectionARCRollbacksFinal Loss (Healthy / ARC)Peak VRAM
GPT-2 Medium355MCrashed at step 30Recovered10.0648 / 0.09367.5 GB
GPT-2 Large774MCrashed at step 30Recovered10.0003 / 0.000616.2 GB
GPT-2 XL1.56BCrashed at step 30Recovered10.0003 / 0.000632.0 GB
Custom Transformer2.65BCrashed at step 30Recovered10.0026 / 0.005353.5 GB

The unprotected run is stopped at the NaN by the script. This shows that rollback fits and runs at 2.65B parameters on one GPU. It is not a recovery rate.

Real-Dataset Recovery

These experiments check whether a recovered model reaches the same quality as one trained without interruption. All ran on an NVIDIA Tesla T4.

CIFAR-10, ResNet-18 (3 seeds)

10 epochs of SGD. A NaN loss was injected at epoch 5, step 100.

ConditionFinal AccuracyRollbacksProgress Lost
Clean baseline (no failure)77.43% ± 0.1200 steps
ARC-protected (NaN at epoch 5)77.42% ± 0.151.02.2 steps

GPT-2 (124M) Fine-Tuning on WikiText-2

300 steps with AdamW. A NaN loss was injected at step 150.

ConditionFinal PerplexityRollbacksProgress Lost
Clean baseline (no failure)15.800
ARC-protected (NaN at step 150)16.41~5 steps

Gradient Explosion, ResNet-18 on CIFAR-10 (lr = 10, 5 seeds)

MethodSurvival RateSteps Completed (of 100)Rollbacks
No Protection0% (all crashed)1.0n/a
Full ARC100%99.01.0

Realistic Training Bugs

Protocol: ResNet-50 on CIFAR-100 for 10 epochs on a CUDA GPU. Each run injects a common real-world bug instead of a synthetic NaN. The healthy run reaches 32.66% top-1 accuracy.
Script: experiments/industrial_benchmark.py

BugNo ProtectionARC Final AccuracyRollbacks
Corrupted batchCrashed after 4 epochs27.66%1
Learning-rate bugCrashed after 4 epochs28.39%1
Gradient-accumulation bugCollapsed to 1.04%26.20%1
AMP overflow24.85%29.36%0

In the same benchmark, unprotected GPT-2 and BERT fine-tuning runs crashed mid-training. The ARC-protected runs completed with one rollback each.

Organic Failures

Protocol: 8 failures caused by real training conditions. None of them assigns NaN to the loss directly. Each runs for 60 steps with and without ARC. Data and loss faults start at step 20 and persist. Measured on ARC 5.1.2, CPU.
Script: experiments/organic_failure_test.py

ScenarioCauseNo ARCWith ARCRollbacks
LR too highSGD at lr=3.0 divergesLoss goes non-finiteRecovered, training continues5
NaN row in dataCorrupt sensor row in every batchLoss goes non-finiteFlagged unrecoverable at step 4224
Zero-variance batchStd-normalization divides by zeroLoss goes non-finiteFlagged unrecoverable at step 4224
log(0) in lossSaturated softmax, no epsilon guardLoss goes non-finiteWeights kept finite, flagged unrecoverable at step 4224
Outlier targetOne sample with a 1012 targetLoss goes non-finiteWeights kept finite, flagged unrecoverable at step 4224
fp16 overflowHalf precision, inputs scaled 60×Loss goes non-finiteWeights kept finite, flagged unrecoverable at step 3329
Dead ReLUs (silent)Large negative bias, gradients vanishStays finite, unnoticedDetected1
RNN gradient explosionSpectral radius > 1, no clippingStays finite, unnoticedDetected1
What this shows

ARC detected all 8 failures. It fully recovered the one fault that lived in the optimization itself, a learning rate that was too high. The other five that break an unprotected run sit in the data or the loss expression, so the same bad input comes back after every rollback. ARC kept the weights finite and, after 3 escape cycles, flagged each run unrecoverable within 33 to 42 steps, warning once and naming the input pipeline or loss as the likely cause. Before 5.1.2, these runs looped forever while reporting "recovered".

Large-Model Stress Tests

Protocol: 20 stable steps, then one catastrophic failure, with recovery checked within 10 steps.
Script: experiments/validate_claims_phase2.py

ModelParamsFailure TypeRecoveryRollbacks
NanoGPT10MLR Spike (50x)Yes2
ResNet-5025.6MLoss SingularityYes1
YOLOv1130MCatastrophic LRYes3
GPT-2 Small50MNaN BombYes4
SD-UNet60MGradient ApocalypseYes4
Wide ResNet68MLoss SupernovaYes3
Llama-style70MCatastrophic LRYes5
ViT-Base86MInf NukeYes1
GPT-2 Medium117MNaN BombYes3

See Billion-Scale Rollback for models from 355M to 2.65B parameters.

Failure Prediction (research)

Protocol: 4 architectures × 5 failure types × 5 seeds × 2 labels = 200 simulated training curves, 5-fold cross-validation.
Script: experiments/prediction_200_v2.py

What this measures

These classifiers are trained and tested on simulated curves labeled by ARC's rule-based labeler. The scores measure the classifier on synthetic data, not ARC on real runs. No trained predictor ships with the package, so FailurePredictor reports risk_level="unknown" unless you load your own model.

ClassifierAccuracyPrecisionRecallF1
Logistic Regression (12f)95.5%100%91.0%0.953
MLP (12 features)97.5% ± 2.2100%95%0.974

v1 to v2 Improvement

Metricv1 (8 feat, LogReg)v2 (12 feat, MLP)
Accuracy86.5%97.5%
Recall73.0%95.0%
F10.8440.974

Lyapunov Early Warning

Protocol: The learning rate ramps linearly from stable to explosive, and we record the step at which each detector first fires. Averaged over 5 seeds. Measured on ARC 5.1, before velocity was normalized by learning rate.

ScenarioLR RangeLyapunov (step)Reactive (step)Lead Time
Moderate ramp0.01 to 2.0238057 steps (72%)
Steep ramp0.01 to 5.0234426 steps (47%)
Gradual ramp0.01 to 1.019120101 steps (84%)

The lead is largest under gradual destabilization, which is the hardest case for threshold-based detectors. These lead times have not been re-measured on 5.2.

Fisher-Aware vs. Naive Rollback

Protocol: CNN on CIFAR-10. The top third of parameters by Fisher importance are corrupted, then recovered with either a uniform rollback or a Fisher-weighted rollback. Test accuracy is measured after 40 recovery steps and averaged over 5 seeds.

Corruption ScaleNaive AccuracyFisher AccuracyDelta
0.0248.7%50.2%+1.5 pp
0.0548.7%50.1%+1.3 pp
0.1048.7%49.5%+0.8 pp

Ablation Study

Protocol: ResNet-18, 5 seeds, ARC 5.1. The metric is the total number of rollbacks needed to survive each scenario, so lower means more efficient recovery. The three scenarios are (A) a gradient explosion every 10 steps, (B) 60% of weights zeroed at step 25, and (C) a NaN every 5 steps for the whole run. Every configuration survives every scenario.

Configuration(A) Instability(B) Silent Decay(C) Persistent NaNTotal
Full ARC10100101
Without gradient clipping400100140
Without LR reduction110100111
Without weight health10100101
Without weight perturbation10100101
Without forecasting10100101
Interpretation

For recurring gradient instability, clipping matters most: without it ARC needed 40× more rollbacks in scenario A. LR reduction comes next (11×) because it breaks the cycle of hitting the same instability again. In 5.1 clipping was on by default. In 5.2 it is opt-in, so set enable_baseline_clipping=True if your run has this pattern. Scenario B did not trip weight-health monitoring under any configuration, because that monitor targets magnitude collapse and explosion, not arbitrary sparsity patterns.

Overhead Breakdown (ARC 5.1, CPU)

Protocol: Median of 100 iterations, time.perf_counter, on a 288K-parameter CNN.
Script: experiments/overhead_measurement.py

ComponentTime (ms)% of Total
Gradient Norm0.129.0%
Weight Statistics1.0676.9%
Loss Analysis0.010.6%
Checkpoint (amortized)0.139.6%
Forecasting0.064.1%
Total ARC1.38100%

Added Time by Model Scale (CPU)

ARC's added time per step next to the baseline step time.

ModelParametersARC (ms)Baseline (ms)Relative
Small MLP50K0.861.45~60%
Medium CNN288K1.3814.17~10%
Large CNN2.5M7.0474.24~9.5%

Relative overhead falls as models grow, because monitoring cost grows more slowly than the forward and backward passes. 5.2 fuses the weight checks into one host sync, so the weight-statistics share above is an upper bound.

Known Limitations

AreaStatus
GPU overhead2.2% on GPT-2 (124M) on an RTX 3050. Not yet profiled on A100/H100/H200 or at multi-billion scale
ScaleRollback exercised at 2.65B parameters on one H200 (5.1, legacy engine). Snapshots live in host RAM: plan for max_checkpoints (3) copies of model plus optimizer state
Organic failuresPartially tested (8-scenario harness, realistic bugs on ResNet-50). Long organic runs at scale are untested
Data faultsDetected but not repairable by rollback. ARC flags them unrecoverable and names the likely cause
Distributed trainingController supports DDP: every rank agrees on each rollback (tested with 2 processes). FSDP/DTensor models are refused with a clear error. Multi-node, straggler, and SDC paths are not yet validated on a live cluster
Framework callbacksThe Hugging Face and Lightning hooks don't receive the loss, so they check gradients, weights, and dynamics. With the trainers' default clipping, a finite exploding gradient is clipped before ARC sees it (NaN/Inf is still caught)
False positives0 rollbacks in 5 clean control runs. Not yet measured on full-size training recipes
Multiplicative weight corruptionScaling all weights (e.g. 1000×) without producing NaN or sparsity is not caught
FrameworksPyTorch only