Skip to content

feat: add support for T0 (theforecastingcompany/t0-alpha)#348

Open
GeoffNN wants to merge 4 commits into
TimeCopilot:mainfrom
GeoffNN:feat/add-t0
Open

feat: add support for T0 (theforecastingcompany/t0-alpha)#348
GeoffNN wants to merge 4 commits into
TimeCopilot:mainfrom
GeoffNN:feat/add-t0

Conversation

@GeoffNN

@GeoffNN GeoffNN commented Jun 12, 2026

Copy link
Copy Markdown

Summary

Adds T0, The Forecasting Company's open-weights time series foundation model, as a new foundation forecaster. T0 (t0-alpha, ~102M params, Apache-2.0) is a decoder-style patch transformer producing probabilistic multi-horizon quantile forecasts — currently #1 on the fev-bench leaderboard (skill score 42.2) and CRPS 0.4941 on GIFT-Eval.

(Disclosure: I work at The Forecasting Company.)

Changes

  • timecopilot/models/foundation/t0.pyT0 forecaster wrapping the tfc-t0 package, following the existing foundation-model pattern (_get_model context manager, TimeSeriesDataset batching, QuantileConverter for levels/quantiles). The model predicts 5 quantile knots and interpolates arbitrary requested levels in a single forward pass; the median is the point forecast. Ragged batches are left-padded with NaN, which T0 treats as missing.
  • pyproject.tomltfc-t0>=0.1.2 for Python 3.11–3.13 (the package's supported range), mirroring the TiRex/uni2ts marker pattern.
  • tests/models/conftest.pyT0(context_length=256, batch_size=2) added to the model matrix under a version guard, plus a test_t0_import_fails guard test mirroring TiRex/Sundial.
  • Docs: API reference entry + Model Hub listing.

Validation

Run locally on macOS / Python 3.12. The lock resolves to tfc-t0 0.1.2 + einops 0.7.0 + jaxtyping 0.2.38:

  • forecast with defaults, quantiles=[0.1, 0.5, 0.9], and level=[80] on multi-series daily data: correct columns, finite values, monotone quantiles, median == point forecast.
  • cross_validation(df, h=6): correct shape and columns.
  • uv run pytest tests/models/test_models.py::test_t0_import_fails (skips on 3.11–3.13, asserts ImportError outside).
  • ruff check + ruff format --check pass on the new/changed files.

Note

tfc-t0 0.1.2 (the version this depends on) is published to PyPI; uv.lock is regenerated and committed. Ready for review.

🤖 Generated with Claude Code

@CLAassistant

CLAassistant commented Jun 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@GeoffNN GeoffNN marked this pull request as ready for review June 14, 2026 21:41
Copilot AI review requested due to automatic review settings June 14, 2026 21:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for the T0 open-weights foundation forecaster, including dependency wiring, test gating by Python version, and documentation references.

Changes:

  • Introduces T0 forecaster wrapper with quantile/level output support.
  • Adds tfc-t0 dependency with Python version markers and registers the model in test fixtures.
  • Documents the new model in the model hub and API docs.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
timecopilot/models/foundation/t0.py Adds the T0 forecaster implementation and forecasting logic.
tests/models/test_models.py Adds an import-failure test for unsupported Python versions.
tests/models/conftest.py Conditionally includes T0 in the models list for supported Python versions.
pyproject.toml Adds tfc-t0 dependency with Python version markers.
docs/model-hub.md Adds T0 to the model hub listing.
docs/api/models/foundation/models.md Adds T0 to the API documentation module list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +185 to +190
fcst_df[self.alias] = fcsts_np[..., median_idx].reshape(-1, 1)
if qc.quantiles is not None:
for q in qc.quantiles:
fcst_df[f"{self.alias}-q-{int(q * 100)}"] = fcsts_np[
..., pred_quantiles.index(q)
].reshape(-1, 1)
Comment on lines +177 to +181
out = model.predict(
self._to_context(batch),
horizon=h,
quantiles=pred_quantiles,
)
Comment on lines +91 to +93
finally:
del model
torch.cuda.empty_cache()
Comment on lines +175 to +181
with self._get_model() as model:
for batch in tqdm(dataset):
out = model.predict(
self._to_context(batch),
horizon=h,
quantiles=pred_quantiles,
)
GeoffNN and others added 2 commits June 15, 2026 02:39
Adds The Forecasting Company's open-weights T0 foundation model as a
foundation forecaster, via the tfc-t0 package (Python 3.11–3.13).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regenerated after tfc-t0 0.1.2 (metadata-only floor relaxation) was
published to PyPI. Resolves to tfc-t0 0.1.2 + einops 0.7.0 +
jaxtyping 0.2.38 — the combo the T0 adapter is verified against.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@GeoffNN

GeoffNN commented Jun 15, 2026

Copy link
Copy Markdown
Author

Hi @AzulGarza — this is ready for your review when you have a moment 🙏 (I don't have permission to add you as a reviewer formally, hence the ping.)

Quick status:

  • CLA signed; CI is currently action_required and needs a maintainer to approve the workflow run (first-time contributor).
  • Added tfc-t0 as a new foundation forecaster following the Toto adapter pattern; tfc-t0 0.1.2 is published on PyPI and uv.lock is regenerated (the large-looking lock churn was just toml-sort normalization — net diff is the single tfc-t0 entry).
  • Verified end-to-end via TimeCopilotForecaster.forecast/cross_validation on air_passengers (point + 80/95% intervals), plus quantile/level paths.

The Copilot auto-review left 4 comments; I checked each against the tfc-t0 API and the existing Toto adapter and they're non-issues (predict is already @torch.inference_mode() and moves inputs to the model device; empty_cache() + reshape(-1, 1) match toto.py). Happy to reply inline with specifics if useful. Thanks!

@AzulGarza

Copy link
Copy Markdown
Member

hey @GeoffNN! thanks for the pr, it looks great! could you take a look at uv.lock? looks like there’s a conflict with main from a recent merge. once that’s fixed, everything should be good to go!

Resolve uv.lock conflict by taking main's resolution (tirex>=0.1.1 bump,
torchvision dropped, xlstm added) plus this branch's tfc-t0 addition.
Verified content-identical to a full `uv lock` regeneration; `uv lock --check`
passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merge main into feat/add-t0 (resolve uv.lock conflict)
@GeoffNN

GeoffNN commented Jun 16, 2026

Copy link
Copy Markdown
Author

@AzulGarza should be good now! Thanks for the review 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants