Skip to content

Python 3.12 support#9

Open
marcpinet wants to merge 11 commits into
decisionintelligence:mainfrom
marcpinet:python312-support
Open

Python 3.12 support#9
marcpinet wants to merge 11 commits into
decisionintelligence:mainfrom
marcpinet:python312-support

Conversation

@marcpinet

@marcpinet marcpinet commented Jul 21, 2026

Copy link
Copy Markdown

Motivation

Python 3.8 reached end of life in October 2024, but the project cannot run on anything newer because the TODS baselines depend on the abandoned d3m ecosystem. This PR makes the benchmark run on Python 3.12 in a plain venv, with all baseline families working.

Changes

Dependencies

  • Updated old pins (numpy, numba, stumpy, ...) to versions compatible with Python 3.12.
  • Added missing packages used by CATCH, DUET and ContraAD (einops, accelerate), plus pyod and salesforce-merlion.
  • Pinned transformers<4.50: the LLM baselines copy GPT-2 code that uses APIs removed in transformers 5.
  • The old d3m pins moved to requirements-optional.txt (Python 3.8 only, for reproducing old results).
  • README updated.

TODS: d3m replaced with pyod

The benchmarked TODS models were thin wrappers around pyod. They now call pyod directly:

  • same model names and outputs, so existing configs and scripts keep working;
  • the defaults of the d3m primitives are set explicitly, since some differ from current pyod defaults (HBOS tol, COF n_neighbors, windowed PCA whiten/n_components);
  • old AutoEncoder argument names (epochs, hidden_neurons, ...) are mapped to the new pyod API instead of raising TypeError;
  • the TODS sliding-window PCA is vendored under tods/pyod_core/ with small numpy/sklearn fixes;
  • the original d3m code is untouched under tods/third_party/;
  • tods.lstmodetectorski is not available (TensorFlow code internal to TODS, unused by the scripts); it raises a clear error.

Other fixes

  • merlion.RandomCutForest could not start its JVM on Java 8 (--add-opens is Java 9+); it now retries without these options.
  • The torch.load calls for the Timer, UniTS and CALF checkpoints now pass weights_only=False, required since PyTorch 2.6.
  • LOF returned the wrong tuple format for the detection strategies, and flattened a T x D input into T*D scores; both fixed.
  • np.complex replaced with np.complex128 in TFAD.
  • .gitignore: venvs, __pycache__, checkpoint folders.

Tests

Python 3.12.11, Linux (WSL2), Java 8, RTX 4070 SUPER.

  • The 10 TODS models and the 17 Merlion models fit and score correctly (scores and labels).
  • Benchmark runs work with both backends (sequential, ray), both splits (fixed, unfixed) and both strategies (score, label).
  • Each of these ran end to end on real data (1 epoch, official script parameters): AnomalyTransformer, DCdetector, ModernTCN, TranAD, CrossAD, ContraAD, TFAD, CATCH, Torsk, Series2Graph, EIF, LeftSTAMPi, SAND, LOF, KMeans, MatrixProfile, DWT_MLEAD, DLinear, NLinear, PatchTST, TimesNet, iTransformer, DUET, TimerModel, UniTS, CALFModel.
  • DualTF trains without errors but is too slow to finish in a reasonable time on this machine (the official scripts give it 16 hours per task).
  • The other LLM and pre-trained variants (GPT4TS, UniTime, Chronos, TimesFM, ...) were not run.

Comparison with published results

AUC-ROC on CalIt2 and Genesis with the repository default configurations, against the values published in the TeamWork paper:

Model CalIt2, published -> PR Genesis, published -> PR
merlion.AutoEncoder 0.767 -> 0.7669 0.931 -> 0.9321
merlion.IsolationForest 0.775 -> 0.7750 0.549 -> 0.5485
tods.ocsvmski 0.804 -> 0.8035 0.733 -> 0.7328
tods.pcaodetectorski 0.790 -> 0.7913 0.815 -> 0.8271
tods.hbosski 0.798 -> 0.7979 0.897 -> 0.1238

Nine values out of ten are within 0.001-0.012 of the published number. The last one (tods.hbosski on Genesis) gives the same 0.1238 with pyod 0.8.9 (the d3m-era version), 1.1.3 and 3.6.2, so the difference does not come from this PR; the published value must have been obtained with tuned hyperparameters rather than the repository defaults.

Known issues (pre-existing, out of scope)

  • The windowed PCA overflows to infinite scores with n_components=None on near-constant channels. The historical default n_components=1 avoids it.
  • Merlion forecast-based detectors produce invalid scores when the test window is much longer than max_forecast_steps.
  • self_impl.VAR_model only has the forecasting interface and cannot run under the detection strategies.

Breaking changes

  • Python 3.8 is no longer supported (target: >= 3.10, tested on 3.12).
  • tods.lstmodetectorski is unavailable.
  • TODS scores can differ in the last decimals from the 2022 d3m stack.
  • transformers is capped below 5.0.

@marcpinet
marcpinet marked this pull request as draft July 21, 2026 16:19
@marcpinet
marcpinet marked this pull request as ready for review July 21, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant