-
Notifications
You must be signed in to change notification settings - Fork 885
[DOC] Add a v1 to v2 migration guide #2349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
echo-xiao
wants to merge
7
commits into
sktime:main
Choose a base branch
from
echo-xiao:migration-guide-v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
993953f
docs: add v2 migration guide skeleton and wire into api_v2 toctree
echo-xiao 2c802f0
docs: add v1 to v2 concept mapping table to migration guide
echo-xiao 25443f7
docs: add TFT before/after example to migration guide
echo-xiao eb9145b
docs: add prose sections and cross-references to migration guide
echo-xiao e81ce6a
docs: list v2 models via auto-generated model-overview in migration g…
echo-xiao d416626
docs: rework v1->v2 migration guide as a developer model-migration gu…
echo-xiao 19914ec
[DOC] surface v1->v2 migration guide in v2 page beta boxes
echo-xiao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| Migrating models from v1 to v2 | ||
| ============================== | ||
|
|
||
| .. warning:: | ||
| The v2 model layer is in active development / beta. Use with caution. | ||
| v1 remains stable for production — see :doc:`v1 API <api>`. | ||
|
|
||
| .. currentmodule:: pytorch_forecasting | ||
|
|
||
| .. note:: | ||
| This is a **developer** guide — how to migrate a model's *implementation* from | ||
| the v1 API to the v2 four-layer architecture, per the roadmap goal *"migrate the | ||
| models from v1 to v2 and deprecate v1"* | ||
| (`#1993 <https://github.com/sktime/pytorch-forecasting/issues/1993>`_), aiming | ||
| for **minimal changes to the model code**. To *use* v2 to build forecasts, see | ||
| the v2 tutorials (``ptf_V2_example`` in :doc:`tutorials_v2`) instead; for the | ||
| general contribution workflow, see the developer guide. | ||
|
|
||
| Overview | ||
| -------- | ||
|
|
||
| Because the ``forward`` contract is unchanged between v1 and v2, migrating a model | ||
| is mostly a **re-organisation of the constructor and the surrounding package | ||
| plumbing**, not a rewrite of the network. A migrated model: | ||
|
|
||
| * inherits the v2 ``BaseModel`` (or ``TslibBaseModel`` for tslib models); | ||
| * takes its sizes from a ``metadata`` dict (supplied by the D2 DataModule) instead | ||
| of from a dataset via ``from_dataset``; | ||
| * is split into a ``model.py`` (the network) and a ``model_pkg.py`` (the package | ||
| class), and is registered so ``TestAllPtForecastersV2`` and ``check_estimator`` | ||
| cover it. | ||
|
|
||
| Changes to the model implementation | ||
| ----------------------------------- | ||
|
|
||
| .. list-table:: | ||
| :header-rows: 1 | ||
| :widths: 20 40 40 | ||
|
|
||
| * - Aspect | ||
| - v1 | ||
| - v2 | ||
| * - Model base class | ||
| - ``BaseModel`` (``models.base._base_model``) | ||
| - ``BaseModel`` (``models.base._base_model_v2``); ``TslibBaseModel`` for tslib models | ||
| * - Construction | ||
| - ``@classmethod from_dataset(cls, dataset, ...)`` — sizes inferred from the dataset | ||
| - ``__init__(..., metadata=None)`` — sizes read from the DataModule's ``metadata`` | ||
| * - Base ``super().__init__`` args | ||
| - dataset-derived + hyperparameters | ||
| - ``loss``, ``logging_metrics``, ``optimizer``, ``optimizer_params``, ``lr_scheduler``, ``lr_scheduler_params`` | ||
| * - Package class | ||
| - inherits ``_BasePtForecaster`` | ||
| - inherits ``Base_pkg`` (adds ``get_cls`` / ``get_datamodule_cls`` / ``get_test_train_params``) | ||
| * - Files | ||
| - one class | ||
| - ``model.py`` (network) + ``model_pkg.py`` (package / metadata) | ||
| * - ``forward`` | ||
| - ``forward(x: dict) -> dict`` | ||
| - **unchanged** | ||
| * - Test discovery | ||
| - ``TestAllPtForecasters`` | ||
| - ``TestAllPtForecastersV2`` (via ``get_test_train_params`` + ``check_estimator``) | ||
|
|
||
| The data layer also changes (``TimeSeriesDataSet`` → a thin D1 ``TimeSeries`` plus a | ||
| D2 ``DataModule``), but a model **does not touch it directly** — it only consumes | ||
| the ``metadata`` the DataModule produces. See :doc:`data_v2`, :doc:`models_v2`, | ||
| :doc:`pkg_v2`. | ||
|
|
||
| Migration procedure | ||
| ------------------- | ||
|
|
||
| **Step 1 — move the network into a v2** ``model.py``. Inherit the v2 ``BaseModel``; | ||
| the ``forward`` body usually transfers unchanged. | ||
|
|
||
| **Step 2 — replace** ``from_dataset`` **with** ``metadata``. In v1 the model read its | ||
| sizes from the dataset; in v2 they come from ``metadata`` (produced by the D2 | ||
| DataModule) and are passed to ``__init__``: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| # v1 — sizes inferred from the dataset via a factory classmethod | ||
| @classmethod | ||
| def from_dataset(cls, dataset, **kwargs): | ||
| return super().from_dataset(dataset, **kwargs) | ||
|
|
||
| # v2 — no from_dataset; sizes come from metadata (as TFT v2 does) | ||
| import torch.nn as nn | ||
| from pytorch_forecasting.models.base._base_model_v2 import BaseModel | ||
|
|
||
|
|
||
| class MyModel(BaseModel): | ||
| def __init__( | ||
| self, | ||
| loss, | ||
| logging_metrics=None, | ||
| optimizer="adam", | ||
| optimizer_params=None, | ||
| lr_scheduler=None, | ||
| lr_scheduler_params=None, | ||
| hidden_size=64, | ||
| metadata=None, | ||
| ): | ||
| super().__init__( | ||
| loss=loss, | ||
| logging_metrics=logging_metrics, | ||
| optimizer=optimizer, | ||
| optimizer_params=optimizer_params, | ||
| lr_scheduler=lr_scheduler, | ||
| lr_scheduler_params=lr_scheduler_params, | ||
| ) | ||
| self.save_hyperparameters(ignore=["loss", "logging_metrics", "metadata"]) | ||
| self.metadata = metadata | ||
| # read sizes from metadata and build layers, e.g.: | ||
| enc_in = metadata["encoder_cont"] + metadata["encoder_cat"] | ||
| self.encoder = nn.Linear(enc_in, hidden_size) | ||
|
|
||
| @classmethod | ||
| def _pkg(cls): | ||
| from pytorch_forecasting.models.my_model._my_model_pkg import MyModel_pkg | ||
| return MyModel_pkg | ||
|
|
||
| def forward(self, x: dict) -> dict: | ||
| ... # unchanged from v1 | ||
|
|
||
| For a real migrated model, see | ||
| ``pytorch_forecasting/models/temporal_fusion_transformer/_tft_v2.py`` — it reads | ||
| ``encoder_cont``, ``decoder_cont``, ``static_categorical_features``, etc. from | ||
| ``metadata``. | ||
|
|
||
| **Step 3 — add a** ``model_pkg.py`` **package class** inheriting ``Base_pkg``, with | ||
| ``_tags`` and the factory methods; point ``get_datamodule_cls`` at a compatible | ||
| DataModule and keep the first ``get_test_train_params`` entry ``{}`` (low-compute): | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from pytorch_forecasting.base._base_pkg import Base_pkg | ||
|
|
||
|
|
||
| class MyModel_pkg(Base_pkg): | ||
| _tags = {"info:name": "MyModel", "authors": ["your-github-handle"]} | ||
|
|
||
| @classmethod | ||
| def get_cls(cls): | ||
| from pytorch_forecasting.models.my_model._my_model import MyModel | ||
| return MyModel | ||
|
|
||
| @classmethod | ||
| def get_datamodule_cls(cls): | ||
| from pytorch_forecasting.data.data_module import ( | ||
| EncoderDecoderTimeSeriesDataModule, | ||
| ) | ||
| return EncoderDecoderTimeSeriesDataModule | ||
|
|
||
| @classmethod | ||
| def get_test_train_params(cls): | ||
| return [{}, {"hidden_size": 8}] | ||
|
|
||
| **Step 4 — register and check.** Register the package class so the ``all_objects`` | ||
| registry and ``TestAllPtForecastersV2`` discover it, then validate the interface: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from pytorch_forecasting.utils._estimator_checks import check_estimator | ||
|
|
||
| check_estimator(MyModel_pkg) | ||
|
|
||
| Migrating tslib models | ||
| ---------------------- | ||
|
|
||
| Models migrated from the Time-Series-Library inherit ``TslibBaseModel`` | ||
| (``models.base._tslib_base_model_v2``) instead of ``BaseModel``. It handles the | ||
| tslib metadata (``context_length``, ``prediction_length``, ``feature_indices``, | ||
| ``n_features``) and the shared initialisation boilerplate, so the subclass mostly | ||
| builds its layers from those. See ``TimeXer`` | ||
| (``models/timexer/_timexer_v2.py``) and ``DLinear`` (``models/dlinear/_dlinear_v2.py``) | ||
| as references. | ||
|
|
||
| Unchanged components | ||
| -------------------- | ||
|
|
||
| - ``forward(x: dict) -> dict`` — the network and its forward pass transfer directly. | ||
| - The PyTorch Lightning ``Trainer`` interface, and the loss / metric classes | ||
| (``MAE``, ``SMAPE``, ``QuantileLoss``, …) from ``pytorch_forecasting.metrics``. | ||
|
|
||
| Migration status | ||
| ---------------- | ||
|
|
||
| Models already available in v2 (auto-generated from the registry — this list grows | ||
| as more are migrated): | ||
|
|
||
| .. model-overview-v2:: | ||
|
|
||
| Remaining models to migrate, and v1 deprecation, are tracked in the roadmap | ||
| (`#1993 <https://github.com/sktime/pytorch-forecasting/issues/1993>`_) and the v2 | ||
| work items (`#1974 <https://github.com/sktime/pytorch-forecasting/issues/1974>`_). | ||
|
|
||
| Getting help | ||
| ------------ | ||
|
|
||
| - Share feedback on the v2 rework in | ||
| `issue #1736 <https://github.com/sktime/pytorch-forecasting/issues/1736>`_. | ||
| - Runnable examples: ``ptf_V2_example`` and ``tslib_v2_example`` in :doc:`tutorials_v2`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this guide should be in the boxes at the top of every page which shows v2 is in works. WHat do you think?