autogluon.timeseries 1.2.1b20250224__py3-none-any.whl → 1.4.1b20251215__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.

Files changed (108) hide show
  1. autogluon/timeseries/configs/__init__.py +3 -2
  2. autogluon/timeseries/configs/hyperparameter_presets.py +62 -0
  3. autogluon/timeseries/configs/predictor_presets.py +106 -0
  4. autogluon/timeseries/dataset/ts_dataframe.py +256 -141
  5. autogluon/timeseries/learner.py +86 -52
  6. autogluon/timeseries/metrics/__init__.py +42 -8
  7. autogluon/timeseries/metrics/abstract.py +89 -19
  8. autogluon/timeseries/metrics/point.py +142 -53
  9. autogluon/timeseries/metrics/quantile.py +46 -21
  10. autogluon/timeseries/metrics/utils.py +4 -4
  11. autogluon/timeseries/models/__init__.py +8 -2
  12. autogluon/timeseries/models/abstract/__init__.py +2 -2
  13. autogluon/timeseries/models/abstract/abstract_timeseries_model.py +361 -592
  14. autogluon/timeseries/models/abstract/model_trial.py +2 -1
  15. autogluon/timeseries/models/abstract/tunable.py +189 -0
  16. autogluon/timeseries/models/autogluon_tabular/__init__.py +2 -0
  17. autogluon/timeseries/models/autogluon_tabular/mlforecast.py +282 -194
  18. autogluon/timeseries/models/autogluon_tabular/per_step.py +513 -0
  19. autogluon/timeseries/models/autogluon_tabular/transforms.py +25 -18
  20. autogluon/timeseries/models/chronos/__init__.py +2 -1
  21. autogluon/timeseries/models/chronos/chronos2.py +361 -0
  22. autogluon/timeseries/models/chronos/model.py +219 -138
  23. autogluon/timeseries/models/chronos/{pipeline/utils.py → utils.py} +81 -50
  24. autogluon/timeseries/models/ensemble/__init__.py +37 -2
  25. autogluon/timeseries/models/ensemble/abstract.py +107 -0
  26. autogluon/timeseries/models/ensemble/array_based/__init__.py +3 -0
  27. autogluon/timeseries/models/ensemble/array_based/abstract.py +240 -0
  28. autogluon/timeseries/models/ensemble/array_based/models.py +185 -0
  29. autogluon/timeseries/models/ensemble/array_based/regressor/__init__.py +12 -0
  30. autogluon/timeseries/models/ensemble/array_based/regressor/abstract.py +88 -0
  31. autogluon/timeseries/models/ensemble/array_based/regressor/linear_stacker.py +186 -0
  32. autogluon/timeseries/models/ensemble/array_based/regressor/per_quantile_tabular.py +94 -0
  33. autogluon/timeseries/models/ensemble/array_based/regressor/tabular.py +107 -0
  34. autogluon/timeseries/models/ensemble/ensemble_selection.py +167 -0
  35. autogluon/timeseries/models/ensemble/per_item_greedy.py +172 -0
  36. autogluon/timeseries/models/ensemble/weighted/__init__.py +8 -0
  37. autogluon/timeseries/models/ensemble/weighted/abstract.py +45 -0
  38. autogluon/timeseries/models/ensemble/weighted/basic.py +91 -0
  39. autogluon/timeseries/models/ensemble/weighted/greedy.py +62 -0
  40. autogluon/timeseries/models/gluonts/__init__.py +1 -1
  41. autogluon/timeseries/models/gluonts/{abstract_gluonts.py → abstract.py} +148 -208
  42. autogluon/timeseries/models/gluonts/dataset.py +109 -0
  43. autogluon/timeseries/models/gluonts/{torch/models.py → models.py} +38 -22
  44. autogluon/timeseries/models/local/__init__.py +0 -7
  45. autogluon/timeseries/models/local/abstract_local_model.py +71 -74
  46. autogluon/timeseries/models/local/naive.py +13 -9
  47. autogluon/timeseries/models/local/npts.py +9 -2
  48. autogluon/timeseries/models/local/statsforecast.py +52 -36
  49. autogluon/timeseries/models/multi_window/multi_window_model.py +65 -45
  50. autogluon/timeseries/models/registry.py +64 -0
  51. autogluon/timeseries/models/toto/__init__.py +3 -0
  52. autogluon/timeseries/models/toto/_internal/__init__.py +9 -0
  53. autogluon/timeseries/models/toto/_internal/backbone/__init__.py +3 -0
  54. autogluon/timeseries/models/toto/_internal/backbone/attention.py +196 -0
  55. autogluon/timeseries/models/toto/_internal/backbone/backbone.py +262 -0
  56. autogluon/timeseries/models/toto/_internal/backbone/distribution.py +70 -0
  57. autogluon/timeseries/models/toto/_internal/backbone/kvcache.py +136 -0
  58. autogluon/timeseries/models/toto/_internal/backbone/rope.py +89 -0
  59. autogluon/timeseries/models/toto/_internal/backbone/rotary_embedding_torch.py +342 -0
  60. autogluon/timeseries/models/toto/_internal/backbone/scaler.py +305 -0
  61. autogluon/timeseries/models/toto/_internal/backbone/transformer.py +333 -0
  62. autogluon/timeseries/models/toto/_internal/dataset.py +165 -0
  63. autogluon/timeseries/models/toto/_internal/forecaster.py +423 -0
  64. autogluon/timeseries/models/toto/dataloader.py +108 -0
  65. autogluon/timeseries/models/toto/hf_pretrained_model.py +200 -0
  66. autogluon/timeseries/models/toto/model.py +249 -0
  67. autogluon/timeseries/predictor.py +685 -297
  68. autogluon/timeseries/regressor.py +94 -44
  69. autogluon/timeseries/splitter.py +8 -32
  70. autogluon/timeseries/trainer/__init__.py +3 -0
  71. autogluon/timeseries/trainer/ensemble_composer.py +444 -0
  72. autogluon/timeseries/trainer/model_set_builder.py +256 -0
  73. autogluon/timeseries/trainer/prediction_cache.py +149 -0
  74. autogluon/timeseries/{trainer.py → trainer/trainer.py} +387 -390
  75. autogluon/timeseries/trainer/utils.py +17 -0
  76. autogluon/timeseries/transforms/__init__.py +2 -13
  77. autogluon/timeseries/transforms/covariate_scaler.py +34 -40
  78. autogluon/timeseries/transforms/target_scaler.py +37 -20
  79. autogluon/timeseries/utils/constants.py +10 -0
  80. autogluon/timeseries/utils/datetime/lags.py +3 -5
  81. autogluon/timeseries/utils/datetime/seasonality.py +1 -3
  82. autogluon/timeseries/utils/datetime/time_features.py +2 -2
  83. autogluon/timeseries/utils/features.py +70 -47
  84. autogluon/timeseries/utils/forecast.py +19 -14
  85. autogluon/timeseries/utils/timer.py +173 -0
  86. autogluon/timeseries/utils/warning_filters.py +4 -2
  87. autogluon/timeseries/version.py +1 -1
  88. autogluon.timeseries-1.4.1b20251215-py3.11-nspkg.pth +1 -0
  89. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info}/METADATA +49 -36
  90. autogluon_timeseries-1.4.1b20251215.dist-info/RECORD +103 -0
  91. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info}/WHEEL +1 -1
  92. autogluon/timeseries/configs/presets_configs.py +0 -79
  93. autogluon/timeseries/evaluator.py +0 -6
  94. autogluon/timeseries/models/chronos/pipeline/__init__.py +0 -11
  95. autogluon/timeseries/models/chronos/pipeline/base.py +0 -160
  96. autogluon/timeseries/models/chronos/pipeline/chronos.py +0 -585
  97. autogluon/timeseries/models/chronos/pipeline/chronos_bolt.py +0 -518
  98. autogluon/timeseries/models/ensemble/abstract_timeseries_ensemble.py +0 -78
  99. autogluon/timeseries/models/ensemble/greedy_ensemble.py +0 -170
  100. autogluon/timeseries/models/gluonts/torch/__init__.py +0 -0
  101. autogluon/timeseries/models/presets.py +0 -360
  102. autogluon.timeseries-1.2.1b20250224-py3.9-nspkg.pth +0 -1
  103. autogluon.timeseries-1.2.1b20250224.dist-info/RECORD +0 -68
  104. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info/licenses}/LICENSE +0 -0
  105. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info/licenses}/NOTICE +0 -0
  106. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info}/namespace_packages.txt +0 -0
  107. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info}/top_level.txt +0 -0
  108. {autogluon.timeseries-1.2.1b20250224.dist-info → autogluon_timeseries-1.4.1b20251215.dist-info}/zip-safe +0 -0
@@ -1,585 +0,0 @@
1
- # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
-
4
- # Original Source: https://github.com/amazon-science/chronos-forecasting
5
- # Authors: Lorenzo Stella <stellalo@amazon.com>, Abdul Fatir Ansari <ansarnd@amazon.com>
6
-
7
- import logging
8
- import warnings
9
- from dataclasses import dataclass
10
- from typing import Any, Dict, List, Literal, Optional, Tuple, Union
11
-
12
- import torch
13
- import torch.nn as nn
14
- from transformers import AutoConfig, AutoModelForSeq2SeqLM, GenerationConfig, PreTrainedModel
15
-
16
- from autogluon.timeseries.utils.warning_filters import set_loggers_level
17
-
18
- from .base import BaseChronosPipeline, ForecastType
19
-
20
- logger = logging.getLogger("autogluon.timeseries.models.chronos")
21
-
22
-
23
- __all__ = ["ChronosConfig", "ChronosPipeline"]
24
-
25
-
26
- @dataclass
27
- class ChronosConfig:
28
- """
29
- This class holds all the configuration parameters to be used
30
- by ``ChronosTokenizer`` and ``ChronosPretrainedModel``.
31
- """
32
-
33
- tokenizer_class: str
34
- tokenizer_kwargs: Dict[str, Any]
35
- n_tokens: int
36
- n_special_tokens: int
37
- pad_token_id: int
38
- eos_token_id: int
39
- use_eos_token: bool
40
- model_type: Literal["seq2seq"]
41
- context_length: int
42
- prediction_length: int
43
- num_samples: int
44
- temperature: float
45
- top_k: int
46
- top_p: float
47
-
48
- def __post_init__(self):
49
- assert self.pad_token_id < self.n_special_tokens and self.eos_token_id < self.n_special_tokens, (
50
- f"Special token id's must be smaller than {self.n_special_tokens=}"
51
- )
52
-
53
- def create_tokenizer(self) -> "ChronosTokenizer":
54
- if self.tokenizer_class == "MeanScaleUniformBins":
55
- return MeanScaleUniformBins(**self.tokenizer_kwargs, config=self)
56
- raise ValueError
57
-
58
-
59
- class ChronosTokenizer:
60
- """
61
- A ``ChronosTokenizer`` defines how time series are mapped into token IDs
62
- and back.
63
-
64
- For details, see the ``input_transform`` and ``output_transform`` methods,
65
- which concrete classes must implement.
66
- """
67
-
68
- def context_input_transform(
69
- self,
70
- context: torch.Tensor,
71
- ) -> Tuple:
72
- """
73
- Turn a batch of time series into token IDs, attention mask, and tokenizer_state.
74
-
75
- Parameters
76
- ----------
77
- context
78
- A tensor shaped (batch_size, time_length), containing the
79
- timeseries to forecast. Use left-padding with ``torch.nan``
80
- to align time series of different lengths.
81
-
82
- Returns
83
- -------
84
- token_ids
85
- A tensor of integers, shaped (batch_size, time_length + 1)
86
- if ``config.use_eos_token`` and (batch_size, time_length)
87
- otherwise, containing token IDs for the input series.
88
- attention_mask
89
- A boolean tensor, same shape as ``token_ids``, indicating
90
- which input observations are not ``torch.nan`` (i.e. not
91
- missing nor padding).
92
- tokenizer_state
93
- An object that can be passed to ``label_input_transform``
94
- and ``output_transform``. Contains the relevant information
95
- to decode output samples into real values,
96
- such as location and scale parameters.
97
- """
98
- raise NotImplementedError()
99
-
100
- def label_input_transform(self, label: torch.Tensor, tokenizer_state: Any) -> Tuple:
101
- """
102
- Turn a batch of label slices of time series into token IDs and attention mask
103
- using the ``tokenizer_state`` provided by ``context_input_transform``.
104
-
105
- Parameters
106
- ----------
107
- label
108
- A tensor shaped (batch_size, time_length), containing the
109
- timeseries label, i.e., the ground-truth future values.
110
- tokenizer_state
111
- An object returned by ``context_input_transform`` containing
112
- relevant information to preprocess data, such as location and
113
- scale. The nature of this depends on the specific tokenizer.
114
- This is used for tokenizing the label, in order to use the same
115
- scaling used to tokenize the context.
116
-
117
- Returns
118
- -------
119
- token_ids
120
- A tensor of integers, shaped (batch_size, time_length + 1)
121
- if ``config.use_eos_token`` and (batch_size, time_length)
122
- otherwise, containing token IDs for the input series.
123
- attention_mask
124
- A boolean tensor, same shape as ``token_ids``, indicating
125
- which input observations are not ``torch.nan`` (i.e. not
126
- missing nor padding).
127
- """
128
- raise NotImplementedError()
129
-
130
- def output_transform(self, samples: torch.Tensor, tokenizer_state: Any) -> torch.Tensor:
131
- """
132
- Turn a batch of sample token IDs into real values.
133
-
134
- Parameters
135
- ----------
136
- samples
137
- A tensor of integers, shaped (batch_size, num_samples, time_length),
138
- containing token IDs of sample trajectories.
139
- tokenizer_state
140
- An object returned by ``input_transform`` containing
141
- relevant context to decode samples, such as location and scale.
142
- The nature of this depends on the specific tokenizer.
143
-
144
- Returns
145
- -------
146
- forecasts
147
- A real tensor, shaped (batch_size, num_samples, time_length),
148
- containing forecasted sample paths.
149
- """
150
- raise NotImplementedError()
151
-
152
-
153
- class MeanScaleUniformBins(ChronosTokenizer):
154
- """
155
- A tokenizer that performs mean scaling and then quantizes the scaled time series into
156
- uniformly-spaced bins between some bounds on the real line.
157
- """
158
-
159
- def __init__(self, low_limit: float, high_limit: float, config: ChronosConfig) -> None:
160
- self.config = config
161
- self.centers = torch.linspace(
162
- low_limit,
163
- high_limit,
164
- config.n_tokens - config.n_special_tokens - 1,
165
- )
166
- self.boundaries = torch.concat(
167
- (
168
- torch.tensor([-1e20], device=self.centers.device),
169
- (self.centers[1:] + self.centers[:-1]) / 2,
170
- torch.tensor([1e20], device=self.centers.device),
171
- )
172
- )
173
-
174
- def _input_transform(
175
- self, context: torch.Tensor, scale: Optional[torch.Tensor] = None
176
- ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
177
- attention_mask = ~torch.isnan(context)
178
-
179
- if scale is None:
180
- scale = torch.nansum(torch.abs(context) * attention_mask, dim=-1) / torch.nansum(attention_mask, dim=-1)
181
- scale[~(scale > 0)] = 1.0
182
-
183
- scaled_context = context / scale.unsqueeze(dim=-1)
184
- token_ids = (
185
- torch.bucketize(
186
- input=scaled_context,
187
- boundaries=self.boundaries,
188
- # buckets are open to the right, see:
189
- # https://pytorch.org/docs/2.1/generated/torch.bucketize.html#torch-bucketize
190
- right=True,
191
- )
192
- + self.config.n_special_tokens
193
- )
194
- token_ids[~attention_mask] = self.config.pad_token_id
195
- token_ids.clamp_(0, self.config.n_tokens - 1)
196
-
197
- return token_ids, attention_mask, scale
198
-
199
- def _append_eos_token(
200
- self, token_ids: torch.Tensor, attention_mask: torch.Tensor
201
- ) -> Tuple[torch.Tensor, torch.Tensor]:
202
- batch_size = token_ids.shape[0]
203
- eos_tokens = torch.full((batch_size, 1), fill_value=self.config.eos_token_id)
204
- token_ids = torch.concat((token_ids, eos_tokens), dim=1)
205
- eos_mask = torch.full((batch_size, 1), fill_value=True)
206
- attention_mask = torch.concat((attention_mask, eos_mask), dim=1)
207
-
208
- return token_ids, attention_mask
209
-
210
- def context_input_transform(self, context: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
211
- length = context.shape[-1]
212
-
213
- if length > self.config.context_length:
214
- context = context[..., -self.config.context_length :]
215
-
216
- token_ids, attention_mask, scale = self._input_transform(context=context)
217
-
218
- if self.config.use_eos_token and self.config.model_type == "seq2seq":
219
- token_ids, attention_mask = self._append_eos_token(token_ids=token_ids, attention_mask=attention_mask)
220
-
221
- return token_ids, attention_mask, scale
222
-
223
- def label_input_transform(self, label: torch.Tensor, scale: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
224
- token_ids, attention_mask, _ = self._input_transform(context=label, scale=scale)
225
-
226
- if self.config.use_eos_token:
227
- token_ids, attention_mask = self._append_eos_token(token_ids=token_ids, attention_mask=attention_mask)
228
-
229
- return token_ids, attention_mask
230
-
231
- def output_transform(self, samples: torch.Tensor, scale: torch.Tensor) -> torch.Tensor:
232
- scale_unsqueezed = scale.unsqueeze(-1).unsqueeze(-1)
233
- indices = torch.clamp(
234
- samples - self.config.n_special_tokens - 1,
235
- min=0,
236
- max=len(self.centers) - 1,
237
- )
238
- return self.centers[indices] * scale_unsqueezed
239
-
240
-
241
- class ChronosPretrainedModel(nn.Module):
242
- """
243
- A ``ChronosPretrainedModel`` wraps a ``PreTrainedModel`` object from ``transformers``
244
- and uses it to predict sample paths for time series tokens.
245
-
246
- Parameters
247
- ----------
248
- config
249
- The configuration to use.
250
- model
251
- The pre-trained model to use.
252
- """
253
-
254
- def __init__(self, config: ChronosConfig, model: PreTrainedModel) -> None:
255
- super().__init__()
256
- self.config = config
257
- self.model = model
258
-
259
- @property
260
- def device(self):
261
- return self.model.device
262
-
263
- def encode(
264
- self,
265
- input_ids: torch.Tensor,
266
- attention_mask: torch.Tensor,
267
- ):
268
- """
269
- Extract the encoder embedding for the given token sequences.
270
-
271
- Parameters
272
- ----------
273
- input_ids
274
- Tensor of indices of input sequence tokens in the vocabulary
275
- with shape (batch_size, sequence_length).
276
- attention_mask
277
- A mask tensor of the same shape as input_ids to avoid attending
278
- on padding or missing tokens.
279
-
280
- Returns
281
- -------
282
- embedding
283
- A tensor of encoder embeddings with shape
284
- (batch_size, sequence_length, d_model).
285
- """
286
- assert self.config.model_type == "seq2seq", "Encoder embeddings are only supported for encoder-decoder models"
287
- return self.model.encoder(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
288
-
289
- def forward(
290
- self,
291
- input_ids: torch.Tensor,
292
- attention_mask: torch.Tensor,
293
- prediction_length: Optional[int] = None,
294
- num_samples: Optional[int] = None,
295
- temperature: Optional[float] = None,
296
- top_k: Optional[int] = None,
297
- top_p: Optional[float] = None,
298
- ) -> torch.Tensor:
299
- """
300
- Predict future sample tokens for the given token sequences.
301
-
302
- Arguments ``prediction_length``, ``num_samples``, ``temperature``,
303
- ``top_k``, ``top_p`` can be used to customize the model inference,
304
- and default to the corresponding attributes in ``self.config`` if
305
- not provided.
306
-
307
- Returns
308
- -------
309
- samples
310
- A tensor of integers, shaped (batch_size, num_samples, time_length),
311
- containing forecasted sample paths.
312
- """
313
- if prediction_length is None:
314
- prediction_length = self.config.prediction_length
315
- if num_samples is None:
316
- num_samples = self.config.num_samples
317
- if temperature is None:
318
- temperature = self.config.temperature
319
- if top_k is None:
320
- top_k = self.config.top_k
321
- if top_p is None:
322
- top_p = self.config.top_p
323
-
324
- preds = self.model.generate(
325
- input_ids=input_ids,
326
- attention_mask=attention_mask.long(), # int64 (long) type conversion needed for ONNX
327
- generation_config=GenerationConfig(
328
- min_new_tokens=prediction_length,
329
- max_new_tokens=prediction_length,
330
- do_sample=True,
331
- num_return_sequences=num_samples,
332
- eos_token_id=self.config.eos_token_id,
333
- pad_token_id=self.config.pad_token_id,
334
- temperature=temperature,
335
- top_k=top_k,
336
- top_p=top_p,
337
- ),
338
- )
339
-
340
- if self.config.model_type == "seq2seq":
341
- preds = preds[..., 1:] # remove the decoder start token
342
- else:
343
- assert self.config.model_type == "causal"
344
- assert preds.size(-1) == input_ids.size(-1) + prediction_length
345
- preds = preds[..., -prediction_length:]
346
-
347
- return preds.reshape(input_ids.size(0), num_samples, -1)
348
-
349
-
350
- class ChronosPipeline(BaseChronosPipeline):
351
- """
352
- A ``ChronosPipeline`` uses the given tokenizer and model to forecast
353
- input time series.
354
-
355
- Use the ``from_pretrained`` class method to load serialized models.
356
- Use the ``predict`` method to get forecasts.
357
-
358
- Parameters
359
- ----------
360
- tokenizer
361
- The tokenizer object to use.
362
- model
363
- The model to use.
364
- """
365
-
366
- tokenizer: ChronosTokenizer
367
- model: ChronosPretrainedModel
368
- forecast_type: ForecastType = ForecastType.SAMPLES
369
-
370
- def __init__(self, tokenizer, model):
371
- super().__init__(inner_model=model.model)
372
- self.tokenizer = tokenizer
373
- self.model = model
374
-
375
- @torch.no_grad()
376
- def embed(self, context: Union[torch.Tensor, List[torch.Tensor]]) -> Tuple[torch.Tensor, Any]:
377
- """
378
- Get encoder embeddings for the given time series.
379
-
380
- Parameters
381
- ----------
382
- context
383
- Input series. This is either a 1D tensor, or a list
384
- of 1D tensors, or a 2D tensor whose first dimension
385
- is batch. In the latter case, use left-padding with
386
- ``torch.nan`` to align series of different lengths.
387
-
388
- Returns
389
- -------
390
- embeddings, tokenizer_state
391
- A tuple of two tensors: the encoder embeddings and the tokenizer_state,
392
- e.g., the scale of the time series in the case of mean scaling.
393
- The encoder embeddings are shaped (batch_size, context_length, d_model)
394
- or (batch_size, context_length + 1, d_model), where context_length
395
- is the size of the context along the time axis if a 2D tensor was provided
396
- or the length of the longest time series, if a list of 1D tensors was
397
- provided, and the extra 1 is for EOS.
398
- """
399
- context_tensor = self._prepare_and_validate_context(context=context)
400
- token_ids, attention_mask, tokenizer_state = self.tokenizer.context_input_transform(context_tensor)
401
- embeddings = self.model.encode(
402
- input_ids=token_ids.to(self.model.device),
403
- attention_mask=attention_mask.to(self.model.device),
404
- ).cpu()
405
- return embeddings, tokenizer_state
406
-
407
- def predict(
408
- self,
409
- context: Union[torch.Tensor, List[torch.Tensor]],
410
- prediction_length: Optional[int] = None,
411
- num_samples: Optional[int] = None,
412
- temperature: Optional[float] = None,
413
- top_k: Optional[int] = None,
414
- top_p: Optional[float] = None,
415
- limit_prediction_length: bool = False,
416
- **kwargs,
417
- ) -> torch.Tensor:
418
- """
419
- Get forecasts for the given time series.
420
-
421
- Parameters
422
- ----------
423
- context
424
- Input series. This is either a 1D tensor, or a list
425
- of 1D tensors, or a 2D tensor whose first dimension
426
- is batch. In the latter case, use left-padding with
427
- ``torch.nan`` to align series of different lengths.
428
- prediction_length
429
- Time steps to predict. Defaults to what specified
430
- in ``self.model.config``.
431
- num_samples
432
- Number of sample paths to predict. Defaults to what
433
- specified in ``self.model.config``.
434
- temperature
435
- Temperature to use for generating sample tokens.
436
- Defaults to what specified in ``self.model.config``.
437
- top_k
438
- Top-k parameter to use for generating sample tokens.
439
- Defaults to what specified in ``self.model.config``.
440
- top_p
441
- Top-p parameter to use for generating sample tokens.
442
- Defaults to what specified in ``self.model.config``.
443
- limit_prediction_length
444
- Force prediction length smaller or equal than the
445
- built-in prediction length from the model. True by
446
- default. When true, fail loudly if longer predictions
447
- are requested, otherwise longer predictions are allowed.
448
-
449
- Returns
450
- -------
451
- samples
452
- Tensor of sample forecasts, of shape
453
- (batch_size, num_samples, prediction_length).
454
- """
455
- context_tensor = self._prepare_and_validate_context(context=context)
456
- if prediction_length is None:
457
- prediction_length = self.model.config.prediction_length
458
-
459
- if prediction_length > self.model.config.prediction_length:
460
- msg = (
461
- f"We recommend keeping prediction length <= {self.model.config.prediction_length}. "
462
- f"The quality of longer predictions may degrade since the model is not optimized for it. "
463
- )
464
- if limit_prediction_length:
465
- msg += "You can turn off this check by setting `limit_prediction_length=False`."
466
- raise ValueError(msg)
467
- warnings.warn(msg, stacklevel=2)
468
-
469
- predictions = []
470
- remaining = prediction_length
471
-
472
- while remaining > 0:
473
- token_ids, attention_mask, scale = self.tokenizer.context_input_transform(context_tensor)
474
- samples = self.model(
475
- token_ids.to(self.model.device),
476
- attention_mask.to(self.model.device),
477
- min(remaining, self.model.config.prediction_length),
478
- num_samples,
479
- temperature,
480
- top_k,
481
- top_p,
482
- )
483
- prediction = self.tokenizer.output_transform(samples.to(scale.device), scale)
484
-
485
- predictions.append(prediction)
486
- remaining -= prediction.shape[-1]
487
-
488
- if remaining <= 0:
489
- break
490
-
491
- context_tensor = torch.cat([context_tensor, prediction.median(dim=1).values], dim=-1)
492
-
493
- return torch.cat(predictions, dim=-1)
494
-
495
- def predict_quantiles(
496
- self,
497
- context: torch.Tensor,
498
- prediction_length: int,
499
- quantile_levels: List[float],
500
- num_samples: Optional[int] = None,
501
- **kwargs,
502
- ) -> Tuple[torch.Tensor, torch.Tensor]:
503
- num_samples = num_samples or self.model.config.num_samples
504
- prediction_samples = (
505
- self.predict(
506
- context,
507
- prediction_length=prediction_length,
508
- num_samples=num_samples,
509
- )
510
- .detach()
511
- .cpu()
512
- .swapaxes(1, 2)
513
- )
514
- mean = prediction_samples.mean(dim=-1, keepdim=True)
515
- quantiles = torch.quantile(
516
- prediction_samples,
517
- q=torch.tensor(quantile_levels, dtype=prediction_samples.dtype),
518
- dim=-1,
519
- ).permute(1, 2, 0)
520
-
521
- return quantiles, mean
522
-
523
- @classmethod
524
- def from_pretrained(cls, *args, **kwargs):
525
- """
526
- Load the model, either from a local path or from the HuggingFace Hub.
527
- Supports the same arguments as ``AutoConfig`` and ``AutoModel``
528
- from ``transformers``.
529
- """
530
- kwargs = kwargs.copy()
531
-
532
- optimization_strategy = kwargs.pop("optimization_strategy", None)
533
- context_length = kwargs.pop("context_length", None)
534
-
535
- config = AutoConfig.from_pretrained(*args, **kwargs)
536
- assert hasattr(config, "chronos_config"), "Not a Chronos config file"
537
-
538
- if context_length is not None:
539
- config.chronos_config["context_length"] = context_length
540
- chronos_config = ChronosConfig(**config.chronos_config)
541
-
542
- assert chronos_config.model_type == "seq2seq"
543
- if optimization_strategy is None:
544
- inner_model = AutoModelForSeq2SeqLM.from_pretrained(*args, **kwargs)
545
- else:
546
- assert optimization_strategy in [
547
- "onnx",
548
- "openvino",
549
- ], "optimization_strategy not recognized. Please provide one of `onnx` or `openvino`"
550
- kwargs.pop("resume_download", None) # Optimized pipeline does not support 'resume_download' kwargs
551
- torch_dtype = kwargs.pop("torch_dtype", "auto")
552
- if torch_dtype != "auto":
553
- logger.warning(f"\t`torch_dtype` will be ignored for optimization_strategy {optimization_strategy}")
554
-
555
- if optimization_strategy == "onnx":
556
- try:
557
- from optimum.onnxruntime import ORTModelForSeq2SeqLM
558
- except ImportError:
559
- raise ImportError(
560
- "Huggingface Optimum library must be installed with ONNX for using the `onnx` strategy. "
561
- "Please try running `pip install optimum[onnxruntime]` or use Chronos-Bolt models for "
562
- "faster performance on the CPU."
563
- )
564
-
565
- assert kwargs.pop("device_map", "cpu") in ["cpu", "auto"], "ONNX mode only available on the CPU"
566
- with set_loggers_level(regex=r"^optimum.*", level=logging.ERROR):
567
- inner_model = ORTModelForSeq2SeqLM.from_pretrained(*args, **{**kwargs, "export": True})
568
- elif optimization_strategy == "openvino":
569
- try:
570
- from optimum.intel import OVModelForSeq2SeqLM
571
- except ImportError:
572
- raise ImportError(
573
- "Huggingface Optimum library must be installed with OpenVINO for using the `openvino` strategy. "
574
- "Please try running `pip install optimum-intel[openvino,nncf] optimum[openvino,nncf]` or use "
575
- "Chronos-Bolt models for faster performance on the CPU."
576
- )
577
- with set_loggers_level(regex=r"^optimum.*", level=logging.ERROR):
578
- inner_model = OVModelForSeq2SeqLM.from_pretrained(
579
- *args, **{**kwargs, "device_map": "cpu", "export": True}
580
- )
581
-
582
- return cls(
583
- tokenizer=chronos_config.create_tokenizer(),
584
- model=ChronosPretrainedModel(config=chronos_config, model=inner_model),
585
- )