ccloud0525 commited on
Commit
e11caaf
·
1 Parent(s): 33595d0

feat: 'main'

Browse files
__init__.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ '''
2
+ * @author: EmpyreanMoon
3
+ *
4
+ * @create: 2025-07-17 19:20
5
+ *
6
+ * @description: FLAME SMALL (2M)
7
+ '''
config.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "activation": "gelu",
3
+ "architectures": [
4
+ "FLAMEForPrediction"
5
+ ],
6
+ "auto_map": {
7
+ "AutoConfig": "configuration_flame.FLAMEConfig",
8
+ "AutoModelForCausalLM": "modeling_flame.FLAMEForPrediction"
9
+ },
10
+ "couple_layers": 3,
11
+ "d_conv": 4,
12
+ "d_couple": 256,
13
+ "d_ff": 512,
14
+ "d_model": 256,
15
+ "dec_layers": 1,
16
+ "dropout": 0.2,
17
+ "enc_layers": 1,
18
+ "expand": 2,
19
+ "head_dim": 64,
20
+ "head_dropout": 0.2,
21
+ "learnable": false,
22
+ "model_type": "flame",
23
+ "n_heads": 4,
24
+ "norm_mode": "layer",
25
+ "patch_len": 48,
26
+ "stride": 48,
27
+ "torch_dtype": "float32",
28
+ "transformers_version": "4.53.2"
29
+ }
configuration_flame.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import PretrainedConfig
2
+
3
+
4
+ class FLAMEConfig(PretrainedConfig):
5
+ model_type = "flame"
6
+
7
+ def __init__(
8
+ self,
9
+ patch_len: int = 48,
10
+ expand: int = 2,
11
+ d_conv: int = 4,
12
+ d_model: int = 256,
13
+ d_ff: int = 512,
14
+ d_couple: int = 256,
15
+ enc_layers: int = 1,
16
+ dec_layers: int = 3,
17
+ couple_layers: int = 5,
18
+ head_dim: int = 64,
19
+ n_heads: int = 4,
20
+ activation: str = "gelu",
21
+ dropout: float = 0.2,
22
+ head_dropout: float = 0.2,
23
+ learnable: bool = False,
24
+ norm_mode: str = 'layer',
25
+ **kwargs,
26
+ ):
27
+ self.patch_len = patch_len
28
+ self.expand = expand
29
+ self.d_conv = d_conv
30
+ self.d_model = d_model
31
+ self.d_ff = d_ff
32
+ self.d_couple = d_couple
33
+ self.enc_layers = enc_layers
34
+ self.dec_layers = dec_layers
35
+ self.couple_layers = couple_layers
36
+ self.head_dim = head_dim
37
+ self.n_heads = n_heads
38
+ self.activation = activation
39
+ self.dropout = dropout
40
+ self.head_dropout = head_dropout
41
+ self.learnable = learnable
42
+ self.norm_mode = norm_mode
43
+
44
+ super().__init__(
45
+ **kwargs,
46
+ )
generation_config.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "transformers_version": "4.53.2"
4
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a9f00f0aded2d0553b4852c1f9351659ad498c03fdcf98b9422940fffc7d7aef
3
+ size 11034704
modeling_flame.py ADDED
@@ -0,0 +1,828 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+ from typing import Tuple
3
+
4
+ import math
5
+ import numpy as np
6
+ import torch
7
+ import torch.nn as nn
8
+ import torch.nn.functional as F
9
+ import zuko
10
+ from einops import rearrange
11
+ from mamba_ssm import Mamba2
12
+ from torch import Tensor
13
+ from transformers import PreTrainedModel
14
+ from transformers.modeling_outputs import MoeCausalLMOutputWithPast
15
+
16
+ from .configuration_flame import FLAMEConfig
17
+ from .ts_generation_mixin import TSGenerationMixin
18
+
19
+
20
+ class Transpose(nn.Module):
21
+ def __init__(self, *dims, contiguous=False):
22
+ super().__init__()
23
+ self.dims, self.contiguous = dims, contiguous
24
+
25
+ def forward(self, x):
26
+ if self.contiguous:
27
+ return x.transpose(*self.dims).contiguous()
28
+ else:
29
+ return x.transpose(*self.dims)
30
+
31
+
32
+ class MultiheadAttention(nn.Module):
33
+ def __init__(self, d_model, n_heads, d_k=None, d_v=None, res_attention=False, attn_dropout=0., proj_dropout=0.,
34
+ qkv_bias=True, lsa=False, rope_type=False):
35
+ """Multi Head Attention Layer
36
+ Input shape:
37
+ Q: [batch_size (bs) x max_q_len x d_model]
38
+ K, V: [batch_size (bs) x q_len x d_model]
39
+ mask: [q_len x q_len]
40
+ """
41
+ super().__init__()
42
+ d_k = d_model // n_heads if d_k is None else d_k
43
+ d_v = d_model // n_heads if d_v is None else d_v
44
+
45
+ self.n_heads, self.d_k, self.d_v = n_heads, d_k, d_v
46
+
47
+ self.W_Q = nn.Linear(d_model, d_k * n_heads, bias=qkv_bias)
48
+ self.W_K = nn.Linear(d_model, d_k * n_heads, bias=qkv_bias)
49
+ self.W_V = nn.Linear(d_model, d_v * n_heads, bias=qkv_bias)
50
+
51
+ # Scaled Dot-Product Attention (multiple heads)
52
+ self.res_attention = res_attention
53
+ self.sdp_attn = ScaledDotProductAttention(d_model, n_heads, attn_dropout=attn_dropout,
54
+ res_attention=self.res_attention, lsa=lsa, rope_type=rope_type)
55
+
56
+ # Poject output
57
+ self.to_out = nn.Sequential(nn.Linear(n_heads * d_v, d_model), nn.Dropout(proj_dropout))
58
+
59
+ def forward(self, Q: Tensor, K: Optional[Tensor] = None, V: Optional[Tensor] = None, prev: Optional[Tensor] = None,
60
+ key_padding_mask: Optional[Tensor] = None, attn_mask: Optional[Tensor] = None):
61
+
62
+ bs = Q.size(0)
63
+ if K is None: K = Q
64
+ if V is None: V = Q
65
+
66
+ # Linear (+ split in multiple heads)
67
+ q_s = self.W_Q(Q).view(bs, -1, self.n_heads, self.d_k).transpose(1,
68
+ 2) # q_s : [bs x n_heads x max_q_len x d_k]
69
+ k_s = self.W_K(K).view(bs, -1, self.n_heads, self.d_k).permute(0, 2, 3,
70
+ 1) # k_s : [bs x n_heads x d_k x q_len] - transpose(1,2) + transpose(2,3)
71
+ v_s = self.W_V(V).view(bs, -1, self.n_heads, self.d_v).transpose(1, 2) # v_s : [bs x n_heads x q_len x d_v]
72
+
73
+ # Apply Scaled Dot-Product Attention (multiple heads)
74
+ if self.res_attention:
75
+ output, attn_weights, attn_scores = self.sdp_attn(q_s, k_s, v_s, prev=prev,
76
+ key_padding_mask=key_padding_mask, attn_mask=attn_mask)
77
+ else:
78
+ output, attn_weights = self.sdp_attn(q_s, k_s, v_s, key_padding_mask=key_padding_mask, attn_mask=attn_mask)
79
+ # output: [bs x n_heads x q_len x d_v], attn: [bs x n_heads x q_len x q_len], scores: [bs x n_heads x max_q_len x q_len]
80
+
81
+ # back to the original inputs dimensions
82
+ output = output.transpose(1, 2).contiguous().view(bs, -1,
83
+ self.n_heads * self.d_v) # output: [bs x q_len x n_heads * d_v]
84
+ output = self.to_out(output)
85
+
86
+ if self.res_attention:
87
+ return output, attn_weights, attn_scores
88
+ else:
89
+ return output, attn_weights
90
+
91
+
92
+ class ScaledDotProductAttention(nn.Module):
93
+ r"""Scaled Dot-Product Attention module (Attention is all you need by Vaswani et al., 2017) with optional residual attention from previous layer
94
+ (Realformer: Transformer likes residual attention by He et al, 2020) and locality self sttention (Vision Transformer for Small-Size Datasets
95
+ by Lee et al, 2021)"""
96
+
97
+ def __init__(self, d_model, n_heads, attn_dropout=0., res_attention=False, lsa=False, rope_type=False):
98
+ super().__init__()
99
+ self.attn_dropout = nn.Dropout(attn_dropout)
100
+ self.res_attention = res_attention
101
+ head_dim = d_model // n_heads
102
+ self.scale = nn.Parameter(torch.tensor(head_dim ** -0.5), requires_grad=lsa)
103
+ self.lsa = lsa
104
+ self.rope_type = rope_type
105
+
106
+ def forward(self, q: Tensor, k: Tensor, v: Tensor, prev: Optional[Tensor] = None,
107
+ key_padding_mask: Optional[Tensor] = None, attn_mask: Optional[Tensor] = None):
108
+ '''
109
+ Input shape:
110
+ q : [bs x n_heads x max_q_len x d_k]
111
+ k : [bs x n_heads x d_k x seq_len]
112
+ v : [bs x n_heads x seq_len x d_v]
113
+ prev : [bs x n_heads x q_len x seq_len]
114
+ key_padding_mask: [bs x seq_len]
115
+ attn_mask : [1 x seq_len x seq_len]
116
+ Output shape:
117
+ output: [bs x n_heads x q_len x d_v]
118
+ attn : [bs x n_heads x q_len x seq_len]
119
+ scores : [bs x n_heads x q_len x seq_len]
120
+ '''
121
+ # using RoPE
122
+ if self.rope_type:
123
+ q, k = RoPE_decoder(q, k.permute(0, 1, 3, 2))
124
+ else:
125
+ q, k = RoPE(q, k.permute(0, 1, 3, 2))
126
+ k = k.permute(0, 1, 3, 2)
127
+
128
+ # Scaled MatMul (q, k) - similarity scores for all pairs of positions in an input sequence
129
+ attn_scores = torch.matmul(q, k) * self.scale # attn_scores : [bs x n_heads x max_q_len x q_len]
130
+
131
+ # Add pre-softmax attention scores from the previous layer (optional)
132
+ if prev is not None: attn_scores = attn_scores + prev
133
+
134
+ # Attention mask (optional)
135
+ if attn_mask is not None: # attn_mask with shape [q_len x seq_len] - only used when q_len == seq_len
136
+ if attn_mask.dtype == torch.bool:
137
+ attn_scores.masked_fill_(attn_mask, -np.inf)
138
+ else:
139
+ attn_scores += attn_mask
140
+
141
+ # Key padding mask (optional)
142
+ if key_padding_mask is not None: # mask with shape [bs x q_len] (only when max_w_len == q_len)
143
+ attn_scores.masked_fill_(key_padding_mask.unsqueeze(1).unsqueeze(2), -np.inf)
144
+
145
+ # normalize the attention weights
146
+ attn_weights = F.softmax(attn_scores, dim=-1) # attn_weights : [bs x n_heads x max_q_len x q_len]
147
+ attn_weights = self.attn_dropout(attn_weights)
148
+
149
+ # compute the new values given the attention weights
150
+ output = torch.matmul(attn_weights, v) # output: [bs x n_heads x max_q_len x d_v]
151
+
152
+ if self.res_attention:
153
+ return output, attn_weights, attn_scores
154
+ else:
155
+ return output, attn_weights
156
+
157
+
158
+ def RoPE(q, k):
159
+ # q,k: (bs, head, max_len, output_dim)
160
+ batch_size = q.shape[0]
161
+ nums_head = q.shape[1]
162
+ max_len = q.shape[2]
163
+ output_dim = q.shape[-1]
164
+
165
+ # (bs, head, max_len, output_dim)
166
+ pos_emb = sinusoidal_position_embedding(batch_size, nums_head, max_len, output_dim, q.device, factor=1)
167
+
168
+ # cos_pos,sin_pos: (bs, head, max_len, output_dim)
169
+ # 看rope公式可知,相邻cos,sin之间是相同的,所以复制一遍。如(1,2,3)变成(1,1,2,2,3,3)
170
+ cos_pos = pos_emb[..., 1::2].repeat_interleave(2, dim=-1) # 将奇数列信息抽取出来也就是cos 拿出来并复制
171
+ sin_pos = pos_emb[..., ::2].repeat_interleave(2, dim=-1) # 将偶数列信息抽取出来也就是sin 拿出来并复制
172
+
173
+ # q,k: (bs, head, max_len, output_dim)
174
+ q2 = torch.stack([-q[..., 1::2], q[..., ::2]], dim=-1)
175
+ q2 = q2.reshape(q.shape) # reshape后就是正负交替了
176
+
177
+ # 更新qw, *对应位置相乘
178
+ q = q * cos_pos + q2 * sin_pos
179
+
180
+ k2 = torch.stack([-k[..., 1::2], k[..., ::2]], dim=-1)
181
+ k2 = k2.reshape(k.shape)
182
+ # 更新kw, *对应位置相乘
183
+ k = k * cos_pos + k2 * sin_pos
184
+
185
+ return q, k
186
+
187
+
188
+ def RoPE_decoder(q, k):
189
+ # q,k: (bs, head, max_len, output_dim)
190
+ batch_size = q.shape[0]
191
+ nums_head = q.shape[1]
192
+ q_max_len = q.shape[2]
193
+ k_max_len = k.shape[2]
194
+ output_dim = q.shape[-1]
195
+
196
+ # (bs, head, max_len, output_dim)
197
+ pos_emb = sinusoidal_position_embedding(batch_size, nums_head, k_max_len + q_max_len, output_dim, q.device,
198
+ factor=1)
199
+
200
+ # cos_pos,sin_pos: (bs, head, max_len, output_dim)
201
+ # 看rope公式可知,相邻cos,sin之间是相同的,所以复制一遍。如(1,2,3)变成(1,1,2,2,3,3)
202
+ cos_pos = pos_emb[..., 1::2].repeat_interleave(2, dim=-1) # 将奇数列信息抽取出来也就是cos 拿出来并复制
203
+ sin_pos = pos_emb[..., ::2].repeat_interleave(2, dim=-1) # 将偶数列信息抽取出来也就是sin 拿出来并复制
204
+
205
+ # q,k: (bs, head, max_len, output_dim)
206
+ q2 = torch.stack([-q[..., 1::2], q[..., ::2]], dim=-1)
207
+ q2 = q2.reshape(q.shape) # reshape后就是正负交替了
208
+
209
+ # 更新qw, *对应位置相乘
210
+ q = q * cos_pos[:, :, -q_max_len:, :] + q2 * sin_pos[:, :, -q_max_len:, :]
211
+
212
+ k2 = torch.stack([-k[..., 1::2], k[..., ::2]], dim=-1)
213
+ k2 = k2.reshape(k.shape)
214
+ # 更新kw, *对应位置相乘
215
+ k = k * cos_pos[:, :, :k_max_len, :] + k2 * sin_pos[:, :, :k_max_len, :]
216
+ return q, k
217
+
218
+
219
+ def sinusoidal_position_embedding(batch_size, nums_head, max_len, output_dim, device, factor=1.0):
220
+ # (max_len * factor, 1)
221
+ position = torch.arange(0, max_len * factor, 1 / factor, dtype=torch.float).unsqueeze(-1)
222
+ # (output_dim//2)
223
+ ids = torch.arange(0, output_dim // 2, dtype=torch.float) # i 范围是 [0, d/2]
224
+ theta = torch.pow(10000, -2 * ids / output_dim)
225
+
226
+ # (max_len * factor, output_dim//2)
227
+ embeddings = position * theta
228
+
229
+ # (max_len * factor, output_dim//2, 2)
230
+ embeddings = torch.stack([torch.sin(embeddings), torch.cos(embeddings)], dim=-1)
231
+
232
+ # (bs, head, max_len * factor, output_dim//2, 2)
233
+ embeddings = embeddings.repeat((batch_size, nums_head, *([1] * len(embeddings.shape))))
234
+
235
+ # (bs, head, max_len * factor, output_dim)
236
+ embeddings = torch.reshape(embeddings, (batch_size, nums_head, -1, output_dim))
237
+ embeddings = embeddings.to(device)
238
+
239
+ # 如果 factor > 1, 使用插值位置来生成更细粒度的嵌入
240
+ if factor > 1.0:
241
+ interpolation_indices = torch.linspace(0, embeddings.shape[2] - 1, max_len).long()
242
+ embeddings = embeddings[:, :, interpolation_indices, :]
243
+
244
+ return embeddings
245
+
246
+
247
+ def causal_attention_mask(seq_length):
248
+ mask = torch.triu(torch.ones(seq_length, seq_length) * float('-inf'), diagonal=1)
249
+ return mask.unsqueeze(0).unsqueeze(0)
250
+
251
+
252
+ def resize(x_tensor, new_shape):
253
+ return F.interpolate(x_tensor.unsqueeze(0), size=new_shape, mode='linear').squeeze(0)
254
+
255
+
256
+ def resample(old: torch.Tensor, new_patch_len: int):
257
+ assert old.dim() == 2, "the size of input tensor should be (d_model, patch_size)"
258
+ if old.size(1) == new_patch_len:
259
+ return old
260
+
261
+ old = old.T
262
+ old_shape = old.size(0)
263
+ factor = new_patch_len / old_shape
264
+
265
+ basis_vectors = torch.eye(old_shape, dtype=torch.get_default_dtype(), device=old.device)
266
+ resize_mat = resize(basis_vectors, new_patch_len).T
267
+ resize_mat_pinv = torch.linalg.pinv(resize_mat.T)
268
+
269
+ resampled_kernels = resize_mat_pinv @ old * math.sqrt(factor)
270
+
271
+ return resampled_kernels.T
272
+
273
+
274
+ class MambaDecoder(nn.Module):
275
+ def __init__(self, configs):
276
+ super(MambaDecoder, self).__init__()
277
+ self.mamba_dec = nn.ModuleList(
278
+ [DecoderLayer(configs)
279
+ for _ in range(configs.dec_layers)])
280
+
281
+ def forward(self, x_enc, x_rec):
282
+ x_dec = x_enc
283
+ for layer in self.mamba_dec:
284
+ x_dec = layer(x_dec, x_rec)
285
+
286
+ return x_dec
287
+
288
+
289
+ class DecoderLayer(nn.Module):
290
+ def __init__(self, configs):
291
+ super(DecoderLayer, self).__init__()
292
+ self.mamba = Mamba2(d_model=configs.d_model,
293
+ expand=configs.expand,
294
+ d_state=configs.d_ff,
295
+ d_conv=configs.d_conv,
296
+ headdim=configs.head_dim)
297
+
298
+ self.cross_attention = MultiheadAttention(configs.d_model, configs.n_heads, attn_dropout=configs.dropout,
299
+ rope_type=True)
300
+ self.mlp = nn.Sequential(nn.Linear(configs.d_model, configs.d_ff), nn.SiLU(),
301
+ nn.Linear(configs.d_ff, configs.d_model))
302
+
303
+ if configs.norm_mode == 'batch':
304
+ self.norm1 = nn.Sequential(Transpose(1, 2), nn.BatchNorm1d(configs.d_model), Transpose(1, 2))
305
+ self.norm2 = nn.Sequential(Transpose(1, 2), nn.BatchNorm1d(configs.d_model), Transpose(1, 2))
306
+ self.norm3 = nn.Sequential(Transpose(1, 2), nn.BatchNorm1d(configs.d_model), Transpose(1, 2))
307
+ else:
308
+ self.norm1 = nn.LayerNorm(configs.d_model)
309
+ self.norm2 = nn.LayerNorm(configs.d_model)
310
+ self.norm3 = nn.LayerNorm(configs.d_model)
311
+
312
+ def forward(self, x_enc, x_rec):
313
+ x_dec = self.mamba(x_enc)
314
+ x_dec = self.norm1(x_dec) + x_enc
315
+
316
+ tokens, _ = self.cross_attention(x_dec, x_rec, x_rec)
317
+ tokens = self.norm2(tokens) + x_dec
318
+
319
+ repr = self.mlp(tokens)
320
+ repr = self.norm3(repr) + tokens
321
+
322
+ return repr
323
+
324
+
325
+ class TSTEncoder(nn.Module):
326
+ def __init__(self, configs, norm='BatchNorm', activation='gelu', res_attention=False, pre_norm=False,
327
+ store_attn=False):
328
+ super().__init__()
329
+
330
+ self.layers = nn.ModuleList(
331
+ [TSTEncoderLayer(configs.d_model, n_heads=configs.n_heads, d_ff=configs.d_ff, norm=norm,
332
+ attn_dropout=configs.dropout, dropout=configs.head_dropout,
333
+ activation=activation, res_attention=res_attention,
334
+ pre_norm=pre_norm, store_attn=store_attn) for _ in
335
+ range(configs.enc_layers)])
336
+ self.res_attention = res_attention
337
+
338
+ def forward(self, src: Tensor):
339
+ """
340
+ src: tensor [bs x q_len x d_model]
341
+ """
342
+ output = src
343
+ scores = None
344
+ if self.res_attention:
345
+ for mod in self.layers: output, scores = mod(output, prev=scores)
346
+ return output
347
+ else:
348
+ for mod in self.layers: output = mod(output)
349
+ return output
350
+
351
+
352
+ class TSTEncoderLayer(nn.Module):
353
+ def __init__(self, d_model, n_heads, d_ff=256, store_attn=False,
354
+ norm='LayerNorm', attn_dropout=0, dropout=0., bias=True,
355
+ activation="gelu", res_attention=False, pre_norm=False):
356
+ super().__init__()
357
+ assert not d_model % n_heads, f"d_model ({d_model}) must be divisible by n_heads ({n_heads})"
358
+ d_k = d_model // n_heads
359
+ d_v = d_model // n_heads
360
+
361
+ # Multi-Head attention
362
+ self.res_attention = res_attention
363
+ self.self_attn = MultiheadAttention(d_model, n_heads, d_k, d_v, attn_dropout=attn_dropout, proj_dropout=dropout,
364
+ res_attention=res_attention)
365
+
366
+ # Add & Norm
367
+ self.dropout_attn = nn.Dropout(dropout)
368
+ if "batch" in norm.lower():
369
+ self.norm_attn = nn.Sequential(Transpose(1, 2), nn.BatchNorm1d(d_model), Transpose(1, 2))
370
+ else:
371
+ self.norm_attn = nn.LayerNorm(d_model)
372
+
373
+ # Position-wise Feed-Forward
374
+ self.ff = nn.Sequential(nn.Linear(d_model, d_ff, bias=bias),
375
+ get_activation_fn(activation),
376
+ nn.Dropout(dropout),
377
+ nn.Linear(d_ff, d_model, bias=bias))
378
+
379
+ # Add & Norm
380
+ self.dropout_ffn = nn.Dropout(dropout)
381
+ if "batch" in norm.lower():
382
+ self.norm_ffn = nn.Sequential(Transpose(1, 2), nn.BatchNorm1d(d_model), Transpose(1, 2))
383
+ else:
384
+ self.norm_ffn = nn.LayerNorm(d_model)
385
+
386
+ self.pre_norm = pre_norm
387
+ self.store_attn = store_attn
388
+
389
+ # # se block
390
+ # self.SE = SE_Block(inchannel=7)
391
+
392
+ def forward(self, src: Tensor, prev: Optional[Tensor] = None):
393
+ """
394
+ src: tensor [bs x q_len x d_model]
395
+ """
396
+ # Multi-Head attention sublayer
397
+ if self.pre_norm:
398
+ src = self.norm_attn(src)
399
+ ## Multi-Head attention
400
+ if self.res_attention:
401
+ src2, attn, scores = self.self_attn(src, src, src, prev)
402
+ else:
403
+ # attention_mask = causal_attention_mask(src.shape[1]).to(src.device)
404
+ # src2, attn = self.self_attn(src, src, src, attn_mask=attention_mask)
405
+ src2, attn = self.self_attn(src, src, src)
406
+ if self.store_attn:
407
+ self.attn = attn
408
+
409
+ # total, num_patch, d_model = src2.size()
410
+ # bs = int(total/7)
411
+
412
+ # src2 = self.SE(src2.reshape(bs, 7, num_patch, -1)).reshape(total, num_patch, -1)
413
+
414
+ ## Add & Norm
415
+ src = src + self.dropout_attn(src2) # Add: residual connection with residual dropout
416
+ if not self.pre_norm:
417
+ src = self.norm_attn(src)
418
+
419
+ # Feed-forward sublayer
420
+ if self.pre_norm:
421
+ src = self.norm_ffn(src)
422
+ ## Position-wise Feed-Forward
423
+ src2 = self.ff(src)
424
+ ## Add & Norm
425
+ src = src + self.dropout_ffn(src2) # Add: residual connection with residual dropout
426
+ if not self.pre_norm:
427
+ src = self.norm_ffn(src)
428
+
429
+ if self.res_attention:
430
+ return src, scores
431
+ else:
432
+ return src
433
+
434
+
435
+ def get_activation_fn(activation):
436
+ if callable(activation):
437
+ return activation()
438
+ elif activation.lower() == "relu":
439
+ return nn.ReLU()
440
+ elif activation.lower() == "gelu":
441
+ return nn.GELU()
442
+ raise ValueError(f'{activation} is not available. You can use "relu", "gelu", or a callable')
443
+
444
+
445
+ class PatchEmbedding(nn.Module):
446
+ def __init__(self, configs):
447
+ super(PatchEmbedding, self).__init__()
448
+ self.patch_len = configs.patch_len
449
+ self.d_model = configs.d_model
450
+ self.proj = nn.Linear(self.patch_len, self.d_model, bias=False)
451
+
452
+ def forward(self, x):
453
+ output = self.proj(x)
454
+ return output
455
+
456
+
457
+ class LegendreMemory(nn.Module):
458
+ def __init__(self, configs):
459
+ super(LegendreMemory, self).__init__()
460
+ self.d_model = configs.d_model
461
+ A, B = self._gen_AB_base_matrices(self.d_model)
462
+ if configs.learnable:
463
+ self.A = nn.Parameter(A)
464
+ self.B = nn.Parameter(B)
465
+ else:
466
+ self.register_buffer("A", A)
467
+ self.register_buffer("B", B)
468
+
469
+ def _pytorch_cont2discrete_zoh(
470
+ self, A: torch.Tensor, B: torch.Tensor, dt: float = 1.0
471
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
472
+ """
473
+ Pytorch-specific implementation of discretization of a continuous-time
474
+ state space model using zero-order hold (ZOH) on the inputs.
475
+ """
476
+ em_upper = torch.cat((A, B), dim=1)
477
+ # Need to stack zeros under the a and b matrices
478
+ em_lower = torch.cat((
479
+ torch.zeros((B.shape[1], B.shape[0]), dtype=A.dtype, device=A.device),
480
+ torch.zeros((B.shape[1], B.shape[1]), dtype=A.dtype, device=A.device)
481
+ ), dim=1)
482
+
483
+ em = torch.cat((em_upper, em_lower), dim=0)
484
+ ms = torch.linalg.matrix_exp(dt * em)
485
+
486
+ # Dispose of the lower rows
487
+ ms = ms[:A.shape[0], :]
488
+
489
+ ad = ms[:, :A.shape[1]]
490
+ bd = ms[:, A.shape[1]:]
491
+
492
+ return ad, bd
493
+
494
+ def _gen_AB_base_matrices(self, order: int) -> Tuple[torch.Tensor, torch.Tensor]:
495
+ # Compute analog A/B matrices
496
+ Q = torch.arange(order, dtype=torch.float64)
497
+ R = (2 * Q + 1).unsqueeze(1)
498
+ i, j = torch.meshgrid(Q, Q, indexing="ij")
499
+ A = torch.where(i < j, -1, (-1.0) ** (i - j + 1)) * R
500
+ B = (-1.0) ** Q.unsqueeze(1) * R
501
+ return A, B
502
+
503
+ def _gen_AB(self, theta, dt=1.0) -> Tuple[torch.Tensor, torch.Tensor]:
504
+ # Discretize
505
+ Ad, Bd = self._pytorch_cont2discrete_zoh(self.A / theta, self.B / theta, dt)
506
+ return Ad.float(), Bd.float()
507
+
508
+ def _one_step(self, Ad, Bd, m, u):
509
+ m_prime = torch.einsum('dk,bk -> bd', Ad, m) + torch.einsum('dk,bk->bd', Bd, u)
510
+ return m_prime
511
+
512
+ def forward(self, x):
513
+ b, theta = x.shape
514
+ Ad, Bd = self._gen_AB(theta)
515
+
516
+ m = torch.zeros(b, self.d_model, dtype=x.dtype, device=x.device)
517
+ for i in range(theta):
518
+ u = x[:, i:i + 1]
519
+ m = self._one_step(Ad, Bd, m, u)
520
+
521
+ return m
522
+
523
+
524
+ class TimeDelayEmbedding(nn.Module):
525
+ def __init__(self, configs):
526
+ super(TimeDelayEmbedding, self).__init__()
527
+ self.patch_len = configs.patch_len
528
+ self.stride = configs.stride
529
+ self.Legendre_Memory = LegendreMemory(configs)
530
+
531
+ def _period_search(self, x):
532
+ xf = torch.fft.rfft(x, dim=-1)
533
+ # find period by amplitudes
534
+ frequency_list = abs(xf).mean(0)
535
+ frequency_list[0] = 0
536
+ _, top_list = torch.topk(frequency_list, 1)
537
+ top_list = top_list.detach().cpu().numpy()
538
+ period = x.shape[1] // top_list
539
+ return period
540
+
541
+ def _embedding(self, x, period=None):
542
+ if period is None:
543
+ period = list(self._period_search(x))[0]
544
+ patch_len = period
545
+ patches = x.unfold(dimension=-1, size=patch_len, step=patch_len)
546
+ b, n, p = patches.shape
547
+ patches = rearrange(patches, 'b n p -> (b n) p')
548
+
549
+ embedding = self.Legendre_Memory(patches)
550
+ embedding = rearrange(embedding, '(b n) d -> b n d', b=b, n=n)
551
+ return embedding
552
+
553
+ def forward(self, x, period=None, num_samples=1):
554
+ if not self.training and num_samples == 1:
555
+ return self._embedding(x, period=period)
556
+
557
+ if period is None:
558
+ period = list(self._period_search(x))[0]
559
+
560
+ seq_len = x.shape[-1]
561
+ period = period if period < seq_len else self.patch_len
562
+
563
+ padding_num = ((self.patch_len + period - 1) // period) * period - self.patch_len
564
+ padding_action = nn.ReplicationPad1d((padding_num, 0))
565
+ padded_x = padding_action(x)
566
+ new_patch_len = self.patch_len + padding_num
567
+ patches = padded_x.unfold(dimension=-1, size=new_patch_len, step=self.stride)
568
+ b, n, p = patches.shape
569
+ patches = rearrange(patches, 'b n p -> (b n) p')
570
+
571
+ embedding = self.Legendre_Memory(patches)
572
+ embedding = rearrange(embedding, '(b n) d -> b n d', b=b, n=n)
573
+ return embedding
574
+
575
+
576
+ class MixedEmbedding(nn.Module):
577
+ def __init__(self, configs):
578
+ super(MixedEmbedding, self).__init__()
579
+ self.configs = configs
580
+ self.patch_len = configs.patch_len
581
+ self.stride = configs.patch_len
582
+ self.d_model = configs.d_model
583
+
584
+ # TimeDelayEmbedding
585
+ self.time_delay_embedding = TimeDelayEmbedding(configs)
586
+
587
+ # PatchEmbedding
588
+ self.patch_embedding = PatchEmbedding(configs)
589
+
590
+ self.dropout = nn.Dropout(configs.dropout)
591
+
592
+ def _flex_embedding(self, x, inference_patch_len):
593
+ patch_len = inference_patch_len
594
+ seq_len = x.shape[-1]
595
+ patch_num = math.ceil((seq_len - patch_len) / patch_len) + 1
596
+ padding = patch_num * patch_len - seq_len
597
+ padding_patch_layer = nn.ReplicationPad1d((0, padding))
598
+ x = padding_patch_layer(x)
599
+
600
+ # [batch_size, patch_num, patch_size]
601
+ patches = x.unfold(dimension=-1, size=patch_len, step=patch_len)
602
+
603
+ proj = nn.Linear(patch_len, self.d_model, bias=False)
604
+ proj.weight.data = resample(old=self.patch_embedding.proj.weight.data, new_patch_len=patch_len)
605
+
606
+ patch_embedding = proj(patches)
607
+ time_delay_embedding = self.time_delay_embedding(x, period=patch_len, num_samples=1)
608
+ embedding = patch_embedding + time_delay_embedding
609
+ return embedding
610
+
611
+ def forward(self, x, inference_patch_len=48, num_samples=1):
612
+ # do patching
613
+ # padding for the original stride
614
+ if not self.training and num_samples == 1:
615
+ return self._flex_embedding(x, inference_patch_len)
616
+
617
+ seq_len = x.shape[-1]
618
+ patch_num = math.ceil((seq_len - self.patch_len) / self.stride) + 1
619
+ padding = self.patch_len + (patch_num - 1) * self.stride - seq_len
620
+ padding_patch_layer = nn.ReplicationPad1d((0, padding))
621
+ x = padding_patch_layer(x)
622
+
623
+ # [batch_size, patch_num, patch_size]
624
+ patches = x.unfold(dimension=-1, size=self.patch_len, step=self.stride)
625
+
626
+ # [batch_size, patch_num, d_model]
627
+ patch_embedding = self.patch_embedding(patches)
628
+
629
+ # [batch_size, patch_num, d_model]
630
+ time_delay_embedding = self.time_delay_embedding(x, num_samples=num_samples)
631
+
632
+ embedding = patch_embedding + time_delay_embedding
633
+
634
+ return self.dropout(embedding)
635
+
636
+
637
+ class FLAMEModel(nn.Module):
638
+ def __init__(self, configs):
639
+ super(FLAMEModel, self).__init__()
640
+ self.patch_len = configs.patch_len
641
+ configs.stride = configs.patch_len
642
+
643
+ self.embedding = MixedEmbedding(configs)
644
+
645
+ self.d_model = configs.d_model
646
+
647
+ self.encoder = TSTEncoder(configs)
648
+
649
+ self.decoder = MambaDecoder(configs)
650
+
651
+ self.proj = nn.Linear(configs.d_model, configs.patch_len, bias=False)
652
+ self.dropout = nn.Dropout(configs.head_dropout)
653
+
654
+ self.flow = zuko.flows.MAF(features=configs.patch_len, context=configs.d_model,
655
+ transforms=configs.couple_layers,
656
+ hidden_features=[configs.d_couple] * configs.couple_layers)
657
+ self.configs = configs
658
+
659
+ def _prob_head(self, dec_out):
660
+ tokens = rearrange(dec_out, 'b n d -> (b n) d')
661
+ dist = self.flow(tokens)
662
+ return dist
663
+
664
+ def _get_weights(self, n_preds, decay_rate=0.5):
665
+ """
666
+ Generate dynamic weights for the replicated tokens using an exponential decay scheme.
667
+
668
+ Args:
669
+ - n_preds (int): Number of predictions to generate weights for.
670
+ - decay_rate (float): The base of the exponential decay. Lower values decay faster (default: 0.9).
671
+
672
+ Returns:
673
+ - torch.Tensor: A tensor of weights with exponential decay.
674
+ """
675
+ # Exponential decay weights
676
+ weights = decay_rate ** torch.arange(n_preds)
677
+ return weights
678
+
679
+ def forward(self, input, target=None, pred_len=None, inference_patch_len=48, num_samples=1):
680
+ if not self.training:
681
+ return self._predict(input, pred_len=pred_len, inference_patch_len=inference_patch_len,
682
+ num_samples=num_samples)
683
+ else:
684
+ return self._loss(input=input, target=target)
685
+
686
+ def _loss(self, input, target, eps=1e2):
687
+ # forward
688
+ pred_len = input.shape[-1]
689
+ x_enc = self.embedding(input)
690
+
691
+ x_enc = self.encoder(x_enc)
692
+ x_rec = rearrange(x_enc, 'b n p -> b (n p)')
693
+
694
+ predict_token_num = math.ceil(pred_len / self.patch_len)
695
+ weights = self._get_weights(predict_token_num).unsqueeze(0).unsqueeze(-1).to(input.device)
696
+ last_token = x_enc[:, -1:, :]
697
+ x_enc = weights * last_token.repeat(1, predict_token_num, 1)
698
+ # decoding
699
+ x_dec = self.decoder(x_enc, x_rec)
700
+
701
+ dec_out = self.proj(self.dropout(x_dec))
702
+
703
+ point_forecasts = rearrange(dec_out, 'b n p -> b (n p)')
704
+
705
+ forecasts = point_forecasts[:, :pred_len]
706
+
707
+ dist = self._prob_head(x_dec.detach())
708
+
709
+ # calculate loss
710
+ point_loss = self.point_loss(forecasts, target)
711
+ rec_loss = self.point_loss(x_rec, input)
712
+ transformed_target = rearrange(target, 'b (n p) c -> (b c n) p', p=self.patch_len)
713
+ raw_prob_loss = -dist.log_prob(transformed_target)
714
+ mask = raw_prob_loss < eps
715
+ raw_prob_loss = torch.where(mask, raw_prob_loss, torch.zeros_like(raw_prob_loss))
716
+
717
+ prob_loss = raw_prob_loss.mean() / self.patch_len
718
+
719
+ return point_loss + rec_loss + prob_loss
720
+
721
+ def _predict(self, input, pred_len, inference_patch_len=48, num_samples=None):
722
+ if num_samples is not None and num_samples > 1:
723
+ return self._prob_predict(input, pred_len, num_samples)
724
+
725
+ x_enc = self.embedding(input, inference_patch_len, num_samples=1)
726
+
727
+ x_rec = self.encoder(x_enc)
728
+
729
+ predict_token_num = math.ceil(pred_len / inference_patch_len)
730
+ weights = self._get_weights(predict_token_num).unsqueeze(0).unsqueeze(-1).to(input.device)
731
+ last_token = x_rec[:, -1:, :]
732
+ x_enc = weights * last_token.repeat(1, predict_token_num, 1)
733
+ # decoding
734
+ x_dec = self.decoder(x_enc, x_rec)
735
+
736
+ proj = nn.Linear(self.d_model, inference_patch_len, bias=False)
737
+ proj.weight.data = resample(old=self.proj.weight.data.T,
738
+ new_patch_len=inference_patch_len).T
739
+
740
+ dec_out = proj(x_dec)
741
+ point_forecasts = rearrange(dec_out, 'b n p -> b (n p)')
742
+ return point_forecasts[:, :pred_len]
743
+
744
+ def _prob_predict(self, input, pred_len, num_samples=None):
745
+
746
+ x_enc = self.embedding(input, num_samples=num_samples)
747
+
748
+ x_rec = self.encoder(x_enc)
749
+
750
+ predict_token_num = math.ceil(pred_len / self.patch_len)
751
+ weights = self._get_weights(predict_token_num).unsqueeze(0).unsqueeze(-1).to(input.device)
752
+ last_token = x_rec[:, -1:, :]
753
+ x_enc = weights * last_token.repeat(1, predict_token_num, 1)
754
+ # decoding
755
+ x_dec = self.decoder(x_enc, x_rec)
756
+
757
+ dist = self._prob_head(x_dec)
758
+
759
+ samples = dist.sample((num_samples,))
760
+ samples = rearrange(samples, 's (b n) p -> b s (n p) ', n=predict_token_num)[:, :, :pred_len]
761
+
762
+ prob_forecasts = samples
763
+
764
+ return prob_forecasts
765
+
766
+
767
+ class FLAMEPretrainedModel(PreTrainedModel):
768
+ config_class = FLAMEConfig
769
+ base_model_prefix = "model"
770
+ supports_gradient_checkpointing = True
771
+ _no_split_modules = ["TSTEncoder", "MambaDecoder"]
772
+ _supports_flash_attn_2 = True
773
+ _supports_sdpa = False
774
+ _supports_cache_class = False
775
+
776
+
777
+ class FLAMEForPrediction(FLAMEPretrainedModel, TSGenerationMixin):
778
+ def __init__(self, config: FLAMEConfig):
779
+ super().__init__(config)
780
+ self.config = config
781
+ self.model = FLAMEModel(config)
782
+
783
+ def set_decoder(self, decoder):
784
+ self.model = decoder
785
+
786
+ def get_decoder(self):
787
+ return self.model
788
+
789
+ def forward(
790
+ self,
791
+ input_ids: torch.FloatTensor = None,
792
+ labels: Optional[torch.FloatTensor] = None,
793
+ max_output_length: Optional[int] = None,
794
+ revin: Optional[bool] = True,
795
+ num_samples: Optional[int] = 1,
796
+ inference_patch_len: Optional[int] = 48,
797
+ ):
798
+ if revin:
799
+ means = input_ids.mean(1, keepdim=True).detach()
800
+ stdev = input_ids.std(dim=1, keepdim=True, unbiased=False).detach() + 1e-5
801
+ input_ids = (input_ids - means) / stdev
802
+
803
+ outputs = self.model(
804
+ input=input_ids,
805
+ target=labels,
806
+ inference_patch_len=inference_patch_len,
807
+ num_samples=num_samples,
808
+ pred_len=max_output_length
809
+ )
810
+
811
+ loss = None
812
+ if labels is not None:
813
+ loss = outputs
814
+ else:
815
+ forecasts = outputs
816
+
817
+ if forecasts.ndim == 2:
818
+ forecasts = forecasts.unsqueeze(1)
819
+ forecasts = forecasts.repeat(1, num_samples, 1)
820
+ if revin:
821
+ stdev = stdev.unsqueeze(1).repeat(1, num_samples, 1)
822
+ means = means.unsqueeze(1).repeat(1, num_samples, 1)
823
+ forecasts = (forecasts * stdev) + means
824
+
825
+ return MoeCausalLMOutputWithPast(
826
+ loss=loss,
827
+ logits=forecasts,
828
+ )
ts_generation_mixin.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict, List, Optional, Union, Callable
2
+
3
+ import torch
4
+ from transformers import GenerationMixin, LogitsProcessorList, StoppingCriteriaList
5
+ from transformers.generation.utils import GenerationConfig, GenerateOutput
6
+ from transformers.utils import ModelOutput
7
+
8
+
9
+ class TSGenerationMixin(GenerationMixin):
10
+ @torch.no_grad()
11
+ def generate(
12
+ self,
13
+ inputs: Optional[torch.Tensor] = None,
14
+ generation_config: Optional[GenerationConfig] = None,
15
+ logits_processor: Optional[LogitsProcessorList] = None,
16
+ stopping_criteria: Optional[StoppingCriteriaList] = None,
17
+ prefix_allowed_tokens_fn: Optional[Callable[[int, torch.Tensor], List[int]]] = None,
18
+ synced_gpus: Optional[bool] = None,
19
+ assistant_model: Optional["PreTrainedModel"] = None,
20
+ streamer: Optional["BaseStreamer"] = None,
21
+ negative_prompt_ids: Optional[torch.Tensor] = None,
22
+ negative_prompt_attention_mask: Optional[torch.Tensor] = None,
23
+ revin: Optional[bool] = True,
24
+ num_samples: Optional[int] = 1,
25
+ max_output_length: Optional[int] = 96,
26
+ inference_patch_len: Optional[int] = 48,
27
+ **kwargs,
28
+ ) -> Union[GenerateOutput, torch.Tensor]:
29
+ if len(inputs.shape) != 2:
30
+ raise ValueError('Input shape must be: [batch_size, seq_len]')
31
+ if revin:
32
+ means = inputs.mean(dim=-1, keepdim=True)
33
+ stdev = inputs.std(dim=-1, keepdim=True, unbiased=False) + 1e-5
34
+ inputs = (inputs - means) / stdev
35
+
36
+ model_inputs = {
37
+ "input_ids": inputs,
38
+ "max_output_length": max_output_length,
39
+ "revin": False,
40
+ "num_samples": num_samples,
41
+ "inference_patch_len": inference_patch_len,
42
+ }
43
+
44
+ outputs = self(**model_inputs)
45
+
46
+ predictions = outputs.logits
47
+
48
+ if revin:
49
+ stdev = stdev.unsqueeze(1).repeat(1, num_samples, 1)
50
+ means = means.unsqueeze(1).repeat(1, num_samples, 1)
51
+ predictions = (predictions * stdev) + means
52
+
53
+ return predictions
54
+
55
+ def _update_model_kwargs_for_generation(
56
+ self,
57
+ outputs: ModelOutput,
58
+ model_kwargs: Dict[str, Any],
59
+ horizon_length: int = 1,
60
+ is_encoder_decoder: bool = False,
61
+ standardize_cache_format: bool = False,
62
+ ) -> Dict[str, Any]:
63
+ return model_kwargs