CtrlK
BlogDocsLog inGet started
Tessl Logo

timesfm-forecasting

Zero-shot time series forecasting with Google's TimesFM foundation model. Use this skill when forecasting ANY univariate time series — sales, sensor readings, stock prices, energy demand, patient vitals, weather, or scientific measurements — without training a custom model. Supports both basic forecasting and advanced covariate forecasting (XReg) with dynamic and static exogenous variables. Automatically checks system RAM/GPU before loading the model, validates dataset fit before processing, supports CSV/DataFrame/array inputs, and returns point forecasts with calibrated prediction intervals. Includes a preflight system checker script that MUST be run before first use to verify the machine can load the model and handle your specific dataset.

73

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

TimesFM Forecasting

Overview

TimesFM (Time Series Foundation Model) is a pretrained decoder-only foundation model developed by Google Research for time-series forecasting. It works zero-shot — feed it any univariate time series and it returns point forecasts with calibrated quantile prediction intervals, no training required.

This skill includes a mandatory preflight system checker that verifies RAM, GPU memory, and disk space before the model is ever loaded so the agent never crashes the user's machine.

Key numbers: TimesFM 2.5 uses 200M parameters (~800 MB on disk, ~1.5 GB in RAM on CPU, ~1 GB VRAM on GPU). The archived v1/v2 500M-parameter model needs ~32 GB RAM. Always run the system checker first.

When to Use This Skill

Use this skill when:

  • Forecasting any univariate time series (sales, demand, sensor, vitals, price, weather)
  • You need zero-shot forecasting without training a custom model
  • You want probabilistic forecasts with calibrated prediction intervals (quantiles)
  • You have time series of any length (the model handles 1–16,384 context points)
  • You need to batch-forecast hundreds or thousands of series efficiently
  • You want a foundation model approach instead of hand-tuning ARIMA/ETS parameters
  • You need covariate forecasting with exogenous variables (price, promotions, holidays, day-of-week effects) → use forecast_with_covariates() (TimesFM 2.5 + pip install timesfm[xreg])

Do not use this skill when:

  • You need classical statistical models with coefficient interpretation → use statsmodels
  • You need time series classification or clustering → use aeon
  • You need multivariate vector autoregression or Granger causality → use statsmodels
  • Your data is tabular (not temporal) → use scikit-learn
  • You cannot install optional dependencies → XReg requires scikit-learn and JAX

Note on Anomaly Detection: TimesFM does not have built-in anomaly detection, but you can use the quantile forecasts as prediction intervals — values outside the 90% CI (q10–q90) are statistically unusual. See examples/anomaly-detection/ for a full example.

⚠️ Mandatory Preflight: System Requirements Check

CRITICAL — ALWAYS run the system checker before loading the model for the first time.

python scripts/check_system.py

This script checks:

  1. Available RAM — warns if below 4 GB, blocks if below 2 GB
  2. GPU availability — detects CUDA/MPS devices and VRAM
  3. Disk space — verifies room for the ~800 MB model download
  4. Python version — requires 3.10+
  5. Existing installation — checks if timesfm and torch are installed

Note: Model weights are NOT stored in this repository. TimesFM weights (~800 MB) download on-demand from HuggingFace on first use and cache in ~/.cache/huggingface/.

flowchart TD
    start["🚀 Run check_system.py"] --> ram{"RAM ≥ 4 GB?"}
    ram -->|"Yes"| gpu{"GPU available?"}
    ram -->|"No (2-4 GB)"| warn_ram["⚠️ Warning: tight RAM<br/>CPU-only, small batches"]
    ram -->|"No (< 2 GB)"| block["🛑 BLOCKED<br/>Insufficient memory"]
    warn_ram --> disk
    gpu -->|"CUDA / MPS"| vram{"VRAM ≥ 2 GB?"}
    gpu -->|"CPU only"| cpu_ok["✅ CPU mode<br/>Slower but works"]
    vram -->|"Yes"| gpu_ok["✅ GPU mode<br/>Fast inference"]
    vram -->|"No"| cpu_ok
    gpu_ok --> disk{"Disk ≥ 2 GB free?"}
    cpu_ok --> disk
    disk -->|"Yes"| ready["✅ READY<br/>Safe to load model"]
    disk -->|"No"| block_disk["🛑 BLOCKED<br/>Need space for weights"]

Dataset Preflight (NEW)

Before loading your actual data, verify it will fit in memory:

# Quick estimate for your dataset
python scripts/check_system.py \
  --num-series 1000 \
  --context-length 1024 \
  --horizon 24 \
  --batch-size 32 \
  --estimate-only

This will show you the estimated memory requirements and warn if your dataset is too large.

Memory Estimation Formula: RAM ≈ 0.8 GB (model) + 0.5 GB (overhead) + (0.2 MB × num_series × context_length / 1000)

Example Outputs:

Dataset Fits:

Total CPU memory: 2.34 GB
Total GPU memory: 2.15 GB

⚠️ Dataset Too Large:

Dataset requires ~12.5 GB RAM but system has 8.0 GB.
Try: context_length=512 or process in chunks of 50 series.

Hardware Requirements by Model Version

ModelParametersRAM (CPU)VRAM (GPU)DiskContext
TimesFM 2.5 (recommended)200M≥ 4 GB≥ 2 GB~800 MBup to 16,384
TimesFM 2.0 (archived)500M≥ 16 GB≥ 8 GB~2 GBup to 2,048
TimesFM 1.0 (archived)200M≥ 8 GB≥ 4 GB~800 MBup to 2,048

Recommendation: Always use TimesFM 2.5 unless you have a specific reason to use an older checkpoint. It is smaller, faster, and supports 8× longer context.

🔧 Installation

Step 1: Verify System (always first)

python scripts/check_system.py

Step 2: Install TimesFM

# Using uv (fast)
uv pip install timesfm[torch]

# Or using pip
pip install timesfm[torch]

# For JAX/Flax backend (faster on TPU/GPU)
uv pip install timesfm[flax]

Step 3: Install PyTorch for Your Hardware

# CUDA 12.1 (NVIDIA GPU)
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cu121

# CPU only
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cpu

# Apple Silicon (MPS)
pip install torch>=2.0.0  # MPS support is built-in

🎯 Quick Start

Minimal Example

import torch, numpy as np, timesfm

torch.set_float32_matmul_precision("high")

model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
    "google/timesfm-2.5-200m-pytorch"
)
model.compile(timesfm.ForecastConfig(
    max_context=1024, max_horizon=256, normalize_inputs=True,
    use_continuous_quantile_head=True, force_flip_invariance=True,
    infer_is_positive=True, fix_quantile_crossing=True,
))

point, quantiles = model.forecast(horizon=24, inputs=[
    np.sin(np.linspace(0, 20, 200)),  # any 1-D array
])
# point.shape == (1, 24)         — median forecast
# quantiles.shape == (1, 24, 10) — 10th–90th percentile bands

Forecast with Covariates (XReg)

TimesFM 2.5+ supports exogenous variables through forecast_with_covariates(). Requires pip install timesfm[xreg].

point, quantiles = model.forecast_with_covariates(
    inputs=inputs,
    dynamic_numerical_covariates={"price": price_arrays},
    dynamic_categorical_covariates={"holiday": holiday_arrays},
    static_categorical_covariates={"region": region_labels},
    xreg_mode="xreg + timesfm",  # or "timesfm + xreg"
)

Anomaly Detection (via Quantile Intervals)

point, q = model.forecast(horizon=H, inputs=[values])

lower_90 = q[0, :, 1]  # 10th percentile
upper_90 = q[0, :, 9]  # 90th percentile

actual = test_values
anomalies = (actual < lower_90) | (actual > upper_90)
SeverityConditionInterpretation
NormalInside 80% CIExpected behavior
WarningOutside 80% CIUnusual but possible
CriticalOutside 90% CIStatistically rare (< 10% probability)

See examples/anomaly-detection/ for a complete worked example with visualization.

📊 Understanding the Output

TimesFM returns (point_forecast, quantile_forecast):

  • point_forecast: shape (batch, horizon) — the median (0.5 quantile)
  • quantile_forecast: shape (batch, horizon, 10) — ten quantile slices:
IndexQuantileUse
0MeanAverage prediction
10.1Lower bound of 80% PI
20.2Lower bound of 60% PI
50.5Median (= point_forecast)
80.8Upper bound of 60% PI
90.9Upper bound of 80% PI
point, q = model.forecast(horizon=H, inputs=data)

lower_80 = q[:, :, 1]  # 10th percentile
upper_80 = q[:, :, 9]  # 90th percentile
median   = q[:, :, 5]

🔧 ForecastConfig Reference

All forecasting behavior is controlled by timesfm.ForecastConfig:

timesfm.ForecastConfig(
    max_context=1024,                    # Max context window
    max_horizon=256,                     # Max forecast horizon
    normalize_inputs=True,               # RECOMMENDED — prevents scale instability
    per_core_batch_size=32,              # Tune for memory
    use_continuous_quantile_head=True,   # Better quantile accuracy for long horizons
    force_flip_invariance=True,          # Ensures f(-x) = -f(x)
    infer_is_positive=True,              # Clamp forecasts ≥ 0 when all inputs > 0
    fix_quantile_crossing=True,          # Ensure q10 ≤ q20 ≤ ... ≤ q90
    return_backcast=False,               # Return backcast (for covariate workflows)
)
ParameterDefaultWhen to Change
max_context0Set to match your longest historical window
normalize_inputsFalseAlways set True
use_continuous_quantile_headFalseSet True for calibrated PIs
infer_is_positiveTrueSet False for series that can be negative
fix_quantile_crossingFalseSet True for monotonic quantiles

See references/api_reference.md for the complete parameter reference.

📋 Common Workflows

Single Series Forecast

import torch, numpy as np, pandas as pd, timesfm, matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

torch.set_float32_matmul_precision("high")
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
    "google/timesfm-2.5-200m-pytorch"
)
model.compile(timesfm.ForecastConfig(
    max_context=512, max_horizon=52, normalize_inputs=True,
    use_continuous_quantile_head=True, fix_quantile_crossing=True,
))

df = pd.read_csv("weekly_demand.csv", parse_dates=["week"])
values = df["demand"].values.astype(np.float32)

point, quantiles = model.forecast(horizon=52, inputs=[values])

fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(values[-104:], label="Historical")
x_fc = range(len(values[-104:]), len(values[-104:]) + 52)
ax.plot(x_fc, point[0], label="Forecast", color="tab:orange")
ax.fill_between(x_fc, quantiles[0, :, 1], quantiles[0, :, 9],
                alpha=0.2, color="tab:orange", label="80% PI")
ax.legend(); ax.set_title("52-Week Demand Forecast")
plt.tight_layout(); plt.savefig("forecast.png", dpi=150)

Batch Forecasting (Many Series)

df = pd.read_csv("all_stores.csv", parse_dates=["date"], index_col="date")
inputs = [df[col].dropna().values.astype(np.float32) for col in df.columns]

point, quantiles = model.forecast(horizon=30, inputs=inputs)

import json
results = {col: {"forecast": point[i].tolist(),
                 "lower_80": quantiles[i, :, 1].tolist(),
                 "upper_80": quantiles[i, :, 9].tolist()}
           for i, col in enumerate(df.columns)}
with open("batch_forecasts.json", "w") as f:
    json.dump(results, f, indent=2)

Evaluate Forecast Accuracy

H = 24
train, actual = values[:-H], values[-H:]
point, quantiles = model.forecast(horizon=H, inputs=[train])
pred = point[0]

mae  = np.mean(np.abs(actual - pred))
rmse = np.sqrt(np.mean((actual - pred) ** 2))
mape = np.mean(np.abs((actual - pred) / actual)) * 100
coverage = np.mean((actual >= quantiles[0, :, 1]) & (actual <= quantiles[0, :, 9])) * 100

print(f"MAE: {mae:.2f} | RMSE: {rmse:.2f} | MAPE: {mape:.1f}% | 80% PI Coverage: {coverage:.1f}%")

⚙️ Performance Tuning

# Always set on Ampere+ GPUs (A100, RTX 3090+)
torch.set_float32_matmul_precision("high")

# Batch size guidelines:
# GPU 8 GB VRAM:  per_core_batch_size=64
# GPU 16 GB VRAM: per_core_batch_size=128
# CPU 8 GB RAM:   per_core_batch_size=8
# CPU 16 GB RAM:  per_core_batch_size=32

# Memory-constrained: process in chunks
CHUNK = 50
results = []
for i in range(0, len(inputs), CHUNK):
    p, q = model.forecast(horizon=H, inputs=inputs[i:i+CHUNK])
    results.append((p, q))

📚 Available Scripts

scripts/check_system.py

Mandatory preflight checker — run before first model load. Now includes dataset-aware memory estimation to prevent OOM errors before loading your data.

# Basic system check
python scripts/check_system.py

# Check if your specific dataset will fit
python scripts/check_system.py \
  --num-series 1000 \
  --context-length 1024 \
  --horizon 24 \
  --batch-size 32

# Quick memory estimate without system checks
python scripts/check_system.py \
  --num-series 5000 \
  --context-length 2048 \
  --estimate-only

What it checks:

  1. Available RAM — warns if below 4 GB, blocks if below 2 GB
  2. GPU availability — detects CUDA/MPS devices and VRAM
  3. Disk space — verifies room for the ~800 MB model download
  4. Python version — requires 3.10+
  5. Existing installation — checks if timesfm and torch are installed
  6. Dataset fit (NEW) — estimates memory for your specific dataset and warns if it won't fit

scripts/forecast_csv.py

End-to-end CSV forecasting CLI.

python scripts/forecast_csv.py input.csv \
    --horizon 24 \
    --date-col date \
    --value-cols sales,revenue \
    --output forecasts.csv

📖 Reference Documentation

FileContents
references/system_requirements.mdHardware tiers, GPU/CPU selection, memory estimation
references/api_reference.mdFull ForecastConfig docs, output shapes, model options
references/data_preparation.mdInput formats, NaN handling, CSV loading, covariate setup

🧪 Examples

ExampleDirectoryWhat It Demonstrates
Global Temperature Forecastexamples/global-temperature/Basic model.forecast(), CSV → PNG → GIF pipeline
Anomaly Detectionexamples/anomaly-detection/Two-phase detrend + Z-score + quantile PI, 2-panel viz
Covariates (XReg)examples/covariates-forecasting/forecast_with_covariates(), 2×2 shared-axis viz
# Run all three examples:
cd examples/global-temperature && python run_forecast.py && python visualize_forecast.py
cd examples/anomaly-detection  && python detect_anomalies.py
cd examples/covariates-forecasting && python demo_covariates.py

Expected Outputs

ExampleKey output filesAcceptance criteria
global-temperatureoutput/forecast_output.json, output/forecast_visualization.pngpoint_forecast has 12 values; PNG shows context + forecast + PI bands
anomaly-detectionoutput/anomaly_detection.json, output/anomaly_detection.pngSep 2023 flagged CRITICAL (z ≥ 3.0)
covariates-forecastingoutput/sales_with_covariates.csv, output/covariates_data.png108 rows (3 stores × 36 weeks); distinct price arrays per store

Model Versions

VersionParamsContextStatusHuggingFace checkpoint
2.5200M16,384Latestgoogle/timesfm-2.5-200m-pytorch
2.0500M2,048Archivedgoogle/timesfm-2.0-500m-pytorch
1.0200M2,048Archivedgoogle/timesfm-1.0-200m-pytorch
  • TimesFM 1.0/2.0: must pass freq=[0] for monthly data
  • TimesFM 2.5: no frequency flag — it was removed

Resources

Quality Checklist

Run after every TimesFM task before declaring success:

  • Output shapepoint_fc is (n_series, horizon), quant_fc is (n_series, horizon, 10)
  • Quantile indices — index 0 = mean, 1 = q10 ... 9 = q90. NOT 0 = q0.
  • Frequency flag — TimesFM 1.0/2.0: pass freq=[0] for monthly. TimesFM 2.5: omit.
  • Series length — context must be ≥ 32 data points.
  • No NaNnp.isnan(point_fc).any() must be False.
  • Axes — multiple panels sharing data must use sharex=True.
  • matplotlib.use('Agg') — before any pyplot import when running headless.
  • infer_is_positive — set False for temperature, financial returns, negatives.

Common Mistakes

  1. Quantile index off-by-onequant_fc[..., 0] is the mean, not q0. q10 = index 1, q90 = index 9. Define: IDX_Q10, IDX_Q90 = 1, 9.

  2. Variable shadowing in covariate loops — don't use the outer loop variable as a comprehension variable when building per-series covariate dicts.

  3. Wrong CSV column name — global-temperature CSV uses anomaly_c, not anomaly. Print df.columns first.

  4. TimesFM 2.5 required for forecast_with_covariates() — TimesFM 1.0 does NOT have this method.

  5. Future covariates must span the full horizon — dynamic covariates need values for BOTH context AND forecast windows.

  6. Context anomaly detection uses residuals — detrend first, then Z-score. Raw Z-scores mislead on trending data.

Validation & Verification

# Anomaly detection regression:
python -c "
import json
d = json.load(open('examples/anomaly-detection/output/anomaly_detection.json'))
assert d['context_summary']['critical'] >= 1, 'Sep 2023 must be CRITICAL'
print('Anomaly detection: PASS')"

# Covariates regression:
python -c "
import pandas as pd
df = pd.read_csv('examples/covariates-forecasting/output/sales_with_covariates.csv')
assert len(df) == 108, f'Expected 108 rows, got {len(df)}'
print('Covariates: PASS')"
Repository
google-research/timesfm
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.