ONNX¶
TiRex-2 is also available as an ONNX model, so you can run it with only numpy and
onnxruntime. You don't need PyTorch or the tirex2 package. The file is model.onnx in the
Hugging Face repository.
Installation¶
pip install numpy onnxruntime huggingface_hub
Forecasting¶
The model always reads a fixed window of 2368 steps: 2048 steps of context followed by 320
steps of horizon. The forecast function below fills your series into that window (padding
with NaN), runs the model, and returns the forecast horizon.
Both univariate and multivariate series are supported. For a multivariate series, pass one row per variate; all variates are forecast jointly.
import numpy as np
import onnxruntime as ort
from huggingface_hub import hf_hub_download
CONTEXT_LEN, FUTURE_LEN, PATCH_SIZE = 2048, 320, 32
QUANTILES = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
onnx_path = hf_hub_download("NX-AI/TiRex-2", "model.onnx")
session = ort.InferenceSession(onnx_path, providers=["CPUExecutionProvider"])
def forecast(session, series, prediction_length):
"""Return [9, prediction_length] quantiles for a 1D series, or
[n_variates, 9, prediction_length] for a 2D (n_variates, length) series."""
window = CONTEXT_LEN + FUTURE_LEN
x = np.atleast_2d(np.asarray(series, dtype=np.float32))
n_variates = x.shape[0]
x = np.pad(x, ((0, 0), (0, FUTURE_LEN)), constant_values=np.nan) # empty horizon
x = np.pad(x, ((0, 0), (max(0, window - x.shape[1]), 0)), constant_values=np.nan)
x = x[:, -window:] # keep only the last 2048 context steps
out = session.run(None, {
"context": x,
"group_vector": np.ones(n_variates, dtype=np.float32), # same group = forecast jointly
"target_mask": np.ones(n_variates, dtype=bool),
})[0]
out = out[:, :, -FUTURE_LEN - PATCH_SIZE:-PATCH_SIZE][..., :prediction_length]
return out[0] if np.ndim(series) == 1 else out
t = np.arange(400)
series = np.sin(2 * np.pi * t / 48)
prediction = forecast(session, series, prediction_length=32) # (9, 32)
median = prediction[QUANTILES.index(0.5)]
low, high = prediction[0], prediction[-1] # 10% and 90% quantiles
# Multivariate: all variates are forecast jointly
multivariate = np.stack([series, np.cos(2 * np.pi * t / 48)]) # (2, 400)
prediction = forecast(session, multivariate, prediction_length=32) # (2, 9, 32)
seriescan be a 1D array, or a 2D array of shape(n_variates, length)for a multivariate series. Use NaN for missing values.prediction_lengthcan be at most 320.
Differences to the tirex2 package
The ONNX file contains the model only. The tirex2 package additionally removes linear
trends before forecasting and recalibrates the quantile band afterwards. For series without
a strong trend, the median is the same and the quantiles are very close. For strongly
trending series, use the tirex2 package if you need identical results.
Running on a GPU¶
Install onnxruntime-gpu[cuda,cudnn] instead of onnxruntime, and turn TF32 off. ONNX Runtime
enables TF32 by default, which reduces accuracy for this model:
session = ort.InferenceSession(
onnx_path,
providers=[("CUDAExecutionProvider", {"use_tf32": 0}), "CPUExecutionProvider"],
)