关于 timesfm-forecasting
timesfm-forecasting 是使用 TimesFM 对单变量时间序列进行本地零样本预测的技能,支持分位数区间和批量处理,并在加载模型前检查系统资源。
主要功能
- 01单变量零样本预测
- 02点预测与分位数预测
- 03使用协变量进行预测
- 04批量处理时间序列
- 05加载前检查系统资源
适用场景
- 01预测销售额或传感器读数
- 02生成预测区间
- 03批量预测多条时间序列
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ crazymsn/ academic-skills --skill timesfm-forecasting安装后在 Claude Code 中输入/timesfm-forecasting确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/anomaly-detection/detect_anomalies.pyexamples/anomaly-detection/output/anomaly_detection.jsonexamples/covariates-forecasting/demo_covariates.pyexamples/covariates-forecasting/output/covariates_metadata.jsonsales_with_covariates.csvexamples/global-temperature/generate_animation_data.pygenerate_gif.pygenerate_html.pyREADME.mdrun_example.shrun_forecast.pytemperature_anomaly.csvvisualize_forecast.pyexamples/global-temperature/output/animation_data.jsonforecast_output.csvforecast_output.jsoninteractive_forecast.htmlreferences/api_reference.mddata_preparation.mdsystem_requirements.mdscripts/check_system.pyforecast_csv.py详细介绍
TimesFM 预测
概述
TimesFM(时间序列基础模型)是由 Google Research 开发的预训练纯解码器基础模型, 用于时间序列预测。它可以零样本运行——输入任意单变量时间序列,即可返回点预测和经过校准的分位数 预测区间,无需训练。
此技能封装了 TimesFM,支持安全、便于 Agent 使用的本地推理。它包含一个 强制预检系统检查器,会在加载模型之前验证 RAM、GPU 内存和磁盘空间, 从而避免 Agent 导致用户的机器崩溃。
关键数据:TimesFM 2.5 使用 200M 个参数(磁盘占用约 800 MB,CPU 上约需 1.5 GB RAM, GPU 上约需 1 GB VRAM)。已归档的 v1/v2 500M 参数模型需要约 32 GB RAM。 请始终先运行系统检查器。
何时使用此技能
在以下情况下使用此技能:
- 预测任意单变量时间序列(销售额、需求、传感器数据、生命体征、价格、天气)
- 需要零样本预测,而无需训练自定义模型
- 需要带校准预测区间(分位数)的概率预测
- 时间序列的长度不限(模型支持 1–16,384 个上下文点)
- 需要高效地对数百或数千个序列进行批量预测
- 希望采用基础模型方案,而不是手动调整 ARIMA/ETS 参数
在以下情况下不要使用此技能:
- 需要能够解释系数的经典统计模型 → 使用
statsmodels - 需要进行时间序列分类或聚类 → 使用
aeon - 需要多变量向量自回归或格兰杰因果检验 → 使用
statsmodels - 数据是表格型数据(非时间序列)→ 使用
scikit-learn
异常检测说明:TimesFM 没有内置异常检测功能,但你可以 将分位数预测用作预测区间——90% 置信区间(q10–q90)之外的值在统计上属于异常值。完整示例请参阅
examples/anomaly-detection/目录。
⚠️ 强制预检:系统要求检查
重要——首次加载模型前务必运行系统检查器。
python scripts/check_system.py
此脚本会检查:
- 可用 RAM——低于 4 GB 时发出警告,低于 2 GB 时阻止运行
- GPU 可用性——检测 CUDA/MPS 设备和 VRAM
- 磁盘空间——确认有足够空间下载约 800 MB 的模型
- Python 版本——需要 3.10+
- 现有安装——检查是否已安装
timesfm和torch
注意:模型权重不会存储在此代码库中。TimesFM 权重(约 800 MB) 首次使用时会按需从 HuggingFace 下载,并缓存到
~/.cache/huggingface/。 预检检查器会在开始任何下载前确认资源充足。
flowchart 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
各模型版本的硬件要求
| 模型 | 参数量 | RAM(CPU) | VRAM(GPU) | 磁盘 | 上下文 |
|---|---|---|---|---|---|
| TimesFM 2.5(推荐) | 200M | ≥ 4 GB | ≥ 2 GB | ~800 MB | 最多 16,384 |
| TimesFM 2.0(已归档) | 500M | ≥ 16 GB | ≥ 8 GB | ~2 GB | 最多 2,048 |
| TimesFM 1.0(已归档) | 200M | ≥ 8 GB | ≥ 4 GB | ~800 MB | 最多 2,048 |
建议:除非有特定理由使用较旧的检查点,否则请始终使用 TimesFM 2.5。 它更小、更快,并支持长 8 倍的上下文。
🔧 安装
步骤 1:验证系统(始终首先执行)
python scripts/check_system.py
步骤 2:安装 TimesFM
# Using uv (recommended by this repo)
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]
步骤 3:根据硬件安装 PyTorch
# 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
步骤 4:验证安装
import timesfm
import numpy as np
print(f"TimesFM version: {timesfm.__version__}")
print("Installation OK")
🎯 快速入门
最简示例(5 行)
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
从 CSV 进行预测
import 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))
带协变量的预测(XReg)
TimesFM 2.5+ 通过 forecast_with_covariates() 支持外生变量。需要安装 timesfm[xreg]。
# 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"
)
| 协变量类型 | 描述 | 示例 |
|---|---|---|
dynamic_numerical | 随时间变化的数值 | 价格、温度、促销支出 |
dynamic_categorical | 随时间变化的类别 | 节假日标记、星期几 |
static_numerical | 每个序列对应的数值 | 门店面积、账户年限 |
static_categorical | 每个序列对应的类别 | 门店类型、地区、产品类别 |
XReg 模式:
"xreg + timesfm"(默认):TimesFM 先进行预测,然后由 XReg 调整残差"timesfm + xreg":XReg 先拟合,然后由 TimesFM 预测残差
完整示例请参阅
examples/covariates-forecasting/,其中使用了合成零售数据。
异常检测(通过分位数区间)
TimesFM 没有内置的异常检测功能,但分位数预测可自然提供预测区间,用于检测异常:
point, 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
| 严重程度 | 条件 | 解释 |
|---|---|---|
| 正常 | 在 80% 置信区间内 | 符合预期的行为 |
| 警告 | 超出 80% 置信区间 | 不寻常但有可能发生 |
| 严重 | 超出 90% 置信区间 | 统计上很罕见(概率 < 10%) |
完整示例和可视化请参阅
examples/anomaly-detection/。
# 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"
)
📊 了解输出
分位数预测结构
TimesFM 返回 (point_forecast, quantile_forecast):
point_forecast:形状为(batch, horizon)— 中位数(0.5 分位数)quantile_forecast:形状为(batch, horizon, 10)— 十个切片:
| 索引 | 分位数 | 用途 |
|---|---|---|
| 0 | 均值 | 平均预测 |
| 1 | 0.1 | 80% 预测区间下界 |
| 2 | 0.2 | 60% 预测区间下界 |
| 3 | 0.3 | — |
| 4 | 0.4 | — |
| 5 | 0.5 | 中位数(= point_forecast) |
| 6 | 0.6 | — |
| 7 | 0.7 | — |
| 8 | 0.8 | 60% 预测区间上界 |
| 9 | 0.9 | 80% 预测区间上界 |
提取预测区间
point, q = model.forecast(horizon=H, inputs=data)
# 80% prediction interval (most common)
lower_80 = q[:, :, 1] # 10th percentile
upper_80 = q[:, :, 9] # 90th percentile
# 60% prediction interval (tighter)
lower_60 = q[:, :, 2] # 20th percentile
upper_60 = q[:, :, 8] # 80th percentile
# Median (same as point forecast)
median = q[:, :, 5]
flowchart LR
accTitle: Quantile Forecast Anatomy
accDescr: Diagram showing how the 10-element quantile vector maps to prediction intervals.
input["📈 Input Series<br/>1-D array"] --> model["🤖 TimesFM<br/>compile + forecast"]
model --> point["📍 Point Forecast<br/>(batch, horizon)"]
model --> quant["📊 Quantile Forecast<br/>(batch, horizon, 10)"]
quant --> pi80["80% PI<br/>q[:,:,1] – q[:,:,9]"]
quant --> pi60["60% PI<br/>q[:,:,2] – q[:,:,8]"]
quant --> median["Median<br/>q[:,:,5]"]
classDef data fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e3a5f
classDef model fill:#f3e8ff,stroke:#9333ea,stroke-width:2px,color:#581c87
classDef output fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
class input data
class model model
class point,quant,pi80,pi60,median output
🔧 ForecastConfig 参考
所有预测行为均由 timesfm.ForecastConfig 控制:
timesfm.ForecastConfig(
max_context=1024, # Max context window (truncates longer series)
max_horizon=256, # Max forecast horizon
normalize_inputs=True, # Normalize inputs (RECOMMENDED for stability)
per_core_batch_size=32, # Batch size per device (tune for memory)
use_continuous_quantile_head=True, # Better quantile accuracy for long horizons
force_flip_invariance=True, # Ensures f(-x) = -f(x) (mathematical consistency)
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)
)
| 参数 | 默认值 | 何时更改 |
|---|---|---|
max_context | 0 | 设置为与最长历史窗口相匹配(例如 512、1024、4096) |
max_horizon | 0 | 设置为最大预测长度 |
normalize_inputs | False | 始终设为 True — 防止依赖尺度的不稳定性 |
per_core_batch_size | 1 | 增大以提高吞吐量;如果内存溢出则减小 |
use_continuous_quantile_head | False | 设为 True 以获得校准后的预测区间 |
force_flip_invariance | True | 保持为 True,除非性能分析显示它会造成影响 |
infer_is_positive | True | 对可能为负值的序列(温度、收益)设为 False |
fix_quantile_crossing | False | 设为 True 以确保分位数单调递增 |
📋 常见工作流
工作流 1:单序列预测
flowchart TD
accTitle: Single Series Forecast Workflow
accDescr: Step-by-step workflow for forecasting a single time series with system checking.
check["1. Run check_system.py"] --> load["2. Load model<br/>from_pretrained()"]
load --> compile["3. Compile with ForecastConfig"]
compile --> prep["4. Prepare data<br/>pd.read_csv → np.array"]
prep --> forecast["5. model.forecast()<br/>horizon=N"]
forecast --> extract["6. Extract point + PI"]
extract --> plot["7. Plot or export results"]
classDef step fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#1f2937
class check,load,compile,prep,forecast,extract,plot step
import torch, numpy as np, pandas as pd, timesfm
# 1. System check (run once)
# python scripts/check_system.py
# 2-3. Load and compile
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,
))
# 4. Prepare data
df = pd.read_csv("weekly_demand.csv", parse_dates=["week"])
values = df["demand"].values.astype(np.float32)
# 5. Forecast
point, quantiles = model.forecast(horizon=52, inputs=[values])
# 6. Extract prediction intervals
forecast_df = pd.DataFrame({
"forecast": point[0],
"lower_80": quantiles[0, :, 1],
"upper_80": quantiles[0, :, 9],
})
# 7. Plot
import matplotlib.pyplot as plt
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, forecast_df["forecast"], label="Forecast", color="tab:orange")
ax.fill_between(x_fc, forecast_df["lower_80"], forecast_df["upper_80"],
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)
print("Saved forecast.png")
工作流 2:批量预测(多个序列)
import pandas as pd, numpy as np
# Load wide-format CSV (one column per 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]
# Forecast all series at once (batched internally)
point, quantiles = model.forecast(horizon=30, inputs=inputs)
# Collect results
results = {}
for i, col in enumerate(df.columns):
results[col] = {
"forecast": point[i].tolist(),
"lower_80": quantiles[i, :, 1].tolist(),
"upper_80": quantiles[i, :, 9].tolist(),
}
# Export
import json
with open("batch_forecasts.json", "w") as f:
json.dump(results, f, indent=2)
print(f"Forecasted {len(results)} series → batch_forecasts.json")
工作流 3:评估预测准确度
import numpy as np
# Hold out the last H points for evaluation
H = 24
train = values[:-H]
actual = values[-H:]
point, quantiles = model.forecast(horizon=H, inputs=[train])
pred = point[0]
# Metrics
mae = np.mean(np.abs(actual - pred))
rmse = np.sqrt(np.mean((actual - pred) ** 2))
mape = np.mean(np.abs((actual - pred) / actual)) * 100
# Prediction interval coverage
lower = quantiles[0, :, 1]
upper = quantiles[0, :, 9]
coverage = np.mean((actual >= lower) & (actual <= upper)) * 100
print(f"MAE: {mae:.2f}")
print(f"RMSE: {rmse:.2f}")
print(f"MAPE: {mape:.1f}%")
print(f"80% PI Coverage: {coverage:.1f}% (target: 80%)")
⚙️ 性能调优
GPU 加速
import torch
# Check GPU availability
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"VRAM: {torch.cuda.get_device_properties(0).total_mem / 1e9:.1f} GB")
elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
print("Apple Silicon MPS available")
else:
print("CPU only — inference will be slower but still works")
# Always set this for Ampere+ GPUs (A100, RTX 3090, etc.)
torch.set_float32_matmul_precision("high")
批量大小调优
# Start conservative, increase until OOM
# GPU with 8 GB VRAM: per_core_batch_size=64
# GPU with 16 GB VRAM: per_core_batch_size=128
# GPU with 24 GB VRAM: per_core_batch_size=256
# CPU with 8 GB RAM: per_core_batch_size=8
# CPU with 16 GB RAM: per_core_batch_size=32
# CPU with 32 GB RAM: per_core_batch_size=64
model.compile(timesfm.ForecastConfig(
max_context=1024,
max_horizon=256,
per_core_batch_size=32, # <-- tune this
normalize_inputs=True,
use_continuous_quantile_head=True,
fix_quantile_crossing=True,
))
内存受限的环境
import gc, torch
# Force garbage collection before loading
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
# Load model
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
# Use small batch size on low-memory machines
model.compile(timesfm.ForecastConfig(
max_context=512, # Reduce context if needed
max_horizon=128, # Reduce horizon if needed
per_core_batch_size=4, # Small batches
normalize_inputs=True,
use_continuous_quantile_head=True,
fix_quantile_crossing=True,
))
# Process series in chunks to avoid OOM
CHUNK = 50
all_results = []
for i in range(0, len(inputs), CHUNK):
chunk = inputs[i:i+CHUNK]
p, q = model.forecast(horizon=H, inputs=chunk)
all_results.append((p, q))
gc.collect() # Clean up between chunks
🔗 与其他技能集成
与 statsmodels 配合使用
将 statsmodels 用于经典模型(ARIMA、SARIMAX),作为比较基准:
# 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-visualization 配合使用
绘制包含预测区间的预测图,生成适合发表的图表。
与 exploratory-data-analysis 配合使用
在预测前对时间序列进行 EDA,以了解趋势、季节性和平稳性。
📚 可用脚本
scripts/check_system.py
强制预检工具。 首次加载模型前运行。
python scripts/check_system.py
输出示例:
=== 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=128
scripts/forecast_csv.py
端到端 CSV 预测,并自动执行系统检查。
python scripts/forecast_csv.py input.csv \
--horizon 24 \
--date-col date \
--value-cols sales,revenue \
--output forecasts.csv
📖 参考文档
references/ 中的详细指南:
| 文件 | 内容 |
|---|---|
references/system_requirements.md | 硬件级别、GPU/CPU 选择、内存估算公式 |
references/api_reference.md | 完整的 ForecastConfig 文档、from_pretrained 选项、输出形状 |
references/data_preparation.md | 输入格式、NaN 处理、CSV 加载、协变量设置 |
常见问题
- 未运行系统检查 → 内存较小的机器上加载模型会崩溃。务必先运行
check_system.py。 - 忘记调用
model.compile()→RuntimeError: Model is not compiled。必须在调用forecast()前调用compile()。 - 未设置
normalize_inputs=True→ 对于数值较大的序列,预测结果不稳定。 - 在内存小于 32 GB 的机器上使用 v1/v2 → 改用 TimesFM 2.5(200M 参数)。
- 未设置
fix_quantile_crossing=True→ 分位数可能不是单调递增的(q10 > q50)。 - 在小型 GPU 上使用过大的
per_core_batch_size→ CUDA 内存不足。从较小值开始,再逐步增大。 - 传入二维数组 → TimesFM 需要的是一维数组列表,而不是二维矩阵。
- 忘记设置
torch.set_float32_matmul_precision("high")→ 在 Ampere 及更新的 GPU 上推理速度会变慢。 - 未处理输出中的 NaN → 极短序列可能会出现边缘情况。务必检查
np.isnan(point).any()。 - 对可能为负数的序列使用
infer_is_positive=True→ 预测值会被限制为零。温度、收益等数据应设为 False。
模型版本
timeline
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
| 版本 | 参数量 | 上下文长度 | 分位数预测头 | 频率标志 | 状态 |
|---|---|---|---|---|---|
| 2.5 | 200M | 16,384 | ✅ 连续型(30M) | ❌ 已移除 | 最新 |
| 2.0 | 500M | 2,048 | ✅ 固定分桶 | ✅ 必需 | 已归档 |
| 1.0 | 200M | 2,048 | ✅ 固定分桶 | ✅ 必需 | 已归档 |
Hugging Face 检查点:
google/timesfm-2.5-200m-pytorch(推荐)google/timesfm-2.5-200m-flaxgoogle/timesfm-2.0-500m-pytorch(已归档)google/timesfm-1.0-200m-pytorch(已归档)
资源
- 论文:仅解码器的时间序列预测基础模型(ICML 2024)
- 代码仓库:https://github.com/google-research/timesfm
- Hugging Face:https://huggingface.co/collections/google/timesfm-release-66e4be5fdb56e960c1e482a6
- Google 博客:https://research.google/blog/a-decoder-only-foundation-model-for-time-series-forecasting/
- BigQuery 集成:https://cloud.google.com/bigquery/docs/timesfm-model
示例
examples/ 中有三个完整可用的参考示例。可将它们作为正确 API 用法和预期输出形状的基准。
| 示例 | 目录 | 演示内容 | 适用场景 |
|---|---|---|---|
| 全球气温预测 | examples/global-temperature/ | 基本的 model.forecast() 调用、CSV -> PNG -> GIF 流程、36 个月 NOAA 上下文 | 入门示例;可复制粘贴,作为任何单变量序列的基线 |
| 异常检测 | examples/anomaly-detection/ | 两阶段检测:对上下文进行线性去趋势和 Z-score 处理,对预测结果进行分位数 PI 处理;双面板可视化 | 需要检测历史数据和预测数据中的离群值时 |
| 协变量(XReg) | examples/covariates-forecasting/ | forecast_with_covariates() API(TimesFM 2.5)、协变量分解、共享坐标轴的 2x2 可视化 | 零售、能源,或任何具有已知外生驱动因素的序列 |
运行示例
# Global temperature (no TimesFM 2.5 needed)
cd examples/global-temperature && python run_forecast.py && python visualize_forecast.py
# Anomaly detection (uses TimesFM 1.0)
cd examples/anomaly-detection && python detect_anomalies.py
# Covariates (API demo -- requires TimesFM 2.5 + timesfm[xreg] for real inference)
cd examples/covariates-forecasting && python demo_covariates.py
预期输出
| 示例 | 关键输出文件 | 验收标准 |
|---|---|---|
| global-temperature | output/forecast_output.json、output/forecast_visualization.png | point_forecast 包含 12 个值;PNG 显示上下文 + 预测 + PI 区间 |
| anomaly-detection | output/anomaly_detection.json、output/anomaly_detection.png | 2023 年 9 月被标记为 CRITICAL(z >= 3.0);注入异常后至少有 2 个预测值为 CRITICAL |
| covariates-forecasting | output/sales_with_covariates.csv、output/covariates_data.png | CSV 包含 108 行(3 家门店 x 36 周);各门店的价格数组各不相同 |
质量检查清单
每次完成 TimesFM 任务后,在宣布成功前运行此检查清单:
- 输出形状正确——
point_fc的形状为(n_series, horizon),quant_fc的形状为(n_series, horizon, 10) - 分位数索引——索引 0 = 均值,1 = q10,2 = q20……9 = q90。不是 0 = q0、1 = q10。
- 频率标志——TimesFM 1.0/2.0:月度数据传入
freq=[0]。TimesFM 2.5:不需要频率标志。 - 序列长度——上下文必须包含 >= 32 个数据点(模型最低要求)。若更短,请发出警告。
- 无 NaN——
np.isnan(point_fc).any()应为 False。先检查输入序列是否存在缺口。 - 可视化坐标轴——如果多个面板共享数据,请使用
sharex=True。所有时间轴必须覆盖相同的范围。 - Git LFS 中的二进制输出——PNG 和 GIF 文件必须通过
.gitattributes跟踪(仓库根目录已配置)。 - 不提交大型数据集——任何大于 1 MB 的真实数据集都应下载到
tempfile.mkdtemp(),并在代码中注明。 -
matplotlib.use('Agg')——无头运行时,必须在导入任何 pyplot 之前调用。 -
infer_is_positive——温度异常、金融收益或任何可能为负值的序列,应设为False。
常见错误
此技能的示例中曾出现以下错误。请引以为戒:
-
分位数索引偏移一位——最常见的错误。
quant_fc[..., 0]是均值,不是 q0。q10 = 索引 1,q90 = 索引 9。请始终定义具名常量:IDX_Q10, IDX_Q20, IDX_Q80, IDX_Q90 = 1, 2, 8, 9。 -
推导式中的变量遮蔽——如果在循环中构建每个序列的协变量字典,不要将循环变量用作推导式变量。应在循环外累积到单独的
dict[str, ndarray]中,然后再赋值。# WRONG -- outer `store_id` gets shadowed: covariates = {store_id: arr[store_id] for store_id in stores} # inside outer loop over store_id # CORRECT -- use a different name or accumulate beforehand: prices_by_store: dict[str, np.ndarray] = {} for store_id, config in stores.items(): prices_by_store[store_id] = compute_price(config) -
CSV 列名错误——global-temperature CSV 使用的是
anomaly_c,而不是anomaly。访问前请始终运行print(df.columns)。 -
使用
sharex=True时出现tight_layout()警告——无害;可通过plt.tight_layout(rect=[0, 0, 1, 0.97])抑制,或忽略。 -
forecast_with_covariates()需要 TimesFM 2.5——TimesFM 1.0 没有此方法。请安装pip install timesfm[xreg]并使用检查点google/timesfm-2.5-200m-pytorch。 -
未来协变量必须覆盖完整预测时域——动态协变量(价格、促销、节假日)必须同时包含上下文和预测时域的值。不能只传入上下文数组。
-
异常阈值必须只定义一次——将
CRITICAL_Z = 3.0、WARNING_Z = 2.0定义为模块级常量。不要在代码中直接写入3或2。 -
上下文异常检测使用残差,而非原始值——始终先去趋势(使用
np.polyfit线性拟合或季节分解),再对残差计算 Z 分数。在趋势数据上使用原始值计算 Z 分数会产生误导。
验证与核验
将示例输出用作回归基准。如果更改了预测逻辑,请验证:
# Anomaly detection regression check:
python -c "
import json
d = json.load(open('examples/anomaly-detection/output/anomaly_detection.json'))
ctx = d['context_summary']
assert ctx['critical'] >= 1, 'Sep 2023 must be CRITICAL'
assert any(r['date'] == '2023-09' and r['severity'] == 'CRITICAL'
for r in d['context_detections']), 'Sep 2023 not found'
print('Anomaly detection regression: PASS')"
# Covariates regression check:
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)}'
prices = df.groupby('store_id')['price'].mean()
assert prices['store_A'] > prices['store_B'] > prices['store_C'], 'Store price ordering wrong'
print('Covariates regression: PASS')"