Understanding the `force_flip_invariance` Parameter in TimesFM

The force_flip_invariance parameter is a boolean configuration flag in the google-research/timesfm repository that enforces affine transformation symmetry by running the model twice—once on the original input and once on the negated input—then averaging the results to guarantee the mathematical property TimesFM(aX + b) = a × TimesFM(X) + b for any scalar a and offset b.

The force_flip_invariance parameter appears in the ForecastConfig dataclass within the TimesFM (Time Series Foundation Model) codebase. According to the implementation in src/timesfm/configs.py, this flag controls whether the forecasting pipeline guarantees symmetry under sign flips and scaling operations, which is crucial for maintaining consistent predictions when input time series undergo affine transformations.

What Is Flip Invariance in TimesFM?

Flip invariance ensures that the model's predictions respect affine transformations of the input time series. When enabled (the default behavior), TimesFM guarantees that for any scalar value a (including negative values) and any offset b, the following property holds:

[ \text{TimesFM}(aX + b) = a \times \text{TimesFM}(X) + b ]

To achieve this, the forecasting pipeline executes two decode passes: one using the original input series and another using the flipped (negated) input. The model then averages these two predictions, ensuring the final output remains symmetric with respect to sign changes. When the flag is set to False, the model skips the second decode pass, returning only the standard forecast. This reduces computational overhead but breaks the symmetry guarantee for negative scalings.

Implementation Details in the Source Code

Configuration Definition in configs.py

The flag is formally defined in src/timesfm/configs.py within the ForecastConfig dataclass. At line 42, force_flip_invariance is declared as a boolean field defaulting to True. This configuration object propagates through the TimesFM initialization and controls the decoding behavior at inference time.


# src/timesfm/configs.py - Line 42

@dataclass
class ForecastConfig:
    max_context: int = 1024
    max_horizon: int = 256
    force_flip_invariance: bool = True  # Default enables symmetry enforcement

Torch Implementation

The Torch-based decoding logic resides in src/timesfm/timesfm_2p5/timesfm_2p5_torch.py. Around line 31, the implementation checks the flag and, when active, invokes self.model.decode on -inputs (the negated series). It then combines these results with the original predictions through averaging to maintain the affine equivariance property.


# Conceptual flow from src/timesfm/timesfm_2p5/timesfm_2p5_torch.py

if forecast_config.force_flip_invariance:
    # Run decoder on negative inputs

    flipped_pred = self.model.decode(-inputs, ...)
    # Average with original prediction

    prediction = (original_pred + flipped_pred) / 2

Flax Implementation

The Flax (JAX) implementation in src/timesfm/timesfm_2p5/timesfm_2p5_flax.py utilizes a dedicated helper function _force_flip_invariance_fn, defined around line 8. This function manages the transformation of quantile outputs from the negated run and ensures proper averaging to preserve the mathematical invariance across different backend implementations.

Configuration and Usage Examples

To utilize this feature, instantiate ForecastConfig and pass it to your model's compile method. The default configuration enables flip invariance, which is recommended for production forecasting to ensure robustness against input transformations.


# Example 1: Default behavior (flip invariance enabled)

from timesfm.configs import ForecastConfig

cfg = ForecastConfig(
    max_context=1024,
    max_horizon=256,
    force_flip_invariance=True,  # Optional; True is default

)

model.compile(forecast_config=cfg)

For latency-sensitive applications where input series are guaranteed to be positively scaled, you can disable the feature to reduce compute by roughly half (avoiding the second decode pass).


# Example 2: Disable for faster inference

cfg = ForecastConfig(
    max_context=1024,
    max_horizon=256,
    force_flip_invariance=False,  # Skip extra decode pass

)

model.compile(forecast_config=cfg)

The timesfm-forecasting/scripts/forecast_csv.py script demonstrates practical usage at line 68, where the configuration is typically instantiated with default values but can be overridden via command-line arguments or direct modification.

Summary

  • force_flip_invariance is defined in src/timesfm/configs.py as a boolean field within ForecastConfig, defaulting to True.
  • When enabled, the model runs two decode passes (original and negated inputs) and averages results to guarantee affine equivariance: TimesFM(aX + b) = a × TimesFM(X) + b.
  • The Torch implementation in timesfm_2p5_torch.py handles this by decoding -inputs and averaging.
  • The Flax implementation in timesfm_2p5_flax.py uses _force_flip_invariance_fn to manage quantile flipping and averaging.
  • Disabling the flag reduces inference latency by eliminating the second decode pass but sacrifices the symmetry guarantee for negative scaling factors.

Frequently Asked Questions

What happens when force_flip_invariance is set to True?

When enabled, TimesFM executes the decoder twice: once on the original input tensor and once on the negated input (-inputs). It then averages these two predictions, which mathematically enforces the property that predictions transform linearly with the input, specifically handling negative scalings correctly.

Does disabling force_flip_invariance affect prediction accuracy?

Disabling the flag does not inherently reduce accuracy for standard positive-scaled inputs, but it removes the guarantee that predictions will correctly transform under affine operations involving negative scalars. If your application involves differenced series or reflections that result in negative values, disabling this flag may lead to inconsistent forecasts.

Where is the force_flip_invariance parameter defined in the codebase?

The parameter is formally defined in src/timesfm/configs.py at line 42 within the ForecastConfig dataclass. It is consumed by the model implementations in src/timesfm/timesfm_2p5/timesfm_2p5_torch.py and src/timesfm/timesfm_2p5/timesfm_2p5_flax.py.

Is there a performance cost to using flip invariance?

Yes. Enabling force_flip_invariance approximately doubles the decoding compute because the model runs the full forward pass twice (once per input sign). According to the implementation in timesfm_2p5_torch.py, this involves calling self.model.decode on both the original and negated inputs, which doubles the inference time for the decoding phase.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →