Skip to content

Conversation

@ahmedkansulum
Copy link

Summary

This PR makes the TimeXer v2 implementation consistent with the v2 / tslib design by removing the duplicated configuration of endogenous and exogenous variables inside TimeXer._forecast.

Instead of re-selecting series using self.endogenous_vars / self.exogenous_vars on top of the tslib metadata, the model now relies solely on the tensors provided by the data pipeline (history_target and history_cont).

This implements option 1 discussed in #2003 ("not overriding or passing twice").

Motivation / Context

In v2, feature configuration is intended to be described by the metadata produced by TslibDataModule and consumed by TslibBaseModel. TimeXer v2 currently has:

  • feature names and indices described in metadata
  • and additional endogenous_vars / exogenous_vars kwargs that are used in _forecast to re-select columns from history_cont

This leads to two different places where the endogenous / exogenous split can be defined, which is exactly the concern raised in #2003.

The maintainers confirmed that option 1 is preferred: relying on the metadata / data pipeline only, i.e. not overriding or passing the configuration twice.

What this PR changes

In pytorch_forecasting/models/timexer/_timexer_v2.py:

  • TimeXer._forecast no longer uses self.endogenous_vars or self.exogenous_vars to re-select columns from history_cont.

  • Instead, the method now follows the v2 convention:

    • endogenous information is taken from history_target
    • exogenous information is taken from all continuous covariates in history_cont

Concretely, the previous block:

# explicitly set endogenous and exogenous variables endogenous_cont = history_target if self.endogenous_vars: endogenous_indices = [ self.feature_names["continuous"].index(var) for var in self.endogenous_vars ] endogenous_cont = history_cont[..., endogenous_indices] exogenous_cont = history_cont if self.exogenous_vars: exogenous_indices = [ self.feature_names["continuous"].index(var) for var in self.exogenous_vars ] exogenous_cont = history_cont[..., exogenous_indices]

is replaced by:

# v2 convention: # - endogenous information comes from the target history # - exogenous information comes from all continuous covariates endogenous_cont = history_target exogenous_cont = history_cont

The rest of _forecast (embedding, encoder, head) remains unchanged.

API / behaviour notes

  • The endogenous_vars and exogenous_vars arguments are still present in TimeXer.__init__ and are stored on self, but they are no longer used in _forecast.
  • This keeps the public signature unchanged for now (no immediate breaking change), while removing the duplicated configuration path that conflicted with the v2 metadata design.
  • In practice, this means TimeXer v2 now always behaves as if the endogenous information is given by the target history and the exogenous information by the continuous covariates provided by TslibDataModule.
  • If desired, a follow-up PR can deprecate or remove these args entirely from the public API.

Tests

On Windows with Python 3.13, I ran:

python -m pytest -k "TimeXer" -q --basetemp="C:\Projects\pytorch-forecasting\.pytest_tmp"
  • 75 tests passed
  • 1 test skipped
  • 0 failures

The failures reported earlier were due to a local Windows permission issue with the default pytest temp directory; pointing --basetemp at a project-local directory resolved that, and the TimeXer tests now run cleanly with the change in place.

Notes

  • This PR is intentionally scoped to the functional change in _forecast only.
  • I am happy to follow up with a separate PR (or extend this one if preferred) to:
    • deprecate/remove the endogenous_vars / exogenous_vars kwargs from TimeXer.__init__, and
    • update the class docstring and docs accordingly.
@codecov
Copy link

codecov bot commented Dec 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@ccc56ef). Learn more about missing BASE report.

Additional details and impacted files
@@ Coverage Diff @@ ## main #2009 +/- ## ======================================= Coverage ? 86.98% ======================================= Files ? 160 Lines ? 9488 Branches ? 0 ======================================= Hits ? 8253 Misses ? 1235 Partials ? 0 
Flag Coverage Δ
cpu 86.98% <ø> (?)
pytest 86.98% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 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.
Copy link
Member

@phoeenniixx phoeenniixx left a comment

Choose a reason for hiding this comment

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

Hello @ahmedkansulum!
Welcome to pytorch-forecasting!
I think there has been some issue while committing, I can't see the changes made by you. Can you please have a look at it?

@ahmedkansulum
Copy link
Author

Hello @ahmedkansulum! Welcome to pytorch-forecasting! I think there has been some issue while committing, I can't see the changes made by you. Can you please have a look at it?

@phoeenniixx Thank you.
I am looking into this now and will revert shortly.

@ahmedkansulum
Copy link
Author

Hi @phoeenniixx,
Thanks for the heads up and the warm welcome! You were right, my earlier commits didn’t actually contain the intended _forecast change, which is why there was no diff versus main.

I have now re-applied the change in pytorch_forecasting/models/timexer/_timexer_v2.py so that _forecast uses history_target for the endogenous input and history_cont for the exogenous covariates, consistent with the v2 metadata / TslibDataModule design. I also re-ran pytest -k "TimeXer" and pre-commit locally and they pass.

Please let me know if anything else needs adjusting.

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

Labels

None yet

2 participants