# Can TimesFM Handle Time Series with Different Scales? Scale-Equivariance Explained

> TimesFM natively handles time series with different scales via scale-equivariance, offering optional normalization for extreme ranges.

- Repository: [Google Research/timesfm](https://github.com/google-research/timesfm)
- Tags: deep-dive
- Published: 2026-04-02

---

**Yes, TimesFM can natively handle time series with vastly different scales through its built-in scale-equivariance guarantee, while also providing optional input normalization pipelines for extreme numerical ranges.**

Time series forecasting pipelines frequently encounter heterogeneous data—from cryptocurrency prices in the thousands to IoT sensor readings in the millionths. According to the google-research/timesfm repository, TimesFM addresses this challenge architecturally rather than through preprocessing alone, allowing models to forecast across orders of magnitude without losing accuracy or requiring separate scaling layers.

## How TimesFM Handles Different Scales

TimesFM implements three distinct mechanisms to ensure robustness across varying magnitudes: a mathematical scale-equivariance property, optional reversible input normalization, and per-series scaling utilities for covariates.

### Scale-Equivariance Guarantee

At the core of TimesFM’s multi-scale capability is a **scale-equivariance** property that satisfies the equation `TimesFM(a·X + b) = a·TimesFM(X) + b` for any non-negative scaling factor `a`. This means the model’s predictions automatically scale linearly with the input magnitude without requiring learned scaling parameters or manual preprocessing.

When the `force_flip_invariance` flag is enabled in the configuration, this property extends to negative scaling factors as well, ensuring the model maintains consistent behavior even when input series are inverted. This guarantee is documented in the `ForecastConfig` dataclass in [`src/timesfm/configs.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/configs.py) (lines 42-44), where the architectural contract is explicitly defined.

### Optional Input Normalization

For scenarios involving extreme magnitudes that might cause numerical instabilities, TimesFM provides an explicit normalization path. Setting `normalize_inputs=True` in the forecast configuration triggers a reversible normalization wrapper (Revin) that standardizes inputs to zero-mean and unit-variance before decoding, then de-standardizes the outputs to restore the original scale.

This logic is implemented in [`src/timesfm/timesfm_2p5/timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/timesfm_2p5/timesfm_2p5_torch.py) (lines 13-18 and 74-76), where the wrapper computes per-batch statistics (`mu`, `sigma`) using `torch.mean` and `torch.std`, applies the transformation, and inverts it after forecasting.

### Per-Series Normalization for X-Regression

When working with covariates (X-regressions) that exhibit heterogeneous scales within the same batch, the library provides dedicated utilities in [`src/timesfm/utils/xreg_lib.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/utils/xreg_lib.py) (lines 60-66). The `normalize` function computes separate mean and standard deviation statistics for each individual time series in a batch, allowing covariates of vastly different magnitudes to coexist without interference. The paired `renormalize` function restores the original scale using these stored statistics.

## Practical Code Examples

### Basic Forecasting Using Scale-Equivariance

You can rely on TimesFM’s native scale-equivariance by disabling normalization. This approach requires no preprocessing even when batching series with wildly different magnitudes:

```python
from timesfm import TimesFM, ForecastConfig

# Configure the model to use scale-equivariance without normalization

cfg = ForecastConfig(
    max_context=256,
    max_horizon=48,
    normalize_inputs=False,   # rely on scale-equivariance

    force_flip_invariance=True,
)

model = TimesFM(
    # model architecture arguments omitted for brevity

)

# Batch with three different scales: small, large, and tiny

inputs = [
    [0.1, 0.15, 0.2, 0.25],                # small values

    [1000, 1100, 1200, 1300, 1400],        # large values

    [5e-6, 1e-5, 2e-5, 3e-5, 4e-5, 5e-5]  # tiny values

]

# Forecast 12 steps ahead

forecast = model.forecast(
    inputs,
    horizon=12,
    forecast_config=cfg,
)

print(forecast.shape)   # (3, 12, q) – predictions respect each series' scale

```

The same model handles all three scales simultaneously because of the equivariance property hardcoded into the architecture.

### Handling Extreme Magnitudes with Normalization

For numerical stability with extreme values, enable the reversible normalization wrapper:

```python
cfg = ForecastConfig(
    max_context=512,
    max_horizon=24,
    normalize_inputs=True,    # enable standardization

    force_flip_invariance=True,
)

forecast = model.forecast(
    inputs,
    horizon=24,
    forecast_config=cfg,
)

```

Under the hood, the decoder receives standardized inputs centered around zero with unit variance. The stored `mu` and `sigma` values from [`timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/timesfm_2p5_torch.py) are then applied to the raw forecasts to return predictions in the original scale.

### Normalizing Heterogeneous Covariates

When using X-regression with covariates of different scales, apply per-series normalization:

```python
from timesfm.utils.xreg_lib import normalize, renormalize

# Covariates with different magnitudes

targets = [[10, 12, 14, 16], [0.001, 0.002, 0.003]]
norm_targets, stats = normalize(targets)   # per-series mean/std

# Feed norm_targets to your regression model...

# After forecasting:

forecasts = renormalize(predicted_norm, stats)

```

The `normalize` utility computes statistics independently for each series (as implemented in [`xreg_lib.py`](https://github.com/google-research/timesfm/blob/main/xreg_lib.py) lines 62-64), ensuring that a covariate with magnitude `10` does not dominate one with magnitude `0.001` during training.

## Key Implementation Files

The multi-scale functionality spans several core files:

- **[`src/timesfm/configs.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/configs.py)** (lines 42-44): Defines `ForecastConfig` with `force_flip_invariance` that documents the scale-equivariance guarantee.
- **[`src/timesfm/timesfm_2p5/timesfm_2p5_torch.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/timesfm_2p5/timesfm_2p5_torch.py)** (lines 13-18, 74-76): Implements the optional `normalize_inputs` path using the Revin wrapper for the PyTorch backend.
- **[`src/timesfm/utils/xreg_lib.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/utils/xreg_lib.py)** (lines 60-66): Houses `normalize` and `renormalize` helpers for per-series covariate scaling.
- **[`src/timesfm/timesfm_2p5/timesfm_2p5_flax.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/timesfm_2p5/timesfm_2p5_flax.py)**: Mirrors the normalization logic for the JAX/Flax backend.
- **[`v1/src/timesfm/timesfm_base.py`](https://github.com/google-research/timesfm/blob/main/v1/src/timesfm/timesfm_base.py)**: Contains the high-level `normalize` flag used by the classic v1 API.

## Summary

- **TimesFM is scale-equivariant by design**, satisfying `TimesFM(a·X + b) = a·TimesFM(X) + b`, which eliminates the need for manual scaling across different magnitudes.
- **Optional normalization is available** via `normalize_inputs=True` in `ForecastConfig`, using reversible standardization for extreme numerical ranges.
- **Per-series normalization utilities** in [`xreg_lib.py`](https://github.com/google-research/timesfm/blob/main/xreg_lib.py) handle heterogeneous covariate scales through independent mean and standard deviation calculations.
- **Both approaches are compatible**: you can rely on native equivariance for most use cases or enable explicit normalization when numerical conditioning requires it.

## Frequently Asked Questions

### Does TimesFM require manual normalization for different scales?

No. TimesFM handles different scales natively through its scale-equivariance property. You only need to enable `normalize_inputs=True` if your data contains extreme magnitudes that could cause numerical instability during computation.

### What is the `force_flip_invariance` parameter in TimesFM?

The `force_flip_invariance` flag, defined in [`src/timesfm/configs.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/configs.py), extends the scale-equivariance guarantee to negative scaling factors. When enabled, the model satisfies `TimesFM(-a·X) = -a·TimesFM(X)`, ensuring consistent predictions even if input series are multiplied by negative constants.

### How does TimesFM handle covariates with different scales?

TimesFM provides the `normalize` and `renormalize` functions in [`src/timesfm/utils/xreg_lib.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/utils/xreg_lib.py) specifically for X-regression tasks. These utilities compute separate mean and standard deviation statistics for each series in a batch, standardize the covariates before processing, and restore the original scale afterward.

### Where is the scale-equivariance property documented in the codebase?

The scale-equivariance guarantee is documented in the `ForecastConfig` dataclass within [`src/timesfm/configs.py`](https://github.com/google-research/timesfm/blob/main/src/timesfm/configs.py) (lines 42-44), where the `force_flip_invariance` field describes the mathematical property. The actual implementation of this behavior is integrated into the core model architecture rather than residing in a separate scaling layer.