Skip to content

fix(examples): migrate anomaly-detection example to TimesFM 2.5 - #466

Open
ihubanov wants to merge 1 commit into
google-research:masterfrom
ihubanov:fix/anomaly-detection-2p5
Open

fix(examples): migrate anomaly-detection example to TimesFM 2.5#466
ihubanov wants to merge 1 commit into
google-research:masterfrom
ihubanov:fix/anomaly-detection-2p5

Conversation

@ihubanov

Copy link
Copy Markdown

Companion to #465, for the other example still on the removed v1 API. Independent of it; either can merge first.

detect_anomalies.py fails on the first model load:

AttributeError: module 'timesfm' has no attribute 'TimesFmHparams'

Changes

  • Load via TimesFM_2p5_200M_torch.from_pretrained + model.compile(ForecastConfig(...)), using the same config as run_forecast.py in the global-temperature example.
  • Pass horizon explicitly to forecast() and drop freq=[0].

The quantile column mapping in this file was already correct (IDX_Q10, IDX_Q20, IDX_Q80, IDX_Q90 = 1, 2, 8, 9), so only the loading path changes. The diff is 20 lines.

Behaviour change in the regenerated artifacts

2.5's continuous quantile head gives noticeably tighter intervals than the checkpoint the committed artifacts came from:

80% PI width month 1 month 12
before 0.227 0.494
after 0.216 0.329

One more month therefore falls outside the band, so the forecast CRITICAL count moves 4 -> 5. Worth flagging rather than burying, though it does not weaken the example:

  • All three injected anomalies are still detected (2025-04, 2025-09, 2025-12).
  • Phase 1 is pure numpy detrend + Z-score and is unaffected: the acceptance criterion in SKILL.md, Sep 2023 CRITICAL, still holds at z=+3.03.
  • The extra detection is 2025-05, a noise month that now sits just outside the narrower 80% band. 2025-11 was already a false positive before this change.

If you would rather keep the old detection counts, the honest lever is the injected offsets in build_synthetic_future() rather than loosening the bands. I left them alone, since tuning the fixture to preserve a number seemed worse than reporting the difference.

Verification

Ran end to end on CPU (Python 3.13, torch 2.13.0+cpu). Regenerated anomaly_detection.json and anomaly_detection.png.

Refs #423

detect_anomalies.py still calls the v1 API that 2.5 removed, so it fails on
the first model load:

    AttributeError: module 'timesfm' has no attribute 'TimesFmHparams'

Port it to from_pretrained + ForecastConfig + forecast(horizon=...) and drop
the frequency indicator, using the same config as run_forecast.py in the
global-temperature example. The quantile column mapping here was already
correct (IDX_Q10..IDX_Q90 = 1/2/8/9), so only the loading path changes.

Regenerate the committed artifacts. The continuous quantile head in 2.5 gives
tighter intervals than the checkpoint the old artifacts came from: the 80% PI
width at month 12 goes 0.494 -> 0.329. One further month therefore falls
outside the band and the forecast CRITICAL count moves 4 -> 5. All three
injected anomalies are still caught, and the acceptance criterion documented
in SKILL.md still holds (Sep 2023 CRITICAL at z=+3.03).

Refs google-research#423
@google-cla

google-cla Bot commented Aug 18, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ihubanov

Copy link
Copy Markdown
Author

@googlebot I signed it!

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