Skip to main content

The Forecasting Company

t0

PyPI Python versions License

Open-weights time-series forecasting foundation model from The Forecasting Company. t0 is a transformer-based model that produces probabilistic multi-horizon forecasts and natively operates on multiple covariates. t0-beta is the current iteration: 256M parameters, 21 natively predicted quantile levels, and an incremental improvement over t0-alpha.

You can use t0 on Retrocast, our platform for forecasting on your own data. You can also compare forecast across different open-weight models.

Model family: t0-beta (PyTorch/MLX) · t0-alpha · Collection

Choose how to run t0-beta

This repository contains the first-party PyTorch and MLX runtimes, published as separate packages so each installation keeps only its native tensor backend. ONNX artifacts and our managed API cover other deployment targets:

Use case Install or open
Local inference with PyTorch pip install "tfc-t0>=0.5.0"
Local inference on Apple silicon with MLX pip install "tfc-t0-mlx>=0.1.0"
Accelerator-oriented local and edge inference with ONNX FP16 t0-alpha-onnx-fp16
CPU and in-browser inference with ONNX INT8 t0-alpha-onnx-int8
Managed inference without local weights The Forecasting Company API

The ONNX artifacts are built from t0-alpha; there is no t0-beta ONNX export yet.

The MLX runtime lives in mlx/. It is inference-only, has a closely matched T0Forecaster.predict() API, loads the same safetensors directly, and does not install PyTorch.

t0 forecasting French national electricity demand in Retrocast

t0 forecasting French national electricity demand in Retrocast. Data: Enedis open data.

📈 Forecasting with covariates

t0 leverages covariate information, in the past and future when available, to improve its forecast.

Without covariates With covariates
t0 forecast without covariates t0 forecast with covariates

Data: Medic'AM, monthly drug reimbursements from the French national health insurance.

The Quickstart below shows the API for both a plain univariate forecast and a multivariate forecast that conditions on historical and known-future covariates.

🚀 Quickstart

pip install "tfc-t0>=0.5.0"

t0-beta normalizes its inputs differently from t0-alpha, and carries the convention in config.json as scaler_eps and scaler_eps_mode. Releases before 0.5.0 do not read those fields: they load these weights without error and run them under t0-alpha's normalization, which silently degrades the forecast. Pin the floor.

The simplest path is a univariate forecast through predict:

import torch
from t0 import T0Forecaster

model = T0Forecaster.from_pretrained("theforecastingcompany/t0-beta").eval()

context = torch.randn(4, 512)  # 4 series, 512 past timesteps
out = model.predict(context, horizon=64, quantile_levels=[0.1, 0.5, 0.9])
out.quantiles  # (4, 64, 3)
out.median     # (4, 64)

predict accepts numpy arrays. 1-D contexts are auto-promoted to a single-row batch. NaN in the context is read as a missing observation. To say that some cells are padding instead, pass a mask. See batched inference.

t0-beta downloads without authentication. t0-alpha is gated: sign in to its model page, accept the access conditions, then run hf auth login (or, in a notebook, from huggingface_hub import login; login()) and pass token=True to from_pretrained.

Forecasting with covariates

Anything you know over the past goes in context — alongside the target, extra variates attend to it and are forecast together. Anything you know over the future (calendar features, planned promotions, weather forecasts) goes in future_covariates, shaped [B, F, context + horizon]. The model conditions on it but does not forecast it.

import torch
from t0 import T0Forecaster

model = T0Forecaster.from_pretrained("theforecastingcompany/t0-beta").eval()

context = torch.randn(2, 512)                    # 2 series, 512 past timesteps
future_covariates = torch.randn(2, 3, 512 + 64)  # 3 covariates known over context + horizon

out = model.predict(
    context,
    horizon=64,
    quantile_levels=[0.1, 0.5, 0.9],
    future_covariates=future_covariates,
)
out.quantiles  # (2, 64, 3)
out.median     # (2, 64)

Batched inference

import numpy as np
from t0 import T0Forecaster, batch_series

model = T0Forecaster.from_pretrained("theforecastingcompany/t0-beta").eval()

daily = np.random.randn(180)    # one series, 180 past timesteps
store = np.random.randn(2, 96)  # one series of 2 variates, 96 past timesteps
hourly = np.random.randn(1024)  # one series, 1024 past timesteps

context, mask, group_ids = batch_series([daily, store, hourly])
context.shape  # (4, 1024) — variates stacked, right-aligned to the longest
group_ids      # [0, 1, 1, 2] — `store`'s two variates are forecast jointly

out = model.predict(
    context,
    horizon=24,
    quantile_levels=[0.1, 0.5, 0.9],
    mask=mask,
    group_ids=group_ids,
)
out.quantiles  # (4, 24, 3)
out.median[0]  # the 24-step median forecast for `daily`

Integrations that prepare complete T0 inputs, including known-future covariates, can batch the native representation directly:

from t0 import TimeSeries

first = TimeSeries.from_array(context_1, future_covariates_1)
second = TimeSeries.from_array(context_2, future_covariates_2)
batch = TimeSeries.batch([first, second])

out = model.predict(
    batch,
    horizon=64,
    context_length=max(context_1.shape[-1], context_2.shape[-1]),
)

Here each context includes its batch axis, for example [1, V, T], and each known-future input is [1, F, T + horizon]. The output is ordered by the flattened target rows in batch.

Converting your data to TimeSeries

TimeSeries is the model's native input. It holds target rows, known-future covariate rows, a mask and group ids, all on one width. predict builds one for you from a raw array. You only need to construct one yourself to batch inputs of different widths, or to call forward directly.

from t0 import TimeSeries

# context only, with `horizon` marking the region to predict
model_input = TimeSeries.from_array(context, horizon=24)          # context: [B, V, T]

# with known-future covariates, whose width sets the horizon
model_input = TimeSeries.from_array(context, future_covariates)   # covariates: [B, F, T + 24]

out = model.predict(model_input, horizon=24, quantile_levels=[0.1, 0.5, 0.9])

predict infers context_length from where the forecast region starts. Pass it explicitly when batching series of different widths. forward takes the same TimeSeries and runs a single differentiable pass over it, with no rollout. That is the entry point for fine-tuning.

For efficient inference at scale, look at Retrocast.

🏗️ Architecture

t0 is a decoder-style patch transformer that alternates time and covariate attention layers. It decodes multiple horizons in parallel — up to 1024 timesteps in one forward pass — and falls back on autoregressive rollout for longer horizons. Quantile levels between the trained ones are interpolated, and levels beyond them extrapolated on exponential tails.

t0-beta t0-alpha
Parameters ~256M ~102M
Layers 24 24
Embedding dim 1024 512
Feedforward dim 2048 2048
Attention heads 8 8
Patch size 32 32
Quantile levels 21, from 0.01 to 0.99 0.1, 0.25, 0.5, 0.75, 0.9
T0Config T0Config.large() T0Config.medium()

🧬 Lineage

t0 builds on ideas — and in places, code — from open-source forecasting models. We gratefully acknowledge:

  • Toto by Datadog (repo) & Chronos-2 by Amazon (repo) — factorizing attention in the time and variates dimension.
  • TiRex by NXAI (repo) — contiguous patch masking.

Code-level attributions are listed in NOTICE, all under Apache-2.0.

🧰 Public API

  • T0Forecaster — nn.Module with from_pretrained / save_pretrained (via huggingface_hub.PyTorchModelHubMixin). It has two forecasting entry points. forward(model_input) runs a single differentiable pass with no rollout. predict(model_input, horizon, quantile_levels, ...) is inference-only and rolls out autoregressively past max_horizon.
  • Forecast — the object returned by the model.
  • T0Config — the configuration of the model. T0Config.large() is t0-beta; T0Config.medium() is t0-alpha.
  • MaskType — the reason a time step is masked out: PAD (a cell that only widens a shorter series out to the batch's width) or MISSING (an absent observation).
  • batch_series — utility to batch time series of potentially different lengths.
  • TimeSeries.from_array / TimeSeries.batch — build the model's native input, including known-future covariates and an explicit forecast horizon. predict accepts either a TimeSeries or a raw context array.

📚 Citation

If our model is useful, please use the following citation and star our repo!

@misc{tfc-t0,
  title  = {t0: A time-series forecasting foundation model},
  author = {The Forecasting Company},
  year   = {2026},
  url    = {https://huggingface.co/theforecastingcompany/t0-beta},
}

⚖️ License

Apache-2.0 — see LICENSE and NOTICE.

Metadata

Release files for tfc-t0 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tfc-t0 0.5.0
File Size Uploaded
tfc_t0-0.5.0.tar.gz 523.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tfc-t0 0.5.0
File Interpreter ABI Platform
tfc_t0-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 578.7 kB

Release files / tfc_t0-0.5.0.tar.gz

Download URL tfc_t0-0.5.0.tar.gz
Size 523.6 kB
Tags Source
SHA-256 checksum
How to use checksums
603e43a16da6210ca11fc26f957b1b43a7f2a60caa59e34643a015ec85335da7
BLAKE2b-256 checksum
How to use checksums
cd5072f469a14395b80efa72c5a94a6a595673cf5fa73e2f92c5dbba082c6c63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release files / tfc_t0-0.5.0-py3-none-any.whl

Download URL tfc_t0-0.5.0-py3-none-any.whl
Size 55.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
551936dfe72b0464d3963d0b3bf4415d49b6ac37c5695ff97b8ff844f12c6a8c
BLAKE2b-256 checksum
How to use checksums
776ba33a4382e70f7612ae82f0c5f4178f5c1132f317508ef6def180054f73cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page