Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Zero-shot time series forecasting with Google's TimesFM foundation model. Use for any univariate time series (sales, sensors, energy, vitals, weather) without training a custom model. Supports CSV/DataFrame/array inputs with point forecasts and prediction intervals. Includes a preflight system checker script to verify RAM/GPU before first use.
.claude/skills/k-dense-ai-timesfm-forecasting/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 52% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 147% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 75% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 140% | 0% |
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 wraps TimesFM for safe, agent-friendly local inference. It 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 a 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.
Use this skill when:
Do not use this skill when:
statsmodelsaeonstatsmodelsscikit-learn> 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 the examples/anomaly-detection/ directory for a full example.
CRITICAL — ALWAYS run the system checker before loading the model for the first time.
bashpython scripts/check_system.py
This script checks:
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/. > The preflight checker ensures sufficient resources before any download begins.
mermaidflowchart TD accTitle: Preflight System Check accDescr: Decision flowchart showing the system requirement checks that must pass before loading TimesFM. 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"] classDef ok fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d classDef warn fill:#fef9c3,stroke:#ca8a04,stroke-width:2px,color:#713f12 classDef block fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d classDef neutral fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#1f2937 class ready,gpu_ok,cpu_ok ok class warn_ram warn class block,block_disk block class start,ram,gpu,vram,disk neutral
| Model | Parameters | RAM (CPU) | VRAM (GPU) | Disk | Context | | ----- | ---------- | --------- | ---------- | ---- | ------- | | TimesFM 2.5 (recommended) | 200M | ≥ 4 GB | ≥ 2 GB | ~800 MB | up to 16,384 | | TimesFM 2.0 (archived) | 500M | ≥ 16 GB | ≥ 8 GB | ~2 GB | up to 2,048 | | TimesFM 1.0 (archived) | 200M | ≥ 8 GB | ≥ 4 GB | ~800 MB | up 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.
bashpython scripts/check_system.py
bash# Using uv (recommended by this repo) uv pip install timesfm[torch] # For JAX/Flax backend (faster on TPU/GPU) uv pip install timesfm[flax]
bash# CUDA 12.1 (NVIDIA GPU) uv pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cu121 # CPU only uv pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cpu # Apple Silicon (MPS) uv pip install torch>=2.0.0 # MPS support is built-in
pythonimport timesfm import numpy as np print(f"TimesFM version: {timesfm.__version__}") print("Installation OK")
pythonimport 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
pythonimport pandas as pd, numpy as np df = pd.read_csv("monthly_sales.csv", parse_dates=["date"], index_col="date") # Convert each column to a list of arrays inputs = [df[col].dropna().values.astype(np.float32) for col in df.columns] point, quantiles = model.forecast(horizon=12, inputs=inputs) # Build a results DataFrame for i, col in enumerate(df.columns): last_date = df[col].dropna().index[-1] future_dates = pd.date_range(last_date, periods=13, freq="MS")[1:] forecast_df = pd.DataFrame({ "date": future_dates, "forecast": point[i], "lower_80": quantiles[i, :, 2], # 20th percentile "upper_80": quantiles[i, :, 8], # 80th percentile }) print(f"\n--- {col} ---") print(forecast_df.to_string(index=False))
TimesFM 2.5+ supports exogenous variables through forecast_with_covariates(). Requires timesfm[xreg].
python# Requires: uv 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" )
| Covariate Type | Description | Example | | -------------- | ----------- | ------- | | dynamic_numerical | Time-varying numeric | price, temperature, promotion spend | | dynamic_categorical | Time-varying categorical | holiday flag, day of week | | static_numerical | Per-series numeric | store size, account age | | static_categorical | Per-series categorical | store type, region, product category |
XReg Modes:
"xreg + timesfm" (default): TimesFM forecasts first, then XReg adjusts residuals"timesfm + xreg": XReg fits first, then TimesFM forecasts residuals> See examples/covariates-forecasting/ for a complete example with synthetic retail data.
TimesFM does not have built-in anomaly detection, but the quantile forecasts naturally provide prediction intervals that can detect anomalies:
pythonpoint, q = model.forecast(horizon=H, inputs=[values]) # 90% prediction interval lower_90 = q[0, :, 1] # 10th percentile upper_90 = q[0, :, 9] # 90th percentile # Detect anomalies: values outside the 90% CI actual = test_values # your holdout data anomalies = (actual < lower_90) | (actual > upper_90) # Severity levels is_warning = (actual < q[0, :, 2]) | (actual > q[0, :, 8]) # outside 80% CI is_critical = anomalies # outside 90% CI
| Severity | Condition | Interpretation | | -------- | --------- | -------------- | | Normal | Inside 80% CI | Expected behavior | | Warning | Outside 80% CI | Unusual but possible | | Critical | Outside 90% CI | Statistically rare (< 10% probability) |
> See examples/anomaly-detection/ for a complete example with visualization.
python# Requires: uv pip install timesfm[xreg] point, quantiles = model.forecast_with_covariates( inputs=inputs, dynamic_numerical_covariates={"temperature": temp_arrays}, dynamic_categorical_covariates={"day_of_week": dow_arrays}, static_categorical_covariates={"region": region_labels}, xreg_mode="xreg + timesfm", # or "timesfm + xreg" )
forecast and the 10 quantile bands, deriving prediction intervals, and every ForecastConfig field.
many-series forecasting from a wide CSV, and backtesting with interval coverage.
setup, per_core_batch_size by available memory, and memory management.
runnable examples, the quality checklist, common mistakes, and regression checks.
statsmodelsUse statsmodels for classical models (ARIMA, SARIMAX) as a comparison baseline:
python# TimesFM forecast tfm_point, tfm_q = model.forecast(horizon=H, inputs=[values]) # statsmodels ARIMA forecast from statsmodels.tsa.arima.model import ARIMA arima = ARIMA(values, order=(1,1,1)).fit() arima_forecast = arima.forecast(steps=H) # Compare print(f"TimesFM MAE: {np.mean(np.abs(actual - tfm_point[0])):.2f}") print(f"ARIMA MAE: {np.mean(np.abs(actual - arima_forecast)):.2f}")
matplotlib / scientific-visualizationPlot forecasts with prediction intervals as publication-quality figures.
exploratory-data-analysisRun EDA on the time series before forecasting to understand trends, seasonality, and stationarity.
scripts/check_system.pyMandatory preflight checker. Run before first model load.
bashpython scripts/check_system.py
Output example:
=== TimesFM System Requirements Check ===
[RAM] Total: 32.0 GB | Available: 24.3 GB ✅ PASS
[GPU] NVIDIA RTX 4090 | VRAM: 24.0 GB ✅ PASS
[Disk] Free: 142.5 GB ✅ PASS
[Python] 3.12.1 ✅ PASS
[timesfm] Installed (2.5.0) ✅ PASS
[torch] Installed (2.4.1+cu121) ✅ PASS
VERDICT: ✅ System is ready for TimesFM 2.5 (GPU mode)
Recommended: per_core_batch_size=128scripts/forecast_csv.pyEnd-to-end CSV forecasting with automatic system check.
bashpython scripts/forecast_csv.py input.csv \ --horizon 24 \ --date-col date \ --value-cols sales,revenue \ --output forecasts.csv
Detailed guides in references/:
| File | Contents | | ---- | -------- | | references/system_requirements.md | Hardware tiers, GPU/CPU selection, memory estimation formulas | | references/api_reference.md | Full ForecastConfig docs, from_pretrained options, output shapes | | references/data_preparation.md | Input formats, NaN handling, CSV loading, covariate setup |
check_system.py first.model.compile() → RuntimeError: Model is not compiled. Must call compile() before forecast().normalize_inputs=True → unstable forecasts for series with large values.fix_quantile_crossing=True → quantiles may not be monotonic (q10 > q50).per_core_batch_size on small GPU → CUDA OOM. Start small, increase.torch.set_float32_matmul_precision("high") → slower inference on Ampere+ GPUs.np.isnan(point).any().infer_is_positive=True for series that can be negative → clamps forecasts at zero. Set False for temperature, returns, etc.mermaidtimeline accTitle: TimesFM Version History accDescr: Timeline of TimesFM model releases showing parameter counts and key improvements. section 2024 TimesFM 1.0 : 200M params, 2K context, JAX only TimesFM 2.0 : 500M params, 2K context, PyTorch + JAX section 2025 TimesFM 2.5 : 200M params, 16K context, quantile head, no frequency indicator
| Version | Params | Context | Quantile Head | Frequency Flag | Status | | ------- | ------ | ------- | ------------- | -------------- | ------ | | 2.5 | 200M | 16,384 | ✅ Continuous (30M) | ❌ Removed | Latest | | 2.0 | 500M | 2,048 | ✅ Fixed buckets | ✅ Required | Archived | | 1.0 | 200M | 2,048 | ✅ Fixed buckets | ✅ Required | Archived |
Hugging Face checkpoints:
google/timesfm-2.5-200m-pytorch (recommended)google/timesfm-2.5-200m-flaxgoogle/timesfm-2.0-500m-pytorch (archived)google/timesfm-1.0-200m-pytorch (archived)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 24,204 | 14,895 | -38% | 1 | 1 | 0% | 5,208 | 7,939 | +52% | 0 | 0 | — |
case-02 | fail→fail | 29,118 | 10,512 | -64% | 1 | 1 | 0% | 5,791 | 5,370 | -7% | 0 | 0 | — |
case-03 | fail→pass | 20,406 | 59,996 | +194% | 1 | 1 | 0% | 4,078 | 10,054 | +147% | 0 | 0 | — |
case-04 | pass→pass | 15,673 | 13,056 | -17% | 1 | 1 | 0% | 3,109 | 7,241 | +133% | 0 | 0 | — |
case-05 | fail→pass | 18,999 | 14,415 | -24% | 1 | 1 | 0% | 4,081 | 7,303 | +79% | 0 | 0 | — |
case-06 | pass→pass | 11,096 | 7,265 | -35% | 1 | 1 | 0% | 2,685 | 6,329 | +136% | 0 | 0 | — |
case-07 | fail→pass | 21,328 | 10,280 | -52% | 1 | 1 | 0% | 3,727 | 6,510 | +75% | 0 | 0 | — |
case-08 | pass→pass | 10,791 | 7,076 | -34% | 1 | 1 | 0% | 2,098 | 5,974 | +185% | 0 | 0 | — |
case-09 | fail→pass | 12,599 | 2,752 | -78% | 1 | 1 | 0% | 2,125 | 5,091 | +140% | 0 | 0 | — |
case-10 | pass→pass | 6,168 | 2,876 | -53% | 1 | 1 | 0% | 1,272 | 5,132 | +303% | 0 | 0 | — |
case-11 | pass→pass | 9,192 | 3,795 | -59% | 1 | 1 | 0% | 1,919 | 5,338 | +178% | 0 | 0 | — |
case-12 | fail→pass | 11,229 | 1,990 | -82% | 1 | 1 | 0% | 2,135 | 4,879 | +129% | 0 | 0 | — |
case-13 | pass→pass | 13,999 | 8,013 | -43% | 1 | 1 | 0% | 2,902 | 6,424 | +121% | 0 | 0 | — |
case-14 | fail→pass | 13,664 | 2,992 | -78% | 1 | 1 | 0% | 2,302 | 5,010 | +118% | 0 | 0 | — |
case-15 | pass→pass | 9,009 | 2,118 | -76% | 1 | 1 | 0% | 1,539 | 4,827 | +214% | 0 | 0 | — |
case-16 | fail→pass | 17,782 | 6,346 | -64% | 1 | 1 | 0% | 2,974 | 5,692 | +91% | 0 | 0 | — |
case-17 | fail→pass | 17,280 | 2,883 | -83% | 1 | 1 | 0% | 1,740 | 5,113 | +194% | 0 | 0 | — |
case-18 | fail→fail | 10,025 | 8,058 | -20% | 1 | 1 | 0% | 2,099 | 6,281 | +199% | 0 | 0 | — |
case-19 | pass→pass | 13,939 | 6,306 | -55% | 1 | 1 | 0% | 2,897 | 5,851 | +102% | 0 | 0 | — |
case-20 | fail→pass | 7,264 | 3,239 | -55% | 1 | 1 | 0% | 1,267 | 5,151 | +307% | 0 | 0 | — |
case-21 | pass→pass | 8,785 | 5,643 | -36% | 1 | 1 | 0% | 1,604 | 5,565 | +247% | 0 | 0 | — |
case-22 | fail→pass | 23,356 | 3,899 | -83% | 1 | 1 | 0% | 3,676 | 5,158 | +40% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +50 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.