Skip to content

FoundationModel¶

skforecast.foundation._foundation_model.FoundationModel ¶

FoundationModel(model_id, **kwargs)

Scikit-learn compatible interface for foundation time-series models.

Currently supports Amazon Chronos-2, Google TimesFM 2.5 and 3.0, Salesforce Moirai-2, TabICLv2, TabPFN-TS, TFC-T0, Synthefy Nori, EDF Lab TS-ICL, Mistral AI Timestral and NX-AI TiRex-2. For full skforecast ecosystem integration (backtesting, model selection, etc.) use ForecasterFoundation instead.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID. The adapter is resolved automatically from the model_id prefix. Available model IDs:

Amazon Chronos-2 (supports exog):

  • 'amazon/chronos-2'
  • 'autogluon/chronos-2-small'
  • 'autogluon/chronos-2-synth'

Google TimesFM 2.5 (does not support exog):

  • 'google/timesfm-2.5-200m-pytorch'

Google TimesFM 3.0 (supports exog):

  • 'google/timesfm-3.0-pytorch'

Salesforce Moirai-2 (does not support exog):

  • 'Salesforce/moirai-2.0-R-small'

TabICLv2 (supports exog):

  • 'soda-inria/tabicl'

Prior Labs TabPFN-TS (supports exog):

  • 'priorlabs/tabpfn-ts'

The Forecasting Company T0 (supports exog):

  • 'theforecastingcompany/t0-alpha'

Synthefy Nori (supports exog):

  • 'Synthefy/Nori'
  • 'Synthefy/Nori-30M'
  • 'Synthefy/Nori-100M'

EDF Lab TS-ICL (supports exog):

  • 'taharnbl/TS-ICL'

Mistral AI Timestral (supports exog):

  • 'mistralai/Timestral-5M'
  • 'mistralai/Timestral-28M'
  • 'mistralai/Timestral-123M'
  • 'mistralai/Timestral-209M'

NX-AI TiRex-2 (supports exog):

  • 'NX-AI/TiRex-2'

See References for links to model documentation and model cards.

required
**kwargs Any

Additional keyword arguments forwarded to the underlying adapter. Valid keys depend on the model selected by model_id. See the corresponding adapter class documentation or the model card linked in the References section below for the full parameter list.

Commonly used kwargs by model:

  • Amazon Chronos-2 (ChronosAdapter): context_length (int, default 8192), device_map (str, default 'auto'), torch_dtype (object, default None), predict_kwargs (dict, default None), cross_learning (bool, default False).
  • Google TimesFM 2.5 (TimesFM25Adapter): context_length (int, default 512), max_horizon (int, default 512), forecast_config_kwargs (dict, default None).
  • Google TimesFM 3.0 (TimesFM3Adapter): context_length (int, default 2048), device (str, default 'auto'), predict_kwargs (dict, default None).
  • Salesforce Moirai-2 (MoiraiAdapter): context_length (int, default 2048), device (str, default 'auto').
  • TabICLv2 (TabICLAdapter): context_length (int, default 4096), point_estimate (str, default 'mean'), tabicl_config (dict, default None), temporal_features (list, default None), show_progress (bool, default False; set to True to show the tqdm bar emitted during inference).
  • Prior Labs TabPFN-TS (TabPFNAdapter): context_length (int, default 32768), mode (str, default 'local'), point_estimate (str, default 'median'), tabpfn_model_config (dict, default None), temporal_features (list, default None), show_progress (bool, default False; set to True to show the tqdm bar emitted during inference).
  • The Forecasting Company T0 (T0Adapter): context_length (int, default 8192), device_map (str, default 'auto'), torch_dtype (object, default None).
  • Synthefy Nori (NoriAdapter): context_length (int, default 4096), point_estimate (str, default 'mean'), add_calendar_features (bool, default True), n_fourier_terms (int, default 2), nori_config (dict, default None).
  • EDF Lab TS-ICL (TSICLAdapter): checkpoint_version (str, default 'tsicl-v1.ckpt'), context_length (int, default 4096), device (str, default 'auto'), allow_auto_download (bool, default True).
  • Mistral AI Timestral (TimestralAdapter): context_length (int, default 4096), device (str, default 'auto'), predict_kwargs (dict, default None).
  • NX-AI TiRex-2 (TiRex2Adapter): context_length (int, default 2048), device (str, default 'auto'), predict_kwargs (dict, default None).
{}

Attributes:

Name Type Description
adapter object

The underlying adapter instance, instantiated automatically based on the model_id prefix. The concrete type depends on the model, e.g. ChronosAdapter for autogluon/chronos-* models.

model_id str

HuggingFace model ID. Mirrors adapter.model_id.

context_ dict[str, pandas Series]

Per-series dict of pandas Series containing the last context_length observations from the training data, stored during fit. Mirrors adapter.context_.

context_exog_ dict

Per-series dict of pandas DataFrame containing the last context_length exog variables from the training data, stored during fit. None if the adapter does not support exogenous variables or no exog was provided. Mirrors adapter.context_exog_.

context_length int

Maximum number of historical observations used as context. Mirrors adapter.context_length.

allow_exog bool

Whether the underlying adapter supports exogenous variables.

supports_past_only_covariates bool

Whether the underlying adapter uses historical exog columns that have no future values as past-only covariates. If False, such columns are ignored at predict time and an IgnoredArgumentWarning is issued.

supports_heterogeneous_covariates bool

Whether the underlying adapter can forecast series with different exog columns in the same backend call. If False, series are grouped by their exog columns at predict time and the adapter is called once per group.

supports_nan_in_series bool

Whether the underlying adapter accepts NaN values in the series used as context. If False, a context with NaN raises a ValueError at predict time.

index_type_ type

Type of index of the input used in training.

index_freq_ pandas DateOffset, int

Frequency of the index of the input used in training. A pandas DateOffset for DatetimeIndex or an int step for RangeIndex.

context_range_ dict[str, pandas Index]

First and last values of the index of the data used during training for each series.

series_names_in_ list

Names of the series (levels) provided by the user during training.

is_multiple_series_ bool

Whether the model was fitted with multiple series.

exog_in_ bool

If the model has been trained using exogenous variable/s.

exog_names_in_ list

Names of the exogenous variables used during training. None if no exog was provided.

exog_names_in_per_series_ dict

Names of the exogenous variables used during training for each series. None if no exog was provided.

exog_type_in_ type

Type of exogenous variable/s used in training. None if no exog was provided.

creation_date str

Date of creation.

is_fitted bool

Tag to identify if the model has been fitted (trained).

fit_date str

Date of last fit.

skforecast_version str

Version of skforecast library used to create the model.

python_version str

Version of python used to create the model.

Notes

Each adapter imports its own backend library lazily (i.e. inside the method that first needs it) rather than at module level. This means that only the library required by the adapter you actually use needs to be installed, other foundation-model backends remain optional.

Device handling is not uniform across adapters; each mirrors the convention of its own backend, so the kwarg used to select the device differs by model:

  • device_map (plus torch_dtype), HuggingFace from_pretrained style: Chronos, T0.
  • device string, resolved internally to a concrete accelerator: Moirai, TS-ICL, TimesFM 3.0, Timestral, TiRex-2.
  • Through the backend configuration dict: TabICL (tabicl_config), TabPFN (tabpfn_model_config), Nori (nori_config).
  • No device parameter: TimesFM 2.5, which relies on its backend's own default device selection.
References

.. [1] Amazon Chronos - GitHub repository. https://github.com/amazon-science/chronos-forecasting

.. [2] Amazon Chronos - HuggingFace collection. https://huggingface.co/collections/amazon/chronos-models-65f1791d630a8d57cb718444

.. [3] Google TimesFM - GitHub repository. https://github.com/google-research/timesfm

.. [4] Google TimesFM - HuggingFace collection. https://huggingface.co/collections/google/timesfm-release-66e4be5fdb56e960c1e482a6

.. [5] Salesforce Moirai (uni2ts) - GitHub repository. https://github.com/SalesforceAIResearch/uni2ts

.. [6] Salesforce Moirai-R - HuggingFace collection. https://huggingface.co/collections/Salesforce/moirai-r-models-65c8d3a94c51428c300e0742

.. [7] TabICL - GitHub repository. https://github.com/soda-inria/tabicl

.. [8] TabICL - Documentation. https://tabicl.readthedocs.io/en/latest/

.. [9] TabPFN-TS - GitHub repository. https://github.com/PriorLabs/tabpfn-time-series

.. [10] Prior Labs TabPFN - Documentation. https://docs.priorlabs.ai/

.. [11] The Forecasting Company T0 - GitHub repository. https://github.com/theforecastingcompany/tfc-t0

.. [12] The Forecasting Company T0 - HuggingFace model card. https://huggingface.co/theforecastingcompany/t0-alpha

.. [13] Synthefy Nori - GitHub repository. https://github.com/Synthefy/synthefy-nori

.. [14] Synthefy Nori - HuggingFace model card. https://huggingface.co/Synthefy/Nori

.. [15] EDF Lab TS-ICL - GitHub repository. https://github.com/EDF-Lab/ts-icl

.. [16] EDF Lab TS-ICL - HuggingFace model card. https://huggingface.co/taharnbl/TS-ICL

.. [17] Mistral AI Timestral - GitHub repository. https://github.com/mistralai/timestral

.. [18] Mistral AI Timestral - HuggingFace collection. https://huggingface.co/collections/mistralai/timestral

.. [19] NX-AI TiRex-2 - GitHub repository. https://github.com/NX-AI/tirex-2

.. [20] NX-AI TiRex-2 - HuggingFace model card. https://huggingface.co/NX-AI/TiRex-2

Methods:

Name Description
fit

Fit the model by storing the training series and optional exog.

predict

Predict n steps ahead.

get_params

Get parameters for this estimator (sklearn-compatible).

set_params

Set parameters for this estimator (sklearn-compatible).

Source code in skforecast/foundation/_foundation_model.py
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
def __init__(
    self,
    model_id: str,
    **kwargs: Any,
) -> None:

    adapter_cls                    = _resolve_adapter(model_id)
    self.adapter                   = adapter_cls(model_id=model_id, **kwargs)
    self.index_type_               = None
    self.index_freq_               = None
    self.context_range_            = None
    self.series_names_in_          = None
    self.is_multiple_series_       = False
    self.exog_in_                  = False
    self.exog_names_in_            = None
    self.exog_names_in_per_series_ = None
    self.exog_type_in_             = None
    self.creation_date             = pd.Timestamp.today().strftime('%Y-%m-%d %H:%M:%S')
    self.fit_date                  = None
    self.skforecast_version        = __version__
    self.python_version            = sys.version.split(" ")[0]

Attributes¶

adapter instance-attribute ¶

adapter = adapter_cls(model_id=model_id, **kwargs)

index_type_ instance-attribute ¶

index_type_ = None

index_freq_ instance-attribute ¶

index_freq_ = None

context_range_ instance-attribute ¶

context_range_ = None

series_names_in_ instance-attribute ¶

series_names_in_ = None

is_multiple_series_ instance-attribute ¶

is_multiple_series_ = False

exog_in_ instance-attribute ¶

exog_in_ = False

exog_names_in_ instance-attribute ¶

exog_names_in_ = None

exog_names_in_per_series_ instance-attribute ¶

exog_names_in_per_series_ = None

exog_type_in_ instance-attribute ¶

exog_type_in_ = None

creation_date instance-attribute ¶

creation_date = pd.Timestamp.today().strftime(
    "%Y-%m-%d %H:%M:%S"
)

fit_date instance-attribute ¶

fit_date = None

skforecast_version instance-attribute ¶

skforecast_version = __version__

python_version instance-attribute ¶

python_version = sys.version.split(' ')[0]

model_id property ¶

model_id

HuggingFace model ID.

Returns:

Name Type Description
model_id str

HuggingFace model ID. Mirrors adapter.model_id.

context_ property ¶

context_

Context stored during fit, used as default context for predict if no override is provided.

Returns:

Name Type Description
context_ dict[str, Series]

Per-series dict of pandas Series containing the last context_length observations from the training data, stored during fit. Mirrors adapter.context_.

context_exog_ property ¶

context_exog_

Context stored during fit, used as default context for predict if no override is provided.

Returns:

Name Type Description
context_exog_ (dict[str, DataFrame], None)

Per-series dict of pandas DataFrame containing the last context_length exog variables from the training data, stored during fit. None if the adapter does not support exogenous variables or no exog was provided. Mirrors adapter.context_exog_.

context_length property ¶

context_length

Maximum number of historical observations used as context.

Returns:

Name Type Description
context_length int

Maximum context length. Mirrors adapter.context_length.

allow_exog property ¶

allow_exog

Whether the underlying adapter supports exogenous variables.

Returns:

Name Type Description
allow_exog bool

True if the adapter accepts and uses exog; False if it ignores covariates (e.g. TimesFM 2.5, Moirai-2).

supports_past_only_covariates property ¶

supports_past_only_covariates

Whether the underlying adapter uses historical exog columns without future values as past-only covariates.

Returns:

Name Type Description
supports_past_only_covariates bool

True if a column present in the historical exog but absent from the future exog is used as a past-only covariate (Chronos-2, TS-ICL, TimesFM 3.0, Timestral, TiRex-2). False if the adapter only uses covariates that also have future values, in which case such columns are ignored and an IgnoredArgumentWarning is issued at predict time (TabICL, TabPFN-TS, TFC-T0, Nori).

supports_heterogeneous_covariates property ¶

supports_heterogeneous_covariates

Whether the underlying adapter can forecast series with different exog columns in the same backend call.

Returns:

Name Type Description
supports_heterogeneous_covariates bool

True if the backend accepts, in one call, series whose exog columns differ (TabPFN-TS, Nori, TiRex-2, and the adapters that ignore exog). False if every series in a call must have the same columns (Chronos-2, TS-ICL, TabICL, TimesFM 3.0, TFC-T0, Timestral); in that case predict groups the series by their exog columns and calls the adapter once per group.

supports_nan_in_series property ¶

supports_nan_in_series

Whether the underlying adapter accepts NaN values in the series used as context.

Returns:

Name Type Description
supports_nan_in_series bool

True if a context with NaN values can be forwarded to the backend. False if predict must raise a ValueError when any series of the context contains NaN.

is_fitted property ¶

is_fitted

Whether the model has been fitted.

Returns:

Name Type Description
is_fitted bool

True after fit has been called at least once, False otherwise.

Methods:¶

fit ¶

fit(series, exog=None)

Fit the model by storing the training series and optional exog.

Parameters:

Name Type Description Default
series pandas Series, pandas DataFrame, dict

Training time series.

  • If pandas Series: single-series mode.
  • If wide pandas DataFrame (each column = one series): multi-series mode.
  • If dict[str, pandas Series]: multi-series mode; keys are series names.
required
exog pandas Series, pandas DataFrame, dict

Historical exogenous variables aligned to series. If the adapter does not support exogenous variables (allow_exog=False), exog is ignored and an IgnoredArgumentWarning is issued.

  • If pandas Series or pandas DataFrame: broadcast to all series.
  • If dict: per-series exogenous variables.
None

Returns:

Name Type Description
self FoundationModel
Source code in skforecast/foundation/_foundation_model.py
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
def fit(
    self,
    series: pd.Series | pd.DataFrame | dict[str, pd.Series],
    exog: (
        pd.Series
        | pd.DataFrame
        | dict[str, pd.DataFrame | pd.Series | None]
        | None
    ) = None,
) -> FoundationModel:
    """
    Fit the model by storing the training series and optional exog.

    Parameters
    ----------
    series : pandas Series, pandas DataFrame, dict
        Training time series.

        - If `pandas Series`: single-series mode.
        - If wide `pandas DataFrame` (each column = one series):
        multi-series mode.
        - If `dict[str, pandas Series]`: multi-series mode; keys are
        series names.
    exog : pandas Series, pandas DataFrame, dict, default None
        Historical exogenous variables aligned to `series`. If the adapter
        does not support exogenous variables (`allow_exog=False`), `exog`
        is ignored and an `IgnoredArgumentWarning` is issued.

        - If `pandas Series` or `pandas DataFrame`: broadcast to all
        series.
        - If `dict`: per-series exogenous variables.

    Returns
    -------
    self : FoundationModel

    """

    if exog is not None and not self.allow_exog:
        warnings.warn(
            f"The model '{self.model_id}' does not support exogenous "
            f"variables. `exog` will be ignored.",
            IgnoredArgumentWarning,
            stacklevel=2,
        )
        exog = None

    self.index_type_                = None
    self.index_freq_                = None
    self.context_range_             = None
    self.series_names_in_           = None
    self.is_multiple_series_        = False
    self.exog_in_                   = False
    self.exog_names_in_             = None
    self.exog_names_in_per_series_  = None
    self.exog_type_in_              = None
    self.fit_date                   = None

    context, series_indexes, series_names_in_, context_exog, exog_names_in_ = (
        self._check_preprocess_context(
            series = series,
            exog   = exog,
        )
    )

    self.adapter.fit(
        context      = context,
        context_exog = context_exog,
    )

    self.series_names_in_    = series_names_in_
    self.is_multiple_series_ = len(series_names_in_) > 1

    if context_exog is not None and len(exog_names_in_) > 0:
        self.exog_in_ = True
        self.exog_names_in_ = exog_names_in_
        self.exog_names_in_per_series_ = {
            k: list(v.columns) if v is not None else None
            for k, v in context_exog.items()
        }
        self.exog_type_in_ = type(exog)

    self.fit_date = pd.Timestamp.today().strftime('%Y-%m-%d %H:%M:%S')
    self.context_range_ = {
        series_name: series_index[[0, -1]]
        for series_name, series_index in series_indexes.items()
    }
    self.index_type_ = type(series_indexes[series_names_in_[0]])
    if isinstance(series_indexes[series_names_in_[0]], pd.DatetimeIndex):
        self.index_freq_ = series_indexes[series_names_in_[0]].freq
    else:
        self.index_freq_ = series_indexes[series_names_in_[0]].step

    return self

predict ¶

predict(
    steps,
    levels=None,
    context=None,
    context_exog=None,
    exog=None,
    quantiles=None,
    check_inputs=True,
)

Predict n steps ahead.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
levels (str, list)

Subset of series to predict. If None, all series in context are predicted.

None
context pandas Series, pandas DataFrame, dict

Override the stored context with this window.

  • If pandas Series: single-series override.
  • If wide pandas DataFrame or dict[str, pandas Series]: multi-series override.
None
context_exog pandas Series, pandas DataFrame, dict

Historical exog corresponding to context.

None
exog pandas Series, pandas DataFrame, dict

Future known exogenous variables for the forecast horizon.

  • If pandas Series or pandas DataFrame: broadcast to all series.
  • If dict: per-series exogenous variables.
None
quantiles (list, tuple)

Quantile levels to return, e.g. [0.1, 0.5, 0.9]. If None, returns a point forecast (median).

None
check_inputs bool

If True, the context and context_exog inputs are validated and normalized via _check_preprocess_context and the columns of exog are validated against context_exog. If False, context must already be a dict[str, pandas Series] and context_exog must be a dict[str, pandas DataFrame | None] or None; context_exog and exog are still aligned to the context and to the forecast horizon. This argument is created for internal use and is not recommended to be changed.

True

Returns:

Name Type Description
predictions pandas DataFrame

Value of predictions. The DataFrame includes the following columns:

  • level: Name of the series.
  • pred: Predicted values (point forecast, median).

If quantiles is not None, the pred column is replaced by one column per quantile level (e.g., q_0.1, q_0.5, q_0.9).

Notes

Foundation models are pre-trained and do not learn from the data passed to fit. The fit method only stores context (the last context_length observations) and metadata. This leads to four distinct behaviors depending on the combination of is_fitted and context:

  • Not fitted, context=None: raises ValueError. There is no context available for prediction.
  • Fitted, context=None: uses the context and context_exog_ stored during fit. If the user supplies context_exog, it is ignored with a warning.
  • Not fitted, context provided (zero-shot mode): The model uses context and context_exog (if provided) as context for prediction.
  • Fitted, context provided: Stored context is ignored, the provided context and context_exog (if provided) are used for prediction.

When the adapter supports exogenous variables, the columns of the future exog are validated per series against the historical exog used as context. A future column with no historical values raises a ValueError. A historical column with no future values is a past-only covariate: it is used as such when supports_past_only_covariates is True. Otherwise it is removed from the historical exog before calling the adapter, so the prediction is the same as without that column, and an IgnoredArgumentWarning is issued (the warning, like the rest of the column validation, only with check_inputs=True).

Before calling the adapter, the historical exog of each series is aligned to the index of its context and the future exog to its forecast horizon (missing timestamps are filled with NaN and reported with a MissingValuesWarning). Each series keeps its own exog columns. When supports_heterogeneous_covariates is False, the series are grouped by their exog columns (past-only and future) and the adapter is called once per group, so the prediction of a series never depends on the exog columns of the other series. When the adapter declares max_series_per_call (backends whose cost per series, or memory, grows with the size of the batch), each group is split into consecutive chunks of at most that many series, and the adapter is called once per chunk. When requires_equal_length_context is True (backends that take the context of a call as a single array), the context and historical exog of each call are left-padded with NaN to the length of its longest series. The index of the predictions is built from the unpadded context.

Source code in skforecast/foundation/_foundation_model.py
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
def predict(
    self,
    steps: int,
    levels: str | list[str] | None = None,
    context: pd.Series | pd.DataFrame | dict[str, pd.Series] | None = None,
    context_exog: (
        pd.Series
        | pd.DataFrame
        | dict[str, pd.DataFrame | pd.Series | None]
        | None
    ) = None,
    exog: (
        pd.Series
        | pd.DataFrame
        | dict[str, pd.DataFrame | pd.Series | None]
        | None
    ) = None,
    quantiles: list[float] | tuple[float, ...] | None = None,
    check_inputs: bool = True,
) -> pd.DataFrame:
    """
    Predict n steps ahead.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    levels : str, list, default None
        Subset of series to predict. If `None`, all series in `context` are 
        predicted. 
    context : pandas Series, pandas DataFrame, dict, default None
        Override the stored context with this window.

        - If `pandas Series`: single-series override.
        - If wide `pandas DataFrame` or `dict[str, pandas Series]`:
        multi-series override.
    context_exog : pandas Series, pandas DataFrame, dict, default None
        Historical exog corresponding to `context`.
    exog : pandas Series, pandas DataFrame, dict, default None
        Future known exogenous variables for the forecast horizon.

        - If `pandas Series` or `pandas DataFrame`: broadcast to all
        series.
        - If `dict`: per-series exogenous variables.
    quantiles : list, tuple, default None
        Quantile levels to return, e.g. `[0.1, 0.5, 0.9]`. If `None`,
        returns a point forecast (median).
    check_inputs : bool, default True
        If `True`, the `context` and `context_exog` inputs are validated
        and normalized via `_check_preprocess_context` and the columns
        of `exog` are validated against `context_exog`. If `False`,
        `context` must already be a `dict[str, pandas Series]` and
        `context_exog` must be a `dict[str, pandas DataFrame | None]`
        or `None`; `context_exog` and `exog` are still aligned to the
        context and to the forecast horizon. This argument is created
        for internal use and is not recommended to be changed.

    Returns
    -------
    predictions : pandas DataFrame
        Value of predictions. The DataFrame includes the following columns:

        - level: Name of the series.
        - pred: Predicted values (point forecast, median).

        If `quantiles` is not `None`, the `pred` column is replaced by
        one column per quantile level (e.g., `q_0.1`, `q_0.5`, `q_0.9`).

    Notes
    -----
    Foundation models are pre-trained and do not learn from the data passed 
    to `fit`. The `fit` method only stores context (the last `context_length` 
    observations) and metadata. This leads to four distinct behaviors 
    depending on the combination of `is_fitted` and `context`:

    - **Not fitted, `context=None`**: raises `ValueError`. There is no context 
    available for prediction.
    - **Fitted, `context=None`**: uses the context and `context_exog_` stored 
    during `fit`. If the user supplies `context_exog`, it is ignored with a 
    warning.
    - **Not fitted, `context` provided (zero-shot mode)**: The model uses 
    `context` and `context_exog` (if provided) as context for prediction.
    - **Fitted, `context` provided**: Stored context is ignored, the 
    provided `context` and `context_exog` (if provided) are used for
    prediction.

    When the adapter supports exogenous variables, the columns of the
    future `exog` are validated per series against the historical exog
    used as context. A future column with no historical values raises a
    `ValueError`. A historical column with no future values is a
    past-only covariate: it is used as such when
    `supports_past_only_covariates` is `True`. Otherwise it is removed
    from the historical exog before calling the adapter, so the
    prediction is the same as without that column, and an
    `IgnoredArgumentWarning` is issued (the warning, like the rest of
    the column validation, only with `check_inputs=True`).

    Before calling the adapter, the historical exog of each series is
    aligned to the index of its context and the future `exog` to its
    forecast horizon (missing timestamps are filled with NaN and reported
    with a `MissingValuesWarning`). Each series keeps its own exog
    columns. When `supports_heterogeneous_covariates` is `False`, the
    series are grouped by their exog columns (past-only and future) and
    the adapter is called once per group, so the prediction of a series
    never depends on the exog columns of the other series. When the
    adapter declares `max_series_per_call` (backends whose cost per
    series, or memory, grows with the size of the batch), each group is
    split into consecutive chunks of at most that many series, and the
    adapter is called once per chunk. When
    `requires_equal_length_context` is `True` (backends that take the
    context of a call as a single array), the context and historical exog
    of each call are left-padded with NaN to the length of its longest
    series. The index of the predictions is built from the unpadded
    context.

    """

    if not self.is_fitted and context is None:
        raise ValueError(
            "Call `fit` before `predict`, or pass `context`."
        )

    if (
        isinstance(steps, bool)
        or not isinstance(steps, (int, np.integer))
        or steps < 1
    ):
        raise ValueError("`steps` must be a positive integer.")

    if quantiles is not None:
        if not isinstance(quantiles, (list, tuple)):
            raise TypeError(
                "`quantiles` must be a `list` or `tuple`. For example, quantiles "
                "0.1, 0.5, and 0.9 should be as `quantiles = [0.1, 0.5, 0.9]`."
            )
        for q in quantiles:
            if not 0.0 <= q <= 1.0:
                raise ValueError(
                    f"All quantiles must be between 0 and 1. Got {q}."
                )

    # Context (past data)
    if context is None:
        if context_exog is not None:
            warnings.warn(
                "`context_exog` is ignored when `context` is not provided. "
                "The stored `context_exog_` from `fit` is used instead.",
                IgnoredArgumentWarning,
                stacklevel=3,
            )
        context = self.adapter.context_
        series_names_in = self.series_names_in_
        context_exog = self.adapter.context_exog_
    elif check_inputs:
        context, _, series_names_in, context_exog, _ = self._check_preprocess_context(
            series = context,
            exog   = context_exog,
        )
    else:
        if not context:
            raise ValueError("`context` cannot be an empty dictionary.")
        series_names_in = list(context.keys())

    if levels is not None:
        if len(levels) == 0:
            raise ValueError("`levels` must be a single string or a list-like of strings, but cannot be empty.")
        requested_levels = [levels] if isinstance(levels, str) else list(levels)
        unknown = [lv for lv in requested_levels if lv not in series_names_in]
        if unknown:
            raise ValueError(
                f"`levels` {unknown} not found in available series "
                f"{list(series_names_in)}."
            )
        series_names_in = requested_levels
        context = {
            series_name: context[series_name] for series_name in requested_levels
        }
        if context_exog is not None:
            context_exog = {
                series_name: context_exog.get(series_name)
                for series_name in requested_levels
            }

    # Future exog
    if not self.allow_exog:
        has_exog = (exog is not None) or (context_exog is not None)
        if has_exog:
            warnings.warn(
                f"{type(self.adapter).__name__} does not currently "
                "support covariates. `exog` and `context_exog` "
                "are ignored.",
                IgnoredArgumentWarning,
                stacklevel=3,
            )
            exog = None
            context_exog = None
    else:
        # Alignment runs on every path: adapters rely on `context_exog`
        # sharing the index of `context` and on `exog` covering exactly
        # `steps` rows. With `check_inputs=False` (internal backtesting
        # path) only the column check, and its warning, is skipped:
        # `_extract_data_folds_multiseries` slices `context_exog` and
        # `exog` from the same per-series DataFrame, so their columns
        # always match by construction.
        if context_exog is not None:
            context_exog = align_context_exog(
                               context         = context,
                               context_exog    = context_exog,
                               series_names_in = series_names_in,
                           )
        exog = self._prepare_future_exog(
                   steps           = steps,
                   context         = context,
                   exog            = exog,
                   series_names_in = series_names_in,
               )
        if check_inputs:
            self._check_exog_columns(
                context_exog    = context_exog,
                exog            = exog,
                series_names_in = series_names_in,
            )
        # Adapters that cannot use past-only covariates never receive
        # them. The historical columns without future values are removed
        # on every path, since the adapter would otherwise forward them
        # to the backend, and before grouping the series, since they are
        # part of the covariate signature.
        if (
            context_exog is not None
            and not self.adapter.supports_past_only_covariates
        ):
            context_exog = drop_past_only_exog(
                               context_exog    = context_exog,
                               exog            = exog,
                               series_names_in = series_names_in,
                           )

    if not self.adapter.supports_nan_in_series:
        series_with_nan = [
            series_name
            for series_name in series_names_in
            if context[series_name].isna().any()
        ]
        if series_with_nan:
            raise ValueError(
                f"{type(self.adapter).__name__} does not accept NaN values "
                f"in the series used as context. Series with NaN: "
                f"{series_with_nan}. Impute or drop them before predicting."
            )

    # Adapters whose backend requires identical covariate columns in a
    # batch are called once per group of series sharing the same columns.
    if self.adapter.supports_heterogeneous_covariates:
        series_groups = [series_names_in]
    else:
        series_groups = group_series_by_exog_signature(
                            series_names_in = series_names_in,
                            context_exog    = context_exog,
                            exog            = exog,
                        )

    # Backends whose cost per series, or memory, grows with the size of
    # the batch are called with chunks of at most `max_series_per_call`
    # series of each group.
    series_calls = []
    for series_names_group in series_groups:
        chunk_size = self.adapter.max_series_per_call or len(series_names_group)
        series_calls.extend(
            series_names_group[start:start + chunk_size]
            for start in range(0, len(series_names_group), chunk_size)
        )

    # Adapter returns dict[str, np.ndarray] with shape (steps, n_q)
    raw_predictions: dict[str, np.ndarray] = {}
    for series_names_call in series_calls:
        call_context = {
            series_name: context[series_name]
            for series_name in series_names_call
        }
        call_context_exog = (
            {
                series_name: context_exog[series_name]
                for series_name in series_names_call
            }
            if context_exog is not None else None
        )
        # Backends that take the context of a call as one array need the
        # same length for every series: left-pad the call with NaN.
        if self.adapter.requires_equal_length_context:
            call_context, call_context_exog = _left_pad_context(
                                                  context      = call_context,
                                                  context_exog = call_context_exog,
                                              )
        raw_predictions.update(
            self.adapter.predict(
                steps        = steps,
                context      = call_context,
                context_exog = call_context_exog,
                exog         = (
                    {
                        series_name: exog[series_name]
                        for series_name in series_names_call
                    }
                    if exog is not None else None
                ),
                quantiles    = quantiles,
            )
        )

    # Build long-format DataFrame from raw predictions
    n_series = len(series_names_in)
    per_series_indices = [
        expand_index(context[series_name].index, steps=steps)
        for series_name in series_names_in
    ]

    if n_series == 1:
        long_index = per_series_indices[0]
    else:
        idx_arr = np.column_stack(
            [idx.to_numpy() for idx in per_series_indices]
        ).ravel()
        long_index = (
            pd.DatetimeIndex(idx_arr)
            if isinstance(per_series_indices[0], pd.DatetimeIndex)
            else pd.Index(idx_arr)
        )
    level_col = np.tile(series_names_in, steps)

    col_names = ["pred"] if quantiles is None else [f"q_{q}" for q in quantiles]
    n_cols = len(col_names)
    # Pre-allocate (steps, n_series, n_cols), fill per series, then reshape
    # to step-major (steps*n_series, n_cols), one allocation instead of one
    # per quantile, and the ravel order matches level_col / long_index.
    pred_matrix = np.empty((steps, n_series, n_cols), dtype=np.float64)
    for i, series_name in enumerate(series_names_in):
        pred_matrix[:, i, :] = raw_predictions[series_name]
    pred_matrix = pred_matrix.reshape(steps * n_series, n_cols)
    predictions: dict[str, np.ndarray] = {"level": level_col}
    for j, col in enumerate(col_names):
        predictions[col] = pred_matrix[:, j]

    predictions = pd.DataFrame(predictions, index=long_index)

    return predictions

get_params ¶

get_params(deep=True)

Get parameters for this estimator (sklearn-compatible).

Parameters:

Name Type Description Default
deep bool

Not used, present here for API consistency by convention.

True

Returns:

Name Type Description
params dict

Parameter names mapped to their current values.

Notes

Required so that sklearn.base.clone can create an unfitted copy of this object. clone is invoked when a ForecasterFoundation is constructed (in its __init__) and by deepcopy_forecaster during model selection and hyperparameter search. The pre-loaded pipeline is intentionally excluded so that clones are created without copying heavy model weights; the pipeline is reloaded lazily on the first predict call.

Source code in skforecast/foundation/_foundation_model.py
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
def get_params(self, deep: bool = True) -> dict:
    """
    Get parameters for this estimator (sklearn-compatible).

    Parameters
    ----------
    deep : bool, default True
        Not used, present here for API consistency by convention.

    Returns
    -------
    params : dict
        Parameter names mapped to their current values.

    Notes
    -----
    Required so that `sklearn.base.clone` can create an unfitted copy of
    this object. `clone` is invoked when a `ForecasterFoundation` is
    constructed (in its `__init__`) and by `deepcopy_forecaster` during
    model selection and hyperparameter search. The pre-loaded pipeline is
    intentionally excluded so that clones are created without copying heavy
    model weights; the pipeline is reloaded lazily on the first `predict`
    call.

    """

    return self.adapter.get_params()

set_params ¶

set_params(**params)

Set parameters for this estimator (sklearn-compatible).

After calling this method, the FoundationModel is reset to an unfitted state.

Parameters:

Name Type Description Default
**params

Estimator parameters forwarded to the underlying adapter's set_params. Use model_id to change the model ID; the adapter class is fixed at construction, so a model_id served by a different adapter (or by none) raises a ValueError. All other keys are adapter-specific.

{}

Returns:

Name Type Description
self FoundationModel

The same object with updated parameters.

Source code in skforecast/foundation/_foundation_model.py
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
def set_params(self, **params) -> FoundationModel:
    """
    Set parameters for this estimator (sklearn-compatible).

    After calling this method, the FoundationModel is reset to an unfitted state.

    Parameters
    ----------
    **params :
        Estimator parameters forwarded to the underlying adapter's
        `set_params`. Use `model_id` to change the model ID; the adapter
        class is fixed at construction, so a `model_id` served by a
        different adapter (or by none) raises a `ValueError`. All other
        keys are adapter-specific.

    Returns
    -------
    self : FoundationModel
        The same object with updated parameters.

    """

    if "model_id" in params:
        new_adapter_cls = _resolve_adapter(params["model_id"])
        if new_adapter_cls is not type(self.adapter):
            raise ValueError(
                f"`model_id` {params['model_id']!r} is served by "
                f"{new_adapter_cls.__name__}, but this FoundationModel uses "
                f"{type(self.adapter).__name__}. The adapter is fixed at "
                f"construction: create a new FoundationModel to switch "
                f"model family."
            )

    try:
        self.adapter.set_params(**params)
    except ValueError as exc:
        adapter_name = type(self.adapter).__name__
        message = str(exc).replace(
            f"Invalid parameter(s) for {adapter_name}:",
            "Invalid parameter(s) for FoundationModel:",
        )
        raise ValueError(message) from exc

    self.index_type_               = None
    self.index_freq_               = None
    self.context_range_            = None
    self.series_names_in_          = None
    self.is_multiple_series_       = False
    self.exog_in_                  = False
    self.exog_names_in_            = None
    self.exog_names_in_per_series_ = None
    self.exog_type_in_             = None
    self.fit_date                  = None
    self.adapter.context_          = None
    self.adapter.context_exog_     = None
    self.adapter.is_fitted         = False

    return self

skforecast.foundation._adapters.ChronosAdapter ¶

ChronosAdapter(
    model_id,
    *,
    pipeline=None,
    context_length=8192,
    predict_kwargs=None,
    device_map="auto",
    torch_dtype=None,
    cross_learning=False
)

Adapter for Amazon Chronos-2 foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "autogluon/chronos-2-small".

required
pipeline BaseChronosPipeline

Pre-loaded pipeline instance. If None, the pipeline is loaded lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Defaults to 8192, which matches the maximum context window of Chronos. Must be a positive integer.

8192
predict_kwargs dict

Additional keyword arguments forwarded to the pipeline's predict_quantiles method.

None
device_map str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu", forwarded to BaseChronosPipeline.from_pretrained.

'auto'
torch_dtype object

Torch dtype forwarded to BaseChronosPipeline.from_pretrained.

None
cross_learning bool

If True, Chronos shares information across the series that are forecast in the same batch when predicting in multi-series mode. Forwarded directly to predict_quantiles. Ignored in single-series mode. FoundationModel batches together only the series that share the same covariate columns, so cross-learning applies within each of those groups.

False

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

predict_kwargs dict

Additional keyword arguments forwarded to predict_quantiles.

device_map str

Device map string for model loading.

torch_dtype object

Torch dtype for model loading.

cross_learning bool

Whether cross-series learning is enabled.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. False for Chronos: FoundationModel groups the series by covariate signature and calls predict once per group.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. True for Chronos, which treats them as missing values.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for Chronos: the weights are downloaded from model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

NaN values in covariates are treated by Chronos as missing values.

References

.. [1] https://github.com/amazon-science/chronos-forecasting

.. [2] https://huggingface.co/amazon/chronos-2

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "autogluon/chronos-2-small".

required
pipeline BaseChronosPipeline

Pre-loaded pipeline instance. If None, the pipeline is loaded lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series (and exog) are stored. At predict time, if context is longer than context_length it is trimmed to this length before inference; if it is shorter, all available observations are passed as-is and the model handles reduced context gracefully. Defaults to 8192, which matches the maximum context window of Chronos. Must be a positive integer.

8192
predict_kwargs dict

Additional keyword arguments forwarded verbatim to the pipeline's predict_quantiles method.

None
device_map str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu", forwarded to BaseChronosPipeline.from_pretrained.

'auto'
torch_dtype object

Torch dtype forwarded to BaseChronosPipeline.from_pretrained (e.g. torch.bfloat16).

None
cross_learning bool

If True, Chronos shares information across all series in the batch when predicting in multi-series mode. Forwarded directly to predict_quantiles. Ignored in single-series mode.

False

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the pipeline when model_id,

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the Chronos pipeline.

Source code in skforecast/foundation/_adapters.py
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
def __init__(
    self,
    model_id: str,
    *,
    pipeline: Any | None = None,
    context_length: int = 8192,
    predict_kwargs: dict[str, Any] | None = None,
    device_map: str = "auto",
    torch_dtype: Any | None = None,
    cross_learning: bool = False,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. "autogluon/chronos-2-small".
    pipeline : BaseChronosPipeline, default None
        Pre-loaded pipeline instance. If `None`, the pipeline is
        loaded lazily on the first call to `predict`.
    context_length : int, default 8192
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` (and `exog`) are stored. At `predict` time, if
        `context` is longer than `context_length` it is trimmed to
        this length before inference; if it is shorter, all available
        observations are passed as-is and the model handles reduced
        context gracefully. Defaults to 8192, which matches the
        maximum context window of Chronos. Must be a positive
        integer.
    predict_kwargs : dict, default None
        Additional keyword arguments forwarded verbatim to the
        pipeline's `predict_quantiles` method.
    device_map : str, default 'auto'
        Device placement for the model. `"auto"` selects the best
        available accelerator (CUDA > MPS > CPU). Also accepts
        explicit values such as `"cuda"`, `"mps"`, or `"cpu"`,
        forwarded to `BaseChronosPipeline.from_pretrained`.
    torch_dtype : object, default None
        Torch dtype forwarded to `BaseChronosPipeline.from_pretrained`
        (e.g. `torch.bfloat16`).
    cross_learning : bool, default False
        If `True`, Chronos shares information across all series in
        the batch when predicting in multi-series mode. Forwarded
        directly to `predict_quantiles`. Ignored in single-series mode.

    """

    _validate_positive_int("context_length", context_length)

    self.model_id       = model_id
    self._pipeline      = pipeline
    self.context_       = None
    self.context_exog_  = None
    self.context_length = context_length
    self.predict_kwargs = predict_kwargs or {}
    self.device_map     = device_map
    self.torch_dtype    = torch_dtype
    self.cross_learning = cross_learning
    self.is_fitted      = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = None

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = True

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = True

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = False

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'chronos-forecasting'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'autogluon/chronos-2-small'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

predict_kwargs instance-attribute ¶

predict_kwargs = predict_kwargs or {}

device_map instance-attribute ¶

device_map = device_map

torch_dtype instance-attribute ¶

torch_dtype = torch_dtype

cross_learning instance-attribute ¶

cross_learning = cross_learning

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, cross_learning, context_length, device_map, torch_dtype, predict_kwargs.

Source code in skforecast/foundation/_adapters.py
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `cross_learning`, `context_length`,
        `device_map`, `torch_dtype`, `predict_kwargs`.

    """
    return {
        'model_id':       self.model_id,
        'cross_learning': self.cross_learning,
        'context_length': self.context_length,
        'device_map':     self.device_map,
        'torch_dtype':    self.torch_dtype,
        'predict_kwargs': self.predict_kwargs or None,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the pipeline when model_id, device_map, or torch_dtype changes, since those are baked into the loaded pipeline.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, cross_learning, context_length, device_map, torch_dtype, predict_kwargs.

{}

Returns:

Name Type Description
self ChronosAdapter
Source code in skforecast/foundation/_adapters.py
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
def set_params(self, **params) -> ChronosAdapter:
    """
    Set adapter parameters. Resets the pipeline when `model_id`,
    `device_map`, or `torch_dtype` changes, since those are baked into the
    loaded pipeline.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `cross_learning`, `context_length`,
        `device_map`, `torch_dtype`, `predict_kwargs`.

    Returns
    -------
    self : ChronosAdapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "predict_kwargs" in candidate_params:
            candidate_params["predict_kwargs"] = (
                candidate_params["predict_kwargs"] or {}
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            (
                {"model_id", "device_map", "torch_dtype"},
                lambda: setattr(self, "_pipeline", None),
            ),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since Chronos is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self ChronosAdapter
Source code in skforecast/foundation/_adapters.py
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> ChronosAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since Chronos is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : ChronosAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the Chronos pipeline.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict

Per-series context windows (already trimmed to context_length).

required
context_exog dict

Per-series past covariates (already trimmed).

required
exog dict

Per-series future covariates for the forecast horizon.

required
quantiles list of float or None

Quantile levels to return. If None, a point forecast (median, quantile 0.5) is produced.

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D array of shape (steps, n_quantiles).

Source code in skforecast/foundation/_adapters.py
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the Chronos pipeline.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : dict
        Per-series past covariates (already trimmed).
    exog : dict
        Per-series future covariates for the forecast horizon.
    quantiles : list of float or None
        Quantile levels to return. If `None`, a point forecast
        (median, quantile 0.5) is produced.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D array of shape
        `(steps, n_quantiles)`.

    """

    # NOTE: the pipeline is loaded lazily here so that the adapter can be
    # instantiated and fitted without requiring Chronos to be installed.
    self._load_pipeline()

    series_names_in = list(context.keys())
    quantile_levels = list(quantiles) if quantiles is not None else [0.5]

    inputs_list = [
        self._build_chronos_input(
            context      = context[series_name].to_numpy(),
            context_exog = (
                context_exog.get(series_name) if context_exog is not None else None
            ),
            exog         = exog.get(series_name) if exog is not None else None,
        )
        for series_name in series_names_in
    ]

    quantile_preds, _ = self._pipeline.predict_quantiles(
        inputs            = inputs_list,
        prediction_length = steps,
        quantile_levels   = quantile_levels,
        cross_learning    = self.cross_learning if len(series_names_in) > 1 else False,
        **self.predict_kwargs,
    )

    predictions: dict[str, np.ndarray] = {}
    for i, series_name in enumerate(series_names_in):
        q_arr = _tensor_to_numpy(quantile_preds[i].squeeze(0))
        predictions[series_name] = q_arr

    return predictions

skforecast.foundation._adapters.TimesFM25Adapter ¶

TimesFM25Adapter(
    model_id,
    *,
    model=None,
    context_length=512,
    max_horizon=512,
    forecast_config_kwargs=None
)

Adapter for Google TimesFM 2.5 foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "google/timesfm-2.5-200m-pytorch". Must start with "google/timesfm-2.5".

required
model object

Pre-loaded model instance. If None, the model is loaded lazily on the first predict call. If passed directly, it should already be compiled.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer.

512
max_horizon int

Maximum forecast horizon. If predict is called with steps > max_horizon, a ValueError is raised. The model is compiled lazily for the exact requested steps (up to this ceiling) to avoid unnecessary decode iterations. Must be a positive integer.

512
forecast_config_kwargs dict

Additional keyword arguments forwarded verbatim to timesfm.ForecastConfig at compile time. Supported keys: normalize_inputs, use_continuous_quantile_head, force_flip_invariance, infer_is_positive, fix_quantile_crossing. Do not include max_context or max_horizon here, since those are controlled by the corresponding adapter parameters.

None

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ (dict, None)

Stored historical exogenous variables after fitting. Never used by this adapter, since TimesFM 2.5 does not support covariates.

context_length int

Maximum number of historical observations used as context.

max_horizon int

Maximum forecast horizon.

forecast_config_kwargs dict

Additional keyword arguments forwarded to ForecastConfig.

allow_exog bool

Whether this adapter accepts exogenous variables. Always False.

supports_past_only_covariates bool

Whether historical exog columns without future values are used as past-only covariates. Always False.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. Always True, since covariates are ignored.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. Always True.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for TimesFM 2.5: the weights are downloaded from model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

TimesFM 2.5 supports only the fixed quantile levels [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]. Requesting any other level raises a ValueError. The point forecast is documented by TimesFM as the mean (in practice the 2.5 checkpoint returns a value equal to quantile 0.5).

Compilation behavior. The model is compiled lazily on the first predict call, sized for the exact number of steps requested (not for max_horizon, which only acts as an upper bound and validation ceiling). When steps is constant across calls, as in a typical backtesting loop, compilation happens only once, on the first fold. A later predict that requests more steps than any previous call triggers a single recompilation for the larger horizon. To avoid any runtime compilation altogether, pass an already-compiled model via the model argument.

References

.. [1] https://github.com/google-research/timesfm

.. [2] https://huggingface.co/google/timesfm-2.5-200m-pytorch

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "google/timesfm-2.5-200m-pytorch". Must start with "google/timesfm-2.5".

required
model object

Pre-loaded model instance. If None, the model is loaded lazily on the first predict call.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are passed as-is. Must be a positive integer.

512
max_horizon int

Maximum forecast horizon. If predict is called with steps > max_horizon, a ValueError is raised. The model is compiled lazily for the exact requested steps (up to this ceiling) to avoid unnecessary decode iterations. Must be a positive integer.

512
forecast_config_kwargs dict

Additional keyword arguments forwarded verbatim to timesfm.ForecastConfig at compile time.

None

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when parameters that affect

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the TimesFM 2.5 model.

Source code in skforecast/foundation/_adapters.py
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 512,
    max_horizon: int = 512,
    forecast_config_kwargs: dict[str, Any] | None = None,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. `"google/timesfm-2.5-200m-pytorch"`.
        Must start with `"google/timesfm-2.5"`.
    model : object, default None
        Pre-loaded model instance. If `None`, the model is loaded
        lazily on the first `predict` call.
    context_length : int, default 512
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` are stored. At `predict` time, if `context` is
        longer than `context_length` it is trimmed to this length;
        if it is shorter, all available observations are passed as-is.
        Must be a positive integer.
    max_horizon : int, default 512
        Maximum forecast horizon. If `predict` is called with
        `steps > max_horizon`, a `ValueError` is raised. The model is
        compiled lazily for the exact requested `steps` (up to this
        ceiling) to avoid unnecessary decode iterations. Must be a
        positive integer.
    forecast_config_kwargs : dict, default None
        Additional keyword arguments forwarded verbatim to
        `timesfm.ForecastConfig` at compile time.

    """

    _validate_model_id_prefix(model_id, self._MODEL_ID_PREFIX, type(self).__name__)
    _validate_positive_int("context_length", context_length)
    _validate_positive_int("max_horizon", max_horizon)

    self.model_id               = model_id
    self._model                 = model
    self.context_               = None
    self.context_exog_          = None
    self.context_length         = context_length
    self.max_horizon            = max_horizon
    self.forecast_config_kwargs = forecast_config_kwargs or {}
    self.is_fitted              = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = [
    0.1,
    0.2,
    0.3,
    0.4,
    0.5,
    0.6,
    0.7,
    0.8,
    0.9,
]

allow_exog class-attribute instance-attribute ¶

allow_exog = False

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = False

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = True

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'timesfm[torch]'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'google/timesfm-2.5-200m-pytorch'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

max_horizon instance-attribute ¶

max_horizon = max_horizon

forecast_config_kwargs instance-attribute ¶

forecast_config_kwargs = forecast_config_kwargs or {}

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, max_horizon, forecast_config_kwargs.

Source code in skforecast/foundation/_adapters.py
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `max_horizon`,
        `forecast_config_kwargs`.

    """

    return {
        'model_id':               self.model_id,
        'context_length':         self.context_length,
        'max_horizon':            self.max_horizon,
        'forecast_config_kwargs': self.forecast_config_kwargs or None,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when parameters that affect loading or compilation change.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, max_horizon, forecast_config_kwargs.

{}

Returns:

Name Type Description
self TimesFM25Adapter
Notes

All four parameters affect the loaded (and compiled) model, so changing any of them discards the cached model, which is reloaded and recompiled lazily on the next predict call.

Source code in skforecast/foundation/_adapters.py
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
def set_params(self, **params) -> TimesFM25Adapter:
    """
    Set adapter parameters. Resets the model when parameters that affect
    loading or compilation change.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `max_horizon`,
        `forecast_config_kwargs`.

    Returns
    -------
    self : TimesFM25Adapter

    Notes
    -----
    All four parameters affect the loaded (and compiled) model, so
    changing any of them discards the cached model, which is reloaded
    and recompiled lazily on the next `predict` call.

    """

    def validate(candidate_params: dict) -> dict:
        if "model_id" in candidate_params:
            _validate_model_id_prefix(
                candidate_params["model_id"],
                self._MODEL_ID_PREFIX,
                type(self).__name__,
            )
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "max_horizon" in candidate_params:
            _validate_positive_int("max_horizon", candidate_params["max_horizon"])
        if "forecast_config_kwargs" in candidate_params:
            candidate_params["forecast_config_kwargs"] = (
                candidate_params["forecast_config_kwargs"] or {}
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            (
                {"model_id", "context_length", "max_horizon",
                 "forecast_config_kwargs"},
                lambda: setattr(self, "_model", None),
            ),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since TimesFM is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables. FoundationModel passes None, since TimesFM 2.5 does not support covariates.

required

Returns:

Name Type Description
self TimesFM25Adapter
Source code in skforecast/foundation/_adapters.py
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TimesFM25Adapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since TimesFM is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables. `FoundationModel`
        passes `None`, since TimesFM 2.5 does not support covariates.

    Returns
    -------
    self : TimesFM25Adapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the TimesFM 2.5 model.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict

Per-series context windows (already trimmed to context_length).

required
context_exog Any

Not used, present here for API consistency by convention.

required
exog Any

Not used, present here for API consistency by convention.

required
quantiles list of float or None

Quantile levels. Must be a subset of SUPPORTED_QUANTILES.

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D array of shape (steps, n_quantiles).

Notes

A ValueError is raised if a requested quantile level is not in SUPPORTED_QUANTILES or if steps exceeds max_horizon.

Source code in skforecast/foundation/_adapters.py
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: Any,
    exog: Any,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the TimesFM 2.5 model.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : Any
        Not used, present here for API consistency by convention.
    exog : Any
        Not used, present here for API consistency by convention.
    quantiles : list of float or None
        Quantile levels. Must be a subset of `SUPPORTED_QUANTILES`.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D array of shape
        `(steps, n_quantiles)`.

    Notes
    -----
    A `ValueError` is raised if a requested quantile level is not in
    `SUPPORTED_QUANTILES` or if `steps` exceeds `max_horizon`.

    """

    quantile_list = _validate_supported_quantiles(
        quantiles, self.SUPPORTED_QUANTILES, "TimesFM"
    )

    if steps > self.max_horizon:
        raise ValueError(
            f"`steps` ({steps}) exceeds `max_horizon` ({self.max_horizon})."
        )

    self._load_model()
    self._ensure_compiled(steps)

    series_names_in = list(context.keys())
    inputs_list = [
        context[series_name].to_numpy() for series_name in series_names_in
    ]

    point_forecast, quantile_forecast = self._model.forecast(
        horizon=steps,
        inputs=inputs_list,
    )
    # point_forecast  : (n_series, steps)
    # quantile_forecast: (n_series, steps, 10), idx 0 = mean, 1-9 = q0.1-q0.9

    predictions: dict[str, np.ndarray] = {}
    for i, series_name in enumerate(series_names_in):
        if quantile_list is None:
            # Point forecast: shape (steps, 1)
            predictions[series_name] = np.asarray(point_forecast[i]).reshape(-1, 1)
        else:
            quantile_indices = [round(q * 10) for q in quantile_list]
            qf = np.asarray(quantile_forecast[i])
            # (steps, n_quantiles)
            predictions[series_name] = qf[:, quantile_indices]

    return predictions

skforecast.foundation._adapters.TimesFM3Adapter ¶

TimesFM3Adapter(
    model_id,
    *,
    model=None,
    context_length=2048,
    device="auto",
    predict_kwargs=None
)

Adapter for Google TimesFM 3.0 foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "google/timesfm-3.0-pytorch". Must start with "google/timesfm-3.0".

required
model object

Pre-loaded TimesFM3Forecaster instance. If None, the model is loaded lazily on the first predict call.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer. TimesFM 3.0 supports context lengths up to roughly 15,360.

2048
device str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu", forwarded to TimesFM3Forecaster.from_pretrained.

'auto'
predict_kwargs dict

Additional keyword arguments forwarded verbatim to predict_batch (e.g. use_znorm, make_positive, use_symmetric_averaging, sort_quantiles). Cannot include contexts, horizon, return_quantiles, past_only_covariates, past_future_covariates, padding_mode, or ts_ids, which are managed internally.

None

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ (dict, None)

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

device str

Device placement for the model.

predict_kwargs dict

Additional keyword arguments forwarded to predict_batch.

allow_exog bool

Whether this adapter accepts exogenous variables. Always True.

supports_past_only_covariates bool

Whether historical exog columns without future values are used as past-only covariates. Always True.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. Always False: predict_batch stacks the covariate arrays of every series in a call, so FoundationModel groups the series by covariate signature and calls predict once per group.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. Always True.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for TimesFM 3.0: the weights are downloaded from model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

TimesFM 3.0 supports only the fixed quantile levels [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]. Requesting any other level raises a ValueError. The point forecast is the median (quantile 0.5).

For each series, columns present in its future exog become known-future covariates spanning context + horizon, built by concatenating the matching historical column from context_exog with the future values; columns present only in its context_exog become past-only covariates. Every series is forwarded with its own covariate columns only: FoundationModel batches together the series that share the same set of past-only and known-future columns and calls predict once per group, so the prediction of a series never depends on the covariates of the other series in the batch. Covariates must be numeric; encode categoricals as numbers before passing them. NaN values inside covariates and inside the target series are linearly interpolated by the backend, and leading NaNs in the target trim the context and its covariates accordingly.

There is no compile step and no horizon ceiling: context length and horizon are handled internally by predict_batch.

The pre-trained weights are released under a non-commercial license, so loading them raises a LicenseWarning.

References

.. [1] https://github.com/google-research/timesfm

.. [2] https://huggingface.co/google/timesfm-3.0-pytorch

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "google/timesfm-3.0-pytorch". Must start with "google/timesfm-3.0".

required
model object

Pre-loaded TimesFM3Forecaster instance. If None, the model is loaded lazily on the first predict call.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are passed as-is. Must be a positive integer.

2048
device str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU).

'auto'
predict_kwargs dict

Additional keyword arguments forwarded verbatim to predict_batch.

None

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when parameters that affect

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the TimesFM 3.0 model.

Source code in skforecast/foundation/_adapters.py
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 2048,
    device: str = "auto",
    predict_kwargs: dict[str, Any] | None = None,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. `"google/timesfm-3.0-pytorch"`. Must
        start with `"google/timesfm-3.0"`.
    model : object, default None
        Pre-loaded `TimesFM3Forecaster` instance. If `None`, the model
        is loaded lazily on the first `predict` call.
    context_length : int, default 2048
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` are stored. At `predict` time, if `context` is
        longer than `context_length` it is trimmed to this length;
        if it is shorter, all available observations are passed as-is.
        Must be a positive integer.
    device : str, default 'auto'
        Device placement for the model. `"auto"` selects the best
        available accelerator (CUDA > MPS > CPU).
    predict_kwargs : dict, default None
        Additional keyword arguments forwarded verbatim to
        `predict_batch`.

    """

    _validate_model_id_prefix(model_id, self._MODEL_ID_PREFIX, type(self).__name__)
    _validate_positive_int("context_length", context_length)
    predict_kwargs = predict_kwargs or {}
    self._validate_predict_kwargs(predict_kwargs)

    self.model_id       = model_id
    self._model         = model
    self.context_       = None
    self.context_exog_  = None
    self.context_length = context_length
    self.device         = device
    self.predict_kwargs = predict_kwargs
    self.is_fitted      = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = [
    0.1,
    0.2,
    0.3,
    0.4,
    0.5,
    0.6,
    0.7,
    0.8,
    0.9,
]

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = True

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = False

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'timesfm[torch]'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'google/timesfm-3.0-pytorch'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

device instance-attribute ¶

device = device

predict_kwargs instance-attribute ¶

predict_kwargs = predict_kwargs

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, device, predict_kwargs.

Source code in skforecast/foundation/_adapters.py
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `device`, `predict_kwargs`.

    """

    return {
        'model_id':       self.model_id,
        'context_length': self.context_length,
        'device':         self.device,
        'predict_kwargs': self.predict_kwargs or None,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when parameters that affect loading change.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, device, predict_kwargs.

{}

Returns:

Name Type Description
self TimesFM3Adapter
Notes

Only model_id and device affect the loaded model, so only those discard the cached model. context_length and predict_kwargs are applied at predict time and never trigger a reload.

Source code in skforecast/foundation/_adapters.py
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
def set_params(self, **params) -> TimesFM3Adapter:
    """
    Set adapter parameters. Resets the model when parameters that affect
    loading change.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `device`,
        `predict_kwargs`.

    Returns
    -------
    self : TimesFM3Adapter

    Notes
    -----
    Only `model_id` and `device` affect the loaded model, so only those
    discard the cached model. `context_length` and `predict_kwargs` are
    applied at predict time and never trigger a reload.

    """

    def validate(candidate_params: dict) -> dict:
        if "model_id" in candidate_params:
            _validate_model_id_prefix(
                candidate_params["model_id"],
                self._MODEL_ID_PREFIX,
                type(self).__name__,
            )
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "predict_kwargs" in candidate_params:
            candidate_params["predict_kwargs"] = (
                candidate_params["predict_kwargs"] or {}
            )
            self._validate_predict_kwargs(candidate_params["predict_kwargs"])
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            ({"model_id", "device"}, lambda: setattr(self, "_model", None)),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since TimesFM is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self TimesFM3Adapter
Source code in skforecast/foundation/_adapters.py
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TimesFM3Adapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since TimesFM is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : TimesFM3Adapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the TimesFM 3.0 model.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict

Per-series context windows (already trimmed to context_length).

required
context_exog (dict, None)

Per-series historical exogenous variables (already trimmed). For each series, columns not also present in its exog are forwarded as past-only covariates.

required
exog (dict, None)

Per-series future exogenous variables for the forecast horizon. Each column is forwarded as a known-future covariate of that series, concatenated with its historical values.

required
quantiles list of float or None

Quantile levels. Must be a subset of SUPPORTED_QUANTILES.

required

Returns:

Name Type Description
predictions dict

Keys are series names, in the same order as context. Each value is a 2-D array of shape (steps, n_quantiles).

Notes

A ValueError is raised if a requested quantile level is not in SUPPORTED_QUANTILES. There is no horizon ceiling.

predict_batch requires all series in one call to share the same covariate layout. FoundationModel guarantees it by grouping the series by covariate signature (get_exog_signature) and calling predict once per group, so the signature of the first series sets the column order for the whole batch. Series of different lengths are accepted: predict_batch left-pads every series and its covariates to the batch context length.

With covariates present, padding_mode="edge" is passed to predict_batch (the default chosen here); with no covariates, padding_mode="none" is used. predict_batch internally rounds the horizon up to a multiple of the output patch length. "edge" repeats the last known-future covariate value up to that rounded length, so those extra positions enter the final patch unmasked, whereas "none" leaves them masked. Both modes return steps rows for any steps ("edge" is not required); "edge" matches the default used by TimesFM's own predict() and can shift the last patch's predictions relative to "none". The point forecast (quantiles is None) is the model's median quantile.

Source code in skforecast/foundation/_adapters.py
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the TimesFM 3.0 model.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : dict, None
        Per-series historical exogenous variables (already trimmed).
        For each series, columns not also present in its `exog` are
        forwarded as past-only covariates.
    exog : dict, None
        Per-series future exogenous variables for the forecast
        horizon. Each column is forwarded as a known-future covariate
        of that series, concatenated with its historical values.
    quantiles : list of float or None
        Quantile levels. Must be a subset of `SUPPORTED_QUANTILES`.

    Returns
    -------
    predictions : dict
        Keys are series names, in the same order as `context`. Each
        value is a 2-D array of shape `(steps, n_quantiles)`.

    Notes
    -----
    A `ValueError` is raised if a requested quantile level is not in
    `SUPPORTED_QUANTILES`. There is no horizon ceiling.

    `predict_batch` requires all series in one call to share the same
    covariate layout. `FoundationModel` guarantees it by grouping the
    series by covariate signature (`get_exog_signature`) and calling
    `predict` once per group, so the signature of the first series sets
    the column order for the whole batch. Series of different lengths
    are accepted: `predict_batch` left-pads every series and its
    covariates to the batch context length.

    With covariates present, `padding_mode="edge"` is passed to
    `predict_batch` (the default chosen here); with no covariates,
    `padding_mode="none"` is used. `predict_batch` internally rounds the
    horizon up to a multiple of the output patch length. `"edge"` repeats
    the last known-future covariate value up to that rounded length, so
    those extra positions enter the final patch unmasked, whereas
    `"none"` leaves them masked. Both modes return `steps` rows for any
    `steps` ("edge" is not required); `"edge"` matches the default used by
    TimesFM's own `predict()` and can shift the last patch's predictions
    relative to `"none"`. The point forecast (`quantiles is None`) is the
    model's median quantile.

    """

    quantile_list = _validate_supported_quantiles(
        quantiles, self.SUPPORTED_QUANTILES, "TimesFM"
    )

    self._load_model()

    names = list(context.keys())

    # Every series in a call shares the same covariate columns
    # (`FoundationModel` groups them by covariate signature), so the
    # signature of the first series sets the column order for the batch.
    past_only_cols, fut_cols = get_exog_signature(
        context_exog = context_exog.get(names[0]) if context_exog is not None else None,
        exog         = exog.get(names[0]) if exog is not None else None,
    )
    has_covariates = bool(past_only_cols) or bool(fut_cols)
    contexts = [context[series_name].to_numpy() for series_name in names]

    past_only_list: list[np.ndarray | None] = []
    past_future_list: list[np.ndarray | None] = []
    for series_name in names:
        past_only, past_future = self._build_covariates(
            context_exog   = (
                context_exog.get(series_name) if context_exog is not None else None
            ),
            exog           = exog.get(series_name) if exog is not None else None,
            past_only_cols = past_only_cols,
            fut_cols       = fut_cols,
        )
        past_only_list.append(past_only)
        past_future_list.append(past_future)

    results = self._model.predict_batch(
        contexts               = contexts,
        horizon                = steps,
        past_only_covariates   = past_only_list if has_covariates else None,
        past_future_covariates = past_future_list if has_covariates else None,
        return_quantiles       = quantile_list is not None,
        padding_mode           = "edge" if has_covariates else "none",
        **self.predict_kwargs,
    )
    outs = dict(zip(names, results))

    if quantile_list is not None:
        quantile_indices = _match_quantile_indices(
            list(self._model.config.quantiles), quantile_list
        )

    predictions: dict[str, np.ndarray] = {}
    for series_name in names:
        out = outs[series_name]
        if quantile_list is None:
            predictions[series_name] = np.asarray(out.forecast).reshape(-1, 1)
        else:
            predictions[series_name] = (
                np.asarray(out.quantiles)[:, quantile_indices]
            )

    return predictions

skforecast.foundation._adapters.MoiraiAdapter ¶

MoiraiAdapter(
    model_id,
    *,
    module=None,
    context_length=2048,
    device="auto"
)

Adapter for Salesforce Moirai foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "Salesforce/moirai-2.0-R-small". Must be a Salesforce/moirai-2.0-R-{small,base,large} variant.

required
module object

Pre-loaded Moirai2Module instance. If None, the module is loaded lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer.

2048
device str

Device placement for the model. "auto" selects CUDA when it is available, otherwise CPU. Also accepts explicit values such as "cuda" or "cpu". MPS is not supported by Moirai (the uni2ts library uses float64 operations internally): "mps" (also with an index, or selected by "auto" on Apple Silicon without CUDA) falls back to CPU with a warning.

'auto'

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Not used, present here for API consistency by convention.

context_length int

Maximum number of historical observations used as context.

device str

Device placement for the model.

_forecast_obj object

Internal Moirai forecast object, populated at the first call to predict.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. True, since covariates are ignored.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for Moirai: the weights are downloaded from model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

Moirai supports only the fixed quantile levels [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]. Requesting any other level raises a ValueError.

Covariate support via the high-level Moirai2Forecast.predict() API is not functional: the padding/truncation loop inside predict() clips every list-valued field (including feat_dynamic_real) to context_length, discarding the future portion that future covariates require. Passing exog or context_exog issues an IgnoredArgumentWarning and the values are discarded.

References

.. [1] https://github.com/SalesforceAIResearch/uni2ts

.. [2] https://huggingface.co/Salesforce/moirai-2.0-R-small

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "Salesforce/moirai-2.0-R-small".

required
module object

Pre-loaded Moirai2Module instance. If None, the module is loaded lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are passed as-is. Must be a positive integer.

2048
device str

Device placement for the model. "auto" selects CUDA when it is available, otherwise CPU. Also accepts explicit values such as "cuda" or "cpu". MPS is not supported by Moirai (the uni2ts library uses float64 operations internally): "mps" (also with an index, or selected by "auto" on Apple Silicon without CUDA) falls back to CPU with a warning.

'auto'

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the module and forecast object when

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using Moirai.

Source code in skforecast/foundation/_adapters.py
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
def __init__(
    self,
    model_id: str,
    *,
    module: Any | None = None,
    context_length: int = 2048,
    device: str = "auto",
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. `"Salesforce/moirai-2.0-R-small"`.
    module : object, default None
        Pre-loaded `Moirai2Module` instance. If `None`, the module
        is loaded lazily on the first call to `predict`.
    context_length : int, default 2048
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` are stored. At `predict` time, if `context`
        is longer than `context_length` it is trimmed to this length;
        if it is shorter, all available observations are passed as-is.
        Must be a positive integer.
    device : str, default 'auto'
        Device placement for the model. `"auto"` selects CUDA when it
        is available, otherwise CPU. Also accepts explicit values such
        as `"cuda"` or `"cpu"`. MPS is not supported by Moirai (the
        uni2ts library uses float64 operations internally): `"mps"`
        (also with an index, or selected by `"auto"` on Apple Silicon
        without CUDA) falls back to CPU with a warning.

    """

    _validate_positive_int("context_length", context_length)

    self.model_id       = model_id
    self._module        = module
    self.context_       = None
    self.context_exog_  = None
    self.context_length = context_length
    self.device         = device
    self._forecast_obj  = None
    self.is_fitted      = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = [
    0.1,
    0.2,
    0.3,
    0.4,
    0.5,
    0.6,
    0.7,
    0.8,
    0.9,
]

allow_exog class-attribute instance-attribute ¶

allow_exog = False

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = False

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = True

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'uni2ts'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'Salesforce/moirai-2.0-R-small'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

device instance-attribute ¶

device = device

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, device.

Source code in skforecast/foundation/_adapters.py
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `device`.
    """
    return {
        'model_id':       self.model_id,
        'context_length': self.context_length,
        'device':         self.device,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the module and forecast object when model_id, context_length, or device changes.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, device.

{}

Returns:

Name Type Description
self MoiraiAdapter
Source code in skforecast/foundation/_adapters.py
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
def set_params(self, **params) -> MoiraiAdapter:
    """
    Set adapter parameters. Resets the module and forecast object when
    `model_id`, `context_length`, or `device` changes.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `device`.

    Returns
    -------
    self : MoiraiAdapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        return candidate_params

    def _reset_module() -> None:
        self._module = None
        self._forecast_obj = None

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            ({"model_id", "context_length", "device"}, _reset_module),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since Moirai is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables. FoundationModel passes None, since Moirai does not support covariates.

required

Returns:

Name Type Description
self MoiraiAdapter
Source code in skforecast/foundation/_adapters.py
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> MoiraiAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since Moirai is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables. `FoundationModel`
        passes `None`, since Moirai does not support covariates.

    Returns
    -------
    self : MoiraiAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using Moirai.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict pandas Series

Per-series context windows (already trimmed to context_length).

required
context_exog Any

Not used, present here for API consistency by convention.

required
exog Any

Not used, present here for API consistency by convention.

required
quantiles list of float or None

Quantile levels. Must be a subset of SUPPORTED_QUANTILES.

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D array of shape (steps, n_quantiles).

Notes

A ValueError is raised if a requested quantile level is not in SUPPORTED_QUANTILES.

Source code in skforecast/foundation/_adapters.py
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: Any,
    exog: Any,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using Moirai.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict pandas Series
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : Any
        Not used, present here for API consistency by convention.
    exog : Any
        Not used, present here for API consistency by convention.
    quantiles : list of float or None
        Quantile levels. Must be a subset of `SUPPORTED_QUANTILES`.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D array of shape
        `(steps, n_quantiles)`.

    Notes
    -----
    A `ValueError` is raised if a requested quantile level is not in
    `SUPPORTED_QUANTILES`.

    """

    quantile_list = _validate_supported_quantiles(
        quantiles, self.SUPPORTED_QUANTILES, "Moirai"
    )

    quantile_levels = quantile_list if quantile_list is not None else [0.5]
    quantile_indices = [
        next(
            i for i, supported_quantile in enumerate(self.SUPPORTED_QUANTILES)
            if abs(q - supported_quantile) < 1e-9
        )
        for q in quantile_levels
    ]

    series_names_in = list(context.keys())
    inputs_list = [
        context[series_name].to_numpy(dtype=np.float32, na_value=np.nan).reshape(-1, 1)
        for series_name in series_names_in
    ]

    raw = self._run_inference(inputs_list, steps)

    predictions: dict[str, np.ndarray] = {}
    for i, series_name in enumerate(series_names_in):
        # (steps, n_quantiles)
        predictions[series_name] = raw[i][quantile_indices, :].T

    return predictions

skforecast.foundation._adapters.TabICLAdapter ¶

TabICLAdapter(
    model_id,
    *,
    model=None,
    context_length=4096,
    point_estimate="mean",
    tabicl_config=None,
    temporal_features=None,
    show_progress=False
)

Adapter for TabICL zero-shot time-series foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "soda-inria/tabicl".

required
model object

Pre-instantiated TabICLForecaster instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer.

4096
point_estimate str

Method used to derive the point forecast from the TabICL output. Accepted values: 'mean', 'median'.

'mean'
tabicl_config dict

Additional keyword arguments forwarded verbatim to TabICLRegressor at inference time. If None, defaults to empty dict (TabICL's own defaults).

None
temporal_features list

List of TimeTransform instances applied to the time series before inference. If None, TabICL uses its default transforms: [IndexEncoder(), DatetimeEncoder(), AutoPeriodicEncoder()]. Pass an empty list to disable all temporal feature engineering.

None
show_progress bool

If False, the tqdm progress bar emitted by the underlying TabICL dispatch loop (GPU 0: ...) is suppressed.

False

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

point_estimate str

Point forecast method.

tabicl_config dict

Additional configuration forwarded to TabICLRegressor.

temporal_features list

Temporal feature transforms applied to the series.

show_progress bool

Whether the TabICL dispatch progress bar is shown.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. False for TabICL, whose long-format input frame holds one column set for every series: FoundationModel groups the series by covariate signature and calls predict once per group.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. True: TabICL drops the rows whose target is NaN.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. 'jingang/TabICL' for TabICL: the backend downloads its checkpoints from that repository whatever the model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

_model object

Internal TabICLForecaster instance. None until the first call to predict, after which it is cached for reuse.

Notes

TabICL supports arbitrary quantile levels (any float in [0, 1]), unlike models with fixed quantile sets such as TimesFM or Moirai.

Covariate support is available for known-future covariates: columns present in both the historical context and the forecast horizon are forwarded as covariates. Historical columns without future values are removed by FoundationModel before calling the adapter, because TabICL does not discard them. NaN values in the future covariates are accepted by TabICL with a warning.

Series with a RangeIndex are accepted. Internally, TabICL requires datetime timestamps, so a synthetic daily DatetimeIndex (starting 2000-01-01) is used. Calendar-based transforms (DatetimeEncoder, AutoPeriodicEncoder) will not be meaningful for such series; consider passing temporal_features=[] or temporal_features=[IndexEncoder()] in that case.

References

.. [1] https://github.com/soda-inria/tabicl

.. [2] https://tabicl.readthedocs.io/en/latest/

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "soda-inria/tabicl".

required
model object

Pre-instantiated TabICLForecaster instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series (and exog) are stored. At predict time, if context is longer than context_length it is trimmed to this length before inference; if it is shorter, all available observations are passed as-is. Must be a positive integer.

4096
point_estimate str

Method used to derive the point forecast. Accepted values: 'mean', 'median'.

'mean'
tabicl_config dict

Additional keyword arguments forwarded verbatim to TabICLRegressor at inference time.

None
temporal_features list

List of TimeTransform instances applied before inference. If None, TabICL uses its defaults. Pass [] to disable all temporal feature engineering.

None
show_progress bool

If False, the tqdm progress bar emitted by the underlying TabICL dispatch loop (GPU 0: ...) is suppressed by redirecting stderr during the predict_df call.

False

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when a parameter that affects

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using TabICL.

Source code in skforecast/foundation/_adapters.py
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 4096,
    point_estimate: str = "mean",
    tabicl_config: dict[str, Any] | None = None,
    temporal_features: list[Any] | None = None,
    show_progress: bool = False,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. `"soda-inria/tabicl"`.
    model : object, default None
        Pre-instantiated `TabICLForecaster` instance. If `None`, a new
        instance is created lazily on the first call to `predict`.
        Intended for testing only.
    context_length : int, default 4096
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` (and `exog`) are stored. At `predict` time, if
        `context` is longer than `context_length` it is trimmed to
        this length before inference; if it is shorter, all available
        observations are passed as-is. Must be a positive integer.
    point_estimate : str, default 'mean'
        Method used to derive the point forecast. Accepted values:
        `'mean'`, `'median'`.
    tabicl_config : dict, default None
        Additional keyword arguments forwarded verbatim to
        `TabICLRegressor` at inference time.
    temporal_features : list, default None
        List of `TimeTransform` instances applied before inference. If
        `None`, TabICL uses its defaults. Pass `[]` to disable all
        temporal feature engineering.
    show_progress : bool, default False
        If `False`, the tqdm progress bar emitted by the underlying
        TabICL dispatch loop (`GPU 0: ...`) is suppressed by
        redirecting stderr during the `predict_df` call.

    """

    _validate_positive_int("context_length", context_length)
    if point_estimate not in ("mean", "median"):
        raise ValueError(
            f"`point_estimate` must be 'mean' or 'median'. Got {point_estimate!r}."
        )

    self.model_id          = model_id
    self._model            = model
    self.context_          = None
    self.context_exog_     = None
    self.context_length    = context_length
    self.point_estimate    = point_estimate
    self.tabicl_config     = tabicl_config or {}
    self.temporal_features = temporal_features
    self.show_progress     = show_progress
    self.is_fitted         = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = None

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = False

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = False

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = 'jingang/TabICL'

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'tabicl[forecast]'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'soda-inria/tabicl'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

point_estimate instance-attribute ¶

point_estimate = point_estimate

tabicl_config instance-attribute ¶

tabicl_config = tabicl_config or {}

temporal_features instance-attribute ¶

temporal_features = temporal_features

show_progress instance-attribute ¶

show_progress = show_progress

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, point_estimate, tabicl_config, temporal_features, show_progress. tabicl_config is returned as None when no additional config was set (i.e. when the internal dict is empty).

Source code in skforecast/foundation/_adapters.py
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `point_estimate`,
        `tabicl_config`, `temporal_features`, `show_progress`.
        `tabicl_config` is returned as `None` when no additional
        config was set (i.e. when the internal dict is empty).

    """
    return {
        "model_id":          self.model_id,
        "context_length":    self.context_length,
        "point_estimate":    self.point_estimate,
        "tabicl_config":     self.tabicl_config or None,
        "temporal_features": self.temporal_features,
        "show_progress":     self.show_progress,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when a parameter that affects the TabICLForecaster instance changes; toggling show_progress does not reset the model.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, point_estimate, tabicl_config, temporal_features, show_progress.

{}

Returns:

Name Type Description
self TabICLAdapter
Source code in skforecast/foundation/_adapters.py
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
def set_params(self, **params) -> TabICLAdapter:
    """
    Set adapter parameters. Resets the model when a parameter that affects
    the `TabICLForecaster` instance changes; toggling `show_progress` does
    not reset the model.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `point_estimate`,
        `tabicl_config`, `temporal_features`, `show_progress`.

    Returns
    -------
    self : TabICLAdapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "point_estimate" in candidate_params and candidate_params[
            "point_estimate"
        ] not in ("mean", "median"):
            raise ValueError(
                f"`point_estimate` must be 'mean' or 'median'. "
                f"Got {candidate_params['point_estimate']!r}."
            )
        if "tabicl_config" in candidate_params:
            candidate_params["tabicl_config"] = (
                candidate_params["tabicl_config"] or {}
            )
        if "show_progress" in candidate_params and not isinstance(
            candidate_params["show_progress"], bool
        ):
            raise ValueError(
                f"`show_progress` must be a bool. "
                f"Got {candidate_params['show_progress']!r}."
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            (
                {"model_id", "context_length", "point_estimate",
                 "tabicl_config", "temporal_features"},
                lambda: setattr(self, "_model", None),
            ),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since TabICL is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self TabICLAdapter
Source code in skforecast/foundation/_adapters.py
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TabICLAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since TabICL is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : TabICLAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using TabICL.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict pandas Series

Per-series context windows (already trimmed to context_length).

required
context_exog dict pandas DataFrame, or None

Per-series past covariates (already trimmed). They only hold columns that also have future values in exog: FoundationModel removes the others.

required
exog dict pandas DataFrame, pandas Series, or None

Per-series future covariates for the forecast horizon.

required
quantiles list of float or None

Quantile levels to return. If None, a point forecast is produced (shape (steps, 1)). Accepts any float in [0, 1].

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D numpy ndarray of shape (steps, n_quantiles).

Source code in skforecast/foundation/_adapters.py
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using TabICL.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict pandas Series
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : dict pandas DataFrame, or None
        Per-series past covariates (already trimmed). They only hold
        columns that also have future values in `exog`: `FoundationModel`
        removes the others.
    exog : dict pandas DataFrame, pandas Series, or None
        Per-series future covariates for the forecast horizon.
    quantiles : list of float or None
        Quantile levels to return. If `None`, a point forecast is
        produced (shape `(steps, 1)`). Accepts any float in `[0, 1]`.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D numpy ndarray of
        shape `(steps, n_quantiles)`.

    """

    self._load_model()

    quantile_list = list(quantiles) if quantiles is not None else None
    tabicl_quantiles = (
        quantile_list
        if quantile_list is not None
        else [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
    )

    series_names_in = list(context.keys())

    first_series = next(iter(context.values()))
    is_datetime = isinstance(first_series.index, pd.DatetimeIndex)

    if not is_datetime:
        warnings.warn(
            "TabICLAdapter received series with a non-DatetimeIndex. "
            "TabICL requires datetime timestamps internally; a synthetic "
            "daily DatetimeIndex (starting 2000-01-01) will be used. "
            "Calendar-based temporal features (DatetimeEncoder, "
            "AutoPeriodicEncoder) will not be meaningful for "
            "integer-indexed data. Consider passing "
            "`temporal_features=[]` to disable calendar feature "
            "transforms.",
            # stacklevel=3: TabICLAdapter.predict → FoundationModel.predict → user
            stacklevel=3,
        )

    context_df = self._build_context_df(
                     series_names = series_names_in, 
                     context      = context, 
                     context_exog = context_exog, 
                     is_datetime  = is_datetime
                 )

    future_df = self._build_future_df(
                    series_names = series_names_in, 
                    context      = context, 
                    exog         = exog, 
                    steps        = steps, 
                    is_datetime  = is_datetime
                )

    _stderr_cm = (
        contextlib.redirect_stderr(io.StringIO())
        if not self.show_progress
        else contextlib.nullcontext()
    )
    with _stderr_cm:
        result_df = self._model.predict_df(
                        context_df = context_df,
                        future_df  = future_df,
                        quantiles  = tabicl_quantiles,
                    )

    # result_df is a plain DataFrame with MultiIndex (item_id, timestamp).
    # columns: "target" (str) and quantile levels as float column names.
    predictions: dict[str, np.ndarray] = {}
    for series_name in series_names_in:
        group = result_df.loc[series_name]  # DataFrame indexed by timestamp
        if quantile_list is None:
            predictions[series_name] = group["target"].to_numpy().reshape(-1, 1)
        else:
            predictions[series_name] = group[quantile_list].to_numpy()

    return predictions

skforecast.foundation._adapters.TabPFNAdapter ¶

TabPFNAdapter(
    model_id,
    *,
    model=None,
    context_length=32768,
    mode="local",
    point_estimate="median",
    tabpfn_model_config=None,
    temporal_features=None,
    show_progress=False
)

Adapter for Prior Labs TabPFN-TS zero-shot time-series foundation models.

TabPFN-TS frames forecasting as tabular regression: the series is featurized (running index, calendar features, automatically detected seasonal features) and a TabPFN regressor predicts the forecast horizon zero-shot.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "priorlabs/tabpfn-ts". Used only to resolve this adapter; the underlying checkpoint is controlled by tabpfn_model_config (key model_path).

required
model object

Pre-instantiated TabPFNTSPipeline instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Defaults to 32768, which matches the TabPFN-TS ship configuration; lower values (e.g. 4096) speed up inference at a small accuracy cost. Must be a positive integer.

32768
mode str

Inference mode. 'local' runs the TabPFN model locally (CUDA > MPS > CPU selected automatically by the library; the checkpoint is downloaded on first use). 'client' sends the featurized data to the Prior Labs cloud API via tabpfn-client (no GPU needed, requires an account/API key).

'local'
point_estimate str

Method used to aggregate the TabPFN ensemble output into the point forecast. Accepted values: 'mean', 'median', 'mode'.

'median'
tabpfn_model_config dict

Additional configuration forwarded verbatim to the underlying TabPFN regressor (e.g. model_path, device). If None, the library defaults are used.

None
temporal_features list

List of FeatureGenerator instances applied to the time series before inference. If None, TabPFN-TS uses its default transforms: [RunningIndexFeature(), CalendarFeature(), AutoSeasonalFeature()]. Pass an empty list to disable all temporal feature engineering.

None
show_progress bool

If False, the tqdm progress bar emitted by the underlying TabPFN-TS dispatch loop (Predicting time series: ... on CPU, GPU 0: ... on GPU) is suppressed.

False

Attributes:

Name Type Description
model_id str

Model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

mode str

Inference mode, 'local' or 'client'.

point_estimate str

Point forecast aggregation method.

tabpfn_model_config dict

Additional configuration forwarded to the TabPFN regressor.

temporal_features list

Temporal feature transforms applied to the series.

show_progress bool

Whether the tqdm progress bar is shown during inference.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. True: the library handles the missing cells of the long-format input frame.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used. True for TabPFN: Prior Labs requires an account token and accepting the license in a browser before the weights are downloaded (mode='local') or the API is called (mode='client').

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. 'Prior-Labs/tabpfn_3_5' for TabPFN: the repository of the TabPFN version pinned by tabpfn-time-series 1.3, whatever the model_id. Earlier versions of the backend download other weights, with a different license, hence the minimum version in backend_package.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id. False for TabPFN, which keeps them in its own cache directory.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

_model object

Internal TabPFNTSPipeline instance. None until the first call to predict, after which it is cached for reuse.

Notes

TabPFN-TS supports arbitrary quantile levels (any float in (0, 1)), unlike models with fixed quantile sets such as TimesFM or Moirai.

Covariate support is available for known-future covariates: extra columns present in both the historical context and the forecast horizon are used by the model. Historical columns without future values are removed by FoundationModel before calling the adapter, because the library does not discard them.

Series with a RangeIndex are accepted. Internally, TabPFN-TS requires datetime timestamps, so a synthetic daily DatetimeIndex (starting 2000-01-01) is used. Calendar-based transforms (CalendarFeature) will not be meaningful for such series; consider passing temporal_features=[] or [RunningIndexFeature()] in that case.

References

.. [1] https://github.com/PriorLabs/tabpfn-time-series

.. [2] https://priorlabs.ai/

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "priorlabs/tabpfn-ts".

required
model object

Pre-instantiated TabPFNTSPipeline instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series (and exog) are stored. At predict time, if context is longer than context_length it is trimmed to this length before inference; if it is shorter, all available observations are passed as-is. Must be a positive integer.

32768
mode str

Inference mode. Accepted values: 'local', 'client'.

'local'
point_estimate str

Method used to aggregate the TabPFN ensemble output into the point forecast. Accepted values: 'mean', 'median', 'mode'.

'median'
tabpfn_model_config dict

Additional configuration forwarded verbatim to the underlying TabPFN regressor.

None
temporal_features list

List of FeatureGenerator instances applied before inference. If None, TabPFN-TS uses its defaults. Pass [] to disable all temporal feature engineering.

None
show_progress bool

If False, the tqdm progress bar emitted by the underlying TabPFN-TS dispatch loop (Predicting time series: ... on CPU, GPU 0: ... on GPU) is suppressed.

False

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when a parameter that affects

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using TabPFN-TS.

Source code in skforecast/foundation/_adapters.py
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 32768,
    mode: str = "local",
    point_estimate: str = "median",
    tabpfn_model_config: dict[str, Any] | None = None,
    temporal_features: list[Any] | None = None,
    show_progress: bool = False,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        Model ID, e.g. `"priorlabs/tabpfn-ts"`.
    model : object, default None
        Pre-instantiated `TabPFNTSPipeline` instance. If `None`, a new
        instance is created lazily on the first call to `predict`.
        Intended for testing only.
    context_length : int, default 32768
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` (and `exog`) are stored. At `predict` time, if
        `context` is longer than `context_length` it is trimmed to
        this length before inference; if it is shorter, all available
        observations are passed as-is. Must be a positive integer.
    mode : str, default 'local'
        Inference mode. Accepted values: `'local'`, `'client'`.
    point_estimate : str, default 'median'
        Method used to aggregate the TabPFN ensemble output into the
        point forecast. Accepted values: `'mean'`, `'median'`, `'mode'`.
    tabpfn_model_config : dict, default None
        Additional configuration forwarded verbatim to the underlying
        TabPFN regressor.
    temporal_features : list, default None
        List of `FeatureGenerator` instances applied before inference.
        If `None`, TabPFN-TS uses its defaults. Pass `[]` to disable all
        temporal feature engineering.
    show_progress : bool, default False
        If `False`, the tqdm progress bar emitted by the underlying
        TabPFN-TS dispatch loop (`Predicting time series: ...` on CPU,
        `GPU 0: ...` on GPU) is suppressed.

    """

    _validate_positive_int("context_length", context_length)
    if mode not in ("local", "client"):
        raise ValueError(
            f"`mode` must be 'local' or 'client'. Got {mode!r}."
        )
    if point_estimate not in ("mean", "median", "mode"):
        raise ValueError(
            f"`point_estimate` must be 'mean', 'median' or 'mode'. "
            f"Got {point_estimate!r}."
        )

    self.model_id            = model_id
    self._model              = model
    self.context_            = None
    self.context_exog_       = None
    self.context_length      = context_length
    self.mode                = mode
    self.point_estimate      = point_estimate
    self.tabpfn_model_config = tabpfn_model_config or {}
    self.temporal_features   = temporal_features
    self.show_progress       = show_progress
    self.is_fitted           = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = None

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = False

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = True

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = True

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = 'Prior-Labs/tabpfn_3_5'

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = False

backend_package class-attribute instance-attribute ¶

backend_package = 'tabpfn-time-series>=1.3'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'priorlabs/tabpfn-ts'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

mode instance-attribute ¶

mode = mode

point_estimate instance-attribute ¶

point_estimate = point_estimate

tabpfn_model_config instance-attribute ¶

tabpfn_model_config = tabpfn_model_config or {}

temporal_features instance-attribute ¶

temporal_features = temporal_features

show_progress instance-attribute ¶

show_progress = show_progress

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, mode, point_estimate, tabpfn_model_config, temporal_features, show_progress. tabpfn_model_config is returned as None when no additional config was set (i.e. when the internal dict is empty).

Source code in skforecast/foundation/_adapters.py
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `mode`, `point_estimate`,
        `tabpfn_model_config`, `temporal_features`, `show_progress`.
        `tabpfn_model_config` is returned as `None` when no additional
        config was set (i.e. when the internal dict is empty).

    """
    return {
        "model_id":            self.model_id,
        "context_length":      self.context_length,
        "mode":                self.mode,
        "point_estimate":      self.point_estimate,
        "tabpfn_model_config": self.tabpfn_model_config or None,
        "temporal_features":   self.temporal_features,
        "show_progress":       self.show_progress,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when a parameter that affects the TabPFNTSPipeline instance changes; toggling show_progress does not reset the model.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, mode, point_estimate, tabpfn_model_config, temporal_features, show_progress.

{}

Returns:

Name Type Description
self TabPFNAdapter
Source code in skforecast/foundation/_adapters.py
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
def set_params(self, **params) -> TabPFNAdapter:
    """
    Set adapter parameters. Resets the model when a parameter that affects
    the `TabPFNTSPipeline` instance changes; toggling `show_progress` does
    not reset the model.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `mode`,
        `point_estimate`, `tabpfn_model_config`, `temporal_features`,
        `show_progress`.

    Returns
    -------
    self : TabPFNAdapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "mode" in candidate_params and candidate_params["mode"] not in (
            "local", "client"
        ):
            raise ValueError(
                f"`mode` must be 'local' or 'client'. "
                f"Got {candidate_params['mode']!r}."
            )
        if "point_estimate" in candidate_params and candidate_params[
            "point_estimate"
        ] not in ("mean", "median", "mode"):
            raise ValueError(
                f"`point_estimate` must be 'mean', 'median' or 'mode'. "
                f"Got {candidate_params['point_estimate']!r}."
            )
        if "tabpfn_model_config" in candidate_params:
            candidate_params["tabpfn_model_config"] = (
                candidate_params["tabpfn_model_config"] or {}
            )
        if "show_progress" in candidate_params and not isinstance(
            candidate_params["show_progress"], bool
        ):
            raise ValueError(
                f"`show_progress` must be a bool. "
                f"Got {candidate_params['show_progress']!r}."
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            (
                {"model_id", "context_length", "mode", "point_estimate",
                 "tabpfn_model_config", "temporal_features"},
                lambda: setattr(self, "_model", None),
            ),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since TabPFN-TS is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self TabPFNAdapter
Source code in skforecast/foundation/_adapters.py
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TabPFNAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since TabPFN-TS is a zero-shot inference
    model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : TabPFNAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using TabPFN-TS.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict pandas Series

Per-series context windows (already trimmed to context_length).

required
context_exog dict pandas DataFrame, or None

Per-series past covariates (already trimmed). They only hold columns that also have future values in exog: FoundationModel removes the others.

required
exog dict pandas DataFrame, pandas Series, or None

Per-series future covariates for the forecast horizon.

required
quantiles list of float or None

Quantile levels to return. If None, a point forecast is produced (shape (steps, 1)). Accepts any float in [0, 1].

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D numpy ndarray of shape (steps, n_quantiles).

Source code in skforecast/foundation/_adapters.py
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using TabPFN-TS.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict pandas Series
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : dict pandas DataFrame, or None
        Per-series past covariates (already trimmed). They only hold
        columns that also have future values in `exog`: `FoundationModel`
        removes the others.
    exog : dict pandas DataFrame, pandas Series, or None
        Per-series future covariates for the forecast horizon.
    quantiles : list of float or None
        Quantile levels to return. If `None`, a point forecast is
        produced (shape `(steps, 1)`). Accepts any float in `[0, 1]`.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D numpy ndarray of
        shape `(steps, n_quantiles)`.

    """

    self._load_model()

    quantile_list = list(quantiles) if quantiles is not None else None
    tabpfn_quantiles = (
        quantile_list
        if quantile_list is not None
        else [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
    )

    series_names_in = list(context.keys())

    first_series = next(iter(context.values()))
    is_datetime = isinstance(first_series.index, pd.DatetimeIndex)

    if not is_datetime:
        warnings.warn(
            "TabPFNAdapter received series with a non-DatetimeIndex. "
            "TabPFN-TS requires datetime timestamps internally; a "
            "synthetic daily DatetimeIndex (starting 2000-01-01) will be "
            "used. Calendar-based temporal features (CalendarFeature) "
            "will not be meaningful for integer-indexed data. Consider "
            "passing `temporal_features=[]` to disable calendar feature "
            "transforms.",
            # stacklevel=3: TabPFNAdapter.predict → FoundationModel.predict → user
            stacklevel=3,
        )

    context_df = self._build_context_df(
                     series_names = series_names_in,
                     context      = context,
                     context_exog = context_exog,
                     is_datetime  = is_datetime
                 )

    future_df = self._build_future_df(
                    series_names = series_names_in,
                    context      = context,
                    exog         = exog,
                    steps        = steps,
                    is_datetime  = is_datetime
                )

    _stderr_cm = (
        contextlib.redirect_stderr(io.StringIO())
        if not self.show_progress
        else contextlib.nullcontext()
    )
    with _stderr_cm:
        result_df = self._model.predict_df(
                        context_df = context_df,
                        future_df  = future_df,
                        quantiles  = tabpfn_quantiles,
                    )

    # result_df is a DataFrame with MultiIndex (item_id, timestamp).
    # columns: "target" (str) and quantile levels as float column names.
    predictions: dict[str, np.ndarray] = {}
    for series_name in series_names_in:
        group = result_df.loc[series_name]  # DataFrame indexed by timestamp
        if quantile_list is None:
            predictions[series_name] = group["target"].to_numpy().reshape(-1, 1)
        else:
            predictions[series_name] = group[quantile_list].to_numpy()

    return predictions

skforecast.foundation._adapters.T0Adapter ¶

T0Adapter(
    model_id,
    *,
    model=None,
    context_length=8192,
    device_map="auto",
    torch_dtype=None
)

Adapter for The Forecasting Company T0 foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "theforecastingcompany/t0-alpha".

required
model T0Forecaster

Pre-loaded model instance. If None, the model is loaded lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer.

8192
device_map str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu".

'auto'
torch_dtype object

Torch dtype used for mixed-precision inference, passed to T0Forecaster.from_pretrained as dtype. With torch.bfloat16 or torch.float16 the predictions are computed under autocast, while the weights stay in float32. With None, or any other dtype, inference runs in float32.

None

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

device_map str

Device map string for model loading.

torch_dtype object

Torch dtype for model loading.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. False for T0, which takes the covariates of all the series as a single array: a covariate that a series lacks would be a row of missing values that can change its forecast, so FoundationModel groups the series by covariate signature and calls predict once per group.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length. True for T0, which takes the context of all the series as a single array: FoundationModel left-pads context and context_exog with NaN to the length of the longest series of the call, and indexes them by a positional pandas RangeIndex. T0 reads that padding as padding, not as missing observations (trim_leading_missing=True), so the forecast of a series does not depend on the length of the others. History and future exog are joined by position.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for T0: the weights are downloaded from model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

T0 conditions on covariates that are known over both the context and the forecast horizon (future-known covariates). skforecast exogenous variables map exactly onto this channel: their historical values (context_exog, aligned to the context) are concatenated with their future values (exog, aligned to the horizon) to form the [context + horizon] covariate stream that T0 expects. Covariates must be numeric; encode categoricals as numbers before passing them. A series with no future exog is forecast without covariates.

NaN values before the first observation of a series are treated as padding (trim_leading_missing=True), the rest as missing observations. The other inference options of T0Forecaster.predict keep the default of the installed tfc-t0. Since tfc-t0 0.6.1, a covariate whose observed values are all equal over the context of a series is ignored for that series (drop_constant_covariates). tfc-t0 0.6.1 requires Python 3.11 or later: on Python 3.10, pip installs 0.6.0, which keeps those covariates, so the forecasts can differ between Python versions.

tfc-t0 0.6 or later is required, with its PyTorch runtime (the torch extra).

References

.. [1] https://github.com/theforecastingcompany/tfc-t0

.. [2] https://huggingface.co/theforecastingcompany/t0-alpha

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "theforecastingcompany/t0-alpha".

required
model T0Forecaster

Pre-loaded model instance. If None, the model is loaded lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series (and exog) are stored. At predict time, if context is longer than context_length it is trimmed to this length before inference; if it is shorter, all available observations are passed as-is. Must be a positive integer.

8192
device_map str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu".

'auto'
torch_dtype object

Torch dtype used for mixed-precision inference, passed to T0Forecaster.from_pretrained as dtype. With torch.bfloat16 or torch.float16 the predictions are computed under autocast, while the weights stay in float32. With None, or any other dtype, inference runs in float32.

None

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when a device, dtype, or

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the T0 model.

Source code in skforecast/foundation/_adapters.py
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 8192,
    device_map: str = "auto",
    torch_dtype: Any | None = None,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. "theforecastingcompany/t0-alpha".
    model : T0Forecaster, default None
        Pre-loaded model instance. If `None`, the model is loaded
        lazily on the first call to `predict`.
    context_length : int, default 8192
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` (and `exog`) are stored. At `predict` time, if `context`
        is longer than `context_length` it is trimmed to this length
        before inference; if it is shorter, all available observations
        are passed as-is. Must be a positive integer.
    device_map : str, default 'auto'
        Device placement for the model. `"auto"` selects the best
        available accelerator (CUDA > MPS > CPU). Also accepts explicit
        values such as `"cuda"`, `"mps"`, or `"cpu"`.
    torch_dtype : object, default None
        Torch dtype used for mixed-precision inference, passed to
        `T0Forecaster.from_pretrained` as `dtype`. With `torch.bfloat16`
        or `torch.float16` the predictions are computed under autocast,
        while the weights stay in `float32`. With `None`, or any other
        dtype, inference runs in `float32`.

    """

    _validate_positive_int("context_length", context_length)

    self.model_id       = model_id
    self._model         = model
    self.context_       = None
    self.context_exog_  = None
    self.context_length = context_length
    self.device_map     = device_map
    self.torch_dtype    = torch_dtype
    self.is_fitted      = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = None

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = False

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = False

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = True

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'tfc-t0[torch]>=0.6'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'theforecastingcompany/t0-alpha'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

device_map instance-attribute ¶

device_map = device_map

torch_dtype instance-attribute ¶

torch_dtype = torch_dtype

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, device_map, torch_dtype.

Source code in skforecast/foundation/_adapters.py
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `device_map`, `torch_dtype`.

    """
    return {
        'model_id':       self.model_id,
        'context_length': self.context_length,
        'device_map':     self.device_map,
        'torch_dtype':    self.torch_dtype,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when a device, dtype, or model_id param changes, since those are baked into the loaded model.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, device_map, torch_dtype.

{}

Returns:

Name Type Description
self T0Adapter
Source code in skforecast/foundation/_adapters.py
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
def set_params(self, **params) -> T0Adapter:
    """
    Set adapter parameters. Resets the model when a device, dtype, or
    model_id param changes, since those are baked into the loaded model.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `device_map`,
        `torch_dtype`.

    Returns
    -------
    self : T0Adapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            (
                {"model_id", "device_map", "torch_dtype"},
                lambda: setattr(self, "_model", None),
            ),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since T0 is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self T0Adapter
Source code in skforecast/foundation/_adapters.py
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> T0Adapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since T0 is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : T0Adapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the T0 model.

All input normalization, validation, context trimming, padding and grouping of the series by covariate signature is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict

Per-series context windows (already trimmed to context_length), left-padded with NaN to a common length and indexed by a positional pandas RangeIndex.

required
context_exog dict

Per-series past covariates (already trimmed), left-padded and indexed like context. They only hold columns that also have future values in exog: FoundationModel removes the others.

required
exog dict

Per-series future covariates for the forecast horizon. Every series of a call has the same covariate columns.

required
quantiles list of float or None

Quantile levels to return, in the requested order. If None, a point forecast (median, quantile 0.5) is produced.

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D array of shape (steps, n_quantiles) with columns ordered to match quantiles.

Source code in skforecast/foundation/_adapters.py
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the T0 model.

    All input normalization, validation, context trimming, padding and
    grouping of the series by covariate signature is performed upstream
    by `FoundationModel`; this method receives pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict
        Per-series context windows (already trimmed to `context_length`),
        left-padded with NaN to a common length and indexed by a
        positional pandas RangeIndex.
    context_exog : dict
        Per-series past covariates (already trimmed), left-padded and
        indexed like `context`. They only hold columns that also have
        future values in `exog`: `FoundationModel` removes the others.
    exog : dict
        Per-series future covariates for the forecast horizon. Every
        series of a call has the same covariate columns.
    quantiles : list of float or None
        Quantile levels to return, in the requested order. If `None`, a
        point forecast (median, quantile 0.5) is produced.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D array of shape
        `(steps, n_quantiles)` with columns ordered to match `quantiles`.

    """

    # NOTE: the model is loaded lazily here so that the adapter can be
    # instantiated and fitted without requiring tfc-t0 to be installed.
    self._load_model()

    requested = list(quantiles) if quantiles is not None else [0.5]
    # T0 requires sorted, unique levels in (0, 1); query those, then
    # reindex the columns back to the order the caller asked for.
    query_levels = sorted(set(requested))

    # All series of the call are forecast in a single batched call.
    # `FoundationModel` left-pads the context of every series to the same
    # length (`requires_equal_length_context=True`) with NaN, so the
    # forecast origin aligns at the end of the window for every series.
    series_names = list(context.keys())
    context_batch = np.stack([
        context[series_name].to_numpy(dtype=np.float32, na_value=np.nan)
        for series_name in series_names
    ])
    context_length = context_batch.shape[1]

    future_covariates = self._build_future_covariates(
        series_names   = series_names,
        context_exog   = context_exog,
        exog           = exog,
        context_length = context_length,
        steps          = steps,
    )

    # `trim_leading_missing=True` makes T0 read the NaN before the first
    # observation of a series as padding instead of missing observations:
    # otherwise the forecast of a series depends on how much it was
    # padded, that is, on the length of the other series of the call.
    forecast = self._model.predict(
        context_batch,
        horizon              = steps,
        quantile_levels      = query_levels,
        future_covariates    = future_covariates,
        trim_leading_missing = True,
    )

    q_arr = _tensor_to_numpy(forecast.quantiles)

    quantile_column_indices = [query_levels.index(q) for q in requested]
    return {
        series_name: q_arr[i][:, quantile_column_indices]
        for i, series_name in enumerate(series_names)
    }

skforecast.foundation._adapters.NoriAdapter ¶

NoriAdapter(
    model_id,
    *,
    model=None,
    context_length=4096,
    point_estimate="mean",
    add_calendar_features=True,
    n_fourier_terms=2,
    nori_config=None
)

Adapter for Synthefy Nori zero-shot tabular foundation models.

Nori is a tabular regression foundation model that predicts via in-context learning: given labeled context rows it predicts query rows in a single forward pass, with no task-specific training or fine-tuning. This adapter frames forecasting as tabular regression: each series is featurized (running index, calendar features, Fourier seasonal terms, and optional known-future covariates) and a NoriRegressor predicts the forecast horizon zero-shot.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "Synthefy/Nori" (6M), "Synthefy/Nori-30M" or "Synthefy/Nori-100M". Used to resolve this adapter and, unless overridden in nori_config, to select the checkpoint downloaded from HuggingFace.

required
model object

Pre-instantiated NoriRegressor instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to use as context rows. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer.

4096
point_estimate str

Method used to derive the point forecast from Nori's predictive distribution. Accepted values: 'mean', 'median', 'mode'.

'mean'
add_calendar_features bool

If True, add calendar features (month, day, day-of-week, day-of-year, quarter, hour) when the series has a DatetimeIndex. Ignored for RangeIndex series.

True
n_fourier_terms int

Number of Fourier (sin/cos) seasonal harmonics added on the yearly and weekly cycles for datetime series (or on the running index for RangeIndex series). Set 0 to disable. Must be a non-negative integer.

2
nori_config dict

Keyword arguments forwarded verbatim to NoriRegressor at instantiation (e.g. device, token, augmentations). The checkpoint defaults to model_id and can be overridden here with model (a registry name such as 'nori-6m' or a HuggingFace repo id) or model_path (a local checkpoint file, which takes precedence over model).

None

Attributes:

Name Type Description
model_id str

Model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

point_estimate str

Point forecast method.

add_calendar_features bool

Whether calendar features are added for datetime series.

n_fourier_terms int

Number of Fourier seasonal harmonics added.

nori_config dict

Additional configuration forwarded to NoriRegressor.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. True: every series is fitted and predicted in its own NoriRegressor call.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. True: NoriRegressor rejects NaN, so the adapter drops the context rows whose target (or any feature) is NaN before the in-context fit.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for Nori: model_id is forwarded to the backend as the checkpoint to load.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

_model object

Internal NoriRegressor instance. None until the first call to predict, after which it is cached for reuse.

Notes

Nori supports arbitrary quantile levels (any float strictly in (0, 1)), unlike models with fixed quantile sets such as TimesFM or Moirai. A bar_distribution checkpoint does not support quantiles.

Covariate support is available for known-future covariates: columns present in both the historical context and the forecast horizon are used as features. Covariates without future values are ignored: FoundationModel removes them before calling the adapter. Covariates must be numeric; encode categoricals as numbers before passing them.

Series with a RangeIndex are accepted; only running-index and Fourier(index) features are meaningful there (calendar features are skipped).

References

.. [1] https://github.com/Synthefy/synthefy-nori

.. [2] https://huggingface.co/Synthefy/Nori

.. [3] https://docs.synthefy.com/nori/

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "Synthefy/Nori".

required
model object

Pre-instantiated NoriRegressor instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series (and exog) are stored. At predict time, if context is longer than context_length it is trimmed to this length before inference; if it is shorter, all available observations are passed as-is. Must be a positive integer.

4096
point_estimate str

Method used to derive the point forecast. Accepted values: 'mean', 'median', 'mode'.

'mean'
add_calendar_features bool

If True, add calendar features when the series has a DatetimeIndex. Ignored for RangeIndex series.

True
n_fourier_terms int

Number of Fourier seasonal harmonics added. Set 0 to disable. Must be a non-negative integer.

2
nori_config dict

Keyword arguments forwarded verbatim to NoriRegressor at instantiation. The checkpoint defaults to model_id and can be overridden here with model or model_path.

None

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the loaded model when a parameter baked

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using Nori.

Source code in skforecast/foundation/_adapters.py
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 4096,
    point_estimate: str = "mean",
    add_calendar_features: bool = True,
    n_fourier_terms: int = 2,
    nori_config: dict[str, Any] | None = None,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        Model ID, e.g. `"Synthefy/Nori"`.
    model : object, default None
        Pre-instantiated `NoriRegressor` instance. If `None`, a new
        instance is created lazily on the first call to `predict`.
        Intended for testing only.
    context_length : int, default 4096
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` (and `exog`) are stored. At `predict` time, if `context`
        is longer than `context_length` it is trimmed to this length
        before inference; if it is shorter, all available observations are
        passed as-is. Must be a positive integer.
    point_estimate : str, default 'mean'
        Method used to derive the point forecast. Accepted values:
        `'mean'`, `'median'`, `'mode'`.
    add_calendar_features : bool, default True
        If `True`, add calendar features when the series has a
        `DatetimeIndex`. Ignored for `RangeIndex` series.
    n_fourier_terms : int, default 2
        Number of Fourier seasonal harmonics added. Set `0` to disable.
        Must be a non-negative integer.
    nori_config : dict, default None
        Keyword arguments forwarded verbatim to `NoriRegressor` at
        instantiation. The checkpoint defaults to `model_id` and can be
        overridden here with `model` or `model_path`.

    """

    _validate_positive_int("context_length", context_length)
    if point_estimate not in ("mean", "median", "mode"):
        raise ValueError(
            f"`point_estimate` must be 'mean', 'median' or 'mode'. "
            f"Got {point_estimate!r}."
        )
    if not isinstance(add_calendar_features, bool):
        raise ValueError(
            f"`add_calendar_features` must be a bool. "
            f"Got {add_calendar_features!r}."
        )
    if not isinstance(n_fourier_terms, int) or n_fourier_terms < 0:
        raise ValueError(
            f"`n_fourier_terms` must be a non-negative integer. "
            f"Got {n_fourier_terms!r}."
        )

    self.model_id              = model_id
    self._model                = model
    self.context_              = None
    self.context_exog_         = None
    self.context_length        = context_length
    self.point_estimate        = point_estimate
    self.add_calendar_features = add_calendar_features
    self.n_fourier_terms       = n_fourier_terms
    self.nori_config           = nori_config or {}
    self.is_fitted             = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = None

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = False

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = True

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'synthefy-nori'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'Synthefy/Nori'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

point_estimate instance-attribute ¶

point_estimate = point_estimate

add_calendar_features instance-attribute ¶

add_calendar_features = add_calendar_features

n_fourier_terms instance-attribute ¶

n_fourier_terms = n_fourier_terms

nori_config instance-attribute ¶

nori_config = nori_config or {}

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, point_estimate, add_calendar_features, n_fourier_terms, nori_config. nori_config is returned as None when no additional config was set (i.e. when the internal dict is empty).

Source code in skforecast/foundation/_adapters.py
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `point_estimate`,
        `add_calendar_features`, `n_fourier_terms`, `nori_config`.
        `nori_config` is returned as `None` when no additional config was
        set (i.e. when the internal dict is empty).

    """
    return {
        "model_id":              self.model_id,
        "context_length":        self.context_length,
        "point_estimate":        self.point_estimate,
        "add_calendar_features": self.add_calendar_features,
        "n_fourier_terms":       self.n_fourier_terms,
        "nori_config":           self.nori_config or None,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the loaded model when a parameter baked into the NoriRegressor instance changes (model_id, nori_config); featurization/inference-time parameters (context_length, point_estimate, add_calendar_features, n_fourier_terms) do not reset the model.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, point_estimate, add_calendar_features, n_fourier_terms, nori_config.

{}

Returns:

Name Type Description
self NoriAdapter
Source code in skforecast/foundation/_adapters.py
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
def set_params(self, **params) -> NoriAdapter:
    """
    Set adapter parameters. Resets the loaded model when a parameter baked
    into the `NoriRegressor` instance changes (`model_id`, `nori_config`);
    featurization/inference-time parameters (`context_length`,
    `point_estimate`, `add_calendar_features`, `n_fourier_terms`) do not
    reset the model.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `point_estimate`,
        `add_calendar_features`, `n_fourier_terms`, `nori_config`.

    Returns
    -------
    self : NoriAdapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "point_estimate" in candidate_params and candidate_params[
            "point_estimate"
        ] not in ("mean", "median", "mode"):
            raise ValueError(
                f"`point_estimate` must be 'mean', 'median' or 'mode'. "
                f"Got {candidate_params['point_estimate']!r}."
            )
        if "add_calendar_features" in candidate_params and not isinstance(
            candidate_params["add_calendar_features"], bool
        ):
            raise ValueError(
                f"`add_calendar_features` must be a bool. "
                f"Got {candidate_params['add_calendar_features']!r}."
            )
        if "n_fourier_terms" in candidate_params and (
            not isinstance(candidate_params["n_fourier_terms"], int)
            or candidate_params["n_fourier_terms"] < 0
        ):
            raise ValueError(
                f"`n_fourier_terms` must be a non-negative integer. "
                f"Got {candidate_params['n_fourier_terms']!r}."
            )
        if "nori_config" in candidate_params:
            candidate_params["nori_config"] = (
                candidate_params["nori_config"] or {}
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            ({"model_id", "nori_config"}, lambda: setattr(self, "_model", None)),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since Nori is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self NoriAdapter
Source code in skforecast/foundation/_adapters.py
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> NoriAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since Nori is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : NoriAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using Nori.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict pandas Series

Per-series context windows (already trimmed to context_length).

required
context_exog dict pandas DataFrame, or None

Per-series past covariates (already trimmed). They only hold columns that also have future values in exog: FoundationModel removes the others.

required
exog dict pandas DataFrame, pandas Series, or None

Per-series future covariates for the forecast horizon.

required
quantiles list of float or None

Quantile levels to return, in the requested order. Must lie strictly in (0, 1). If None, a point forecast is produced (shape (steps, 1)).

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D numpy ndarray of shape (steps, n_quantiles) with columns ordered to match quantiles.

Notes

A ValueError is raised if a requested quantile level is not strictly in (0, 1).

Source code in skforecast/foundation/_adapters.py
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using Nori.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict pandas Series
        Per-series context windows (already trimmed to `context_length`).
    context_exog : dict pandas DataFrame, or None
        Per-series past covariates (already trimmed). They only hold
        columns that also have future values in `exog`: `FoundationModel`
        removes the others.
    exog : dict pandas DataFrame, pandas Series, or None
        Per-series future covariates for the forecast horizon.
    quantiles : list of float or None
        Quantile levels to return, in the requested order. Must lie
        strictly in `(0, 1)`. If `None`, a point forecast is produced
        (shape `(steps, 1)`).

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D numpy ndarray of shape
        `(steps, n_quantiles)` with columns ordered to match `quantiles`.

    Notes
    -----
    A `ValueError` is raised if a requested quantile level is not
    strictly in `(0, 1)`.

    """

    quantile_list = list(quantiles) if quantiles is not None else None
    if quantile_list is not None and any(
        (q <= 0.0) or (q >= 1.0) for q in quantile_list
    ):
        raise ValueError(
            "NoriAdapter quantiles must lie strictly in (0, 1). "
            f"Got {quantile_list!r}."
        )

    # Nori does not guarantee that the output column order matches the
    # requested quantiles, so query sorted, unique levels and reindex the
    # columns back to the caller's order afterwards.
    if quantile_list is not None:
        query_levels = sorted(set(quantile_list))
        quantile_column_indices = [query_levels.index(q) for q in quantile_list]

    self._load_model()

    first_series = next(iter(context.values()))
    is_datetime = isinstance(first_series.index, pd.DatetimeIndex)
    if not is_datetime and self.add_calendar_features:
        warnings.warn(
            "NoriAdapter received series with a non-DatetimeIndex; "
            "calendar features are skipped. Only running-index and "
            "Fourier(index) features are used.",
            # stacklevel=3: NoriAdapter.predict → FoundationModel.predict → user
            stacklevel=3,
        )

    predictions: dict[str, np.ndarray] = {}
    for series_name, series in context.items():
        ctx_exog = (
            context_exog.get(series_name) if context_exog is not None else None
        )
        fut_exog = exog.get(series_name) if exog is not None else None
        # `FoundationModel` removes the historical columns without future
        # values, so every column of `ctx_exog` is a known-future one.
        exog_cols = list(ctx_exog.columns) if ctx_exog is not None else []

        X_ctx = self._featurize(
            series, is_datetime, ctx_exog, exog_cols, offset=0, n=len(series)
        )
        X_fut = self._featurize(
            series, is_datetime, fut_exog, exog_cols, offset=len(series), n=steps
        )
        y_ctx = series.to_numpy(dtype=float)

        # NoriRegressor rejects NaN. Rows whose target or any feature is
        # NaN are dropped from the context: the running-index feature is
        # an absolute offset, so dropping interior rows keeps the
        # remaining rows correctly positioned in time.
        valid_rows = ~np.isnan(y_ctx) & ~np.isnan(X_ctx).any(axis=1)
        if not valid_rows.any():
            raise ValueError(
                f"Series '{series_name}' has no context rows without NaN in the "
                f"target and the covariates. NoriAdapter cannot predict it."
            )
        X_ctx = X_ctx[valid_rows]
        y_ctx = y_ctx[valid_rows]

        # Nori fits in-context (no gradient training); the cached model is
        # re-conditioned on each series' context rows before predicting.
        self._model.fit(X_ctx, y_ctx)

        if quantile_list is None:
            y_hat = self._model.predict(X_fut, output_type=self.point_estimate)
            predictions[series_name] = self._to_numpy(y_hat).reshape(-1, 1)
        else:
            q = self._to_numpy(
                self._model.predict(
                    X_fut, output_type="quantiles", quantiles=query_levels
                )
            )
            # Nori returns (n_quantiles, steps); skforecast expects
            # (steps, n_quantiles). Reorder columns to the requested order.
            q = q.reshape(len(query_levels), steps).T
            predictions[series_name] = q[:, quantile_column_indices]

    return predictions

skforecast.foundation._adapters.TSICLAdapter ¶

TSICLAdapter(
    model_id,
    *,
    model=None,
    checkpoint_version="tsicl-v1.ckpt",
    context_length=4096,
    device="auto",
    allow_auto_download=True
)

Adapter for EDF Lab TS-ICL foundation model.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "taharnbl/TS-ICL". Used only to resolve this adapter; the underlying checkpoint is always downloaded from the taharnbl/TS-ICL Hugging Face repository, controlled by checkpoint_version.

required
model object

Pre-instantiated TSICL model instance. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
checkpoint_version str

Checkpoint filename to download from the taharnbl/TS-ICL Hugging Face repository.

'tsicl-v1.ckpt'
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer.

4096
device str

Device placement for inference. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu". Note that TS-ICL currently falls back to CPU whenever CUDA is unavailable, so "mps" has no effect on Apple Silicon.

'auto'
allow_auto_download bool

Whether to allow automatic download of the checkpoint from Hugging Face Hub if it is not already cached locally.

True

Attributes:

Name Type Description
model_id str

Model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

checkpoint_version str

Checkpoint filename downloaded from Hugging Face Hub.

context_length int

Maximum number of historical observations used as context.

device str

Device placement for inference.

allow_auto_download bool

Whether automatic checkpoint download is allowed.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. False for TS-ICL: FoundationModel groups the series by covariate signature and calls predict once per group.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: each series is passed with its own length.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. None: FoundationModel sends every series of a group in one call.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. 'taharnbl/TS-ICL' for TS-ICL: the backend downloads its checkpoints from that repository whatever the model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

TS-ICL conditions on covariates that are known over the context, the forecast horizon, or both. skforecast exogenous variables map directly onto this channel: historical values (context_exog) are forwarded as past_covariates and future values (exog) as future_covariates. Covariates must be numeric; encode categoricals as numbers before passing them.

TS-ICL only supports quantile levels on a 0.01 grid in [0.01, 0.99] (i.e. a subset of [0.01, 0.02, ..., 0.99]); requesting any other level raises a ValueError from the underlying library.

References

.. [1] https://github.com/EDF-Lab/ts-icl

.. [2] https://huggingface.co/taharnbl/TS-ICL

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "taharnbl/TS-ICL". Used only to resolve this adapter.

required
model object

Pre-instantiated TSICL model instance. If None, a new instance is created lazily on the first call to predict.

None
checkpoint_version str

Checkpoint filename to download from the taharnbl/TS-ICL Hugging Face repository.

'tsicl-v1.ckpt'
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series (and exog) are stored. At predict time, if context is longer than context_length it is trimmed to this length before inference; if it is shorter, all available observations are passed as-is. Must be a positive integer.

4096
device str

Device placement for inference. "auto" selects the best available accelerator (CUDA > MPS > CPU).

'auto'
allow_auto_download bool

Whether to allow automatic download of the checkpoint from Hugging Face Hub if it is not already cached locally.

True

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when checkpoint_version

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the TS-ICL model.

Source code in skforecast/foundation/_adapters.py
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    checkpoint_version: str = "tsicl-v1.ckpt",
    context_length: int = 4096,
    device: str = "auto",
    allow_auto_download: bool = True,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        Model ID, e.g. `"taharnbl/TS-ICL"`. Used only to resolve this
        adapter.
    model : object, default None
        Pre-instantiated `TSICL` model instance. If `None`, a new
        instance is created lazily on the first call to `predict`.
    checkpoint_version : str, default 'tsicl-v1.ckpt'
        Checkpoint filename to download from the `taharnbl/TS-ICL`
        Hugging Face repository.
    context_length : int, default 4096
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` (and `exog`) are stored. At `predict` time, if
        `context` is longer than `context_length` it is trimmed to
        this length before inference; if it is shorter, all available
        observations are passed as-is. Must be a positive integer.
    device : str, default 'auto'
        Device placement for inference. `"auto"` selects the best
        available accelerator (CUDA > MPS > CPU).
    allow_auto_download : bool, default True
        Whether to allow automatic download of the checkpoint from
        Hugging Face Hub if it is not already cached locally.

    """

    _validate_positive_int("context_length", context_length)

    self.model_id             = model_id
    self._model               = model
    self._resolved_device     = None
    self.context_             = None
    self.context_exog_        = None
    self.checkpoint_version   = checkpoint_version
    self.context_length       = context_length
    self.device               = device
    self.allow_auto_download  = allow_auto_download
    self.is_fitted            = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = [
    round(0.01 * i, 2) for i in range(1, 100)
]

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = True

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = False

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = None

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = 'taharnbl/TS-ICL'

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'tsicl'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'taharnbl/TS-ICL'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

checkpoint_version instance-attribute ¶

checkpoint_version = checkpoint_version

context_length instance-attribute ¶

context_length = context_length

device instance-attribute ¶

device = device

allow_auto_download instance-attribute ¶

allow_auto_download = allow_auto_download

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, checkpoint_version, context_length, device, allow_auto_download.

Source code in skforecast/foundation/_adapters.py
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `checkpoint_version`, `context_length`,
        `device`, `allow_auto_download`.

    """
    return {
        'model_id':             self.model_id,
        'checkpoint_version':   self.checkpoint_version,
        'context_length':       self.context_length,
        'device':               self.device,
        'allow_auto_download':  self.allow_auto_download,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when checkpoint_version or allow_auto_download changes, since those control which checkpoint is loaded.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, checkpoint_version, context_length, device, allow_auto_download.

{}

Returns:

Name Type Description
self TSICLAdapter
Source code in skforecast/foundation/_adapters.py
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
def set_params(self, **params) -> TSICLAdapter:
    """
    Set adapter parameters. Resets the model when `checkpoint_version`
    or `allow_auto_download` changes, since those control which
    checkpoint is loaded.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `checkpoint_version`, `context_length`,
        `device`, `allow_auto_download`.

    Returns
    -------
    self : TSICLAdapter

    """

    def validate(candidate_params: dict) -> dict:
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            (
                {"checkpoint_version", "allow_auto_download"},
                lambda: setattr(self, "_model", None),
            ),
            ({"device"}, lambda: setattr(self, "_resolved_device", None)),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since TS-ICL is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self TSICLAdapter
Source code in skforecast/foundation/_adapters.py
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TSICLAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since TS-ICL is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : TSICLAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the TS-ICL model.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict

Per-series context windows (already trimmed to context_length).

required
context_exog dict

Per-series past covariates (already trimmed).

required
exog dict

Per-series future covariates for the forecast horizon.

required
quantiles list of float or None

Quantile levels to return. If None, a point forecast (median, quantile 0.5) is produced.

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D array of shape (steps, n_quantiles).

Source code in skforecast/foundation/_adapters.py
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the TS-ICL model.

    All input normalization, validation, and context trimming is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict
        Per-series context windows (already trimmed to
        `context_length`).
    context_exog : dict
        Per-series past covariates (already trimmed).
    exog : dict
        Per-series future covariates for the forecast horizon.
    quantiles : list of float or None
        Quantile levels to return. If `None`, a point forecast
        (median, quantile 0.5) is produced.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D array of shape
        `(steps, n_quantiles)`.

    """

    # NOTE: the model is loaded lazily here so that the adapter can be
    # instantiated and fitted without requiring tsicl to be installed.
    self._load_model()

    import torch

    quantile_list = list(quantiles) if quantiles is not None else None
    query_levels = quantile_list if quantile_list is not None else [0.5]

    series_names_in = list(context.keys())
    inputs_list = [
        self._build_tsicl_input(
            context      = context[series_name].to_numpy(),
            context_exog = (
                context_exog.get(series_name) if context_exog is not None else None
            ),
            exog         = exog.get(series_name) if exog is not None else None,
        )
        for series_name in series_names_in
    ]

    if self._resolved_device is None:
        self._resolved_device = _resolve_torch_device(self.device)
    device = torch.device(self._resolved_device)

    _, quantile_preds = self._model.forecast(
        inputs            = inputs_list,
        prediction_length = steps,
        quantile_levels   = query_levels,
        context_length    = self.context_length,
        device            = device,
        denormalize       = True,
        squeeze_output    = False,
    )

    predictions: dict[str, np.ndarray] = {}
    for i, series_name in enumerate(series_names_in):
        q_arr = _tensor_to_numpy(quantile_preds[i])
        predictions[series_name] = q_arr[0]  # drop the single-variate dim

    return predictions

skforecast.foundation._adapters.TimestralAdapter ¶

TimestralAdapter(
    model_id,
    *,
    model=None,
    context_length=4096,
    device="auto",
    predict_kwargs=None
)

Adapter for Mistral AI Timestral foundation models.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "mistralai/Timestral-28M". Must start with "mistralai/Timestral".

required
model object

Pre-loaded TimestralForecaster instance. If None, the model is loaded lazily on the first predict call.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer. Timestral supports context lengths up to 32,768: with a larger value, the backend only uses the last 32,768 observations.

4096
device str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as "cuda", "mps", or "cpu", forwarded to TimestralForecaster.from_pretrained. MPS is not supported by Timestral 1.0.0: it falls back to CPU with a warning.

'auto'
predict_kwargs dict

Additional keyword arguments forwarded verbatim to forecast (e.g. symmetric_averaging, clip_nonnegative). Cannot include context, prediction_length, observation_mask, past_covariates, known_covariates, categorical_past_covariates or categorical_known_covariates, which are managed internally.

None

Attributes:

Name Type Description
model_id str

HuggingFace model ID.

context_ dict

Stored training series after fitting.

context_exog_ (dict, None)

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

device str

Device placement for the model.

predict_kwargs dict

Additional keyword arguments forwarded to forecast.

allow_exog bool

Whether this adapter accepts exogenous variables. Always True.

supports_past_only_covariates bool

Whether historical exog columns without future values are used as past-only covariates. Always True.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. Always False: forecast takes the covariates of every series as one array, so FoundationModel groups the series by covariate signature and calls predict once per group.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length. Always True: forecast takes the context of every series as one array, so FoundationModel left-pads the context and the historical exog of each call with NaN, which Timestral treats as missing values.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. 50: the cost per series and the memory of forecast grow with the size of the batch, so FoundationModel splits each group into calls of at most 50 series, and left-pads each call separately.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. Always True.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. True: the adapter maps the labels of each non-numeric column to integer codes and Timestral encodes them per series.

SUPPORTED_QUANTILES (list, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Declared per adapter, not per checkpoint.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None means the repository is model_id. None for Timestral: the weights are downloaded from model_id.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter (e.g. by skforecast documentation and tools that need a concrete checkpoint).

is_fitted bool

Whether the adapter has been fitted.

Notes

Timestral supports only 21 fixed quantile levels: 0.01, 0.05, every multiple of 0.05 up to 0.95, and 0.99. Requesting any other level raises a ValueError. The point forecast is the median (quantile 0.5).

Each series is forecast as an independent target. For each series, columns present in its future exog become known covariates spanning context + horizon, built by concatenating the matching historical column from context_exog with the future values; columns present only in its context_exog become past covariates. Numeric and boolean columns are passed as numeric covariates. Any other column is passed as a categorical covariate: its labels are mapped to integer codes over the history and the horizon of each series, and missing labels become NaN. Whether a column is numeric is decided by its dtype, which is the same in every series. NaN values in the series and in the numeric covariates are treated as missing values by the backend; in a categorical covariate, a missing label is encoded as a category of its own (except in the left padding, which is ignored). Infinite values in numeric covariates are turned into NaN.

A known covariate that is constant over the context and changes over the forecast horizon (for example a price, or a 0/1 indicator that is 0 over the whole context) can make Timestral 1.0.0 return very large quantiles (mistralai/timestral#7). The adapter raises a FeatureOutOfRangeWarning naming the affected series and columns. Setting the historical values of those columns to NaN avoids the issue.

The pre-trained weights are released under a license that excludes companies above a revenue threshold, so loading them raises a LicenseWarning.

References

.. [1] https://github.com/mistralai/timestral

.. [2] https://huggingface.co/collections/mistralai/timestral

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. "mistralai/Timestral-28M". Must start with "mistralai/Timestral".

required
model object

Pre-loaded TimestralForecaster instance. If None, the model is loaded lazily on the first predict call.

None
context_length int

Maximum number of historical observations to retain as context. At fit time only the last context_length observations of series are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are passed as-is. Must be a positive integer.

4096
device str

Device placement for the model. "auto" selects the best available accelerator (CUDA > MPS > CPU). MPS falls back to CPU with a warning.

'auto'
predict_kwargs dict

Additional keyword arguments forwarded verbatim to forecast.

None

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when parameters that affect

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the Timestral model.

Source code in skforecast/foundation/_adapters.py
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 4096,
    device: str = "auto",
    predict_kwargs: dict[str, Any] | None = None,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. `"mistralai/Timestral-28M"`. Must
        start with `"mistralai/Timestral"`.
    model : object, default None
        Pre-loaded `TimestralForecaster` instance. If `None`, the model
        is loaded lazily on the first `predict` call.
    context_length : int, default 4096
        Maximum number of historical observations to retain as context.
        At `fit` time only the last `context_length` observations of
        `series` are stored. At `predict` time, if `context` is
        longer than `context_length` it is trimmed to this length;
        if it is shorter, all available observations are passed as-is.
        Must be a positive integer.
    device : str, default 'auto'
        Device placement for the model. `"auto"` selects the best
        available accelerator (CUDA > MPS > CPU). MPS falls back to CPU
        with a warning.
    predict_kwargs : dict, default None
        Additional keyword arguments forwarded verbatim to `forecast`.

    """

    _validate_model_id_prefix(model_id, self._MODEL_ID_PREFIX, type(self).__name__)
    _validate_positive_int("context_length", context_length)
    predict_kwargs = predict_kwargs or {}
    self._validate_predict_kwargs(predict_kwargs)

    self.model_id       = model_id
    self._model         = model
    self.context_       = None
    self.context_exog_  = None
    self.context_length = context_length
    self.device         = device
    self.predict_kwargs = predict_kwargs
    self.is_fitted      = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = [
    0.01,
    0.05,
    0.1,
    0.15,
    0.2,
    0.25,
    0.3,
    0.35,
    0.4,
    0.45,
    0.5,
    0.55,
    0.6,
    0.65,
    0.7,
    0.75,
    0.8,
    0.85,
    0.9,
    0.95,
    0.99,
]

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = True

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = True

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = False

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = True

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = 50

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = "timestral @ git+https://github.com/mistralai/timestral.git"

default_model_id class-attribute instance-attribute ¶

default_model_id = 'mistralai/Timestral-28M'

model_id instance-attribute ¶

model_id = model_id

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

context_length instance-attribute ¶

context_length = context_length

device instance-attribute ¶

device = device

predict_kwargs instance-attribute ¶

predict_kwargs = predict_kwargs

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, device, predict_kwargs.

Source code in skforecast/foundation/_adapters.py
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `device`, `predict_kwargs`.

    """

    return {
        "model_id":       self.model_id,
        "context_length": self.context_length,
        "device":         self.device,
        "predict_kwargs": self.predict_kwargs or None,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when parameters that affect loading change.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, device, predict_kwargs.

{}

Returns:

Name Type Description
self TimestralAdapter
Notes

Only model_id and device affect the loaded model, so only those discard the cached model. context_length and predict_kwargs are applied at predict time and never trigger a reload.

Source code in skforecast/foundation/_adapters.py
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
def set_params(self, **params) -> TimestralAdapter:
    """
    Set adapter parameters. Resets the model when parameters that affect
    loading change.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `device`,
        `predict_kwargs`.

    Returns
    -------
    self : TimestralAdapter

    Notes
    -----
    Only `model_id` and `device` affect the loaded model, so only those
    discard the cached model. `context_length` and `predict_kwargs` are
    applied at predict time and never trigger a reload.

    """

    def validate(candidate_params: dict) -> dict:
        if "model_id" in candidate_params:
            _validate_model_id_prefix(
                candidate_params["model_id"],
                self._MODEL_ID_PREFIX,
                type(self).__name__,
            )
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "predict_kwargs" in candidate_params:
            candidate_params["predict_kwargs"] = (
                candidate_params["predict_kwargs"] or {}
            )
            self._validate_predict_kwargs(candidate_params["predict_kwargs"])
        return candidate_params

    return _apply_set_params(
        self, params,
        validate=validate,
        resets=(
            ({"model_id", "device"}, lambda: setattr(self, "_model", None)),
        ),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since Timestral is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self TimestralAdapter
Source code in skforecast/foundation/_adapters.py
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TimestralAdapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since Timestral is a zero-shot inference
    model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : TimestralAdapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the Timestral model.

All input normalization, validation, context trimming and padding is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast.

required
context dict

Per-series context windows (already trimmed to context_length and left-padded with NaN to the same length).

required
context_exog (dict, None)

Per-series historical exogenous variables (already trimmed and padded). For each series, columns not also present in its exog are forwarded as past covariates.

required
exog (dict, None)

Per-series future exogenous variables for the forecast horizon. Each column is forwarded as a known covariate of that series, concatenated with its historical values.

required
quantiles list of float or None

Quantile levels. Must be a subset of SUPPORTED_QUANTILES.

required

Returns:

Name Type Description
predictions dict

Keys are series names, in the same order as context. Each value is a 2-D array of shape (steps, n_quantiles).

Notes

A ValueError is raised if a requested quantile level is not in SUPPORTED_QUANTILES.

forecast requires all series in one call to share the same context length and covariate layout. FoundationModel guarantees both: it groups the series by covariate signature (get_exog_signature), splits each group into calls of at most max_series_per_call series and left-pads each call, so the signature of the first series sets the column order for the whole batch. The point forecast (quantiles is None) is the model's median quantile.

Source code in skforecast/foundation/_adapters.py
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the Timestral model.

    All input normalization, validation, context trimming and padding is
    performed upstream by `FoundationModel`; this method receives
    pre-processed dicts only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast.
    context : dict
        Per-series context windows (already trimmed to
        `context_length` and left-padded with NaN to the same length).
    context_exog : dict, None
        Per-series historical exogenous variables (already trimmed and
        padded). For each series, columns not also present in its `exog`
        are forwarded as past covariates.
    exog : dict, None
        Per-series future exogenous variables for the forecast
        horizon. Each column is forwarded as a known covariate of that
        series, concatenated with its historical values.
    quantiles : list of float or None
        Quantile levels. Must be a subset of `SUPPORTED_QUANTILES`.

    Returns
    -------
    predictions : dict
        Keys are series names, in the same order as `context`. Each
        value is a 2-D array of shape `(steps, n_quantiles)`.

    Notes
    -----
    A `ValueError` is raised if a requested quantile level is not in
    `SUPPORTED_QUANTILES`.

    `forecast` requires all series in one call to share the same
    context length and covariate layout. `FoundationModel` guarantees
    both: it groups the series by covariate signature
    (`get_exog_signature`), splits each group into calls of at most
    `max_series_per_call` series and left-pads each call, so the
    signature of the first series sets the column order for the whole
    batch. The point forecast
    (`quantiles is None`) is the model's median quantile.

    """

    quantile_list = _validate_supported_quantiles(
        quantiles, self.SUPPORTED_QUANTILES, "Timestral"
    )

    # NOTE: the model is loaded lazily here so that the adapter can be
    # instantiated and fitted without requiring timestral to be installed.
    self._load_model()

    names = list(context.keys())

    # Every series in a call shares the same covariate columns
    # (`FoundationModel` groups them by covariate signature), so the
    # signature of the first series sets the column order for the batch.
    past_only_cols, fut_cols = get_exog_signature(
        context_exog = context_exog.get(names[0]) if context_exog is not None else None,
        exog         = exog.get(names[0]) if exog is not None else None,
    )
    categorical_cols = self._categorical_columns(
        context_exog   = context_exog.get(names[0]) if context_exog is not None else None,
        exog           = exog.get(names[0]) if exog is not None else None,
        past_only_cols = past_only_cols,
        fut_cols       = fut_cols,
    )
    if fut_cols:
        self._warn_if_constant_known_covariates(
            names        = names,
            context_exog = context_exog,
            exog         = exog,
            fut_cols     = fut_cols,
        )

    covariates = [
        self._build_covariates(
            context_exog     = (
                context_exog.get(series_name) if context_exog is not None else None
            ),
            exog             = exog.get(series_name) if exog is not None else None,
            past_only_cols   = past_only_cols,
            fut_cols         = fut_cols,
            categorical_cols = categorical_cols,
        )
        for series_name in names
    ]
    covariate_kwargs = {
        key: np.stack([series_covariates[key] for series_covariates in covariates])
        for key in covariates[0]
    }

    forecast = self._model.forecast(
        context           = np.stack([
                                context[series_name].to_numpy(dtype=np.float64, na_value=np.nan)
                                for series_name in names
                            ])[:, np.newaxis, :],
        prediction_length = steps,
        **covariate_kwargs,
        **self.predict_kwargs,
    )

    # Shape (n_series, steps, n_levels): one target per series.
    q_arr = _tensor_to_numpy(forecast.quantiles)[:, 0]
    quantile_indices = _match_quantile_indices(
        list(forecast.quantile_levels),
        quantile_list if quantile_list is not None else [0.5],
    )

    return {
        series_name: q_arr[i][:, quantile_indices]
        for i, series_name in enumerate(names)
    }

skforecast.foundation._adapters.TiRex2Adapter ¶

TiRex2Adapter(
    model_id,
    *,
    model=None,
    context_length=2048,
    device="auto",
    predict_kwargs=None
)

Adapter for the NX-AI TiRex-2 zero-shot forecaster.

TiRex-2 forecasts one or more target variates directly from their history, optionally conditioned on past and future-known covariates. Each series is passed to the backend as its own TimeseriesType, with its own covariates, so FoundationModel sends every series in the same call, whatever its covariates, in chunks of at most max_series_per_call series. The backend keeps each series apart when it mixes the variates, so the forecast of a series does not depend on the other series of the call (up to float32 rounding).

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "NX-AI/TiRex-2". Used to resolve this adapter and as the Hugging Face repository the weights are downloaded from.

required
model object

Pre-instantiated model as returned by tirex2.load_model. If None, a new instance is created lazily on the first call to predict. Intended for testing only.

None
context_length int

Maximum number of historical observations to use as context. At fit time only the last context_length observations are stored. At predict time, if context is longer than context_length it is trimmed to this length; if it is shorter, all available observations are used as-is. Must be a positive integer. The default is the maximum context length of NX-AI/TiRex-2 and NX-AI/TiRex-2-fevbench (context_len: 2048); the two gifteval checkpoints accept up to 8192.

2048
device str

Device placement for inference. "auto" selects the best available accelerator (CUDA > MPS > CPU). An explicit value must be exactly "cuda", "mps" or "cpu": the backend does not accept a device index such as "cuda:1".

'auto'
predict_kwargs dict

Extra keyword arguments forwarded to the backend forecast call, e.g. {"tta_sign_flip": True} to opt into sign-flip test-time augmentation. Arguments owned by the adapter (timeseries, prediction_length, output_type, yield_per_batch, return_inference_time) are rejected at construction time.

None

Attributes:

Name Type Description
model_id str

Model ID.

context_ dict

Stored training series after fitting.

context_exog_ dict

Stored historical exogenous variables after fitting.

context_length int

Maximum number of historical observations used as context.

device str

Device placement for inference.

predict_kwargs dict

Extra keyword arguments forwarded to the backend forecast call.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. True for TiRex-2: every TimeseriesType carries its own covariates, so the backend accepts series with different covariate sets in a single call.

requires_equal_length_context bool

Whether the backend needs every series of a call to have the same context length, so that FoundationModel left-pads them with NaN. False: the backend left-pads each call with NaN itself.

max_series_per_call (int, None)

Maximum number of series sent to the backend in one call. 64: the backend mixes the variates of every series of a call in one attention, so its memory grows faster than linearly with the size of the call, and FoundationModel splits the series into calls of at most 64.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context. True for TiRex-2: the backend masks NaN in forward and pads short contexts with NaN itself.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False for TiRex-2: covariates must be numeric.

SUPPORTED_QUANTILES list

Quantile levels accepted by the backend. TiRex-2 forecasts the native nine-quantile grid [0.1, ..., 0.9], so requesting any other level raises a ValueError.

requires_hf_auth bool

Whether the checkpoints served by this adapter are gated on the Hugging Face Hub. False for TiRex-2.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub. False for TiRex-2, which is released under Apache 2.0.

weights_repo_id (str, None)

Hugging Face repository the backend downloads the weights from when it is not model_id. None for TiRex-2: load_model(self.model_id, ...) downloads the weights from model_id itself.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache.

backend_package str

Package that provides the backend, as passed to pip install.

default_model_id str

Model ID used by default for this adapter.

is_fitted bool

Whether the adapter has been fitted.

Notes

TiRex-2 is a zero-shot model, so fit only stores the series and no training occurs. The tirex-2 package is not a skforecast dependency and is imported lazily inside the adapter, so the adapter can be created and fitted without it installed. tirex-2 requires Python >= 3.11.

Each checkpoint forecasts at most future_len steps ahead (320 for NX-AI/TiRex-2 and NX-AI/TiRex-2-fevbench, 928 for the two gifteval checkpoints). The backend truncates longer horizons with only a log warning, so predict reads the limit from the loaded model and rejects steps above it with a ValueError before calling the backend.

Past covariates are forwarded as past_covariates and future-known covariates as future_covariates, concatenated with their historical values as the backend expects. Covariates must be numeric; encode categoricals as numbers before passing them.

References

.. [1] https://github.com/NX-AI/tirex-2

.. [2] https://huggingface.co/NX-AI/TiRex-2

Initialise the adapter.

Parameters:

Name Type Description Default
model_id str

Model ID, e.g. "NX-AI/TiRex-2". Used to resolve this adapter and as the Hugging Face repository the weights are downloaded from.

required
model object

Pre-instantiated model as returned by tirex2.load_model. If None, a new instance is created lazily on the first call to predict.

None
context_length int

Maximum number of historical observations to retain as context. Must be a positive integer.

2048
device str

Device placement for inference. "auto" selects the best available accelerator (CUDA > MPS > CPU). An explicit value must be exactly "cuda", "mps" or "cpu".

'auto'
predict_kwargs dict

Extra keyword arguments forwarded to the backend forecast call. Adapter-managed arguments are rejected.

None

Methods:

Name Description
get_params

Return the adapter's constructor parameters.

set_params

Set adapter parameters. Resets the model when model_id or device

fit

Store the training series and optional historical exogenous variables.

predict

Generate predictions using the TiRex-2 model.

Source code in skforecast/foundation/_adapters.py
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
def __init__(
    self,
    model_id: str,
    *,
    model: Any | None = None,
    context_length: int = 2048,
    device: str = "auto",
    predict_kwargs: dict[str, Any] | None = None,
) -> None:
    """
    Initialise the adapter.

    Parameters
    ----------
    model_id : str
        Model ID, e.g. `"NX-AI/TiRex-2"`. Used to resolve this adapter and
        as the Hugging Face repository the weights are downloaded from.
    model : object, default None
        Pre-instantiated model as returned by `tirex2.load_model`. If
        `None`, a new instance is created lazily on the first call to
        `predict`.
    context_length : int, default 2048
        Maximum number of historical observations to retain as context.
        Must be a positive integer.
    device : str, default 'auto'
        Device placement for inference. `"auto"` selects the best available
        accelerator (CUDA > MPS > CPU). An explicit value must be exactly
        `"cuda"`, `"mps"` or `"cpu"`.
    predict_kwargs : dict, default None
        Extra keyword arguments forwarded to the backend `forecast` call.
        Adapter-managed arguments are rejected.

    """

    _validate_model_id_prefix(model_id, self._MODEL_ID_PREFIX, type(self).__name__)
    _validate_positive_int("context_length", context_length)
    predict_kwargs = predict_kwargs or {}
    self._validate_predict_kwargs(predict_kwargs)
    self.model_id       = model_id
    self._model         = model
    self.context_length = context_length
    self.device         = device
    self.predict_kwargs = predict_kwargs
    self.context_       = None
    self.context_exog_  = None
    self.is_fitted      = False

Attributes¶

SUPPORTED_QUANTILES class-attribute instance-attribute ¶

SUPPORTED_QUANTILES = [
    0.1,
    0.2,
    0.3,
    0.4,
    0.5,
    0.6,
    0.7,
    0.8,
    0.9,
]

allow_exog class-attribute instance-attribute ¶

allow_exog = True

supports_past_only_covariates class-attribute instance-attribute ¶

supports_past_only_covariates = True

supports_categorical_covariates class-attribute instance-attribute ¶

supports_categorical_covariates = False

supports_heterogeneous_covariates class-attribute instance-attribute ¶

supports_heterogeneous_covariates = True

requires_equal_length_context class-attribute instance-attribute ¶

requires_equal_length_context = False

max_series_per_call class-attribute instance-attribute ¶

max_series_per_call = 64

supports_nan_in_series class-attribute instance-attribute ¶

supports_nan_in_series = True

requires_hf_auth class-attribute instance-attribute ¶

requires_hf_auth = False

requires_provider_auth class-attribute instance-attribute ¶

requires_provider_auth = False

weights_repo_id class-attribute instance-attribute ¶

weights_repo_id = None

weights_in_hf_cache class-attribute instance-attribute ¶

weights_in_hf_cache = True

backend_package class-attribute instance-attribute ¶

backend_package = 'tirex-2'

default_model_id class-attribute instance-attribute ¶

default_model_id = 'NX-AI/TiRex-2'

model_id instance-attribute ¶

model_id = model_id

context_length instance-attribute ¶

context_length = context_length

device instance-attribute ¶

device = device

predict_kwargs instance-attribute ¶

predict_kwargs = predict_kwargs

context_ instance-attribute ¶

context_ = None

context_exog_ instance-attribute ¶

context_exog_ = None

is_fitted instance-attribute ¶

is_fitted = False

Methods:¶

get_params ¶

get_params()

Return the adapter's constructor parameters.

Returns:

Name Type Description
params dict

Keys: model_id, context_length, device, predict_kwargs.

Source code in skforecast/foundation/_adapters.py
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
def get_params(self) -> dict:
    """
    Return the adapter's constructor parameters.

    Returns
    -------
    params : dict
        Keys: `model_id`, `context_length`, `device`, `predict_kwargs`.

    """

    return {
        "model_id":       self.model_id,
        "context_length": self.context_length,
        "device":         self.device,
        "predict_kwargs": self.predict_kwargs or None,
    }

set_params ¶

set_params(**params)

Set adapter parameters. Resets the model when model_id or device changes, since those control which checkpoint is loaded and where it runs.

Parameters:

Name Type Description Default
**params

Valid keys: model_id, context_length, device, predict_kwargs.

{}

Returns:

Name Type Description
self TiRex2Adapter
Source code in skforecast/foundation/_adapters.py
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
def set_params(self, **params) -> TiRex2Adapter:
    """
    Set adapter parameters. Resets the model when `model_id` or `device`
    changes, since those control which checkpoint is loaded and where it
    runs.

    Parameters
    ----------
    **params :
        Valid keys: `model_id`, `context_length`, `device`,
        `predict_kwargs`.

    Returns
    -------
    self : TiRex2Adapter

    """

    def validate(candidate_params: dict) -> dict:
        if "model_id" in candidate_params:
            _validate_model_id_prefix(
                candidate_params["model_id"],
                self._MODEL_ID_PREFIX,
                type(self).__name__,
            )
        if "context_length" in candidate_params:
            _validate_positive_int(
                "context_length", candidate_params["context_length"]
            )
        if "predict_kwargs" in candidate_params:
            candidate_params["predict_kwargs"] = (
                candidate_params["predict_kwargs"] or {}
            )
            self._validate_predict_kwargs(candidate_params["predict_kwargs"])
        return candidate_params

    return _apply_set_params(
        self,
        params,
        validate=validate,
        resets=(({"model_id", "device"}, lambda: setattr(self, "_model", None)),),
    )

fit ¶

fit(context, context_exog)

Store the training series and optional historical exogenous variables. No model training occurs since TiRex-2 is a zero-shot inference model.

All input normalization and validation is performed upstream by FoundationModel; this method receives canonical dicts only.

Parameters:

Name Type Description Default
context dict pandas Series

Normalized training series, one entry per series.

required
context_exog dict pandas DataFrame, pandas Series, or None

Per-series historical exogenous variables (past covariates).

required

Returns:

Name Type Description
self TiRex2Adapter
Source code in skforecast/foundation/_adapters.py
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
def fit(
    self,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
) -> TiRex2Adapter:
    """
    Store the training series and optional historical exogenous variables.
    No model training occurs since TiRex-2 is a zero-shot inference model.

    All input normalization and validation is performed upstream by
    `FoundationModel`; this method receives canonical dicts only.

    Parameters
    ----------
    context : dict pandas Series
        Normalized training series, one entry per series.
    context_exog : dict pandas DataFrame, pandas Series, or None
        Per-series historical exogenous variables (past covariates).

    Returns
    -------
    self : TiRex2Adapter

    """

    return super().fit(context=context, context_exog=context_exog)

predict ¶

predict(steps, context, context_exog, exog, quantiles)

Generate predictions using the TiRex-2 model.

All input normalization, validation, and context trimming is performed upstream by FoundationModel; this method receives pre-processed dicts only.

Parameters:

Name Type Description Default
steps int

Number of steps ahead to forecast. Must not exceed the maximum horizon of the loaded checkpoint (its future_len).

required
context dict

Per-series context windows (already trimmed to context_length).

required
context_exog dict

Per-series past covariates (already trimmed).

required
exog dict

Per-series future covariates for the forecast horizon.

required
quantiles list of float, tuple of float, None

Quantile levels to return. If None, a point forecast (median, quantile 0.5) is produced.

required

Returns:

Name Type Description
predictions dict

Keys are series names. Each value is a 2-D array of shape (steps, n_quantiles).

Notes

A ValueError is raised if steps is larger than the maximum horizon of the loaded checkpoint (its future_len), before the backend is called.

Source code in skforecast/foundation/_adapters.py
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
def predict(
    self,
    steps: int,
    context: dict[str, pd.Series],
    context_exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    exog: dict[str, pd.DataFrame | pd.Series | None] | None,
    quantiles: list[float] | tuple[float, ...] | None,
) -> dict[str, np.ndarray]:
    """
    Generate predictions using the TiRex-2 model.

    All input normalization, validation, and context trimming is performed
    upstream by `FoundationModel`; this method receives pre-processed dicts
    only.

    Parameters
    ----------
    steps : int
        Number of steps ahead to forecast. Must not exceed the maximum
        horizon of the loaded checkpoint (its `future_len`).
    context : dict
        Per-series context windows (already trimmed to `context_length`).
    context_exog : dict
        Per-series past covariates (already trimmed).
    exog : dict
        Per-series future covariates for the forecast horizon.
    quantiles : list of float, tuple of float, None
        Quantile levels to return. If `None`, a point forecast (median,
        quantile 0.5) is produced.

    Returns
    -------
    predictions : dict
        Keys are series names. Each value is a 2-D array of shape
        `(steps, n_quantiles)`.

    Notes
    -----
    A `ValueError` is raised if `steps` is larger than the maximum horizon
    of the loaded checkpoint (its `future_len`), before the backend is
    called.

    """

    quantile_list = _validate_supported_quantiles(
        quantiles, self.SUPPORTED_QUANTILES, "TiRex-2"
    )
    self._load_model()
    # `future_len` of the loaded checkpoint. Longer horizons are truncated
    # by the backend with only a log warning, so they are rejected here.
    max_steps = self._model.future_len
    if steps > max_steps:
        raise ValueError(
            f"`steps` must be <= {max_steps}, the maximum forecast horizon "
            f"of {self.model_id} (`future_len`). Got {steps}. Longer "
            f"horizons are truncated by the backend, so the adapter rejects "
            f"them instead of returning a shorter forecast than requested."
        )
    _, TimeseriesType = self._import_backend()
    import torch

    names = list(context)
    timeseries = []
    for name in names:
        past_cols, future_cols = get_exog_signature(
            context_exog=(context_exog or {}).get(name),
            exog=(exog or {}).get(name),
        )
        past, future = self._build_covariates(
            (context_exog or {}).get(name),
            (exog or {}).get(name),
            past_cols,
            future_cols,
        )
        target = torch.as_tensor(
            context[name].to_numpy(dtype=np.float32, na_value=np.nan)[None, :],
            dtype=torch.float32,
        )
        if past is not None:
            past = torch.as_tensor(past, dtype=torch.float32)
        if future is not None:
            future = torch.as_tensor(future, dtype=torch.float32)
        timeseries.append(
            TimeseriesType(
                target=target,
                past_covariates=past,
                future_covariates=future,
            )
        )

    forecasts = self._model.forecast(
        timeseries,
        prediction_length=steps,
        output_type="numpy",
        **self.predict_kwargs,
    )
    if len(forecasts) != len(names):
        raise ValueError(
            "TiRex-2 returned an unexpected number of forecasts: "
            f"{len(forecasts)}. Expected {len(names)}."
        )

    # Each forecast has shape (n_targets, n_quantiles, steps), with the
    # quantile levels of the loaded checkpoint. A point forecast is the
    # median.
    quantile_grid = [float(q) for q in self._model.quantiles]
    quantile_indices = _match_quantile_indices(
        quantile_grid, quantile_list if quantile_list is not None else [0.5]
    )
    expected_shape = (1, len(quantile_grid), steps)
    predictions = {}
    for name, forecast in zip(names, forecasts):
        values = np.asarray(forecast)
        if values.shape != expected_shape:
            raise ValueError(
                "TiRex-2 returned an unexpected forecast shape: "
                f"{values.shape!r}. Expected {expected_shape}."
            )
        predictions[name] = values[0, quantile_indices, :].T

    return predictions

skforecast.foundation._model_info.get_model_info ¶

get_model_info(model_id)

Return the capabilities and requirements of a foundation model.

The adapter is resolved from model_id in the same way as FoundationModel does, but neither the backend library nor the weights are loaded, so the backend does not need to be installed.

Parameters:

Name Type Description Default
model_id str

HuggingFace model ID, e.g. 'autogluon/chronos-2-small'.

required

Returns:

Name Type Description
info FoundationModelInfo

Capabilities and requirements of model_id. The license fields and weights_repo_id are resolved for this specific model_id.

Source code in skforecast/foundation/_model_info.py
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
def get_model_info(model_id: str) -> FoundationModelInfo:
    """
    Return the capabilities and requirements of a foundation model.

    The adapter is resolved from `model_id` in the same way as
    `FoundationModel` does, but neither the backend library nor the weights
    are loaded, so the backend does not need to be installed.

    Parameters
    ----------
    model_id : str
        HuggingFace model ID, e.g. `'autogluon/chronos-2-small'`.

    Returns
    -------
    info : FoundationModelInfo
        Capabilities and requirements of `model_id`. The license fields and
        `weights_repo_id` are resolved for this specific `model_id`.

    """

    if not isinstance(model_id, str):
        raise TypeError(
            f"`model_id` must be a string. Got {type(model_id).__name__}."
        )

    adapter_cls = _resolve_adapter(model_id)

    return _build_model_info(model_id=model_id, adapter_cls=adapter_cls)

skforecast.foundation._model_info.list_adapters ¶

list_adapters(as_frame=False)

Return the capabilities and requirements of every foundation model adapter supported by skforecast.

Each adapter is described by its default_model_id, so the license fields and weights_repo_id refer to that model ID. Use get_model_info to resolve them for a different checkpoint.

Parameters:

Name Type Description Default
as_frame bool

If True, return a pandas DataFrame with one row per adapter, indexed by the adapter name, instead of a list of FoundationModelInfo.

False

Returns:

Name Type Description
adapters list, pandas DataFrame

One FoundationModelInfo per adapter, in registration order. If as_frame=True, a DataFrame with one row per adapter (index adapter) and one column per remaining field of FoundationModelInfo.

Source code in skforecast/foundation/_model_info.py
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
def list_adapters(
    as_frame: bool = False
) -> list[FoundationModelInfo] | pd.DataFrame:
    """
    Return the capabilities and requirements of every foundation model
    adapter supported by skforecast.

    Each adapter is described by its `default_model_id`, so the license
    fields and `weights_repo_id` refer to that model ID. Use `get_model_info` to resolve them for a
    different checkpoint.

    Parameters
    ----------
    as_frame : bool, default False
        If `True`, return a pandas DataFrame with one row per adapter, indexed
        by the adapter name, instead of a list of `FoundationModelInfo`.

    Returns
    -------
    adapters : list, pandas DataFrame
        One `FoundationModelInfo` per adapter, in registration order. If
        `as_frame=True`, a DataFrame with one row per adapter (index
        `adapter`) and one column per remaining field of
        `FoundationModelInfo`.

    """

    adapter_classes = list(dict.fromkeys(_ADAPTER_REGISTRY.values()))
    adapters = [
        _build_model_info(model_id=cls.default_model_id, adapter_cls=cls)
        for cls in adapter_classes
    ]

    if as_frame:
        adapters = pd.DataFrame(
            [asdict(adapter) for adapter in adapters]
        ).set_index("adapter")

    return adapters

skforecast.foundation._model_info.FoundationModelInfo dataclass ¶

FoundationModelInfo(
    *,
    model_id,
    adapter,
    model_id_prefixes,
    default_model_id,
    default_context_length,
    backend_package,
    allow_exog,
    supports_past_only_covariates,
    supports_categorical_covariates,
    supports_heterogeneous_covariates,
    supports_nan_in_series,
    supported_quantiles,
    requires_hf_auth,
    requires_provider_auth,
    weights_repo_id,
    weights_in_hf_cache,
    license,
    license_url,
    commercial_use_restricted
)

Capabilities and requirements of a foundation model supported by skforecast.

Instances are created by get_model_info and list_adapters; they are immutable and can be converted to a dict with dataclasses.asdict.

The weights and license fields (weights_repo_id, weights_in_hf_cache, license, license_url and commercial_use_restricted) describe the default configuration of the adapter. They do not reflect the backend configuration passed to it (tabicl_config, nori_config, tabpfn_model_config), which can select other weights or a local file, nor the cloud API of TabPFN (mode='client'), which downloads no weights and is subject to the terms of the provider.

Attributes:

Name Type Description
model_id str

HuggingFace model ID the information refers to.

adapter str

Name of the adapter class that serves model_id.

model_id_prefixes tuple

Model ID prefixes routed to adapter.

default_model_id str

Model ID used by default for adapter.

default_context_length int

Default maximum number of historical observations used as context.

backend_package str

Package that provides the backend, as passed to pip install.

allow_exog bool

Whether exogenous variables (covariates) are supported.

supports_past_only_covariates bool

Whether covariates without future values are used as past-only covariates. When False, they are ignored with a warning.

supports_categorical_covariates bool

Whether the backend supports non-numeric covariates natively, so they do not have to be encoded as numbers. False also when the adapter forwards them unchanged but skforecast does not verify how the backend handles them.

supports_heterogeneous_covariates bool

Whether series with different covariate columns can be forecast in the same backend call. When False, the series are grouped by their covariate columns and the backend is called once per group.

supports_nan_in_series bool

Whether the backend accepts NaN values in the series used as context.

supported_quantiles (tuple, None)

Quantile levels accepted by the backend. None means any level in (0, 1).

requires_hf_auth bool

Whether the checkpoints served by adapter are gated on the Hugging Face Hub, so an authenticated account that has accepted the model license is needed. Unlike the license fields, it is declared per adapter, not resolved for model_id.

requires_provider_auth bool

Whether the model provider requires its own account or license acceptance, outside the Hugging Face Hub, before the weights can be used (e.g. the Prior Labs token and license acceptance of TabPFN). Declared per adapter, not resolved for model_id.

weights_repo_id str

Hugging Face repository the backend downloads the weights from by default. It is model_id unless the backend takes the weights from a fixed repository (e.g. 'jingang/TabICL' for TabICL). The backend configuration of the adapter (e.g. a local model_path) can override it.

weights_in_hf_cache bool

Whether the downloaded weights are stored in the Hugging Face Hub cache, under weights_repo_id. When False (TabPFN keeps them in its own cache directory), the Hugging Face Hub cache does not tell whether the weights are already downloaded.

license str

License of the weights registered in skforecast: an SPDX identifier (e.g. 'Apache-2.0'), or the license name of the Hugging Face model card when it is not a standard license (e.g. 'timesfm-non-commercial-license-v1.0'). Providers can change their terms, so check license_url before relying on it.

license_url str

Link to the terms of license: the license file of the provider, or the model card of weights_repo_id for standard licenses.

commercial_use_restricted bool

Whether license restricts commercial use of the weights. When True, a LicenseWarning is raised when they are loaded.

Attributes¶

model_id instance-attribute ¶

model_id

adapter instance-attribute ¶

adapter

model_id_prefixes instance-attribute ¶

model_id_prefixes

default_model_id instance-attribute ¶

default_model_id

default_context_length instance-attribute ¶

default_context_length

backend_package instance-attribute ¶

backend_package

allow_exog instance-attribute ¶

allow_exog

supports_past_only_covariates instance-attribute ¶

supports_past_only_covariates

supports_categorical_covariates instance-attribute ¶

supports_categorical_covariates

supports_heterogeneous_covariates instance-attribute ¶

supports_heterogeneous_covariates

supports_nan_in_series instance-attribute ¶

supports_nan_in_series

supported_quantiles instance-attribute ¶

supported_quantiles

requires_hf_auth instance-attribute ¶

requires_hf_auth

requires_provider_auth instance-attribute ¶

requires_provider_auth

weights_repo_id instance-attribute ¶

weights_repo_id

weights_in_hf_cache instance-attribute ¶

weights_in_hf_cache

license instance-attribute ¶

license

license_url instance-attribute ¶

license_url

commercial_use_restricted instance-attribute ¶

commercial_use_restricted