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 and EDF Lab TS-ICL.
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'
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). 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 (TFC-T0, TabPFN-TS, Nori, 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); 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, and ignored with an
IgnoredArgumentWarning otherwise.
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.
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`, and ignored with an `IgnoredArgumentWarning` otherwise. 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. """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 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,)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,)# Adapter returns dict[str, np.ndarray] with shape (steps, n_q)raw_predictions:dict[str,np.ndarray]={}forseries_names_groupinseries_groups:raw_predictions.update(self.adapter.predict(steps=steps,context={series_name:context[series_name]forseries_nameinseries_names_group},context_exog=({series_name:context_exog[series_name]forseries_nameinseries_names_group}ifcontext_exogisnotNoneelseNone),exog=({series_name:exog[series_name]forseries_nameinseries_names_group}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 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 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 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=self._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 the best
available accelerator (CUDA > MPS > CPU). Also accepts explicit
values such as "cuda", "mps", or "cpu".
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 the best
available accelerator (CUDA > MPS > CPU). Also accepts
explicit values such as "cuda", "mps", or "cpu".
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 the best available accelerator (CUDA > MPS > CPU). Also accepts explicit values such as `"cuda"`, `"mps"`, or `"cpu"`. """_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).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 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: extra columns in context and exog
are forwarded as covariates. TabICL uses only the intersection of columns
present in both context and future data. 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, pandas Series, or None Per-series past covariates (already trimmed). 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 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. Covariates without future values are discarded by
the library.
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, pandas Series, or None Per-series past covariates (already trimmed). 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 the loaded model is cast to (e.g. torch.bfloat16).
When None the model keeps its default float32 weights.
Whether series with different covariate columns can be forecast in
the same backend call. True: T0 defines NaN as an absent covariate
value, so the adapter pools the columns of all series and fills the
missing cells with NaN.
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.
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 the loaded model is cast to (e.g. torch.bfloat16).
When None the model keeps its default float32 weights.
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 the loaded model is cast to (e.g. `torch.bfloat16`). When `None` the model keeps its default `float32` weights. """_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)
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, 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, 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))series_names=list(context.keys())arrays=[np.asarray(context[series_name].to_numpy(),dtype=np.float32)forseries_nameinseries_names]lengths=[a.shape[0]forainarrays]context_length=max(lengths)# All series are forecast in a single batched call. Series shorter than# the longest are left-padded with NaN, which T0 treats as MISSING; the# forecast origin therefore aligns at the end of the window for every# series.context_batch=np.full((len(series_names),context_length),np.nan,dtype=np.float32)forrow,arrayinzip(context_batch,arrays):row[context_length-array.shape[0]:]=arrayfuture_covariates=self._build_future_covariates(series_names=series_names,context_exog=context_exog,exog=exog,context_length=context_length,steps=steps,)forecast=self._model.predict(context=context_batch,horizon=steps,quantiles=query_levels,future_covariates=future_covariates,)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 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. 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, pandas Series, or None Per-series past covariates (already trimmed). 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)ifexogisnotNoneelseNoneexog_cols=self._known_future_columns(ctx_exog,fut_exog)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 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
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.