Skip to content

feat: add T0Model foundation model - #3142

Open
GeoffNN wants to merge 10 commits into
unit8co:masterfrom
theforecastingcompany:feature/add-t0-foundation-model
Open

GeoffNN wants to merge 10 commits into
unit8co:masterfrom
theforecastingcompany:feature/add-t0-foundation-model

Conversation

@GeoffNN

@GeoffNN GeoffNN commented Jun 23, 2026

Copy link
Copy Markdown

Hi folks! Great work on darts! 🙏
We just released our first open-source model: t0-alpha. Adding it to your library so people can easily use it, benchmark it etc.

Checklist before merging this PR:

  • Mentioned all issues that this PR fixes or addresses.
  • Summarized the updates of this PR under Summary.
  • Added an entry under Unreleased in the Changelog.

Summary

Adds T0Model, a Darts wrapper around The Forecasting Company's open-weights T0 foundation model (~100M-parameter patch transformer for zero-shot forecasting). It follows the existing foundation-model pattern, closest to TiRexModel (delegates to an optional pip package) while also supporting future covariates like Chronos2Model.

  • Subclasses FoundationModel; zero-shot inference for univariate, multivariate, and multiple series.
  • Delegates all forecasting logic and weight loading to the optional tfc-t0 package (from t0 import T0Forecaster), declared in the optional dependency group (not pulled by darts[torch]).
  • Future covariates supported (supports_future_covariates=True): forward() reassembles Darts' (x_past, x_future) into T0's [B, F, context + horizon] covariate layout, NaN-filling the output_chunk_shift gap (T0 treats NaN as missing). Past covariates are not supported.
  • Probabilistic forecasts via QuantileRegression. Any quantiles in (0, 1) are accepted — T0 interpolates levels it was not trained on (it was trained on [0.1, 0.25, 0.5, 0.75, 0.9]).
  • Fine-tuning is explicitly rejected — T0 is a zero-shot inference model (predict() runs under torch.inference_mode()).

Registered in the models lazy-import table, conftest availability flag (T0_AVAILABLE), README / INSTALL / docs model tables, pyproject.toml optional group, and CHANGELOG.md.

Other Information

Tests in darts/tests/models/forecasting/test_t0.py mock T0Forecaster.from_pretrained so CI never downloads weights (gated behind T0_AVAILABLE, matching the TiRex test pattern). Covers creation/validation, deterministic + probabilistic, multivariate, future covariates, and multiple series.

Verified locally against the real theforecastingcompany/t0-alpha weights — univariate deterministic, probabilistic with interpolated quantiles (0.05/0.95), future-covariate, and multivariate forecasts all produce finite outputs of the expected shape.

🤖 Generated with Claude Code

@GeoffNN
GeoffNN requested a review from dennisbader as a code owner June 23, 2026 20:47
GeoffNN added a commit to theforecastingcompany/darts that referenced this pull request Jun 23, 2026
GeoffNN added a commit to theforecastingcompany/darts that referenced this pull request Jun 23, 2026
@daidahao

Copy link
Copy Markdown
Contributor

Nice PR! @GeoffNN

Leaving my two cents here as the original contributor of FoundationModel:

Would you consider relaxing t0 python bounds to 3.10+ so all users can access your model?

Also, is there a reason why past covariates cannot be supported? I have not looked into the model architecture, but would implanting past covariates as part of the context help improve the forecast quality? If so, I would suggest appending past covariates to the context and dropping them from the output.

PS. It would be nice if a technical report / blog post can be provided to help us and users understand the model better.

@GeoffNN

GeoffNN commented Jun 25, 2026

Copy link
Copy Markdown
Author

Hi @daidahao !
Thanks for reviewing 🙏
We treat past covariates as more targets essentially - since the targets are handled in a multi-variate way. I'll fix this in the PR.

The tech report & blog post are both incoming, we'll release this a bit later.
Cheers!

@dennisbader

Copy link
Copy Markdown
Collaborator

Thanks a lot for this PR @GeoffNN 🚀 Before giving a full review, there are two points:

  • As @daidahao mentioned, can you enable python 3.10 support in the tfc-t0 package itself?
  • All foundation models in Darts currently support (simple) fine-tuning. The idea was that we only add models that support this (since we're open-source). Would it be possible to relax the inference-mode requirement so that the parameters can be updated when running the model? We had a similar conversation on the TiRex integration (here), where the authors also enabled support for it :)

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 97.06%. Comparing base (8232dd1) to head (6e79b18).

Files with missing lines Patch % Lines
darts/models/forecasting/t0_model.py 98.66% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3142   +/-   ##
=======================================
  Coverage   97.05%   97.06%           
=======================================
  Files         169      170    +1     
  Lines       18903    18978   +75     
=======================================
+ Hits        18347    18421   +74     
- Misses        556      557    +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@GeoffNN

GeoffNN commented Jun 27, 2026

Copy link
Copy Markdown
Author

Hi both!

  • We're working on enabling the 3.10 requirement. cc @jfainberg on our side
  • Re: finetuning, is it just adding the enable_finetuning flag? From the tirex conversation, I understand that you're not asking for model-specific finetuning code.

Since the model is Apache 2.0, there's no restriction on our side for this!

@dennisbader

Copy link
Copy Markdown
Collaborator

Thanks a lot for the updates @GeoffNN, that sounds great 🚀

Regarding fine-tuning:

  • Yes, it's about the enable_finetuning flag and we don't need model-specific fine-tuning code. Adding the model to our existing foundation model fine-tuning tests here should be enough.
  • From your PR description I read that your model is currently running under the @inference_mode decorator. To enable fine-tuning (parameter updates), you would need to expose a method that is not running under inference mode.

Let me know if it's clear or whether we can support in any way.

@dennisbader

Copy link
Copy Markdown
Collaborator

@GeoffNN another question regarding adding tfc-t0 as a dependency to Darts: I quickly checked out your dependency requirements and noticed that all have an upper version cap here. Is there a specific reason you limit the upper versions? That would mean that at some point, tfc-t0 would block Darts users from installing newer dependency versions. Would it be possible to relax (remove) these caps?

@GeoffNN

GeoffNN commented Jul 11, 2026

Copy link
Copy Markdown
Author

Hello! Sorry for the delay here, we've been traveling - and want to think about the API surface we expose, especially for the with-gradients side.

Re: versions - I believe we gate against untested (future) versions, to avoid breaking the package silently if the dependencies change their API on a major version. Let me double check.

@dennisbader

Copy link
Copy Markdown
Collaborator

Thanks for the updates @GeoffNN 🚀

In the open-source world the continuous dependency integration (e.g. checking against newest versions and then fixing the package continuously if there are some breaking changes in dependencies) is a pro-active way to keep the package up-to-date. So, I would always recommend to go that way (except maybe where you're developing apps or similar where you want to ensure everyone user gets the exact same fixed environment (via dependency lockfiles for example).

Let me know what you think

huikan-tfc added a commit to theforecastingcompany/darts that referenced this pull request Jul 20, 2026
Resolve CHANGELOG.md conflict by dropping the unit8co#1915, unit8co#3147 and unit8co#1917
unreleased entries that master has since shipped in 0.46.0, keeping the
still-unreleased T0Model entry (unit8co#3142).

Bump the tfc-t0 pin to >=0.2.2, whose release drops the dependency upper
bounds (and the requires-python ceiling) raised in review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@huikan-tfc
huikan-tfc force-pushed the feature/add-t0-foundation-model branch 2 times, most recently from 134a5a1 to 667e480 Compare July 24, 2026 14:19
- Add classes to use t0-alpha for inference and fine-tuning.
- Add t0-alpha fine-tuning example to the dedicated notebook.
- Add tests for T0Model classes
- Add tfc-t0 v0.4.0 to the optional dependencies

Co-authored-by: Huikan Xiang <huikan-tfc@users.noreply.github.com>
Co-authored-by: Geoffrey Négiar <GeoffNN@users.noreply.github.com>
@LTMeyer
LTMeyer force-pushed the feature/add-t0-foundation-model branch from 1d84b09 to 3d704c6 Compare September 15, 2026 21:49
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@LTMeyer

LTMeyer commented Sep 15, 2026

Copy link
Copy Markdown

Hi @dennisbader and @daidahao,
Thank you for the time you've already taken to review this PR. With @GeoffNN, @huikan-tfc and myself, we reworked the PR by simplifying the T0Model interface and allowing fine tuning.

Also, is there a reason why past covariates cannot be supported? I have not looked into the model architecture, but would implanting past covariates as part of the context help improve the forecast quality? If so, I would suggest appending past covariates to the context and dropping them from the output.

It should be done now. Thanks for the suggestion. The model indeed supports past (passed along the context) and future covariates.

From your PR description I read that your model is currently running under the @inference_mode decorator. To enable fine-tuning (parameter updates), you would need to expose a method that is not running under inference mode.

We now rely on the forward method of the model directly for the fine-tuning. We've added an example for the fine-tuning to the dedicated notebook. We checked it was running (see image below).

Screenshot 2026-09-15 at 15 29 01

One important note on the model, it is currently gated on Hugging Face. Still, anyone can have access to it, and again it has been released under Apache 2 license. We added a note to the notebook, but I don't know whether it may bother your CI.

PS. It would be nice if a technical report / blog post can be provided to help us and users understand the model better.

The tech report is coming very shortly. I'll drop a comment here whenever it's released.

@LTMeyer

LTMeyer commented Sep 17, 2026

Copy link
Copy Markdown

The tech report is coming very shortly. I'll drop a comment here whenever it's released.

Here it is.

@dennisbader

Copy link
Copy Markdown
Collaborator

Thanks for the updates and all the changes both on this PR and the tfc-t0 repo @LTMeyer, @GeoffNN, @huikan-tfc 🚀

I've tested it on my side and also made the PR work with our torch module I/O refactor #3204.

Would it be possible to grant me write permission to your Darts fork? Then I could apply the changes there directly.

@jfainberg

Copy link
Copy Markdown

Hi @dennisbader , thank you! I just granted you access to our Darts fork. Much appreciated! 🙌

@dennisbader

dennisbader commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the invite @jfainberg :) For some reason I'm still not able to push to the branch due to missing permissions. Could you maybe check again for the correct permissions?

remote: Permission to theforecastingcompany/darts.git denied to dennisbader.
fatal: unable to access 'https://github.com/theforecastingcompany/darts/': The requested URL returned error: 403

@dennisbader

Copy link
Copy Markdown
Collaborator

@jfainberg sorry, nevermind, now it works :) I was using the wrong token 🙈.

@jfainberg

Copy link
Copy Markdown

no problem @dennisbader ! :)

@dennisbader

dennisbader commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Hi all and thanks a lot for the great PR @GeoffNN, @LTMeyer, @huikan-tfc and @jfainberg 🚀

I've applied some minor changes to make the model ready for merging:

  • doc updates
  • added some more tests
  • mention t0-beta and make it the default model

I wanted to double check with you to make sure everything is implemented correctly for t0-beta in our Darts model wrapper.

Below you can find an example comparing t0-alpha against t0-beta using our T0Model implementation (it's the same example we show in the foundation model example notebook here). t0-alpha captures the weekend - weekday pattern well, whereas t0-beta seems to struggle a bit there. Of course I'm aware that foundation models are not expected to work great on all examples. Just wanted to make sure that we're not forgetting about additional steps for t0-beta in how it is currently implemented in Darts :)

Would you mind reviewing once the current Darts implementation so we can get it ready for merging? Thanks a lot!

Code example
from darts.datasets import ElectricityConsumptionZurichDataset
from darts.models import T0Model

# use past month to forecast one week (in quarterly hours)
context_length = 30 * 24 * 4
horizon = 7 * 24 * 4

series = ElectricityConsumptionZurichDataset().load().astype("f")["Value_NE5"]
train = series[:-horizon]

fig = series[-2*horizon:].plotly(label="actual")
for model_card, color in zip(
    ["theforecastingcompany/t0-alpha", "theforecastingcompany/t0-beta"],
    ["red", "green"],
):
    model = T0Model(
        input_chunk_length=30 * 24 * 4,
        output_chunk_length=horizon,
        hub_model_name=model_card,
    )
    forecast = model.fit(train).predict(n=horizon, series=train)
    name = model_card.split("/")[-1]
    fig = forecast.plotly(label=f"forecast: {name}", fig=fig, color=color)
fig.show()
image

@LTMeyer

LTMeyer commented Sep 21, 2026

Copy link
Copy Markdown

Thank you @dennisbader for the update and providing this new example. t0-alpha and t0-beta have some differences internally, but this should be already captured by the model card. Let me dig a bit more!

@LTMeyer

LTMeyer commented Sep 22, 2026

Copy link
Copy Markdown

Hi @dennisbader, thank you again for raising the issue. We were able to reproduce it locally. It seems, so far, t0-beta is indeed not performing great on this time series and this context size. Still, we believe we can move on with this PR, if it's good for you, while we will work on fixing t0-beta on this example.

This branch has not been deployed

No deployments
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