How to Compile the TimesFM Model for Forecasting: PyTorch and JAX Guide
To compile the TimesFM model, load the pretrained weights for your chosen backend, configure the context and horizon lengths, and call model.compile() to build an optimized decode kernel that validates input dimensions and enables high-performance batched inference.
The google-research/timesfm repository provides a 200M parameter time-series foundation model with dual backend support. Compiling the TimesFM model is a mandatory initialization step that prepares the architecture for inference by aligning patch sizes, enforcing context limits, and generating backend-specific execution kernels. This guide details the compilation API for both PyTorch and Flax/JAX implementations using the exact source paths and method signatures from the codebase.
Why Compile the TimesFM Model?
Compilation performs three critical functions before you can call model.forecast():
- Kernel Generation: Creates a custom decode closure (PyTorch) or
nnx.pmapkernel (Flax) that executes the forward pass with fixedmax_contextandmax_horizondimensions. - Validation: Automatically adjusts input and output lengths to be multiples of the model's patch sizes (
pfor input patches,ofor output patches) and verifies thatmax_context + max_horizondoes not exceed the model's internal context limit. - Configuration Storage: Persists a
ForecastConfigobject (PyTorch) or scalar parameters (Flax) that control optional behaviors including input normalization, flip invariance, and continuous quantile heads.
According to src/timesfm/timesfm_2p5/timesfm_2p5_base.py:59-61, the base class explicitly checks that self.compiled_decode exists and raises a clear error if compilation was skipped.
Compiling the PyTorch Backend
The PyTorch implementation requires a ForecastConfig dataclass and performs rigorous limit checking during compilation.
Step-by-Step Compilation Process
In src/timesfm/timesfm_2p5/timesfm_2p5_torch.py, the compile() method executes the following sequence (lines 68-124):
- Size Alignment: Adjusts
max_contextandmax_horizonto be multiples of patch sizespando(lines 68-84). - Limit Enforcement: Validates that
max_context + max_horizondoes not exceedself.model.config.context_limit, raising an error if violated (lines 84-89). - Config Storage: Assigns the
ForecastConfiginstance toself.forecast_config(line 94). - Kernel Construction: Builds a
_compiled_decodeclosure that handles tensor casting, optional normalization, and quantile processing (lines 96-124). - Assignment: Stores the closure in
self.compiled_decode(line 87).
PyTorch Compilation Example
import torch
import numpy as np
import timesfm
from timesfm import ForecastConfig
# Load the pretrained TimesFM-2.5 200M PyTorch model
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
# Configure forecasting parameters
fc = ForecastConfig(
max_context=1024, # Input window length (adjusted to patch multiple)
max_horizon=256, # Prediction steps (adjusted to patch multiple)
normalize_inputs=True, # Enable Revin normalization
use_continuous_quantile_head=True,
force_flip_invariance=True,
infer_is_positive=True,
fix_quantile_crossing=True,
)
# Compile the model (creates optimized decode kernel)
model.compile(fc)
# Execute forecast
inputs = [np.linspace(0, 1, 100), np.sin(np.linspace(0, 20, 67))]
point, quantile = model.forecast(horizon=12, inputs=inputs)
The ForecastConfig dataclass is defined in src/timesfm/configs.py, while the compilation logic resides in src/timesfm/timesfm_2p5/timesfm_2p5_torch.py.
Compiling the Flax/JAX Backend
The Flax implementation uses direct integer arguments rather than a configuration object and leverages JAX's nnx.pmap for parallel execution.
JAX Compilation Parameters
In src/timesfm/timesfm_2p5/timesfm_2p5_flax.py, the compile() method (lines 43-73) performs:
- Patch Alignment: Rounds
contextandhorizonto valid patch multiples using the same logic as PyTorch (lines 43-56). - Parameter Storage: Assigns
self.context,self.horizon, andself.per_core_batch_size(lines 58-60). - Parallel Kernel: Constructs
compiled_decode_kernelusingnnx.pmapto callmodel.decodeacross all available devices (lines 62-73).
Unlike the PyTorch backend, the Flax implementation does not explicitly check context limits during compilation; out-of-bounds errors surface during kernel execution.
Flax Compilation Example
import jax.numpy as jnp
import timesfm
from timesfm import TimesFM_2p5_200M_flax
# Load the Flax/JAX checkpoint
model = TimesFM_2p5_200M_flax.from_pretrained(
"google/timesfm-2.5-200m-flax"
)
# Compile with explicit integers (must be patch multiples)
model.compile(context=1024, horizon=256, per_core_batch_size=1)
# Prepare inputs and forecast
inputs = [jnp.linspace(0, 1, 100), jnp.sin(jnp.linspace(0, 20, 67))]
point, quantile = model.forecast(horizon=12, inputs=inputs)
Post-decode processing in Flax (flip invariance, quantile head application, and crossing fixes) occurs in separate JIT-compiled helpers invoked during forecast(), as seen in src/timesfm/timesfm_2p5/timesfm_2p5_flax.py around lines 70-150.
Summary
Compiling the TimesFM model is a required prerequisite for inference that ensures optimal performance and valid input dimensions:
- PyTorch: Pass a
ForecastConfigobject tocompile(); the method validates context limits atsrc/timesfm/timesfm_2p5/timesfm_2p5_torch.py:84-89. - Flax/JAX: Pass integer
contextandhorizonvalues; compilation builds annnx.pmapkernel atsrc/timesfm/timesfm_2p5/timesfm_2p5_flax.py:62-73. - Both backends validate patch-size alignment and store compilation state required by the base class check in
src/timesfm/timesfm_2p5/timesfm_2p5_base.py:59-61. - Execute compilation once after
from_pretrained()and before the firstforecast()call.
Frequently Asked Questions
What happens if I call forecast() without compiling the TimesFM model?
The base class implementation in src/timesfm/timesfm_2p5/timesfm_2p5_base.py:59-61 explicitly checks for the presence of self.compiled_decode. If you attempt to run inference before compilation, the model raises a clear runtime error indicating that the decode kernel has not been initialized.
Can I change the context length after compilation?
No. The compilation process fixes max_context and max_horizon to create an optimized decode kernel. If you need to forecast with different input or output lengths, you must re-invoke model.compile() with the new dimensions. This constraint applies to both the PyTorch and Flax/JAX backends.
How do the PyTorch and JAX compilation approaches differ?
PyTorch compilation uses a ForecastConfig dataclass from src/timesfm/configs.py and enforces strict context limit checks during the compile phase. JAX compilation accepts direct integer arguments for context and horizon, builds a parallelized kernel using nnx.pmap, and delegates limit validation to runtime. The PyTorch backend stores a closure for post-processing, while Flax applies post-decode transformations through separate JIT-compiled functions.
What is the correct per_core_batch_size for JAX compilation?
The per_core_batch_size parameter in Flax compilation determines the batch size per device before parallelization. Set this value based on your hardware memory constraints; the total batch size equals per_core_batch_size multiplied by the device count. For single-device inference, use per_core_batch_size=1 as shown in the Flax example, then scale up for multi-GPU or TPU pods.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →