Ray-zyy/TS-Fault

[ICDE-2027] TS-Fault: Benchmarking Time Series Forecasters against Structural Faults

Python

10

55 commits

updated Sep 23, 2026

See the code

README

⚡ TS-Fault

Benchmarking Time Series Forecasters Against Structural Faults

Yuyang Zhao¹ · Lian Xu² · Hao Miao³ · Chenxi Liu⁴ · Hao Xue¹ ✉

¹ Hong Kong University of Science and Technology (Guangzhou)  ·  ² The University of Western Australia  ·  ³ The Hong Kong Polytechnic University  ·  ⁴ CAIR, Hong Kong Institute of Science & Innovation, Chinese Academy of Sciences

21 models  ·  9 datasets / 6 domains  ·  4 failure modes  ·  5 severity levels  ·  ~3,800 evaluated cells

Why  •  Failure modes  •  Repository  •  Datasets  •  Quick start  •  Results  •  Extended experiments  •  Reproducibility  • 

TL;DR — Clean-data leaderboards do not predict robustness. TS-Fault stops treating faults as i.i.d. noise. It injects four structurally-coupled failure modes — abstracted from the anatomy of real grid-scale failures — into the input window of nine standard forecasting datasets across six domains, then measures how far each model degrades. Under the two mechanism-level modes, the ranking is reordered: state-of-the-art Transformers and foundation models collapse, while a plain LSTM/GRU — or even a naïve baseline — becomes the most robust.

The TS-Fault pipeline
The TS-Fault pipeline. A clean pair (X, Y) is turned into a structured instance: a window-importance score selects the prediction-critical window W★, a parameterized fault operator TΘ acts there at a chosen severity, and the scenario parameters Θ and difficulty δ are reported with the instance and used to condition evaluation.

📌 Why TS-Fault?

For two decades, long-horizon forecasting progress has been measured by one number — average error on clean, complete, evenly-sampled held-out data — under the implicit assumption that it predicts deployed reliability. Real faults are not white noise. They are structured events: a transient with onset–peak–decay, a silently broken cross-variable dependency, a regime change coupled with block-missingness, a fault cascading through a sensing pipeline. None of these can be expressed by i.i.d. perturbations, no matter how the variance or masking rate is tuned.

TS-Fault changes the object of evaluation, replacing the clean test pair (X, Y) with a structured instance (X̃, Ỹ, Θ, δ) produced by an explicit, parameterized fault operator. Because Θ is exposed, a model's degradation can be attributed to a named mechanism at a tunable severity — turning a pass/fail noise test into an ablation-style diagnostic tool.

Headline findings

1 · Clean accuracy anti-correlates with robustness Spearman ρ = −0.544 (p = 0.011) across all 21 models — and −0.509 over the 18 non-foundation models, so foundation models strengthen the effect.

2 · Stratified by mode Observation-level faults preserve the ranking (ρ > 0.92); mechanism-level faults destroy it (ρ < 0.06).

3 · Catastrophe is structural All 884 catastrophic failures (≥ 10× error inflation) fall in the two mechanism-level modes; Modes I/II never trigger one.

4 · Strong, but fragile TimesFM is 2nd on clean MSE yet the worst of all 21 on robustness (ratio ≈ 555).


🧩 The four failure modes

Each mode corrupts only the lookback window (L = 336); the forecast target (H = 96) is never touched, so degradation isolates the cost of a corrupted history. A single difficulty scalar d ∈ {0.2, 0.4, 0.6, 0.8, 1.0} (written d02 … d10) sweeps severity monotonically. The modes span a 2 × 2 taxonomy — observation- vs. mechanism-level × univariate vs. multivariate — and form a constructive minimum: omitting any one renders an entire class of deployment failure invisible.

The 2x2 fault taxonomy
FileModeTaxonomy cellWhat breaksReal-world analogue
Mode1.pyI · Time-Warped ShockObservation × Univariatea shaped transient (onset–peak–decay) + a local time-warpdemand spike / brief sensor glitch
Mode2.pyII · Dependency-Fracture ShockObservation × Multivariatecross-channel lead–lag and gain silently falsified; each series alone still looks plausibleregions that usually co-move decouple
Mode3.pyIII · Regime-Transition MissingnessMechanism × Univariatea regime switch + state-dependent block-missingness around the transition (hardest mode)grid emergency / firm load shed
Mode4.pyIV · Cascading Sensor-to-System FailureMechanism × Multivariatean upstream drift propagates downstream with a lag, inducing secondary dropoutsa fault cascading through coupled subsystems

Observation-level (I, II) corrupt observations while the data-generating process stays intact → mild. Mechanism-level (III, IV) rewrite the process itself → severe, and account for 100% of catastrophic failures.


📂 Repository contents

This repository ships the data-generation pipeline, model implementations, evaluation drivers, trained checkpoints, and the complete results workbook. The four fault generators are included in full, so the perturbed dataset can be regenerated from scratch.

.
├── README.md
├── requirements.txt
│
├── benchmark.py                 # benchmark orchestration helpers
├── dataset_loader.py            # load + normalise the clean CSVs into windows
├── window_selector.py           # select the anchor lookback / horizon windows
│
├── Mode1.py                     # Fault Mode I   — Time-Warped Shock
├── Mode2.py                     # Fault Mode II  — Dependency-Fracture Shock
├── Mode3.py                     # Fault Mode III — Regime-Transition Missingness
├── Mode4.py                     # Fault Mode IV  — Cascading Sensor-to-System Failure
├── run_TS-Fault.py              # ▶ MAIN entry point: build the perturbed benchmark
│
├── classical_models.py          # statistical / linear / recurrent / conv. forecasters
├── foundation_models.py         # TimesFM / Chronos / Moirai (zero-shot wrappers)
├── eval_classical_phase1.py     # evaluate classical + baseline models → results CSV
├── eval_foundation_phase1.py    # evaluate foundation models → results CSV
├── checkpoints/                 # released trained weights
├── ablation_placement.py        # window-placement ablation: top-K S(W) vs random vs anti-selected
├── ablation_lambda.py           # one-at-a-time sensitivity of the S(W) weights λ
├── adapt_foundation.py          # LP / FT / FT-fault adaptation of the three foundation models
├── compose_faults.py            # ⊛ compound faults: T_B ∘ T_A at matched severity
└── figures/                     # paper figures used in this README

The 21 evaluated forecasters

The paper evaluates 21 models across six methodological families, so the conclusions are not an artifact of a single inductive bias:

FamilyModels
Statistical (4)Naive · SeasonalNaive · ARIMA · ETS
Linear / lightweight (3)DLinear · NLinear · N-BEATS
Recurrent / convolutional (3)LSTM · GRU · TCN
Decomposition Transformer (2)Autoformer · FEDformer
Attention / SOTA (6)PatchTST · iTransformer · TimeXer · TimeMixer · TimesNet · Nonstationary-Transformer
Foundation, zero-shot (3)TimesFM · Chronos · Moirai

Statistical, linear, and recurrent/convolutional models live in classical_models.py; the eight Transformer-family models are trained via the Time-Series-Library (see § Transformer-family); the three foundation models run strictly zero-shot via foundation_models.py. The repository's classical_models.py additionally bundles a few exploratory baselines (e.g. RandomForest, XGBoost) that fall outside the 21-model paper subset.


📊 Datasets (clean originals)

TS-Fault perturbs nine long-horizon datasets spanning six domains — energy, load, climate, finance, IT/Ops, and healthcare — deliberately chosen to cover a wide range of dimensionality (7 → 321 channels) and granularity (5-second → daily). Every clean window is a length-336 history and a length-96 target. We do not redistribute the raw data — download it and place each file at the path the loader expects.

DatasetDomainChannelsGranularitySizePath expected
ETTh1 / ETTh2Energy7hourly17,420dataset/ETT-small/ETTh1.csv, …/ETTh2.csv
ETTm1 / ETTm2Energy715-min69,680dataset/ETT-small/ETTm1.csv, …/ETTm2.csv
Electricity (ECL)Load321hourly26,304dataset/electricity/electricity.csv
WeatherClimate2110-min52,696dataset/weather/weather.csv
Exchange-RateFinance8daily7,588dataset/exchange_rate/exchange_rate.csv
BizITObs-Service-KPIIT / Ops7210-sec8,835dataset/bizitobs/service_kpi.csv
VitalDB-CoreHealthcare85-sec962 casesdataset/vitaldb/vitaldb_core.csv
Download links (canonical)

The first seven, one bundle (recommended) — official Time-Series-Library mirror on HuggingFace (CC BY 4.0): https://huggingface.co/datasets/thuml/Time-Series-Library

from huggingface_hub import hf_hub_download
for f in ["ETT-small/ETTh1.csv", "ETT-small/ETTh2.csv",
          "ETT-small/ETTm1.csv", "ETT-small/ETTm2.csv",
          "electricity/electricity.csv", "weather/weather.csv",
          "exchange_rate/exchange_rate.csv"]:
    hf_hub_download("thuml/Time-Series-Library", f, repo_type="dataset")

🚀 Quick start

1 · Install

git clone https://github.com/Ray-zyy/TS-Fault.git
cd TS-Fault
pip install -r requirements.txt

2 · Get the clean datasets

Download the nine CSVs (see § Datasets) into:

dataset/ETT-small/{ETTh1,ETTh2,ETTm1,ETTm2}.csv
dataset/electricity/electricity.csv
dataset/weather/weather.csv
dataset/exchange_rate/exchange_rate.csv
dataset/bizitobs/service_kpi.csv
dataset/vitaldb/vitaldb_core.csv  

3 · Generate the perturbed benchmark

run_TS-Fault.py slides the anchor windows (window_selector.py), loads & normalises the clean series (dataset_loader.py), and applies each of the four fault modes (Mode1.py … Mode4.py) across all five difficulties:

python run_TS-Fault.py \
    --data_root ./dataset \
    --out ./TS-Fault_output \
    --n_windows 20

This writes one .npz per (dataset, Mode, difficulty) to TS-Fault_output/<Dataset>/<Dataset>_Mode<k>_d<dd>.npz — 9 datasets × 4 modes × 5 difficulties = 180 files, each containing:

arrayshapemeaning
x_clean(N, 336, C)clean lookback windows
x_corrupt(N, 336, C)perturbed lookback windows
y_target(N, 96, C)forecast target (never perturbed)

4 · Evaluate

Classical / baseline models (deep ones train once per dataset on clean windows; statistical ones need no training):

python eval_classical_phase1.py \
    --models Naive SeasonalNaive ARIMA ETS \
             DLinear NLinear NBEATS \
             LSTM GRU TCN \
    --npz_root ./TS-Fault_output \
    --out ./results/eval_classical.csv --gpu 0 --resume

Foundation models (zero-shot — see § Foundation models):

python eval_foundation_phase1.py \
    --models timesfm chronos moirai \
    --npz_root ./TS-Fault_output \
    --out ./results/eval_foundation.csv --gpu 0 --resume

Each evaluator emits the canonical wide schema, one row per (model, dataset, Mode, difficulty):

model, dataset, Mode, difficulty, mse_corrupt, mae_corrupt, mse_clean, mae_clean, n_samples, time_sec

mse_clean is the error on the clean input window, mse_corrupt on the perturbed window — both predicting the same untouched target. The robustness ratio r = mse_corrupt / mse_clean isolates the cost of corrupted history; r = 1 is perfect robustness and r ≥ 10 is a catastrophic failure. Concatenate the per-group CSVs (classical + foundation + the TSLib Transformer rows) into the master workbook eval_results_full.xlsx (also mirrored as the flat eval_results_full_23.csv).


🧪 Evaluating the Transformer-family models

The eight Transformer/attention models (PatchTST, iTransformer, Autoformer, FEDformer, Nonstationary-Transformer, TimeMixer, TimeXer, TimesNet) are trained and run with the Time-Series-Library (TSLib).

  1. Clone TSLib and place the same nine clean CSVs under its ./dataset/.

  2. Train / evaluate each model with run.py under the TS-Fault protocol (seq_len=336, pred_len=96, features=M, MSE loss). Example:

    python -u run.py \
        --task_name long_term_forecast --is_training 1 \
        --root_path ./dataset/ETT-small/ --data_path ETTh1.csv \
        --model_id ETTh1_336_96 --model PatchTST --data ETTh1 \
        --features M --seq_len 336 --label_len 48 --pred_len 96 \
        --e_layers 2 --d_layers 1 --enc_in 7 --dec_in 7 --c_out 7 \
        --train_epochs 10 --batch_size 32 --learning_rate 1e-4 --itr 1
    
  3. Score each trained checkpoint on the TS-Fault .npz windows (clean vs. corrupt) and write rows in the same wide schema, then merge into the master workbook eval_results_full.xlsx.

Shared hyperparameters & model-specific notes

Shared across all models: seq_len=336, label_len=48, pred_len=96, e_layers=2, d_layers=1, d_model=128–512, train_epochs=10, batch_size=32 (16 for Electricity), MSE loss, instance/RevIN normalisation.

  • TimeMixer — --down_sampling_layers 3 --down_sampling_window 2 --down_sampling_method avg --channel_independence 1
  • Nonstationary-Transformer — --p_hidden_dims 128 128 --p_hidden_layers 2
  • DLinear — --individual is a store-true flag
  • Reduce d_model / batch_size for TimesNet / FEDformer / Autoformer on 11 GB GPUs.

🧱 Installing the foundation models

These libraries pull heavy / conflicting dependencies. The recipe that works (verified on CUDA 12.1, torch 2.5.1):

# TimesFM + Chronos are clean pip installs
pip install timesfm chronos-forecasting

# Moirai (uni2ts) pins torch<2.5 and WILL try to downgrade torch.
# Install WITHOUT deps so it cannot touch torch, then hand-add what it needs:
git clone https://github.com/SalesforceAIResearch/uni2ts.git
cd uni2ts && pip install -e . --no-deps && touch .env
pip install "gluonts==0.14.4" "einops==0.7.0" jaxtyping --no-deps

Behind a mirror, set export HF_ENDPOINT=https://hf-mirror.com before the first run. All three run zero-shot (no fine-tuning) and are wrapped channel-independently for multivariate inputs.


🏆 Results

The complete results workbook

Every number in this README — and a great many that did not fit — is shipped in eval_results_full.xlsx, the full evaluation table. It holds one row per (model, dataset, mode, difficulty) cell for the entire grid of 21 models × 9 datasets × 4 modes × 5 severities ≈ 3,800 rows (ARIMA is omitted on the 321-channel Electricity, where per-series fitting is impractical), under the same wide schema produced by the evaluators:

model · dataset · Mode · difficulty · mse_corrupt · mae_corrupt · mse_clean · mae_clean · n_samples · time_sec

From these columns the robustness ratio r = mse_corrupt / mse_clean, the relative degradation (r − 1) × 100%, the severity slope d10/d02, and every per-mode / per-dataset aggregate in the paper can be recomputed directly — no rerun required. A flat-CSV mirror is provided as eval_results_full_23.csv.

Aggregate — the clean and faulted leaderboards are near mirror images

The most robust models (GRU, LSTM, TCN, near-unit ratios) are only mid-pack on clean accuracy, while the clean-accuracy leaders (N-BEATS, TimesFM, iTransformer, TimeXer) sit at the bottom of the robustness order with ratios in the hundreds.

Aggregate results: robustness ratio, severity sweep, per-mode breakdown
Left: clean/faulted MSE-MAE and robustness ratio. Center: degradation across severities d02→d10 and the d10/d02 sensitivity slope. Right: per-mode relative degradation — note the jump from single-digit % under Modes I/II to thousands–to–tens-of-thousands % under Modes III/IV.

Rank reordering — preserved under observation-level faults, destroyed under mechanism-level

ModeSpearman ρ (clean vs. faulted rank)pVerdict
I · Time-Warped Shock+0.925< 0.001ranking preserved
II · Dependency Fracture+0.952< 0.001ranking preserved
III · Regime Missingness+0.0320.889ranking destroyed
IV · Cascading Failure+0.0550.814ranking destroyed

Per-dataset — fragility is structural; dimensionality sets the amplitude

The model ordering is highly consistent across datasets (fragility is a property of the architecture), but dense cross-channel correlation amplifies it: on the 321-channel Electricity, TimesFM's ratio peaks at 2090 and TimeXer at 1112, while GRU/LSTM stay near 1.2 everywhere.

Per-dataset corrupted MSE and robustness ratios across six datasets
Per-dataset corrupted MSE and robustness ratios across six datasets
MSE on corrupted inputs per dataset
MSE on corrupted inputs per dataset

MSE on corrupted inputs per dataset (lower is better). Recurrent models (LSTM, GRU) sit at the bottom of every panel; foundation models (gold) sit at the top.

Catastrophic failures (r ≥ 10): 884 total — 0 in Mode I, 0 in Mode II, 537 in Mode III (85.9% of its cells), 347 in Mode IV (55.5%). Mechanism-level modes account for 100% of them.

Three new domains — finance, IT/Ops, healthcare

The added datasets were chosen to break the energy/climate monoculture of the original release, not to make the benchmark easier. They do not change the verdict.

Model6-dataset rExchange-RateBizITObsVitalDB
Naive105.7199.2196.1474.5
SeasonalNaive165.5266.4197.8435.9
ARIMA120.7239.1212.9521.6
ETS122.9254.1209.4523.1
DLinear197.3197.3180.3271.9
NLinear142.1251.9226.2399.7
N-BEATS54.6110.4217.9408.7
LSTM1.071.081.121.20
GRU1.141.171.271.44
TCN7.8919.37.4515.6
Autoformer48.043.544.486.2
FEDformer22.643.739.999.9
PatchTST262.6204.6304.7412.8
iTransformer272.3212.9239.5285.9
TimeXer301.2235.7253.8328.0
TimeMixer264.2196.5255.0331.2
TimesNet141.786.6207.5260.3
Nonstationary-Transformer101.1118.0168.2219.9
TimesFM (FM)555.2430.81,038.81,902.8
Chronos (FM)512.5452.0519.4787.6
Moirai (FM)365.6425.9476.5841.8

Which mechanism dominates depends on the domain — and it depends on it in the direction the taxonomy predicts.

Dataset#Ch.Mode IMode IIMode IIIMode IVIV / III
ETT (mean of four)71.0751.047361.1135.40.375
Weather211.0831.001124.614.80.119
Electricity3211.3641.0052,229.421.20.009
Exchange-Rate81.121.07680800.118
BizITObs-Service-KPI721.181.038351150.138
VitalDB-Core81.261.021,4901450.097

(mean r over the 21 models, averaged across the five severities)


🧪 Extended experiments

Four follow-up studies run on top of the same released grid. Each has its own driver script and its own results CSV, so every number below can be recomputed without touching the main pipeline.

1 · Compound faults — do co-occurring failures interact?

Real incidents rarely arrive one at a time. Because the four modes are operators, they compose: TΘ = TΘ_B ∘ TΘ_A (Eq. 19). Both operators act on the same critical window W★, each keeps its own Θ, and at every severity the two constituents are matched at the same nominal difficulty, κ_A(Θ_A) = κ_B(Θ_B) = δ_s. One fixed application order per pair — composition is not commutative, so the order is itself a scenario parameter.

python compose_faults.py \
    --pairs I+II I+III I+IV II+III II+IV III+IV \
    --npz_root ./TS-Fault_output --out ./results_compound.csv

The amplification factor Ψ(A∘B) = r(A∘B) / max(r_A, r_B) asks whether a compound fault is worse than its more damaging half.

CompositionMean rΨ
single-mode reference: Mode I1.12—
single-mode reference: Mode II1.03—
single-mode reference: Mode III618.1—
single-mode reference: Mode IV97.1—
I ∘ II1.241.11
II ∘ IV103.81.07
I ∘ IV118.71.22
II ∘ III763.41.24
I ∘ III1,047.61.69
III ∘ IV2,183.73.53
  • No pair cancels. All six satisfy Ψ ≥ 1.07 — a compound fault is never easier than its worse half.
  • Mechanism × mechanism is superadditive. III ∘ IV reaches Ψ = 3.53: a regime switch that a cascade then propagates is more than three times worse than either alone.
  • Two observation-level faults do not add up to a mechanism-level one. I ∘ II tops out at r = 1.24. The stratification of Finding 2 survives composition — it is not an artifact of testing one mode at a time.

2 · Where the fault is placed — is S(W) doing any work?

S(W) is the claim that a benchmark should stress the window a model relies on. If placement did not matter, TS-Fault would be a noise test with extra steps. We compare three placement policies at severity s₃ (d06), over 9 datasets × 21 models × 5 seeds, with random placement δ-matched so only the location differs:

python ablation_placement.py --policy topk random anti --severity d06 --seeds 5 \
    --out ./results_placement.csv
ModePlacementMedian RD (%)Mean rCatastrophic cells (%)Seed IQR / medianρ(clean, faulted)
IAnti-selected0.431.0090.01.37+0.999
IRandom1.471.0350.01.18+0.996
ITop-K S(W)5.111.1100.00.27+0.983
IIAnti-selected0.0121.0010.01.63+1.000
IIRandom0.0341.0040.01.46+0.999
IITop-K S(W)0.111.0100.00.34+0.999
IIIAnti-selected9,872216.462.71.08+0.286
IIIRandom (δ-matched)18,436398.775.40.84+0.147
IIITop-K S(W)26,232560.988.80.31+0.023
IVAnti-selected68413.738.11.21+0.374
IVRandom (δ-matched)1,53629.458.70.91+0.218
IVTop-K S(W)2,87852.772.80.29+0.082

Anti-selected < Random < Top-K in every mode, on both metrics. Two consequences beyond "the score works": importance-based placement cuts seed-to-seed variability by 3–4× (the IQR/median column), so a given robustness number means something; and as placement is weakened the faulted ranking drifts back toward the clean ranking (Mode III ρ: 0.023 → 0.147 → 0.286). Random placement would have partially hidden the model-selection risk that motivates the benchmark.

3 · Sensitivity to the S(W) weights

The per-mode weights and window hyperparameters, in full:

Modeλ₁ (S_cp)λ₂ (S_per)λ₃ (S_var)λ₄ (S_pred)top-K|W|σ_p
I · Time-Warped Shock0.150.150.350.355240.15P
II · Dependency Fracture0.150.200.250.405240.15P
III · Regime Missingness0.400.250.150.205240.15P
IV · Sensor-to-System Cascade0.200.150.300.355240.15P

One-at-a-time perturbation at severity s₃ (ablation_lambda.py):

ModePerturbationΔ median RDρ vs. default ranking
Iλ₃ × 0.5−18.7%0.958
Iλ₃ × 2+12.6%0.964
Iλ₄ → 0−43.8%0.890
Iλ₁ → 0+1.9%0.982
IIλ₄ → 0−51.4%0.871
IIλ₂ × 2−3.7%0.969
IIIλ₁ × 0.5−29.6%0.934
IIIλ₁ → 0−54.2%0.877
IIIλ₃ × 2+6.8%0.969
IVλ₄ → 0−41.9%0.884
IVλ₂ → 0−2.3%0.979

The weight each mode is designed around is the one that matters: zeroing λ₄ (occlusion) costs 42–51% of the degradation in Modes I/II/IV, and zeroing λ₁ (change-point) costs 54% in Mode III. Removing a weight the mode does not emphasise moves the result by at most 2.3%. Crucially, the model ranking is stable throughout (ρ ≥ 0.871): the weights control how hard the benchmark is, not who wins.

4 · Can adaptation fix the foundation models?

The zero-shot fragility result invites the obvious question. We adapted all three foundation models under four settings and re-ran the full grid:

SettingWhat is trainedEvaluated on
ZSnothing — released weightsfull grid
LPforecasting head only, clean datafull grid
FTall parameters, clean datafull grid
FT-faultall parameters, low-severity faulted data (s₁–s₂)held-out severities s₃–s₅
python adapt_foundation.py --model timesfm --setting ft_fault \
    --train_severities d02 d04 --eval_severities d06 d08 d10 \
    --out ./results_foundation_adapt.csv
ModelSettingClean MSEFaulted MSEΔMSEAVG rMode III rMode IV rWC r
TimesFMZS0.516162.7162.25552,0132054,073
TimesFMLP0.468108.7108.2344.51,248128.02,687
TimesFMFT0.37858.357.9182.665474.21,426
TimesFMFT-fault0.4126.786.3712.238.78.2476.5
ChronosZS0.613165.6165.05131,8392093,745
ChronosLP0.548119.4118.9339.51,217139.02,468
ChronosFT0.43764.864.4188.167278.51,384
ChronosFT-fault0.4798.367.8814.346.29.1391.7
MoiraiZS0.682153.1152.43661,2961642,544
MoiraiLP0.59689.789.1214.476887.61,538
MoiraiFT0.46243.643.1109.939245.4814
MoiraiFT-fault0.5075.925.419.7430.86.1755.4
(reference) LSTMtrained0.7330.7800.0471.071.171.101.25
  • Clean-data adaptation buys accuracy, not robustness. LP improves TimesFM's ratio only 1.6× (555 → 344.5). Full fine-tuning cuts absolute faulted error 2.6–3.5× yet leaves ratios at 110–188 — still two orders of magnitude from an LSTM.
  • Only fault structure in the training signal closes the gap. FT-fault drops the ratios to 12.2 / 14.3 / 9.74 and faulted MSE by a further 7.4–8.6× over clean fine-tuning, at a clean-accuracy cost of just 9–10%. Note this is measured on held-out severities — the models never saw s₃–s₅ during adaptation, so this is generalisation along κ, not memorisation of a severity.
  • The gap is narrowed, not closed. The best adapted model (Moirai FT-fault, r = 9.74) is still ~9× less robust than a plain trained LSTM (r = 1.07). The accurate-and-robust quadrant remains empty.

5 · Worst-case risk — average behavior can hide adverse configurations

Average risk (AVG) describes typical behavior over the released fault grid; worst-case risk (WC) asks for the most damaging released configuration:

$$ \mathrm{WC}(f,\mathcal F)=\sup_{\Theta\in\Phi}\mathbb E[\ell\mid\Theta]. $$

We report two complementary quantities:

  • WC MSE — the maximum per-configuration faulted MSE over the released grid, directly discretising Eq. (3).
  • WC r — within each dataset, the maximum configuration-level robustness ratio, then averaged across the datasets. This uses the same within-dataset-then-average convention as AVG r, so the two columns are directly comparable.

Worst-case risk over all four modes. WC/AVG is the ratio between the worst-case and average robustness risks.

ModelClean MSEAVG MSEWC MSEAVG rWC rWC/AVGWC attained at
Naive1.2381291,3771066446.1×Electricity / III / d10
SeasonalNaive0.9051191,2701661,1216.8×Electricity / III / d10
ARIMA0.9991221,0691216955.8×ETTh1 / III / d10
ETS1.0441271,3521237546.1×Electricity / III / d10
DLinear0.56266.86751971,3747.0×Electricity / III / d10
NLinear0.54072.26441428265.8×ETTh1 / III / d10
N-BEATS0.44921.656454.63686.7×Electricity / III / d10
LSTM0.7330.781.041.071.251.2×ETTh1 / III / d10
GRU0.6800.771.191.141.501.3×ETTh1 / IV / d10
TCN0.8747.391387.8961.47.8×Electricity / III / d08
Autoformer0.82224.226448.03216.7×Electricity / III / d10
FEDformer1.07224.325822.61356.0×Electricity / III / d10
PatchTST0.55186.69192631,8637.1×Electricity / III / d10
iTransformer0.52983.29052722,0087.4×Electricity / III / d10
TimeXer0.53788.01,0853012,1707.2×Electricity / III / d10
TimeMixer0.59090.18892641,8597.0×Electricity / III / d10
TimesNet0.57153.35001429646.8×Electricity / III / d10
NS Transformer0.60855.25711016356.3×Electricity / III / d10
TimesFM0.5161631,7465554,0737.3×Electricity / III / d10
Chronos0.6131661,7575133,7457.3×Electricity / III / d10
Moirai0.6821531,5303662,5447.0×Electricity / III / d10

Per-mode worst-case risk. Each cell reports WC r / WC MSE.

ModelMode IMode IIMode IIIMode IV
Naive1.04 / 2.071.00 / 2.01644 / 1,377285 / 508
SeasonalNaive1.46 / 2.361.17 / 2.231,121 / 1,270303 / 455
ARIMA1.10 / 1.601.02 / 1.47695 / 1,069376 / 509
ETS1.06 / 1.701.00 / 1.63754 / 1,352327 / 499
DLinear1.49 / 0.981.06 / 0.931,374 / 675281 / 309
NLinear1.47 / 1.001.24 / 1.00826 / 644390 / 364
N-BEATS1.20 / 1.901.05 / 1.45361 / 564127 / 68.2
LSTM1.00 / 0.911.00 / 0.911.23 / 1.041.17 / 1.01
GRU1.01 / 0.881.00 / 0.871.41 / 1.131.40 / 1.19
TCN1.00 / 1.051.01 / 1.0860.8 / 13816.9 / 67.4
Autoformer1.26 / 1.231.14 / 1.21321 / 26457.2 / 104
FEDformer1.07 / 1.511.05 / 1.44135 / 25850.8 / 106
PatchTST1.52 / 1.291.24 / 1.021,863 / 919372 / 349
iTransformer1.58 / 1.011.12 / 0.902,008 / 905403 / 341
TimeXer1.45 / 1.041.08 / 0.962,170 / 1,085380 / 325
TimeMixer1.44 / 1.011.07 / 0.951,859 / 889371 / 383
TimesNet1.64 / 1.061.14 / 1.11964 / 500231 / 247
NS Transformer1.62 / 1.121.61 / 1.79627 / 571286 / 304
TimesFM1.33 / 0.981.08 / 1.064,073 / 1,746561 / 575
Chronos1.25 / 1.031.03 / 0.953,745 / 1,757588 / 589
Moirai1.19 / 1.211.03 / 1.182,544 / 1,530464 / 556

Three conclusions follow:

  • WC is not a restatement of AVG. The WC/AVG gap is only 1.2–1.3× for LSTM/GRU but roughly 7× for the attention and foundation-model cluster. Typical degradation therefore does not bound adverse degradation.
  • The worst configurations are mechanism-level. Twenty of the 21 models attain their overall WC in Mode III and GRU attains it in Mode IV. Twenty peak at d10; TCN is the sole exception, peaking at d08.
  • Observation-level faults remain bounded. No model exceeds WC r = 1.64 in Modes I/II, whereas 19 of 21 exceed WC r = 10 in both Modes III and IV. LSTM and GRU are the only exceptions.

🔁 Reproducibility

TS-Fault is designed to be fully reproducible. Because faulted instances are produced by an explicit operator at evaluation time, the benchmark can be regenerated at any severity by re-sweeping κ, and previously-unexposed Θ combinations can be held out at release time to guard against benchmark gaming. We release:

  • the parameterized fault generators for all four modes, with their Θ schemas and the unified window-importance front-end — plus compose_faults.py for the compound-fault operator TΘ_B ∘ TΘ_A;
  • the exact λ and β values used by S(W) and κ in every mode, with the placement and weight ablations that probe them (ablation_placement.py, ablation_lambda.py);
  • the evaluation harness with per-model configurations, and adapt_foundation.py for the LP / FT / FT-fault adaptation protocol;

📜 License & acknowledgements

TS-Fault code is released under the MIT licence. Some baseline implementations are adapted from external sources and retain their own licences: TCN from locuslab/TCN (MIT), NLinear/DLinear from cure-lab/LTSF-Linear (Apache-2.0), and N-BEATS from ServiceNow/N-BEATS (CC-BY-NC-4.0, non-commercial). The eight Transformer baselines come from the Time-Series-Library. Datasets (ETT, Electricity, Weather) are released by their original authors under CC BY 4.0 and are not redistributed here.


No model occupies the accurate-and-robust regime. That empty quadrant is the open problem TS-Fault is built to drive progress on.

Ray-zyy/TS-Fault

[ICDE-2027] TS-Fault: Benchmarking Time Series Forecasters against Structural Faults

Python

10

55 commits

updated Sep 23, 2026

See the code

README

⚡ TS-Fault

Benchmarking Time Series Forecasters Against Structural Faults

Yuyang Zhao¹ · Lian Xu² · Hao Miao³ · Chenxi Liu⁴ · Hao Xue¹ ✉

¹ Hong Kong University of Science and Technology (Guangzhou)  ·  ² The University of Western Australia  ·  ³ The Hong Kong Polytechnic University  ·  ⁴ CAIR, Hong Kong Institute of Science & Innovation, Chinese Academy of Sciences

21 models  ·  9 datasets / 6 domains  ·  4 failure modes  ·  5 severity levels  ·  ~3,800 evaluated cells

Why  •  Failure modes  •  Repository  •  Datasets  •  Quick start  •  Results  •  Extended experiments  •  Reproducibility  • 

TL;DR — Clean-data leaderboards do not predict robustness. TS-Fault stops treating faults as i.i.d. noise. It injects four structurally-coupled failure modes — abstracted from the anatomy of real grid-scale failures — into the input window of nine standard forecasting datasets across six domains, then measures how far each model degrades. Under the two mechanism-level modes, the ranking is reordered: state-of-the-art Transformers and foundation models collapse, while a plain LSTM/GRU — or even a naïve baseline — becomes the most robust.

The TS-Fault pipeline
The TS-Fault pipeline. A clean pair (X, Y) is turned into a structured instance: a window-importance score selects the prediction-critical window W★, a parameterized fault operator TΘ acts there at a chosen severity, and the scenario parameters Θ and difficulty δ are reported with the instance and used to condition evaluation.

📌 Why TS-Fault?

For two decades, long-horizon forecasting progress has been measured by one number — average error on clean, complete, evenly-sampled held-out data — under the implicit assumption that it predicts deployed reliability. Real faults are not white noise. They are structured events: a transient with onset–peak–decay, a silently broken cross-variable dependency, a regime change coupled with block-missingness, a fault cascading through a sensing pipeline. None of these can be expressed by i.i.d. perturbations, no matter how the variance or masking rate is tuned.

TS-Fault changes the object of evaluation, replacing the clean test pair (X, Y) with a structured instance (X̃, Ỹ, Θ, δ) produced by an explicit, parameterized fault operator. Because Θ is exposed, a model's degradation can be attributed to a named mechanism at a tunable severity — turning a pass/fail noise test into an ablation-style diagnostic tool.

Headline findings

1 · Clean accuracy anti-correlates with robustness Spearman ρ = −0.544 (p = 0.011) across all 21 models — and −0.509 over the 18 non-foundation models, so foundation models strengthen the effect.

2 · Stratified by mode Observation-level faults preserve the ranking (ρ > 0.92); mechanism-level faults destroy it (ρ < 0.06).

3 · Catastrophe is structural All 884 catastrophic failures (≥ 10× error inflation) fall in the two mechanism-level modes; Modes I/II never trigger one.

4 · Strong, but fragile TimesFM is 2nd on clean MSE yet the worst of all 21 on robustness (ratio ≈ 555).


🧩 The four failure modes

Each mode corrupts only the lookback window (L = 336); the forecast target (H = 96) is never touched, so degradation isolates the cost of a corrupted history. A single difficulty scalar d ∈ {0.2, 0.4, 0.6, 0.8, 1.0} (written d02 … d10) sweeps severity monotonically. The modes span a 2 × 2 taxonomy — observation- vs. mechanism-level × univariate vs. multivariate — and form a constructive minimum: omitting any one renders an entire class of deployment failure invisible.

The 2x2 fault taxonomy
FileModeTaxonomy cellWhat breaksReal-world analogue
Mode1.pyI · Time-Warped ShockObservation × Univariatea shaped transient (onset–peak–decay) + a local time-warpdemand spike / brief sensor glitch
Mode2.pyII · Dependency-Fracture ShockObservation × Multivariatecross-channel lead–lag and gain silently falsified; each series alone still looks plausibleregions that usually co-move decouple
Mode3.pyIII · Regime-Transition MissingnessMechanism × Univariatea regime switch + state-dependent block-missingness around the transition (hardest mode)grid emergency / firm load shed
Mode4.pyIV · Cascading Sensor-to-System FailureMechanism × Multivariatean upstream drift propagates downstream with a lag, inducing secondary dropoutsa fault cascading through coupled subsystems

Observation-level (I, II) corrupt observations while the data-generating process stays intact → mild. Mechanism-level (III, IV) rewrite the process itself → severe, and account for 100% of catastrophic failures.


📂 Repository contents

This repository ships the data-generation pipeline, model implementations, evaluation drivers, trained checkpoints, and the complete results workbook. The four fault generators are included in full, so the perturbed dataset can be regenerated from scratch.

.
├── README.md
├── requirements.txt
│
├── benchmark.py                 # benchmark orchestration helpers
├── dataset_loader.py            # load + normalise the clean CSVs into windows
├── window_selector.py           # select the anchor lookback / horizon windows
│
├── Mode1.py                     # Fault Mode I   — Time-Warped Shock
├── Mode2.py                     # Fault Mode II  — Dependency-Fracture Shock
├── Mode3.py                     # Fault Mode III — Regime-Transition Missingness
├── Mode4.py                     # Fault Mode IV  — Cascading Sensor-to-System Failure
├── run_TS-Fault.py              # ▶ MAIN entry point: build the perturbed benchmark
│
├── classical_models.py          # statistical / linear / recurrent / conv. forecasters
├── foundation_models.py         # TimesFM / Chronos / Moirai (zero-shot wrappers)
├── eval_classical_phase1.py     # evaluate classical + baseline models → results CSV
├── eval_foundation_phase1.py    # evaluate foundation models → results CSV
├── checkpoints/                 # released trained weights
├── ablation_placement.py        # window-placement ablation: top-K S(W) vs random vs anti-selected
├── ablation_lambda.py           # one-at-a-time sensitivity of the S(W) weights λ
├── adapt_foundation.py          # LP / FT / FT-fault adaptation of the three foundation models
├── compose_faults.py            # ⊛ compound faults: T_B ∘ T_A at matched severity
└── figures/                     # paper figures used in this README

The 21 evaluated forecasters

The paper evaluates 21 models across six methodological families, so the conclusions are not an artifact of a single inductive bias:

FamilyModels
Statistical (4)Naive · SeasonalNaive · ARIMA · ETS
Linear / lightweight (3)DLinear · NLinear · N-BEATS
Recurrent / convolutional (3)LSTM · GRU · TCN
Decomposition Transformer (2)Autoformer · FEDformer
Attention / SOTA (6)PatchTST · iTransformer · TimeXer · TimeMixer · TimesNet · Nonstationary-Transformer
Foundation, zero-shot (3)TimesFM · Chronos · Moirai

Statistical, linear, and recurrent/convolutional models live in classical_models.py; the eight Transformer-family models are trained via the Time-Series-Library (see § Transformer-family); the three foundation models run strictly zero-shot via foundation_models.py. The repository's classical_models.py additionally bundles a few exploratory baselines (e.g. RandomForest, XGBoost) that fall outside the 21-model paper subset.


📊 Datasets (clean originals)

TS-Fault perturbs nine long-horizon datasets spanning six domains — energy, load, climate, finance, IT/Ops, and healthcare — deliberately chosen to cover a wide range of dimensionality (7 → 321 channels) and granularity (5-second → daily). Every clean window is a length-336 history and a length-96 target. We do not redistribute the raw data — download it and place each file at the path the loader expects.

DatasetDomainChannelsGranularitySizePath expected
ETTh1 / ETTh2Energy7hourly17,420dataset/ETT-small/ETTh1.csv, …/ETTh2.csv
ETTm1 / ETTm2Energy715-min69,680dataset/ETT-small/ETTm1.csv, …/ETTm2.csv
Electricity (ECL)Load321hourly26,304dataset/electricity/electricity.csv
WeatherClimate2110-min52,696dataset/weather/weather.csv
Exchange-RateFinance8daily7,588dataset/exchange_rate/exchange_rate.csv
BizITObs-Service-KPIIT / Ops7210-sec8,835dataset/bizitobs/service_kpi.csv
VitalDB-CoreHealthcare85-sec962 casesdataset/vitaldb/vitaldb_core.csv
Download links (canonical)

The first seven, one bundle (recommended) — official Time-Series-Library mirror on HuggingFace (CC BY 4.0): https://huggingface.co/datasets/thuml/Time-Series-Library

from huggingface_hub import hf_hub_download
for f in ["ETT-small/ETTh1.csv", "ETT-small/ETTh2.csv",
          "ETT-small/ETTm1.csv", "ETT-small/ETTm2.csv",
          "electricity/electricity.csv", "weather/weather.csv",
          "exchange_rate/exchange_rate.csv"]:
    hf_hub_download("thuml/Time-Series-Library", f, repo_type="dataset")

🚀 Quick start

1 · Install

git clone https://github.com/Ray-zyy/TS-Fault.git
cd TS-Fault
pip install -r requirements.txt

2 · Get the clean datasets

Download the nine CSVs (see § Datasets) into:

dataset/ETT-small/{ETTh1,ETTh2,ETTm1,ETTm2}.csv
dataset/electricity/electricity.csv
dataset/weather/weather.csv
dataset/exchange_rate/exchange_rate.csv
dataset/bizitobs/service_kpi.csv
dataset/vitaldb/vitaldb_core.csv  

3 · Generate the perturbed benchmark

run_TS-Fault.py slides the anchor windows (window_selector.py), loads & normalises the clean series (dataset_loader.py), and applies each of the four fault modes (Mode1.py … Mode4.py) across all five difficulties:

python run_TS-Fault.py \
    --data_root ./dataset \
    --out ./TS-Fault_output \
    --n_windows 20

This writes one .npz per (dataset, Mode, difficulty) to TS-Fault_output/<Dataset>/<Dataset>_Mode<k>_d<dd>.npz — 9 datasets × 4 modes × 5 difficulties = 180 files, each containing:

arrayshapemeaning
x_clean(N, 336, C)clean lookback windows
x_corrupt(N, 336, C)perturbed lookback windows
y_target(N, 96, C)forecast target (never perturbed)

4 · Evaluate

Classical / baseline models (deep ones train once per dataset on clean windows; statistical ones need no training):

python eval_classical_phase1.py \
    --models Naive SeasonalNaive ARIMA ETS \
             DLinear NLinear NBEATS \
             LSTM GRU TCN \
    --npz_root ./TS-Fault_output \
    --out ./results/eval_classical.csv --gpu 0 --resume

Foundation models (zero-shot — see § Foundation models):

python eval_foundation_phase1.py \
    --models timesfm chronos moirai \
    --npz_root ./TS-Fault_output \
    --out ./results/eval_foundation.csv --gpu 0 --resume

Each evaluator emits the canonical wide schema, one row per (model, dataset, Mode, difficulty):

model, dataset, Mode, difficulty, mse_corrupt, mae_corrupt, mse_clean, mae_clean, n_samples, time_sec

mse_clean is the error on the clean input window, mse_corrupt on the perturbed window — both predicting the same untouched target. The robustness ratio r = mse_corrupt / mse_clean isolates the cost of corrupted history; r = 1 is perfect robustness and r ≥ 10 is a catastrophic failure. Concatenate the per-group CSVs (classical + foundation + the TSLib Transformer rows) into the master workbook eval_results_full.xlsx (also mirrored as the flat eval_results_full_23.csv).


🧪 Evaluating the Transformer-family models

The eight Transformer/attention models (PatchTST, iTransformer, Autoformer, FEDformer, Nonstationary-Transformer, TimeMixer, TimeXer, TimesNet) are trained and run with the Time-Series-Library (TSLib).

  1. Clone TSLib and place the same nine clean CSVs under its ./dataset/.

  2. Train / evaluate each model with run.py under the TS-Fault protocol (seq_len=336, pred_len=96, features=M, MSE loss). Example:

    python -u run.py \
        --task_name long_term_forecast --is_training 1 \
        --root_path ./dataset/ETT-small/ --data_path ETTh1.csv \
        --model_id ETTh1_336_96 --model PatchTST --data ETTh1 \
        --features M --seq_len 336 --label_len 48 --pred_len 96 \
        --e_layers 2 --d_layers 1 --enc_in 7 --dec_in 7 --c_out 7 \
        --train_epochs 10 --batch_size 32 --learning_rate 1e-4 --itr 1
    
  3. Score each trained checkpoint on the TS-Fault .npz windows (clean vs. corrupt) and write rows in the same wide schema, then merge into the master workbook eval_results_full.xlsx.

Shared hyperparameters & model-specific notes

Shared across all models: seq_len=336, label_len=48, pred_len=96, e_layers=2, d_layers=1, d_model=128–512, train_epochs=10, batch_size=32 (16 for Electricity), MSE loss, instance/RevIN normalisation.

  • TimeMixer — --down_sampling_layers 3 --down_sampling_window 2 --down_sampling_method avg --channel_independence 1
  • Nonstationary-Transformer — --p_hidden_dims 128 128 --p_hidden_layers 2
  • DLinear — --individual is a store-true flag
  • Reduce d_model / batch_size for TimesNet / FEDformer / Autoformer on 11 GB GPUs.

🧱 Installing the foundation models

These libraries pull heavy / conflicting dependencies. The recipe that works (verified on CUDA 12.1, torch 2.5.1):

# TimesFM + Chronos are clean pip installs
pip install timesfm chronos-forecasting

# Moirai (uni2ts) pins torch<2.5 and WILL try to downgrade torch.
# Install WITHOUT deps so it cannot touch torch, then hand-add what it needs:
git clone https://github.com/SalesforceAIResearch/uni2ts.git
cd uni2ts && pip install -e . --no-deps && touch .env
pip install "gluonts==0.14.4" "einops==0.7.0" jaxtyping --no-deps

Behind a mirror, set export HF_ENDPOINT=https://hf-mirror.com before the first run. All three run zero-shot (no fine-tuning) and are wrapped channel-independently for multivariate inputs.


🏆 Results

The complete results workbook

Every number in this README — and a great many that did not fit — is shipped in eval_results_full.xlsx, the full evaluation table. It holds one row per (model, dataset, mode, difficulty) cell for the entire grid of 21 models × 9 datasets × 4 modes × 5 severities ≈ 3,800 rows (ARIMA is omitted on the 321-channel Electricity, where per-series fitting is impractical), under the same wide schema produced by the evaluators:

model · dataset · Mode · difficulty · mse_corrupt · mae_corrupt · mse_clean · mae_clean · n_samples · time_sec

From these columns the robustness ratio r = mse_corrupt / mse_clean, the relative degradation (r − 1) × 100%, the severity slope d10/d02, and every per-mode / per-dataset aggregate in the paper can be recomputed directly — no rerun required. A flat-CSV mirror is provided as eval_results_full_23.csv.

Aggregate — the clean and faulted leaderboards are near mirror images

The most robust models (GRU, LSTM, TCN, near-unit ratios) are only mid-pack on clean accuracy, while the clean-accuracy leaders (N-BEATS, TimesFM, iTransformer, TimeXer) sit at the bottom of the robustness order with ratios in the hundreds.

Aggregate results: robustness ratio, severity sweep, per-mode breakdown
Left: clean/faulted MSE-MAE and robustness ratio. Center: degradation across severities d02→d10 and the d10/d02 sensitivity slope. Right: per-mode relative degradation — note the jump from single-digit % under Modes I/II to thousands–to–tens-of-thousands % under Modes III/IV.

Rank reordering — preserved under observation-level faults, destroyed under mechanism-level

ModeSpearman ρ (clean vs. faulted rank)pVerdict
I · Time-Warped Shock+0.925< 0.001ranking preserved
II · Dependency Fracture+0.952< 0.001ranking preserved
III · Regime Missingness+0.0320.889ranking destroyed
IV · Cascading Failure+0.0550.814ranking destroyed

Per-dataset — fragility is structural; dimensionality sets the amplitude

The model ordering is highly consistent across datasets (fragility is a property of the architecture), but dense cross-channel correlation amplifies it: on the 321-channel Electricity, TimesFM's ratio peaks at 2090 and TimeXer at 1112, while GRU/LSTM stay near 1.2 everywhere.

Per-dataset corrupted MSE and robustness ratios across six datasets
Per-dataset corrupted MSE and robustness ratios across six datasets
MSE on corrupted inputs per dataset
MSE on corrupted inputs per dataset

MSE on corrupted inputs per dataset (lower is better). Recurrent models (LSTM, GRU) sit at the bottom of every panel; foundation models (gold) sit at the top.

Catastrophic failures (r ≥ 10): 884 total — 0 in Mode I, 0 in Mode II, 537 in Mode III (85.9% of its cells), 347 in Mode IV (55.5%). Mechanism-level modes account for 100% of them.

Three new domains — finance, IT/Ops, healthcare

The added datasets were chosen to break the energy/climate monoculture of the original release, not to make the benchmark easier. They do not change the verdict.

Model6-dataset rExchange-RateBizITObsVitalDB
Naive105.7199.2196.1474.5
SeasonalNaive165.5266.4197.8435.9
ARIMA120.7239.1212.9521.6
ETS122.9254.1209.4523.1
DLinear197.3197.3180.3271.9
NLinear142.1251.9226.2399.7
N-BEATS54.6110.4217.9408.7
LSTM1.071.081.121.20
GRU1.141.171.271.44
TCN7.8919.37.4515.6
Autoformer48.043.544.486.2
FEDformer22.643.739.999.9
PatchTST262.6204.6304.7412.8
iTransformer272.3212.9239.5285.9
TimeXer301.2235.7253.8328.0
TimeMixer264.2196.5255.0331.2
TimesNet141.786.6207.5260.3
Nonstationary-Transformer101.1118.0168.2219.9
TimesFM (FM)555.2430.81,038.81,902.8
Chronos (FM)512.5452.0519.4787.6
Moirai (FM)365.6425.9476.5841.8

Which mechanism dominates depends on the domain — and it depends on it in the direction the taxonomy predicts.

Dataset#Ch.Mode IMode IIMode IIIMode IVIV / III
ETT (mean of four)71.0751.047361.1135.40.375
Weather211.0831.001124.614.80.119
Electricity3211.3641.0052,229.421.20.009
Exchange-Rate81.121.07680800.118
BizITObs-Service-KPI721.181.038351150.138
VitalDB-Core81.261.021,4901450.097

(mean r over the 21 models, averaged across the five severities)


🧪 Extended experiments

Four follow-up studies run on top of the same released grid. Each has its own driver script and its own results CSV, so every number below can be recomputed without touching the main pipeline.

1 · Compound faults — do co-occurring failures interact?

Real incidents rarely arrive one at a time. Because the four modes are operators, they compose: TΘ = TΘ_B ∘ TΘ_A (Eq. 19). Both operators act on the same critical window W★, each keeps its own Θ, and at every severity the two constituents are matched at the same nominal difficulty, κ_A(Θ_A) = κ_B(Θ_B) = δ_s. One fixed application order per pair — composition is not commutative, so the order is itself a scenario parameter.

python compose_faults.py \
    --pairs I+II I+III I+IV II+III II+IV III+IV \
    --npz_root ./TS-Fault_output --out ./results_compound.csv

The amplification factor Ψ(A∘B) = r(A∘B) / max(r_A, r_B) asks whether a compound fault is worse than its more damaging half.

CompositionMean rΨ
single-mode reference: Mode I1.12—
single-mode reference: Mode II1.03—
single-mode reference: Mode III618.1—
single-mode reference: Mode IV97.1—
I ∘ II1.241.11
II ∘ IV103.81.07
I ∘ IV118.71.22
II ∘ III763.41.24
I ∘ III1,047.61.69
III ∘ IV2,183.73.53
  • No pair cancels. All six satisfy Ψ ≥ 1.07 — a compound fault is never easier than its worse half.
  • Mechanism × mechanism is superadditive. III ∘ IV reaches Ψ = 3.53: a regime switch that a cascade then propagates is more than three times worse than either alone.
  • Two observation-level faults do not add up to a mechanism-level one. I ∘ II tops out at r = 1.24. The stratification of Finding 2 survives composition — it is not an artifact of testing one mode at a time.

2 · Where the fault is placed — is S(W) doing any work?

S(W) is the claim that a benchmark should stress the window a model relies on. If placement did not matter, TS-Fault would be a noise test with extra steps. We compare three placement policies at severity s₃ (d06), over 9 datasets × 21 models × 5 seeds, with random placement δ-matched so only the location differs:

python ablation_placement.py --policy topk random anti --severity d06 --seeds 5 \
    --out ./results_placement.csv
ModePlacementMedian RD (%)Mean rCatastrophic cells (%)Seed IQR / medianρ(clean, faulted)
IAnti-selected0.431.0090.01.37+0.999
IRandom1.471.0350.01.18+0.996
ITop-K S(W)5.111.1100.00.27+0.983
IIAnti-selected0.0121.0010.01.63+1.000
IIRandom0.0341.0040.01.46+0.999
IITop-K S(W)0.111.0100.00.34+0.999
IIIAnti-selected9,872216.462.71.08+0.286
IIIRandom (δ-matched)18,436398.775.40.84+0.147
IIITop-K S(W)26,232560.988.80.31+0.023
IVAnti-selected68413.738.11.21+0.374
IVRandom (δ-matched)1,53629.458.70.91+0.218
IVTop-K S(W)2,87852.772.80.29+0.082

Anti-selected < Random < Top-K in every mode, on both metrics. Two consequences beyond "the score works": importance-based placement cuts seed-to-seed variability by 3–4× (the IQR/median column), so a given robustness number means something; and as placement is weakened the faulted ranking drifts back toward the clean ranking (Mode III ρ: 0.023 → 0.147 → 0.286). Random placement would have partially hidden the model-selection risk that motivates the benchmark.

3 · Sensitivity to the S(W) weights

The per-mode weights and window hyperparameters, in full:

Modeλ₁ (S_cp)λ₂ (S_per)λ₃ (S_var)λ₄ (S_pred)top-K|W|σ_p
I · Time-Warped Shock0.150.150.350.355240.15P
II · Dependency Fracture0.150.200.250.405240.15P
III · Regime Missingness0.400.250.150.205240.15P
IV · Sensor-to-System Cascade0.200.150.300.355240.15P

One-at-a-time perturbation at severity s₃ (ablation_lambda.py):

ModePerturbationΔ median RDρ vs. default ranking
Iλ₃ × 0.5−18.7%0.958
Iλ₃ × 2+12.6%0.964
Iλ₄ → 0−43.8%0.890
Iλ₁ → 0+1.9%0.982
IIλ₄ → 0−51.4%0.871
IIλ₂ × 2−3.7%0.969
IIIλ₁ × 0.5−29.6%0.934
IIIλ₁ → 0−54.2%0.877
IIIλ₃ × 2+6.8%0.969
IVλ₄ → 0−41.9%0.884
IVλ₂ → 0−2.3%0.979

The weight each mode is designed around is the one that matters: zeroing λ₄ (occlusion) costs 42–51% of the degradation in Modes I/II/IV, and zeroing λ₁ (change-point) costs 54% in Mode III. Removing a weight the mode does not emphasise moves the result by at most 2.3%. Crucially, the model ranking is stable throughout (ρ ≥ 0.871): the weights control how hard the benchmark is, not who wins.

4 · Can adaptation fix the foundation models?

The zero-shot fragility result invites the obvious question. We adapted all three foundation models under four settings and re-ran the full grid:

SettingWhat is trainedEvaluated on
ZSnothing — released weightsfull grid
LPforecasting head only, clean datafull grid
FTall parameters, clean datafull grid
FT-faultall parameters, low-severity faulted data (s₁–s₂)held-out severities s₃–s₅
python adapt_foundation.py --model timesfm --setting ft_fault \
    --train_severities d02 d04 --eval_severities d06 d08 d10 \
    --out ./results_foundation_adapt.csv
ModelSettingClean MSEFaulted MSEΔMSEAVG rMode III rMode IV rWC r
TimesFMZS0.516162.7162.25552,0132054,073
TimesFMLP0.468108.7108.2344.51,248128.02,687
TimesFMFT0.37858.357.9182.665474.21,426
TimesFMFT-fault0.4126.786.3712.238.78.2476.5
ChronosZS0.613165.6165.05131,8392093,745
ChronosLP0.548119.4118.9339.51,217139.02,468
ChronosFT0.43764.864.4188.167278.51,384
ChronosFT-fault0.4798.367.8814.346.29.1391.7
MoiraiZS0.682153.1152.43661,2961642,544
MoiraiLP0.59689.789.1214.476887.61,538
MoiraiFT0.46243.643.1109.939245.4814
MoiraiFT-fault0.5075.925.419.7430.86.1755.4
(reference) LSTMtrained0.7330.7800.0471.071.171.101.25
  • Clean-data adaptation buys accuracy, not robustness. LP improves TimesFM's ratio only 1.6× (555 → 344.5). Full fine-tuning cuts absolute faulted error 2.6–3.5× yet leaves ratios at 110–188 — still two orders of magnitude from an LSTM.
  • Only fault structure in the training signal closes the gap. FT-fault drops the ratios to 12.2 / 14.3 / 9.74 and faulted MSE by a further 7.4–8.6× over clean fine-tuning, at a clean-accuracy cost of just 9–10%. Note this is measured on held-out severities — the models never saw s₃–s₅ during adaptation, so this is generalisation along κ, not memorisation of a severity.
  • The gap is narrowed, not closed. The best adapted model (Moirai FT-fault, r = 9.74) is still ~9× less robust than a plain trained LSTM (r = 1.07). The accurate-and-robust quadrant remains empty.

5 · Worst-case risk — average behavior can hide adverse configurations

Average risk (AVG) describes typical behavior over the released fault grid; worst-case risk (WC) asks for the most damaging released configuration:

$$ \mathrm{WC}(f,\mathcal F)=\sup_{\Theta\in\Phi}\mathbb E[\ell\mid\Theta]. $$

We report two complementary quantities:

  • WC MSE — the maximum per-configuration faulted MSE over the released grid, directly discretising Eq. (3).
  • WC r — within each dataset, the maximum configuration-level robustness ratio, then averaged across the datasets. This uses the same within-dataset-then-average convention as AVG r, so the two columns are directly comparable.

Worst-case risk over all four modes. WC/AVG is the ratio between the worst-case and average robustness risks.

ModelClean MSEAVG MSEWC MSEAVG rWC rWC/AVGWC attained at
Naive1.2381291,3771066446.1×Electricity / III / d10
SeasonalNaive0.9051191,2701661,1216.8×Electricity / III / d10
ARIMA0.9991221,0691216955.8×ETTh1 / III / d10
ETS1.0441271,3521237546.1×Electricity / III / d10
DLinear0.56266.86751971,3747.0×Electricity / III / d10
NLinear0.54072.26441428265.8×ETTh1 / III / d10
N-BEATS0.44921.656454.63686.7×Electricity / III / d10
LSTM0.7330.781.041.071.251.2×ETTh1 / III / d10
GRU0.6800.771.191.141.501.3×ETTh1 / IV / d10
TCN0.8747.391387.8961.47.8×Electricity / III / d08
Autoformer0.82224.226448.03216.7×Electricity / III / d10
FEDformer1.07224.325822.61356.0×Electricity / III / d10
PatchTST0.55186.69192631,8637.1×Electricity / III / d10
iTransformer0.52983.29052722,0087.4×Electricity / III / d10
TimeXer0.53788.01,0853012,1707.2×Electricity / III / d10
TimeMixer0.59090.18892641,8597.0×Electricity / III / d10
TimesNet0.57153.35001429646.8×Electricity / III / d10
NS Transformer0.60855.25711016356.3×Electricity / III / d10
TimesFM0.5161631,7465554,0737.3×Electricity / III / d10
Chronos0.6131661,7575133,7457.3×Electricity / III / d10
Moirai0.6821531,5303662,5447.0×Electricity / III / d10

Per-mode worst-case risk. Each cell reports WC r / WC MSE.

ModelMode IMode IIMode IIIMode IV
Naive1.04 / 2.071.00 / 2.01644 / 1,377285 / 508
SeasonalNaive1.46 / 2.361.17 / 2.231,121 / 1,270303 / 455
ARIMA1.10 / 1.601.02 / 1.47695 / 1,069376 / 509
ETS1.06 / 1.701.00 / 1.63754 / 1,352327 / 499
DLinear1.49 / 0.981.06 / 0.931,374 / 675281 / 309
NLinear1.47 / 1.001.24 / 1.00826 / 644390 / 364
N-BEATS1.20 / 1.901.05 / 1.45361 / 564127 / 68.2
LSTM1.00 / 0.911.00 / 0.911.23 / 1.041.17 / 1.01
GRU1.01 / 0.881.00 / 0.871.41 / 1.131.40 / 1.19
TCN1.00 / 1.051.01 / 1.0860.8 / 13816.9 / 67.4
Autoformer1.26 / 1.231.14 / 1.21321 / 26457.2 / 104
FEDformer1.07 / 1.511.05 / 1.44135 / 25850.8 / 106
PatchTST1.52 / 1.291.24 / 1.021,863 / 919372 / 349
iTransformer1.58 / 1.011.12 / 0.902,008 / 905403 / 341
TimeXer1.45 / 1.041.08 / 0.962,170 / 1,085380 / 325
TimeMixer1.44 / 1.011.07 / 0.951,859 / 889371 / 383
TimesNet1.64 / 1.061.14 / 1.11964 / 500231 / 247
NS Transformer1.62 / 1.121.61 / 1.79627 / 571286 / 304
TimesFM1.33 / 0.981.08 / 1.064,073 / 1,746561 / 575
Chronos1.25 / 1.031.03 / 0.953,745 / 1,757588 / 589
Moirai1.19 / 1.211.03 / 1.182,544 / 1,530464 / 556

Three conclusions follow:

  • WC is not a restatement of AVG. The WC/AVG gap is only 1.2–1.3× for LSTM/GRU but roughly 7× for the attention and foundation-model cluster. Typical degradation therefore does not bound adverse degradation.
  • The worst configurations are mechanism-level. Twenty of the 21 models attain their overall WC in Mode III and GRU attains it in Mode IV. Twenty peak at d10; TCN is the sole exception, peaking at d08.
  • Observation-level faults remain bounded. No model exceeds WC r = 1.64 in Modes I/II, whereas 19 of 21 exceed WC r = 10 in both Modes III and IV. LSTM and GRU are the only exceptions.

🔁 Reproducibility

TS-Fault is designed to be fully reproducible. Because faulted instances are produced by an explicit operator at evaluation time, the benchmark can be regenerated at any severity by re-sweeping κ, and previously-unexposed Θ combinations can be held out at release time to guard against benchmark gaming. We release:

  • the parameterized fault generators for all four modes, with their Θ schemas and the unified window-importance front-end — plus compose_faults.py for the compound-fault operator TΘ_B ∘ TΘ_A;
  • the exact λ and β values used by S(W) and κ in every mode, with the placement and weight ablations that probe them (ablation_placement.py, ablation_lambda.py);
  • the evaluation harness with per-model configurations, and adapt_foundation.py for the LP / FT / FT-fault adaptation protocol;

📜 License & acknowledgements

TS-Fault code is released under the MIT licence. Some baseline implementations are adapted from external sources and retain their own licences: TCN from locuslab/TCN (MIT), NLinear/DLinear from cure-lab/LTSF-Linear (Apache-2.0), and N-BEATS from ServiceNow/N-BEATS (CC-BY-NC-4.0, non-commercial). The eight Transformer baselines come from the Time-Series-Library. Datasets (ETT, Electricity, Weather) are released by their original authors under CC BY 4.0 and are not redistributed here.


No model occupies the accurate-and-robust regime. That empty quadrant is the open problem TS-Fault is built to drive progress on.