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.
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 `pandas Series` or `pandas DataFrame`: broadcast to all series. - If `dict`: per-series exogenous variables. Returns ------- self : FoundationModel """self.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.
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],)->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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
defpredict(self,steps:int,context:dict[str,pd.Series],context_exog:dict[str,pd.DataFrame|pd.Series|None],exog:dict[str,pd.DataFrame|pd.Series|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.
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. Stored for API consistency but never used, since TimesFM 2.5 does not support covariates. Returns ------- self : TimesFM25Adapter """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
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.
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 (e.g. via transformer_exog) 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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
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".
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:Any,)->MoiraiAdapter:""" Store the training series. 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 : Any Not used, present here for API consistency by convention. Returns ------- self : MoiraiAdapter """self.context_=contextself.is_fitted=Truereturnself
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.
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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
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.
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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
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.
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.
T0 checkpoints (e.g. theforecastingcompany/t0-alpha) are gated on the
Hugging Face Hub: visit the model page while logged in to accept its
license, then authenticate locally (hf auth login or the HF_TOKEN
environment variable) before first use.
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],)->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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
defpredict(self,steps:int,context:dict[str,pd.Series],context_exog:dict[str,pd.DataFrame|pd.Series|None],exog:dict[str,pd.DataFrame|pd.Series|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.
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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
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.
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],)->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 """self.context_=contextself.context_exog_=context_exogself.is_fitted=Truereturnself
defpredict(self,steps:int,context:dict[str,pd.Series],context_exog:dict[str,pd.DataFrame|pd.Series|None],exog:dict[str,pd.DataFrame|pd.Series|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