Transformer Configuration Details for TimesFM 2.5: Complete Architecture Guide
TimesFM 2.5 (also referred to as TimesFM 2.S) implements a 20-layer stacked transformer architecture with 1280-dimensional hidden states, 16 attention heads, RMSNorm normalization throughout, rotary positional embeddings (RoPE), and bias-free Swish-activated feed-forward networks, all centralized in the TransformerConfig dataclass.
The google-research/timesfm repository contains the official implementation of TimesFM 2.5, a foundation model for time series forecasting. Understanding the transformer configuration details for TimesFM 2.5 is essential for fine-tuning, extending, or debugging the model, as every architectural hyperparameter is explicitly defined in the source code and exposed through the TimesFM_2p5_200M_Definition class.
Core Transformer Configuration Parameters
TimesFM 2.5 defines its architecture through the TransformerConfig dataclass located in src/timesfm/configs.py. The concrete instantiation for the 200M parameter model appears in TimesFM_2p5_200M_Definition within src/timesfm/timesfm_2p5/timesfm_2p5_base.py (lines 101–117).
| Parameter | Value | Description |
|---|---|---|
model_dims |
1280 |
Hidden dimension size for all transformer layers. |
hidden_dims |
1280 |
Intermediate size of the feed-forward network (FFN). |
num_heads |
16 |
Number of attention heads (head dimension = 80). |
num_layers |
20 |
Total stacked transformer blocks in the model. |
attention_norm |
"rms" |
Applies RMSNorm before and after the attention block. |
feedforward_norm |
"rms" |
Applies RMSNorm before and after the FFN block. |
qk_norm |
"rms" |
Applies RMSNorm to query and key vectors within attention heads. |
use_bias |
False |
All linear projections (attention and FFN) operate without bias terms. |
use_rotary_position_embeddings |
True |
Enables RoPE for Q/K vectors before attention computation. |
ff_activation |
"swish" |
Uses the Swish non-linearity in the FFN. |
fuse_qkv |
True |
Enables fused QKV projection for optimized JAX execution. |
Configuration Implementation in the Codebase
Model Definition in timesfm_2p5_base.py
The TimesFM_2p5_200M_Definition class assembles the full model by stacking 20 identical transformer layers. The configuration is passed through StackedTransformersConfig:
# src/timesfm/timesfm_2p5/timesfm_2p5_base.py (lines 101-117)
stacked_transformers = StackedTransformersConfig(
num_layers=20,
transformer=TransformerConfig(
model_dims=1280,
hidden_dims=1280,
num_heads=16,
attention_norm="rms",
feedforward_norm="rms",
qk_norm="rms",
use_bias=False,
use_rotary_position_embeddings=True,
ff_activation="swish",
fuse_qkv=True,
),
)
Transformer Block Implementation in transformer.py
The Transformer class in src/timesfm/flax/transformer.py (lines 291–357) consumes this configuration to build each layer using Flax NNX. The constructor initializes:
- Pre-attention RMSNorm (
pre_attn_ln) and post-attention RMSNorm (post_attn_ln) - MultiHeadAttention with RoPE, per-dimension scaling, and Q/K RMSNorm
- Pre-FFN RMSNorm (
pre_ff_ln) and post-FFN RMSNorm (post_ff_ln) - Bias-free linear layers
ff0(1280→1280) andff1(1280→1280) with Swish activation
Step-by-Step Architecture Flow
During the forward pass, each of the 20 transformer blocks executes the following residual operations:
- Pre-attention RMSNorm normalizes the input before feeding it into the multi-head attention mechanism.
- Multi-Head Attention computes attention using rotary positional embeddings on Q/K, RMSNorm on Q/K (via
qk_norm), and a causal mask generated bymake_attn_mask. - Post-attention RMSNorm stabilizes the residual stream after the attention output is added.
- Pre-FFN RMSNorm prepares the signal for the feed-forward network.
- FFN Computation passes through
ff0→ Swish activation →ff1, with no bias terms. - Post-FFN RMSNorm finalizes the block before the residual addition returns control to the next layer.
Practical Code Examples
Inspecting the Default Configuration
Retrieve the exact hyperparameters from the model definition:
from timesfm.timesfm_2p5.timesfm_2p5_base import TimesFM_2p5_200M_Definition
cfg = TimesFM_2p5_200M_Definition.stacked_transformers.transformer
print("Model dim :", cfg.model_dims) # 1280
print("Heads :", cfg.num_heads) # 16
print("FFN hidden:", cfg.hidden_dims) # 1280
print("Rotary PE :", cfg.use_rotary_position_embeddings) # True
Building a Single Transformer Layer
Instantiate a standalone transformer block matching the TimesFM 2.5 specification:
import jax
import jax.numpy as jnp
from flax import nnx
from timesfm.flax.transformer import Transformer
from timesfm.configs import TransformerConfig
config = TransformerConfig(
model_dims=1280,
hidden_dims=1280,
num_heads=16,
attention_norm="rms",
feedforward_norm="rms",
qk_norm="rms",
use_bias=False,
use_rotary_position_embeddings=True,
ff_activation="swish",
fuse_qkv=True,
)
rngs = nnx.Rngs(0)
transformer = Transformer(config, rngs=rngs)
# Dummy input: batch=2, seq_len=64, dim=1280
x = jnp.zeros((2, 64, 1280))
patch_mask = jnp.zeros((2, 64), dtype=bool)
out, _ = transformer(x, patch_mask)
print(out.shape) # (2, 64, 1280)
Stacking the Full 20-Layer Model
Construct the complete stacked architecture programmatically:
from timesfm.flax.transformer import Transformer
from timesfm.configs import StackedTransformersConfig, TransformerConfig
stack_cfg = StackedTransformersConfig(
num_layers=20,
transformer=TransformerConfig(
model_dims=1280,
hidden_dims=1280,
num_heads=16,
attention_norm="rms",
feedforward_norm="rms",
qk_norm="rms",
use_bias=False,
use_rotary_position_embeddings=True,
ff_activation="swish",
fuse_qkv=True,
),
)
rngs = nnx.Rngs(0)
layers = [Transformer(stack_cfg.transformer, rngs=rngs)
for _ in range(stack_cfg.num_layers)]
def forward(x, mask):
cache = None
for layer in layers:
x, cache = layer(x, mask, decode_cache=cache)
return x
Summary
- 20 transformer layers form the backbone of TimesFM 2.5, each with 1280 model dimensions and 1280 FFN hidden dimensions.
- 16 attention heads split the hidden space into 80-dimensional heads, utilizing RMSNorm for attention, feed-forward, and Q/K normalization.
- Rotary positional embeddings provide positional information, while bias-free linear layers and Swish activation optimize the FFN.
- Configuration is centralized in
TransformerConfigand instantiated viaTimesFM_2p5_200M_Definitioninsrc/timesfm/timesfm_2p5/timesfm_2p5_base.py.
Frequently Asked Questions
What is the difference between TimesFM 2.5 and TimesFM 2.S?
They refer to the same model. The source code uses "2.S" (indicating version 2.5) in identifiers like TimesFM_2p5_200M_Definition, while public documentation and release notes refer to it as TimesFM 2.5.
Why does TimesFM 2.5 use RMSNorm instead of LayerNorm?
The configuration explicitly sets attention_norm, feedforward_norm, and qk_norm to "rms". RMSNorm offers similar stabilization benefits to LayerNorm with reduced computational overhead, which the Transformer class implements in src/timesfm/flax/transformer.py using RMSNorm modules before and after each sub-layer.
How many parameters does the TimesFM 2.5 transformer have?
The TimesFM_2p5_200M_Definition class implements approximately 200 million parameters, derived from the 20 stacked layers, 1280-dimensional hidden states, and corresponding feed-forward networks.
Can I modify the transformer configuration for custom training?
Yes. You can instantiate a custom TransformerConfig with alternative model_dims, num_heads, or num_layers values and pass it to the Transformer constructor or StackedTransformersConfig. Note that pre-trained checkpoints released by Google Research are only compatible with the default 1280-dimensional, 20-layer configuration.
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 →