patchfm 2.2.2__tar.gz → 3.0.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchfm
3
- Version: 2.2.2
3
+ Version: 3.0.0
4
4
  Summary: a Foundation Model for Univariate Time Series Forecasting
5
5
  Author-email: Samy-Melwan Vilhes <samy-melwan.vilhes@insa-rouen.fr>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "patchfm"
3
- version = "2.2.2"
3
+ version = "3.0.0"
4
4
  authors = [
5
5
  { name="Samy-Melwan Vilhes", email="samy-melwan.vilhes@insa-rouen.fr" },
6
6
  ]
@@ -24,6 +24,7 @@ class Forecaster(nn.Module):
24
24
 
25
25
  print("Loading base model from HuggingFace Hub...")
26
26
  base_model = PatchFM.from_pretrained("vilhess/PatchFM")
27
+
27
28
  self._init_from_base(base_model)
28
29
 
29
30
  self.eval()
@@ -46,7 +47,7 @@ class Forecaster(nn.Module):
46
47
  self.transformer_encoder = TransformerEncoder(
47
48
  d_model=self.d_model,
48
49
  n_heads=self.n_heads,
49
- n_layers=self.n_layers_encoder
50
+ n_layers=self.n_layers_encoder,
50
51
  )
51
52
  self.proj_output = ResidualBlock(
52
53
  in_dim=self.d_model,
@@ -69,15 +70,7 @@ class Forecaster(nn.Module):
69
70
  # Default horizon = patch_len
70
71
  forecast_horizon = forecast_horizon or self.patch_len
71
72
 
72
- x = self.converter.convert(x)
73
- assert x.ndim in (1, 2), f"Input dimension must be 1D (time) or 2D (batch, time), got {x.ndim}D."
74
-
75
- batch_dim=True
76
- if x.ndim != 2:
77
- x = x.unsqueeze(0)
78
- batch_dim=False
79
73
  bs, ws = x.size()
80
-
81
74
  x = x.to(self.device)
82
75
 
83
76
  if ws > self.max_seq_len:
@@ -153,26 +146,39 @@ class Forecaster(nn.Module):
153
146
  pred_median = torch.zeros_like(pred_median)
154
147
  pred_quantiles = torch.zeros_like(pred_quantiles)
155
148
 
156
- if not batch_dim:
157
- pred_median = pred_median.squeeze(0)
158
- pred_quantiles = pred_quantiles.squeeze(0)
159
-
160
- pred_median, pred_quantiles = self.converter.deconvert(pred_median, pred_quantiles)
161
149
  return pred_median, pred_quantiles
162
150
 
163
151
  def __call__(self, context: torch.Tensor, forecast_horizon: int | None = None, quantiles: list[float] | None = None, flip_equivariance: bool = False) -> torch.Tensor:
152
+
153
+ x = self.converter.convert(context)
154
+ assert x.ndim in (1, 2), f"Input dimension must be 1D (time) or 2D (batch, time), got {x.ndim}D."
155
+
156
+ batch_dim=True
157
+ if x.ndim != 2:
158
+ x = x.unsqueeze(0)
159
+ batch_dim=False
160
+
161
+ bs, ws = x.size()
162
+
164
163
  if flip_equivariance:
165
- print("Flip equivariance enabled: forecast = (f(x) - f(-x)) / 2. This requires multiplying by 2 the batch size (Reverso: Efficient Time Series Foundation Models for Zero-shot Forecasting).")
164
+
166
165
  bs = context.size(0)
167
- context_flipped = -context
168
- concat_context = torch.cat([context, context_flipped], dim=0)
169
- pred_median_full, pred_quantiles_full = self.auto_regressive_quantile_decoding(concat_context, forecast_horizon, quantiles)
166
+ x_flipped = -x
167
+ concat_x = torch.cat([x, x_flipped], dim=0)
168
+ pred_median_full, pred_quantiles_full = self.auto_regressive_quantile_decoding(concat_x, forecast_horizon, quantiles)
170
169
  pred_median, pred_quantiles = pred_median_full[:bs], pred_quantiles_full[:bs]
171
170
  pred_median2, pred_quantiles2 = pred_median_full[bs:], pred_quantiles_full[bs:]
172
171
  pred_median = (pred_median - pred_median2) / 2
173
172
  pred_quantiles = (pred_quantiles - flip_last_dim(pred_quantiles2)) / 2
174
173
  else:
175
- pred_median, pred_quantiles = self.auto_regressive_quantile_decoding(context, forecast_horizon, quantiles)
174
+ pred_median, pred_quantiles = self.auto_regressive_quantile_decoding(x, forecast_horizon, quantiles)
175
+
176
+ if not batch_dim:
177
+ pred_median = pred_median.squeeze(0)
178
+ pred_quantiles = pred_quantiles.squeeze(0)
179
+
180
+ pred_median, pred_quantiles = self.converter.deconvert(pred_median, pred_quantiles)
181
+
176
182
  return pred_median, pred_quantiles
177
183
 
178
184
  def clear_cache(self):
@@ -204,7 +204,7 @@ class MultiHeadAttention(nn.Module):
204
204
  self.v_cache = None
205
205
 
206
206
  self.last = last
207
-
207
+
208
208
  def forward(self, q):
209
209
  bs, context, dim = q.size()
210
210
  offset = 0
@@ -319,7 +319,7 @@ class PatchFM(nn.Module, PyTorchModelHubMixin):
319
319
  self.transformer_encoder = TransformerEncoder(
320
320
  d_model=self.d_model,
321
321
  n_heads=self.n_heads,
322
- n_layers=self.n_layers_encoder
322
+ n_layers=self.n_layers_encoder,
323
323
  )
324
324
  self.proj_output = ResidualBlock(
325
325
  in_dim=self.d_model,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchfm
3
- Version: 2.2.2
3
+ Version: 3.0.0
4
4
  Summary: a Foundation Model for Univariate Time Series Forecasting
5
5
  Author-email: Samy-Melwan Vilhes <samy-melwan.vilhes@insa-rouen.fr>
6
6
  License: MIT License
File without changes
File without changes
File without changes
File without changes