autogluon.timeseries 1.4.1b20251115__py3-none-any.whl → 1.5.0b20251221__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of autogluon.timeseries might be problematic. Click here for more details.
- autogluon/timeseries/configs/hyperparameter_presets.py +13 -28
- autogluon/timeseries/configs/predictor_presets.py +23 -39
- autogluon/timeseries/dataset/ts_dataframe.py +32 -34
- autogluon/timeseries/learner.py +67 -33
- autogluon/timeseries/metrics/__init__.py +4 -4
- autogluon/timeseries/metrics/abstract.py +8 -8
- autogluon/timeseries/metrics/point.py +9 -9
- autogluon/timeseries/metrics/quantile.py +4 -4
- autogluon/timeseries/models/__init__.py +2 -1
- autogluon/timeseries/models/abstract/abstract_timeseries_model.py +52 -50
- autogluon/timeseries/models/abstract/model_trial.py +2 -1
- autogluon/timeseries/models/abstract/tunable.py +8 -8
- autogluon/timeseries/models/autogluon_tabular/mlforecast.py +30 -26
- autogluon/timeseries/models/autogluon_tabular/per_step.py +13 -11
- autogluon/timeseries/models/autogluon_tabular/transforms.py +2 -2
- autogluon/timeseries/models/chronos/__init__.py +2 -1
- autogluon/timeseries/models/chronos/chronos2.py +395 -0
- autogluon/timeseries/models/chronos/model.py +30 -25
- autogluon/timeseries/models/chronos/utils.py +5 -5
- autogluon/timeseries/models/ensemble/__init__.py +17 -10
- autogluon/timeseries/models/ensemble/abstract.py +13 -9
- autogluon/timeseries/models/ensemble/array_based/__init__.py +2 -2
- autogluon/timeseries/models/ensemble/array_based/abstract.py +24 -31
- autogluon/timeseries/models/ensemble/array_based/models.py +146 -11
- autogluon/timeseries/models/ensemble/array_based/regressor/__init__.py +2 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/abstract.py +6 -5
- autogluon/timeseries/models/ensemble/array_based/regressor/linear_stacker.py +186 -0
- autogluon/timeseries/models/ensemble/array_based/regressor/per_quantile_tabular.py +44 -83
- autogluon/timeseries/models/ensemble/array_based/regressor/tabular.py +21 -55
- autogluon/timeseries/models/ensemble/ensemble_selection.py +167 -0
- autogluon/timeseries/models/ensemble/per_item_greedy.py +172 -0
- autogluon/timeseries/models/ensemble/weighted/abstract.py +7 -3
- autogluon/timeseries/models/ensemble/weighted/basic.py +26 -13
- autogluon/timeseries/models/ensemble/weighted/greedy.py +21 -144
- autogluon/timeseries/models/gluonts/abstract.py +30 -29
- autogluon/timeseries/models/gluonts/dataset.py +9 -9
- autogluon/timeseries/models/gluonts/models.py +0 -7
- autogluon/timeseries/models/local/__init__.py +0 -7
- autogluon/timeseries/models/local/abstract_local_model.py +13 -16
- autogluon/timeseries/models/local/naive.py +2 -2
- autogluon/timeseries/models/local/npts.py +7 -1
- autogluon/timeseries/models/local/statsforecast.py +13 -13
- autogluon/timeseries/models/multi_window/multi_window_model.py +38 -23
- autogluon/timeseries/models/registry.py +3 -4
- autogluon/timeseries/models/toto/_internal/backbone/attention.py +3 -4
- autogluon/timeseries/models/toto/_internal/backbone/backbone.py +6 -6
- autogluon/timeseries/models/toto/_internal/backbone/rope.py +4 -9
- autogluon/timeseries/models/toto/_internal/backbone/rotary_embedding_torch.py +342 -0
- autogluon/timeseries/models/toto/_internal/backbone/scaler.py +2 -3
- autogluon/timeseries/models/toto/_internal/backbone/transformer.py +10 -10
- autogluon/timeseries/models/toto/_internal/dataset.py +2 -2
- autogluon/timeseries/models/toto/_internal/forecaster.py +8 -8
- autogluon/timeseries/models/toto/dataloader.py +4 -4
- autogluon/timeseries/models/toto/hf_pretrained_model.py +97 -16
- autogluon/timeseries/models/toto/model.py +30 -17
- autogluon/timeseries/predictor.py +531 -136
- autogluon/timeseries/regressor.py +18 -23
- autogluon/timeseries/splitter.py +2 -2
- autogluon/timeseries/trainer/ensemble_composer.py +323 -129
- autogluon/timeseries/trainer/model_set_builder.py +9 -9
- autogluon/timeseries/trainer/prediction_cache.py +16 -16
- autogluon/timeseries/trainer/trainer.py +235 -145
- autogluon/timeseries/trainer/utils.py +3 -4
- autogluon/timeseries/transforms/covariate_scaler.py +7 -7
- autogluon/timeseries/transforms/target_scaler.py +8 -8
- autogluon/timeseries/utils/constants.py +10 -0
- autogluon/timeseries/utils/datetime/lags.py +1 -3
- autogluon/timeseries/utils/datetime/seasonality.py +1 -3
- autogluon/timeseries/utils/features.py +22 -9
- autogluon/timeseries/utils/forecast.py +1 -2
- autogluon/timeseries/utils/timer.py +173 -0
- autogluon/timeseries/version.py +1 -1
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/METADATA +23 -21
- autogluon_timeseries-1.5.0b20251221.dist-info/RECORD +103 -0
- autogluon_timeseries-1.4.1b20251115.dist-info/RECORD +0 -96
- /autogluon.timeseries-1.4.1b20251115-py3.9-nspkg.pth → /autogluon.timeseries-1.5.0b20251221-py3.11-nspkg.pth +0 -0
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/WHEEL +0 -0
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/licenses/LICENSE +0 -0
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/licenses/NOTICE +0 -0
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/namespace_packages.txt +0 -0
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/top_level.txt +0 -0
- {autogluon_timeseries-1.4.1b20251115.dist-info → autogluon_timeseries-1.5.0b20251221.dist-info}/zip-safe +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import logging
|
|
2
|
-
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
|
|
4
6
|
from transformers import PretrainedConfig, PreTrainedModel
|
|
5
7
|
|
|
@@ -15,8 +17,8 @@ class TotoConfig(PretrainedConfig):
|
|
|
15
17
|
embed_dim: int = 768,
|
|
16
18
|
num_heads: int = 12,
|
|
17
19
|
num_layers: int = 12,
|
|
18
|
-
output_distribution_classes:
|
|
19
|
-
output_distribution_kwargs:
|
|
20
|
+
output_distribution_classes: list[str] | None = None,
|
|
21
|
+
output_distribution_kwargs: dict | None = None,
|
|
20
22
|
patch_size: int = 64,
|
|
21
23
|
scale_factor_exponent: float = 10.0,
|
|
22
24
|
spacewise_every_n_layers: int = 12,
|
|
@@ -69,12 +71,10 @@ class TotoPretrainedModel(PreTrainedModel):
|
|
|
69
71
|
scale_factor_exponent=config.scale_factor_exponent,
|
|
70
72
|
**getattr(config, "extra_kwargs", {}),
|
|
71
73
|
)
|
|
72
|
-
self._register_load_state_dict_pre_hook(self._remap_state_dict_keys_hook)
|
|
73
74
|
self.post_init()
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
):
|
|
76
|
+
@staticmethod
|
|
77
|
+
def _remap_state_dict_keys(state_dict):
|
|
78
78
|
remap = {
|
|
79
79
|
"mlp.0.w12.weight": "mlp.0.weight",
|
|
80
80
|
"mlp.0.w12.bias": "mlp.0.bias",
|
|
@@ -82,6 +82,7 @@ class TotoPretrainedModel(PreTrainedModel):
|
|
|
82
82
|
"mlp.0.w3.bias": "mlp.2.bias",
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
new_state = {}
|
|
85
86
|
keys_to_remap = []
|
|
86
87
|
for key in list(state_dict.keys()):
|
|
87
88
|
for old, new in remap.items():
|
|
@@ -90,11 +91,81 @@ class TotoPretrainedModel(PreTrainedModel):
|
|
|
90
91
|
keys_to_remap.append((key, new_key))
|
|
91
92
|
break
|
|
92
93
|
|
|
94
|
+
new_state = state_dict.copy()
|
|
93
95
|
for old_key, new_key in keys_to_remap:
|
|
94
|
-
|
|
96
|
+
new_state[new_key] = new_state.pop(old_key)
|
|
97
|
+
|
|
98
|
+
return new_state
|
|
95
99
|
|
|
96
100
|
@classmethod
|
|
97
|
-
def
|
|
101
|
+
def load_from_checkpoint(
|
|
102
|
+
cls,
|
|
103
|
+
checkpoint_path,
|
|
104
|
+
device_map: str = "cpu",
|
|
105
|
+
strict=True,
|
|
106
|
+
**model_kwargs,
|
|
107
|
+
):
|
|
108
|
+
"""
|
|
109
|
+
Custom checkpoint loading. Used to load a local
|
|
110
|
+
safetensors checkpoint with an optional config.json file.
|
|
111
|
+
"""
|
|
112
|
+
import safetensors.torch as safetorch
|
|
113
|
+
|
|
114
|
+
if os.path.isdir(checkpoint_path):
|
|
115
|
+
safetensors_file = os.path.join(checkpoint_path, "model.safetensors")
|
|
116
|
+
else:
|
|
117
|
+
safetensors_file = checkpoint_path
|
|
118
|
+
|
|
119
|
+
if os.path.exists(safetensors_file):
|
|
120
|
+
model_state = safetorch.load_file(safetensors_file, device=device_map)
|
|
121
|
+
else:
|
|
122
|
+
raise FileNotFoundError(f"Model checkpoint not found at: {safetensors_file}")
|
|
123
|
+
|
|
124
|
+
# Load configuration from config.json if it exists.
|
|
125
|
+
config_file = os.path.join(checkpoint_path, "config.json")
|
|
126
|
+
config = {}
|
|
127
|
+
if os.path.exists(config_file):
|
|
128
|
+
with open(config_file, "r") as f:
|
|
129
|
+
config = json.load(f)
|
|
130
|
+
|
|
131
|
+
# Merge any extra kwargs into the configuration.
|
|
132
|
+
config.update(model_kwargs)
|
|
133
|
+
|
|
134
|
+
remapped_state_dict = cls._remap_state_dict_keys(model_state)
|
|
135
|
+
|
|
136
|
+
instance = cls(**config)
|
|
137
|
+
|
|
138
|
+
# Filter out unexpected keys
|
|
139
|
+
filtered_remapped_state_dict = {
|
|
140
|
+
k: v
|
|
141
|
+
for k, v in remapped_state_dict.items()
|
|
142
|
+
if k in instance.state_dict() and not k.endswith("rotary_emb.freqs")
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
instance.load_state_dict(filtered_remapped_state_dict, strict=strict)
|
|
146
|
+
instance.to(device_map) # type: ignore
|
|
147
|
+
|
|
148
|
+
return instance
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def from_pretrained(
|
|
152
|
+
cls,
|
|
153
|
+
*,
|
|
154
|
+
model_id: str,
|
|
155
|
+
revision: str | None = None,
|
|
156
|
+
cache_dir: Path | str | None = None,
|
|
157
|
+
force_download: bool = False,
|
|
158
|
+
proxies: dict | None = None,
|
|
159
|
+
resume_download: bool | None = None,
|
|
160
|
+
local_files_only: bool = False,
|
|
161
|
+
token: str | bool | None = None,
|
|
162
|
+
device_map: str = "cpu",
|
|
163
|
+
strict: bool = False,
|
|
164
|
+
**model_kwargs,
|
|
165
|
+
):
|
|
166
|
+
"""Load Pytorch pretrained weights and return the loaded model."""
|
|
167
|
+
from huggingface_hub import constants, hf_hub_download
|
|
168
|
+
|
|
98
169
|
transformers_logger = logging.getLogger("transformers.modeling_utils")
|
|
99
170
|
original_level = transformers_logger.level
|
|
100
171
|
|
|
@@ -103,13 +174,23 @@ class TotoPretrainedModel(PreTrainedModel):
|
|
|
103
174
|
# remapping hook is only called after the initial model loading.
|
|
104
175
|
transformers_logger.setLevel(logging.ERROR)
|
|
105
176
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
177
|
+
if os.path.isdir(model_id):
|
|
178
|
+
print("Loading weights from local directory")
|
|
179
|
+
model_file = os.path.join(model_id, constants.SAFETENSORS_SINGLE_FILE)
|
|
180
|
+
model = cls.load_from_checkpoint(model_file, device_map, strict, **model_kwargs)
|
|
181
|
+
else:
|
|
182
|
+
model_file = hf_hub_download(
|
|
183
|
+
repo_id=model_id,
|
|
184
|
+
filename=constants.SAFETENSORS_SINGLE_FILE,
|
|
185
|
+
revision=revision,
|
|
186
|
+
cache_dir=cache_dir,
|
|
187
|
+
force_download=force_download,
|
|
188
|
+
proxies=proxies,
|
|
189
|
+
resume_download=resume_download,
|
|
190
|
+
token=token,
|
|
191
|
+
local_files_only=local_files_only,
|
|
192
|
+
)
|
|
193
|
+
model = cls.load_from_checkpoint(model_file, device_map, strict, **model_kwargs)
|
|
113
194
|
finally:
|
|
114
195
|
transformers_logger.setLevel(original_level)
|
|
115
196
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
-
from typing import TYPE_CHECKING, Any,
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Sequence
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import pandas as pd
|
|
@@ -61,12 +61,12 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
61
61
|
|
|
62
62
|
def __init__(
|
|
63
63
|
self,
|
|
64
|
-
path:
|
|
65
|
-
name:
|
|
66
|
-
hyperparameters:
|
|
67
|
-
freq:
|
|
64
|
+
path: str | None = None,
|
|
65
|
+
name: str | None = None,
|
|
66
|
+
hyperparameters: dict[str, Any] | None = None,
|
|
67
|
+
freq: str | None = None,
|
|
68
68
|
prediction_length: int = 1,
|
|
69
|
-
covariate_metadata:
|
|
69
|
+
covariate_metadata: CovariateMetadata | None = None,
|
|
70
70
|
target: str = "target",
|
|
71
71
|
quantile_levels: Sequence[float] = (0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9),
|
|
72
72
|
eval_metric: Any = None,
|
|
@@ -87,9 +87,9 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
87
87
|
eval_metric=eval_metric,
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
-
self._forecaster:
|
|
90
|
+
self._forecaster: TotoForecaster | None = None
|
|
91
91
|
|
|
92
|
-
def save(self, path:
|
|
92
|
+
def save(self, path: str | None = None, verbose: bool = True) -> str:
|
|
93
93
|
forecaster = self._forecaster
|
|
94
94
|
self._forecaster = None
|
|
95
95
|
path = super().save(path=path, verbose=verbose)
|
|
@@ -110,7 +110,7 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
110
110
|
|
|
111
111
|
return torch.cuda.is_available()
|
|
112
112
|
|
|
113
|
-
def get_minimum_resources(self, is_gpu_available: bool = False) -> dict[str,
|
|
113
|
+
def get_minimum_resources(self, is_gpu_available: bool = False) -> dict[str, int | float]:
|
|
114
114
|
return {"num_cpus": 1, "num_gpus": 1}
|
|
115
115
|
|
|
116
116
|
def load_forecaster(self):
|
|
@@ -126,7 +126,7 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
126
126
|
|
|
127
127
|
hyperparameters = self.get_hyperparameters()
|
|
128
128
|
pretrained_model = TotoPretrainedModel.from_pretrained(
|
|
129
|
-
self.model_path,
|
|
129
|
+
model_id=self.model_path,
|
|
130
130
|
config=TotoConfig.from_pretrained(self.model_path),
|
|
131
131
|
device_map=hyperparameters["device"],
|
|
132
132
|
)
|
|
@@ -147,9 +147,21 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
147
147
|
"num_samples": 256,
|
|
148
148
|
"device": "cuda",
|
|
149
149
|
"context_length": 4096,
|
|
150
|
-
"compile_model":
|
|
150
|
+
"compile_model": False,
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
def _get_sample_batch_size(self) -> int:
|
|
154
|
+
num_samples = self.get_hyperparameter("num_samples")
|
|
155
|
+
batch_size = num_samples
|
|
156
|
+
while batch_size > 32:
|
|
157
|
+
for factor in range(2, int(batch_size**0.5) + 1):
|
|
158
|
+
if batch_size % factor == 0:
|
|
159
|
+
batch_size //= factor
|
|
160
|
+
break
|
|
161
|
+
else: # batch_size is prime
|
|
162
|
+
return batch_size
|
|
163
|
+
return batch_size
|
|
164
|
+
|
|
153
165
|
@property
|
|
154
166
|
def allowed_hyperparameters(self) -> list[str]:
|
|
155
167
|
return super().allowed_hyperparameters + [
|
|
@@ -171,10 +183,10 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
171
183
|
def _fit(
|
|
172
184
|
self,
|
|
173
185
|
train_data: TimeSeriesDataFrame,
|
|
174
|
-
val_data:
|
|
175
|
-
time_limit:
|
|
176
|
-
num_cpus:
|
|
177
|
-
num_gpus:
|
|
186
|
+
val_data: TimeSeriesDataFrame | None = None,
|
|
187
|
+
time_limit: float | None = None,
|
|
188
|
+
num_cpus: int | None = None,
|
|
189
|
+
num_gpus: int | None = None,
|
|
178
190
|
verbosity: int = 2,
|
|
179
191
|
**kwargs,
|
|
180
192
|
) -> None:
|
|
@@ -182,7 +194,7 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
182
194
|
self.load_forecaster()
|
|
183
195
|
|
|
184
196
|
def _predict(
|
|
185
|
-
self, data: TimeSeriesDataFrame, known_covariates:
|
|
197
|
+
self, data: TimeSeriesDataFrame, known_covariates: TimeSeriesDataFrame | None = None, **kwargs
|
|
186
198
|
) -> TimeSeriesDataFrame:
|
|
187
199
|
import torch
|
|
188
200
|
|
|
@@ -198,6 +210,7 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
198
210
|
dataset = TotoInferenceDataset(
|
|
199
211
|
target_df=data.fill_missing_values("auto"),
|
|
200
212
|
max_context_length=hyperparameters["context_length"],
|
|
213
|
+
target_column=self.target,
|
|
201
214
|
)
|
|
202
215
|
loader = TotoDataLoader(
|
|
203
216
|
dataset,
|
|
@@ -214,7 +227,7 @@ class TotoModel(AbstractTimeSeriesModel):
|
|
|
214
227
|
masked_timeseries,
|
|
215
228
|
prediction_length=self.prediction_length,
|
|
216
229
|
num_samples=hyperparameters["num_samples"],
|
|
217
|
-
samples_per_batch=
|
|
230
|
+
samples_per_batch=self._get_sample_batch_size(),
|
|
218
231
|
)
|
|
219
232
|
|
|
220
233
|
batch_means.append(forecast.mean.cpu().numpy())
|