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.
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).
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.
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_.
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.
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.
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:
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_.
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).
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.
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.
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.
deffit(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 """ifexogisnotNoneandnotself.allow_exog:warnings.warn(f"The model '{self.model_id}' does not support exogenous "f"variables. `exog` will be ignored.",IgnoredArgumentWarning,stacklevel=2,)exog=Noneself.index_type_=Noneself.index_freq_=Noneself.context_range_=Noneself.series_names_in_=Noneself.is_multiple_series_=Falseself.exog_in_=Falseself.exog_names_in_=Noneself.exog_names_in_per_series_=Noneself.exog_type_in_=Noneself.fit_date=Nonecontext,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_)>1ifcontext_exogisnotNoneandlen(exog_names_in_)>0:self.exog_in_=Trueself.exog_names_in_=exog_names_in_self.exog_names_in_per_series_={k:list(v.columns)ifvisnotNoneelseNonefork,vincontext_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]]forseries_name,series_indexinseries_indexes.items()}self.index_type_=type(series_indexes[series_names_in_[0]])ifisinstance(series_indexes[series_names_in_[0]],pd.DatetimeIndex):self.index_freq_=series_indexes[series_names_in_[0]].freqelse:self.index_freq_=series_indexes[series_names_in_[0]].stepreturnself
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
defpredict(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. """ifnotself.is_fittedandcontextisNone:raiseValueError("Call `fit` before `predict`, or pass `context`.")if(isinstance(steps,bool)ornotisinstance(steps,(int,np.integer))orsteps<1):raiseValueError("`steps` must be a positive integer.")ifquantilesisnotNone:ifnotisinstance(quantiles,(list,tuple)):raiseTypeError("`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]`.")forqinquantiles:ifnot0.0<=q<=1.0:raiseValueError(f"All quantiles must be between 0 and 1. Got {q}.")# Context (past data)ifcontextisNone:ifcontext_exogisnotNone: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_elifcheck_inputs:context,_,series_names_in,context_exog,_=self._check_preprocess_context(series=context,exog=context_exog,)else:ifnotcontext:raiseValueError("`context` cannot be an empty dictionary.")series_names_in=list(context.keys())iflevelsisnotNone:iflen(levels)==0:raiseValueError("`levels` must be a single string or a list-like of strings, but cannot be empty.")requested_levels=[levels]ifisinstance(levels,str)elselist(levels)unknown=[lvforlvinrequested_levelsiflvnotinseries_names_in]ifunknown:raiseValueError(f"`levels` {unknown} not found in available series "f"{list(series_names_in)}.")series_names_in=requested_levelscontext={series_name:context[series_name]forseries_nameinrequested_levels}ifcontext_exogisnotNone:context_exog={series_name:context_exog.get(series_name)forseries_nameinrequested_levels}# Future exogifnotself.allow_exog:has_exog=(exogisnotNone)or(context_exogisnotNone)ifhas_exog:warnings.warn(f"{type(self.adapter).__name__} does not currently ""support covariates. `exog` and `context_exog` ""are ignored.",IgnoredArgumentWarning,stacklevel=3,)exog=Nonecontext_exog=Noneelse:# 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.ifcontext_exogisnotNone: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,)ifcheck_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_exogisnotNoneandnotself.adapter.supports_past_only_covariates):context_exog=drop_past_only_exog(context_exog=context_exog,exog=exog,series_names_in=series_names_in,)ifnotself.adapter.supports_nan_in_series:series_with_nan=[series_nameforseries_nameinseries_names_inifcontext[series_name].isna().any()]ifseries_with_nan:raiseValueError(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.ifself.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=[]forseries_names_groupinseries_groups:chunk_size=self.adapter.max_series_per_callorlen(series_names_group)series_calls.extend(series_names_group[start:start+chunk_size]forstartinrange(0,len(series_names_group),chunk_size))# Adapter returns dict[str, np.ndarray] with shape (steps, n_q)raw_predictions:dict[str,np.ndarray]={}forseries_names_callinseries_calls:call_context={series_name:context[series_name]forseries_nameinseries_names_call}call_context_exog=({series_name:context_exog[series_name]forseries_nameinseries_names_call}ifcontext_exogisnotNoneelseNone)# Backends that take the context of a call as one array need the# same length for every series: left-pad the call with NaN.ifself.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]forseries_nameinseries_names_call}ifexogisnotNoneelseNone),quantiles=quantiles,))# Build long-format DataFrame from raw predictionsn_series=len(series_names_in)per_series_indices=[expand_index(context[series_name].index,steps=steps)forseries_nameinseries_names_in]ifn_series==1:long_index=per_series_indices[0]else:idx_arr=np.column_stack([idx.to_numpy()foridxinper_series_indices]).ravel()long_index=(pd.DatetimeIndex(idx_arr)ifisinstance(per_series_indices[0],pd.DatetimeIndex)elsepd.Index(idx_arr))level_col=np.tile(series_names_in,steps)col_names=["pred"]ifquantilesisNoneelse[f"q_{q}"forqinquantiles]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)fori,series_nameinenumerate(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}forj,colinenumerate(col_names):predictions[col]=pred_matrix[:,j]predictions=pd.DataFrame(predictions,index=long_index)returnpredictions
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
defget_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. """returnself.adapter.get_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.
defset_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"inparams:new_adapter_cls=_resolve_adapter(params["model_id"])ifnew_adapter_clsisnottype(self.adapter):raiseValueError(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)exceptValueErrorasexc:adapter_name=type(self.adapter).__name__message=str(exc).replace(f"Invalid parameter(s) for {adapter_name}:","Invalid parameter(s) for FoundationModel:",)raiseValueError(message)fromexcself.index_type_=Noneself.index_freq_=Noneself.context_range_=Noneself.series_names_in_=Noneself.is_multiple_series_=Falseself.exog_in_=Falseself.exog_names_in_=Noneself.exog_names_in_per_series_=Noneself.exog_type_in_=Noneself.fit_date=Noneself.adapter.context_=Noneself.adapter.context_exog_=Noneself.adapter.is_fitted=Falsereturnself
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.
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.
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.
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.
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.
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.
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.
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_idself._pipeline=pipelineself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.predict_kwargs=predict_kwargsor{}self.device_map=device_mapself.torch_dtype=torch_dtypeself.cross_learning=cross_learningself.is_fitted=False
defset_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 """defvalidate(candidate_params:dict)->dict:if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"predict_kwargs"incandidate_params:candidate_params["predict_kwargs"]=(candidate_params["predict_kwargs"]or{})returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","device_map","torch_dtype"},lambda:setattr(self,"_pipeline",None),),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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)ifquantilesisnotNoneelse[0.5]inputs_list=[self._build_chronos_input(context=context[series_name].to_numpy(),context_exog=(context_exog.get(series_name)ifcontext_exogisnotNoneelseNone),exog=exog.get(series_name)ifexogisnotNoneelseNone,)forseries_nameinseries_names_in]quantile_preds,_=self._pipeline.predict_quantiles(inputs=inputs_list,prediction_length=steps,quantile_levels=quantile_levels,cross_learning=self.cross_learningiflen(series_names_in)>1elseFalse,**self.predict_kwargs,)predictions:dict[str,np.ndarray]={}fori,series_nameinenumerate(series_names_in):q_arr=_tensor_to_numpy(quantile_preds[i].squeeze(0))predictions[series_name]=q_arrreturnpredictions
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.
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.
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.
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.
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.
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.
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.
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_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.max_horizon=max_horizonself.forecast_config_kwargs=forecast_config_kwargsor{}self.is_fitted=False
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.
defset_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. """defvalidate(candidate_params:dict)->dict:if"model_id"incandidate_params:_validate_model_id_prefix(candidate_params["model_id"],self._MODEL_ID_PREFIX,type(self).__name__,)if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"max_horizon"incandidate_params:_validate_positive_int("max_horizon",candidate_params["max_horizon"])if"forecast_config_kwargs"incandidate_params:candidate_params["forecast_config_kwargs"]=(candidate_params["forecast_config_kwargs"]or{})returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","context_length","max_horizon","forecast_config_kwargs"},lambda:setattr(self,"_model",None),),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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")ifsteps>self.max_horizon:raiseValueError(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()forseries_nameinseries_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.9predictions:dict[str,np.ndarray]={}fori,series_nameinenumerate(series_names_in):ifquantile_listisNone:# Point forecast: shape (steps, 1)predictions[series_name]=np.asarray(point_forecast[i]).reshape(-1,1)else:quantile_indices=[round(q*10)forqinquantile_list]qf=np.asarray(quantile_forecast[i])# (steps, n_quantiles)predictions[series_name]=qf[:,quantile_indices]returnpredictions
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.
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.
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.
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.
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.
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.
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.
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.
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_kwargsor{}self._validate_predict_kwargs(predict_kwargs)self.model_id=model_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.device=deviceself.predict_kwargs=predict_kwargsself.is_fitted=False
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.
defset_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. """defvalidate(candidate_params:dict)->dict:if"model_id"incandidate_params:_validate_model_id_prefix(candidate_params["model_id"],self._MODEL_ID_PREFIX,type(self).__name__,)if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"predict_kwargs"incandidate_params:candidate_params["predict_kwargs"]=(candidate_params["predict_kwargs"]or{})self._validate_predict_kwargs(candidate_params["predict_kwargs"])returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","device"},lambda:setattr(self,"_model",None)),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
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.
defpredict(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])ifcontext_exogisnotNoneelseNone,exog=exog.get(names[0])ifexogisnotNoneelseNone,)has_covariates=bool(past_only_cols)orbool(fut_cols)contexts=[context[series_name].to_numpy()forseries_nameinnames]past_only_list:list[np.ndarray|None]=[]past_future_list:list[np.ndarray|None]=[]forseries_nameinnames:past_only,past_future=self._build_covariates(context_exog=(context_exog.get(series_name)ifcontext_exogisnotNoneelseNone),exog=exog.get(series_name)ifexogisnotNoneelseNone,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_listifhas_covariateselseNone,past_future_covariates=past_future_listifhas_covariateselseNone,return_quantiles=quantile_listisnotNone,padding_mode="edge"ifhas_covariateselse"none",**self.predict_kwargs,)outs=dict(zip(names,results))ifquantile_listisnotNone:quantile_indices=_match_quantile_indices(list(self._model.config.quantiles),quantile_list)predictions:dict[str,np.ndarray]={}forseries_nameinnames:out=outs[series_name]ifquantile_listisNone:predictions[series_name]=np.asarray(out.forecast).reshape(-1,1)else:predictions[series_name]=(np.asarray(out.quantiles)[:,quantile_indices])returnpredictions
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.
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.
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.
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.
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.
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.
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.
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_idself._module=moduleself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.device=deviceself._forecast_obj=Noneself.is_fitted=False
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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_listifquantile_listisnotNoneelse[0.5]quantile_indices=[next(ifori,supported_quantileinenumerate(self.SUPPORTED_QUANTILES)ifabs(q-supported_quantile)<1e-9)forqinquantile_levels]series_names_in=list(context.keys())inputs_list=[context[series_name].to_numpy(dtype=np.float32,na_value=np.nan).reshape(-1,1)forseries_nameinseries_names_in]raw=self._run_inference(inputs_list,steps)predictions:dict[str,np.ndarray]={}fori,series_nameinenumerate(series_names_in):# (steps, n_quantiles)predictions[series_name]=raw[i][quantile_indices,:].Treturnpredictions
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.
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.
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.
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.
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.
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.
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.
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.
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)ifpoint_estimatenotin("mean","median"):raiseValueError(f"`point_estimate` must be 'mean' or 'median'. Got {point_estimate!r}.")self.model_id=model_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.point_estimate=point_estimateself.tabicl_config=tabicl_configor{}self.temporal_features=temporal_featuresself.show_progress=show_progressself.is_fitted=False
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).
defget_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_configorNone,"temporal_features":self.temporal_features,"show_progress":self.show_progress,}
Set adapter parameters. Resets the model when a parameter that affects
the TabICLForecaster instance changes; toggling show_progress does
not reset the model.
defset_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 """defvalidate(candidate_params:dict)->dict:if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"point_estimate"incandidate_paramsandcandidate_params["point_estimate"]notin("mean","median"):raiseValueError(f"`point_estimate` must be 'mean' or 'median'. "f"Got {candidate_params['point_estimate']!r}.")if"tabicl_config"incandidate_params:candidate_params["tabicl_config"]=(candidate_params["tabicl_config"]or{})if"show_progress"incandidate_paramsandnotisinstance(candidate_params["show_progress"],bool):raiseValueError(f"`show_progress` must be a bool. "f"Got {candidate_params['show_progress']!r}.")returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","context_length","point_estimate","tabicl_config","temporal_features"},lambda:setattr(self,"_model",None),),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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)ifquantilesisnotNoneelseNonetabicl_quantiles=(quantile_listifquantile_listisnotNoneelse[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)ifnotis_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 → userstacklevel=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())ifnotself.show_progresselsecontextlib.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]={}forseries_nameinseries_names_in:group=result_df.loc[series_name]# DataFrame indexed by timestampifquantile_listisNone:predictions[series_name]=group["target"].to_numpy().reshape(-1,1)else:predictions[series_name]=group[quantile_list].to_numpy()returnpredictions
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.
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.
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.
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.
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.
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').
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.
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.
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.
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.
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.
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)ifmodenotin("local","client"):raiseValueError(f"`mode` must be 'local' or 'client'. Got {mode!r}.")ifpoint_estimatenotin("mean","median","mode"):raiseValueError(f"`point_estimate` must be 'mean', 'median' or 'mode'. "f"Got {point_estimate!r}.")self.model_id=model_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.mode=modeself.point_estimate=point_estimateself.tabpfn_model_config=tabpfn_model_configor{}self.temporal_features=temporal_featuresself.show_progress=show_progressself.is_fitted=False
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).
defget_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_configorNone,"temporal_features":self.temporal_features,"show_progress":self.show_progress,}
Set adapter parameters. Resets the model when a parameter that affects
the TabPFNTSPipeline instance changes; toggling show_progress does
not reset the model.
defset_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 """defvalidate(candidate_params:dict)->dict:if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"mode"incandidate_paramsandcandidate_params["mode"]notin("local","client"):raiseValueError(f"`mode` must be 'local' or 'client'. "f"Got {candidate_params['mode']!r}.")if"point_estimate"incandidate_paramsandcandidate_params["point_estimate"]notin("mean","median","mode"):raiseValueError(f"`point_estimate` must be 'mean', 'median' or 'mode'. "f"Got {candidate_params['point_estimate']!r}.")if"tabpfn_model_config"incandidate_params:candidate_params["tabpfn_model_config"]=(candidate_params["tabpfn_model_config"]or{})if"show_progress"incandidate_paramsandnotisinstance(candidate_params["show_progress"],bool):raiseValueError(f"`show_progress` must be a bool. "f"Got {candidate_params['show_progress']!r}.")returncandidate_paramsreturn_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),),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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)ifquantilesisnotNoneelseNonetabpfn_quantiles=(quantile_listifquantile_listisnotNoneelse[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)ifnotis_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 → userstacklevel=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())ifnotself.show_progresselsecontextlib.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]={}forseries_nameinseries_names_in:group=result_df.loc[series_name]# DataFrame indexed by timestampifquantile_listisNone:predictions[series_name]=group["target"].to_numpy().reshape(-1,1)else:predictions[series_name]=group[quantile_list].to_numpy()returnpredictions
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.
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.
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.
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.
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.
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.
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).
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.
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_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.device_map=device_mapself.torch_dtype=torch_dtypeself.is_fitted=False
defset_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 """defvalidate(candidate_params:dict)->dict:if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","device_map","torch_dtype"},lambda:setattr(self,"_model",None),),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
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.
defpredict(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)ifquantilesisnotNoneelse[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)forseries_nameinseries_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)forqinrequested]return{series_name:q_arr[i][:,quantile_column_indices]fori,series_nameinenumerate(series_names)}
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).
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.
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.
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.
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.
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.
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.
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).
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.
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)ifpoint_estimatenotin("mean","median","mode"):raiseValueError(f"`point_estimate` must be 'mean', 'median' or 'mode'. "f"Got {point_estimate!r}.")ifnotisinstance(add_calendar_features,bool):raiseValueError(f"`add_calendar_features` must be a bool. "f"Got {add_calendar_features!r}.")ifnotisinstance(n_fourier_terms,int)orn_fourier_terms<0:raiseValueError(f"`n_fourier_terms` must be a non-negative integer. "f"Got {n_fourier_terms!r}.")self.model_id=model_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.point_estimate=point_estimateself.add_calendar_features=add_calendar_featuresself.n_fourier_terms=n_fourier_termsself.nori_config=nori_configor{}self.is_fitted=False
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).
defget_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_configorNone,}
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.
defset_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 """defvalidate(candidate_params:dict)->dict:if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"point_estimate"incandidate_paramsandcandidate_params["point_estimate"]notin("mean","median","mode"):raiseValueError(f"`point_estimate` must be 'mean', 'median' or 'mode'. "f"Got {candidate_params['point_estimate']!r}.")if"add_calendar_features"incandidate_paramsandnotisinstance(candidate_params["add_calendar_features"],bool):raiseValueError(f"`add_calendar_features` must be a bool. "f"Got {candidate_params['add_calendar_features']!r}.")if"n_fourier_terms"incandidate_paramsand(notisinstance(candidate_params["n_fourier_terms"],int)orcandidate_params["n_fourier_terms"]<0):raiseValueError(f"`n_fourier_terms` must be a non-negative integer. "f"Got {candidate_params['n_fourier_terms']!r}.")if"nori_config"incandidate_params:candidate_params["nori_config"]=(candidate_params["nori_config"]or{})returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","nori_config"},lambda:setattr(self,"_model",None)),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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)ifquantilesisnotNoneelseNoneifquantile_listisnotNoneandany((q<=0.0)or(q>=1.0)forqinquantile_list):raiseValueError("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.ifquantile_listisnotNone:query_levels=sorted(set(quantile_list))quantile_column_indices=[query_levels.index(q)forqinquantile_list]self._load_model()first_series=next(iter(context.values()))is_datetime=isinstance(first_series.index,pd.DatetimeIndex)ifnotis_datetimeandself.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 → userstacklevel=3,)predictions:dict[str,np.ndarray]={}forseries_name,seriesincontext.items():ctx_exog=(context_exog.get(series_name)ifcontext_exogisnotNoneelseNone)fut_exog=exog.get(series_name)ifexogisnotNoneelseNone# `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)ifctx_exogisnotNoneelse[]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)ifnotvalid_rows.any():raiseValueError(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)ifquantile_listisNone: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).Tpredictions[series_name]=q[:,quantile_column_indices]returnpredictions
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.
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.
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.
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.
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.
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.
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.
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.
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_idself._model=modelself._resolved_device=Noneself.context_=Noneself.context_exog_=Noneself.checkpoint_version=checkpoint_versionself.context_length=context_lengthself.device=deviceself.allow_auto_download=allow_auto_downloadself.is_fitted=False
defset_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 """defvalidate(candidate_params:dict)->dict:if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])returncandidate_paramsreturn_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)),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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()importtorchquantile_list=list(quantiles)ifquantilesisnotNoneelseNonequery_levels=quantile_listifquantile_listisnotNoneelse[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)ifcontext_exogisnotNoneelseNone),exog=exog.get(series_name)ifexogisnotNoneelseNone,)forseries_nameinseries_names_in]ifself._resolved_deviceisNone: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]={}fori,series_nameinenumerate(series_names_in):q_arr=_tensor_to_numpy(quantile_preds[i])predictions[series_name]=q_arr[0]# drop the single-variate dimreturnpredictions
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.
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.
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.
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.
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.
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.
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.
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.
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.
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_kwargsor{}self._validate_predict_kwargs(predict_kwargs)self.model_id=model_idself._model=modelself.context_=Noneself.context_exog_=Noneself.context_length=context_lengthself.device=deviceself.predict_kwargs=predict_kwargsself.is_fitted=False
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.
defset_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. """defvalidate(candidate_params:dict)->dict:if"model_id"incandidate_params:_validate_model_id_prefix(candidate_params["model_id"],self._MODEL_ID_PREFIX,type(self).__name__,)if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"predict_kwargs"incandidate_params:candidate_params["predict_kwargs"]=(candidate_params["predict_kwargs"]or{})self._validate_predict_kwargs(candidate_params["predict_kwargs"])returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","device"},lambda:setattr(self,"_model",None)),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
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.
defpredict(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])ifcontext_exogisnotNoneelseNone,exog=exog.get(names[0])ifexogisnotNoneelseNone,)categorical_cols=self._categorical_columns(context_exog=context_exog.get(names[0])ifcontext_exogisnotNoneelseNone,exog=exog.get(names[0])ifexogisnotNoneelseNone,past_only_cols=past_only_cols,fut_cols=fut_cols,)iffut_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)ifcontext_exogisnotNoneelseNone),exog=exog.get(series_name)ifexogisnotNoneelseNone,past_only_cols=past_only_cols,fut_cols=fut_cols,categorical_cols=categorical_cols,)forseries_nameinnames]covariate_kwargs={key:np.stack([series_covariates[key]forseries_covariatesincovariates])forkeyincovariates[0]}forecast=self._model.forecast(context=np.stack([context[series_name].to_numpy(dtype=np.float64,na_value=np.nan)forseries_nameinnames])[:,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_listifquantile_listisnotNoneelse[0.5],)return{series_name:q_arr[i][:,quantile_indices]fori,series_nameinenumerate(names)}
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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_kwargsor{}self._validate_predict_kwargs(predict_kwargs)self.model_id=model_idself._model=modelself.context_length=context_lengthself.device=deviceself.predict_kwargs=predict_kwargsself.context_=Noneself.context_exog_=Noneself.is_fitted=False
defset_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 """defvalidate(candidate_params:dict)->dict:if"model_id"incandidate_params:_validate_model_id_prefix(candidate_params["model_id"],self._MODEL_ID_PREFIX,type(self).__name__,)if"context_length"incandidate_params:_validate_positive_int("context_length",candidate_params["context_length"])if"predict_kwargs"incandidate_params:candidate_params["predict_kwargs"]=(candidate_params["predict_kwargs"]or{})self._validate_predict_kwargs(candidate_params["predict_kwargs"])returncandidate_paramsreturn_apply_set_params(self,params,validate=validate,resets=(({"model_id","device"},lambda:setattr(self,"_model",None)),),)
deffit(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 """returnsuper().fit(context=context,context_exog=context_exog)
defpredict(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_lenifsteps>max_steps:raiseValueError(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()importtorchnames=list(context)timeseries=[]fornameinnames:past_cols,future_cols=get_exog_signature(context_exog=(context_exogor{}).get(name),exog=(exogor{}).get(name),)past,future=self._build_covariates((context_exogor{}).get(name),(exogor{}).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,)ifpastisnotNone:past=torch.as_tensor(past,dtype=torch.float32)iffutureisnotNone: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,)iflen(forecasts)!=len(names):raiseValueError("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)forqinself._model.quantiles]quantile_indices=_match_quantile_indices(quantile_grid,quantile_listifquantile_listisnotNoneelse[0.5])expected_shape=(1,len(quantile_grid),steps)predictions={}forname,forecastinzip(names,forecasts):values=np.asarray(forecast)ifvalues.shape!=expected_shape:raiseValueError("TiRex-2 returned an unexpected forecast shape: "f"{values.shape!r}. Expected {expected_shape}.")predictions[name]=values[0,quantile_indices,:].Treturnpredictions
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'.
defget_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`. """ifnotisinstance(model_id,str):raiseTypeError(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)
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
deflist_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)forclsinadapter_classes]ifas_frame:adapters=pd.DataFrame([asdict(adapter)foradapterinadapters]).set_index("adapter")returnadapters
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.
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.
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.
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.
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.
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.
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 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.