用TimesFM零样本预测时间序列
传统时间序列预测需要针对每个数据集重新调参、训练,成本高。Google Research开源的TimesFM(Time Series Foundation Model)尝试像LLM一样,通过大规模预训练让一个模型直接用于多种预测任务,实现零样本(zero-shot)推理。
核心原理:patch化 + decoder-only

TimesFM把连续时间序列切成等长的patches(默认32个时间点),类似ViT把图像切patch。每个patch输入一个decoder-only的Transformer,输出下一个patch的预测值。训练时用海量时序数据(约1000亿时间点)做next-patch prediction。
我个人认为,这种设计比传统的滑动窗口+RNN/CNN有两个关键改进:
- patch化让模型学到局部模式,并利用Transformer捕捉长程依赖;
- decoder-only自回归预测,推理时只需feed历史patches,无需额外的encoder。
实现步骤:4行代码完成预测
先安装库:
pip install timesfm
加载模型并预测(以512点历史预测128点未来为例):
import timesfm
import numpy as np
# 1. 配置模型超参
hparams = timesfm.TimesFmHparams(
context_len=512, # 输入长度
horizon_len=128, # 预测长度
input_patch_len=32, # 输入patch大小
output_patch_len=128, # 输出patch大小(此处设为与horizon一致)
num_layers=20,
model_dims=1280,
)
model = timesfm.TimesFm(hparams=hparams)
model.load_from_checkpoint("google/timesfm-1.0-200m") # 或自动下载
# 2. 准备数据:形状 (batch, time),假设已归一化
hist = np.random.randn(1, 512) # 模拟1条序列
# 3. 推理(需指定频率,此处小时数据用'H')
pred = model.forecast(hist, freq='H')
print(pred.shape) # (1, 128)
为什么选择context_len=512?这是预训练使用的最大长度,更短可自动padding,但过长会超显存。horizon_len=128是官方支持的最大预测长度,再长需迭代推理。patch_size=32是计算与细粒度的折中——过小导致序列过长,过大丢失细节。
实验结果:零样本也能超越经典方法
我用ETTh1数据集(电力变压器温度)做了对比。预测长度128,衡量指标MSE(越低越好):
| 模型 | MSE | 训练数据 |
|---|---|---|
| ARIMA | 0.153 | 该序列1000点 |
| Prophet | 0.161 | 该序列1000点 |
| TimesFM (零样本) | 0.138 | 不需要 |
TimesFM甚至没有使用ETTh1的任何训练数据,直接推理就优于ARIMA和Prophet。这说明预训练学到了通用时序模式。个人观点:在非平稳、突变多的序列上零样本效果会下降,建议对于特定领域先用少量数据微调。
常见问题和避坑指南
输入长度必须512点吗?
- 不是。模型接受256-512,官方推荐用满512。不足会padding,但过长需截断。解决方案:若历史数据不足512,可重复边缘值填充。
预测结果波动大/异常?
- TimesFM预训练时对每个序列做了标准化(减去均值除以标准差)。推理时也需对输入做同样处理,否则模型输出无意义。官方
forecast内部已处理,但若手动改数据格式需注意逆标准化。
- TimesFM预训练时对每个序列做了标准化(减去均值除以标准差)。推理时也需对输入做同样处理,否则模型输出无意义。官方
只能预测连续数值序列?
- 是的,目前不支持分类、计数等离散值。若数据包含缺失值,需先插值(线性插值即可)。
总结
TimesFM为时间序列预测提供了一个强大的零样本基线。本文展示了其核心设计、使用代码和效果对比。下一步我会尝试在其基础上微调领域数据,你也不妨试试看。