fuyisong commited on
Commit
015f461
·
verified ·
1 Parent(s): 073af79

add modeling_zeus.py

Browse files
Files changed (1) hide show
  1. modeling_zeus.py +759 -0
modeling_zeus.py ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import torch
3
+ from torch import nn
4
+ import math
5
+ from typing import Tuple, Optional
6
+ from transformers import PreTrainedModel
7
+ from .configuration_zeus import ZeusConfig
8
+ from basicts.modules import ACT2FN
9
+ from basicts.modules.transformer import DecoderOnlyLayer, MultiHeadAttention, RotaryPositionEmbedding, AutoRegressiveDecoder
10
+ from basicts.modules.norm import RMSNorm
11
+ from flash_attn import flash_attn_varlen_func
12
+ from flash_attn.bert_padding import unpad_input, pad_input
13
+
14
+
15
+ class ZeusFlashAttention(nn.Module):
16
+ """
17
+ Encoder-only (BERT-style) Multi-Head Attention with FlashAttention v2
18
+ """
19
+ def __init__(
20
+ self,
21
+ hidden_size: int,
22
+ n_heads: int,
23
+ dropout: float = 0.0,
24
+ kv_heads: Optional[int] = None,
25
+ rope: Optional[torch.nn.Module] = None,
26
+ ):
27
+ super().__init__()
28
+ assert hidden_size % n_heads == 0
29
+
30
+ self.hidden_size = hidden_size
31
+ self.n_heads = n_heads
32
+ self.head_size = hidden_size // n_heads
33
+
34
+ self.q_proj = nn.Linear(hidden_size, hidden_size)
35
+ self.k_proj = nn.Linear(hidden_size, hidden_size)
36
+ self.v_proj = nn.Linear(hidden_size, hidden_size)
37
+ self.out_proj = nn.Linear(hidden_size, hidden_size, bias=False)
38
+
39
+ self.dropout_p = dropout
40
+ self.rope = rope
41
+
42
+ def _shape(self, x: torch.Tensor, B: int, L: int) -> torch.Tensor:
43
+ # [B, L, H*D] -> [B, L, H, D]
44
+ return x.view(B, L, self.n_heads, self.head_size)
45
+
46
+ def forward(
47
+ self,
48
+ hidden_states: torch.Tensor,
49
+ attention_mask: Optional[torch.Tensor] = None,
50
+ position_ids: Optional[torch.LongTensor] = None,
51
+ past_key_value: Optional[object] = None,
52
+ use_cache: bool = False,
53
+ output_attentions: bool = False,
54
+ layer_idx: Optional[int] = None,
55
+ ):
56
+ assert not output_attentions, \
57
+ "FlashAttention v2 does not support returning attention weights efficiently."
58
+
59
+ B, L, _ = hidden_states.shape
60
+ device = hidden_states.device
61
+
62
+ q = self._shape(self.q_proj(hidden_states), B, L)
63
+ k = self._shape(self.k_proj(hidden_states), B, L)
64
+ v = self._shape(self.v_proj(hidden_states), B, L)
65
+
66
+ if attention_mask is None:
67
+ mask = torch.ones((B, L), device=device, dtype=torch.bool)
68
+
69
+ q_unpad, indices, cu_seqlens, max_seqlen, _ = unpad_input(q, attention_mask)
70
+ k_unpad, _, _, _, _ = unpad_input(k, attention_mask)
71
+ v_unpad, _, _, _, _ = unpad_input(v, attention_mask)
72
+
73
+ if self.rope is not None:
74
+ if position_ids is None:
75
+ position_ids = torch.arange(L, device=device).unsqueeze(0).expand(B, -1)
76
+ pos = position_ids.reshape(-1)[indices]
77
+ q_unpad, k_unpad = self.rope(q_unpad, k_unpad, pos)
78
+
79
+ dropout_p = self.dropout_p if self.training else 0.0
80
+
81
+ attn_unpad = flash_attn_varlen_func(
82
+ q_unpad,
83
+ k_unpad,
84
+ v_unpad,
85
+ cu_seqlens_q=cu_seqlens,
86
+ cu_seqlens_k=cu_seqlens,
87
+ max_seqlen_q=max_seqlen,
88
+ max_seqlen_k=max_seqlen,
89
+ dropout_p=dropout_p,
90
+ causal=False,
91
+ )
92
+
93
+ attn_unpad = attn_unpad.reshape(-1, self.hidden_size)
94
+ context = pad_input(attn_unpad, indices, B, L)
95
+
96
+ output = self.out_proj(context)
97
+
98
+ return output, None, past_key_value
99
+
100
+
101
+ class ZeusMLP(nn.Module):
102
+
103
+ def __init__(self, hidden_size: int, intermediate_size: int, hidden_act: str):
104
+ super().__init__()
105
+ self.hidden_size = hidden_size
106
+ self.intermediate_size = intermediate_size
107
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
108
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
109
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
110
+ self.act_fn = ACT2FN[hidden_act]
111
+
112
+ def forward(self, hidden_state):
113
+ return self.down_proj(self.act_fn(self.gate_proj(hidden_state)) * self.up_proj(hidden_state))
114
+
115
+
116
+ class ZeusInputEmbedding(nn.Module):
117
+
118
+ def __init__(self, input_size: int, hidden_size: int, hidden_act: str = "gelu"):
119
+ super().__init__()
120
+ self.input_size = input_size
121
+ self.hidden_size = hidden_size
122
+ self.intermediate_size = 4 * self.hidden_size
123
+ self.res_proj = nn.Linear(self.input_size, self.hidden_size, bias=False)
124
+ self.gate_proj = nn.Linear(self.input_size, self.intermediate_size, bias=True)
125
+ self.up_proj = nn.Linear(self.input_size, self.intermediate_size, bias=True)
126
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
127
+ self.act_fn = ACT2FN[hidden_act]
128
+
129
+ def forward(self, x: torch.Tensor):
130
+ return self.res_proj(x) + \
131
+ self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
132
+
133
+
134
+ class EncoderLayer(DecoderOnlyLayer):
135
+ def __init__(self, config: ZeusConfig, stage: int):
136
+
137
+ attn_cls = ZeusFlashAttention \
138
+ if config.attn_implementation == "flash_attention_2" else MultiHeadAttention
139
+
140
+ self_attn = attn_cls(
141
+ hidden_size=config.hidden_size[stage],
142
+ n_heads=config.n_heads[stage],
143
+ dropout=config.dropout,
144
+ rope=RotaryPositionEmbedding(
145
+ dim=config.hidden_size[stage] // config.n_heads[stage],
146
+ max_position_embeddings=4096
147
+ )
148
+ )
149
+ ffn_layer = ZeusMLP(
150
+ config.hidden_size[stage],
151
+ config.intermediate_size[stage],
152
+ config.hidden_act
153
+ )
154
+ super().__init__(self_attn, ffn_layer, (RMSNorm, config.hidden_size[stage]))
155
+
156
+
157
+ class ZeusEncoder(AutoRegressiveDecoder):
158
+ def __init__(self, config: ZeusConfig, stage: int):
159
+
160
+ decoder_layers = nn.ModuleList(
161
+ [
162
+ EncoderLayer(config, stage)
163
+ for _ in range(config.num_layers[stage])
164
+ ]
165
+ )
166
+
167
+ layer_norm = RMSNorm(config.hidden_size[stage])
168
+ super().__init__(decoder_layers, layer_norm)
169
+
170
+ self.num_reg_tokens = config.num_reg_tokens
171
+
172
+ if self.num_reg_tokens > 0:
173
+ self.reg_tokens = nn.Parameter(
174
+ torch.randn(
175
+ 1, self.num_reg_tokens, config.hidden_size[stage]
176
+ ) * config.initializer_range
177
+ )
178
+
179
+ def forward(
180
+ self,
181
+ hidden_states: torch.Tensor,
182
+ attention_mask: torch.Tensor | None = None,
183
+ **kwargs
184
+ ):
185
+
186
+ B, L, _ = hidden_states.size()
187
+ position_ids = torch.arange(
188
+ L,
189
+ dtype=torch.long,
190
+ device=hidden_states.device
191
+ ).unsqueeze(0)
192
+
193
+ if self.num_reg_tokens > 0:
194
+ reg_tokens = self.reg_tokens.expand(B, -1, -1)
195
+ hidden_states = torch.cat(
196
+ [reg_tokens, hidden_states], dim=1
197
+ )
198
+ position_ids = torch.cat(
199
+ [torch.zeros(
200
+ 1, self.num_reg_tokens,
201
+ dtype=torch.long,
202
+ device=hidden_states.device
203
+ ), position_ids], dim=1
204
+ )
205
+
206
+ hidden_states, attn_weights, kv_cache = super().forward(
207
+ hidden_states=hidden_states,
208
+ attention_mask=attention_mask,
209
+ position_ids=position_ids.expand(B, -1),
210
+ **kwargs
211
+ )
212
+
213
+ reg_tokens = hidden_states[:, :self.num_reg_tokens]
214
+ hidden_states = hidden_states[:, self.num_reg_tokens:]
215
+
216
+ return hidden_states, attn_weights, kv_cache, reg_tokens
217
+
218
+ class ZeusPoolingLayer(nn.Module):
219
+
220
+ def __init__(self, config: ZeusConfig, stage: int):
221
+ super().__init__()
222
+ self.stage = stage
223
+ self.config = config
224
+ self.factor = config.scales[stage] // config.scales[stage - 1]
225
+ self.proj = nn.Linear(
226
+ self.factor * config.hidden_size[stage - 1],
227
+ config.hidden_size[stage],
228
+ bias=False
229
+ )
230
+
231
+ def forward(self, hidden_states: torch.Tensor, padding_mask: torch.Tensor):
232
+ batch_size, _, hidden_size = hidden_states.size()
233
+ hidden_states = hidden_states.reshape(batch_size, -1, self.factor * hidden_size)
234
+ hidden_states = self.proj(hidden_states)
235
+ padding_mask = padding_mask.reshape(batch_size, -1, self.factor, 1).any(dim=2)
236
+ return hidden_states, padding_mask
237
+
238
+ class ZeusUnpoolingLayer(nn.Module):
239
+
240
+ def __init__(self, config: ZeusConfig, stage: int):
241
+ super().__init__()
242
+ self.stage = stage
243
+ self.config = config
244
+ self.factor = config.scales[stage - 1] // config.scales[stage]
245
+ self.proj = nn.Linear(
246
+ config.hidden_size[stage - 1],
247
+ self.factor * config.hidden_size[stage],
248
+ bias=False
249
+ )
250
+
251
+ def forward(self, hidden_states: torch.Tensor, skip_connection: torch.Tensor):
252
+ batch_size, _, hidden_size = skip_connection.size()
253
+ hidden_states = self.proj(hidden_states)
254
+ hidden_states = hidden_states.reshape(batch_size, -1, hidden_size)
255
+ hidden_states = hidden_states + skip_connection
256
+ return hidden_states
257
+
258
+ class ZeusPreTrainedModel(PreTrainedModel):
259
+ config_class = ZeusConfig
260
+
261
+ def _init_weights(self, module):
262
+ std = self.config.initializer_range
263
+ if isinstance(module, torch.nn.Linear):
264
+ module.weight.data.normal_(mean=0.0, std=std)
265
+ if module.bias is not None:
266
+ module.bias.data.zero_()
267
+ elif isinstance(module, torch.nn.Embedding):
268
+ module.weight.data.normal_(mean=0.0, std=std)
269
+ if module.padding_idx is not None:
270
+ module.weight.data[module.padding_idx].zero_()
271
+
272
+
273
+ class Zeus(ZeusPreTrainedModel):
274
+
275
+ _supports_flash_attn_2 = True
276
+
277
+ def __init__(self, config: ZeusConfig):
278
+ super().__init__(config)
279
+ self.config = config
280
+ self.scales = config.scales
281
+ self.num_reg_tokens = config.num_reg_tokens
282
+ self.num_scales = len(self.scales)
283
+
284
+ self.input_mlp = ZeusInputEmbedding(
285
+ config.input_dim,
286
+ config.hidden_size[0],
287
+ config.hidden_act
288
+ )
289
+
290
+ self.special_tokens = nn.Embedding(2, config.hidden_size[0])
291
+ self.pad_token_id = 0
292
+ self.mask_token_id = 1
293
+
294
+ self.encoders = nn.ModuleList()
295
+ self.downsamplers = nn.ModuleList()
296
+ self.upsamplers = nn.ModuleList()
297
+
298
+ # first layer
299
+ self.encoders.append(ZeusEncoder(config, 0))
300
+
301
+ # down samplers
302
+ for i in range(1, self.num_scales // 2 + 1):
303
+ self.encoders.append(ZeusEncoder(config, i))
304
+ self.downsamplers.append(ZeusPoolingLayer(config, i))
305
+
306
+ for i in range(self.num_scales // 2 + 1, self.num_scales):
307
+ self.encoders.append(ZeusEncoder(config, i))
308
+ self.upsamplers.append(ZeusUnpoolingLayer(config, i))
309
+
310
+ self.num_quantiles = len(config.quantiles)
311
+ quantiles = torch.tensor(config.quantiles)
312
+ self.register_buffer("quantiles", quantiles, persistent=False)
313
+ self.head = nn.Linear(config.hidden_size[-1], self.num_quantiles)
314
+
315
+ self.post_init()
316
+
317
+ def _prepare_embedding(
318
+ self,
319
+ inputs: torch.Tensor,
320
+ targets_mask: torch.Tensor,
321
+ padding_mask: torch.Tensor = None,
322
+ ):
323
+
324
+ B, L, _ = inputs.shape
325
+ input_embeds = self.input_mlp(inputs) # [B, L, D]
326
+
327
+ is_target = targets_mask == 1
328
+ input_embeds = torch.where(
329
+ is_target,
330
+ self.special_tokens(
331
+ torch.full_like(targets_mask.squeeze(-1), self.mask_token_id)
332
+ ),
333
+ input_embeds)
334
+
335
+ if padding_mask is not None:
336
+ is_padding = padding_mask == 0
337
+ input_embeds = torch.where(
338
+ is_padding,
339
+ self.special_tokens(
340
+ torch.full_like(padding_mask.squeeze(-1), self.pad_token_id)
341
+ ),
342
+ input_embeds)
343
+ if padding_mask is None:
344
+ padding_mask = torch.ones(
345
+ (B, L, 1), device=input_embeds.device, dtype=torch.long)
346
+
347
+ # pad
348
+ max_scale = max(self.scales)
349
+ pad_len = math.ceil(L / max_scale) * max_scale - L
350
+ if pad_len > 0:
351
+ pad_tokens = self.special_tokens(
352
+ torch.full(
353
+ (B, pad_len),
354
+ self.pad_token_id,
355
+ device=input_embeds.device
356
+ )
357
+ )
358
+
359
+ input_embeds = torch.cat(
360
+ [input_embeds, pad_tokens],dim=1)
361
+
362
+ padding_mask = torch.cat(
363
+ [
364
+ padding_mask,
365
+ torch.zeros(
366
+ (B, pad_len, 1),
367
+ device=input_embeds.device,
368
+ dtype=padding_mask.dtype)
369
+ ],
370
+ dim=1
371
+ )
372
+
373
+ return input_embeds, padding_mask
374
+
375
+ def _prepare_attn_mask(
376
+ self,
377
+ hidden_states: torch.Tensor,
378
+ padding_mask: torch.Tensor = None,
379
+ ):
380
+ device = hidden_states.device
381
+ B, L, _ = hidden_states.shape
382
+
383
+ if padding_mask is None:
384
+ padding_mask = torch.ones(
385
+ (B, L, 1), device=device, dtype=torch.long)
386
+
387
+ # reg tokens
388
+ if self.num_reg_tokens > 0:
389
+ attention_mask = torch.cat(
390
+ [
391
+ torch.ones(
392
+ (B, self.num_reg_tokens, 1),
393
+ device=device,
394
+ dtype=padding_mask.dtype
395
+ ),
396
+ padding_mask
397
+ ],
398
+ dim=1
399
+ )
400
+ else:
401
+ attention_mask = padding_mask
402
+
403
+ if self.config.attn_implementation == "eager":
404
+ attention_mask = attention_mask.view(B, 1, 1, -1) # [B, 1, 1, L]
405
+ attention_mask = (1 - attention_mask.float()) * torch.finfo(hidden_states.dtype).min
406
+ else:
407
+ attention_mask = attention_mask.squeeze(-1) # [B, L]
408
+ return attention_mask
409
+
410
+ def forward(
411
+ self,
412
+ inputs: torch.Tensor,
413
+ targets_mask: Optional[torch.Tensor],
414
+ targets: Optional[torch.Tensor] = None,
415
+ padding_mask: Optional[torch.Tensor] = None,
416
+ return_all_hidden_states: bool = False
417
+ ):
418
+ """
419
+ x: [B, L, 1]
420
+ padding_mask: [B, L, 1] (0 for padding, 1 for valid)
421
+ target_mask: [B, L, 1] (1 for target/predict, 0 for context)
422
+ """
423
+
424
+ # embedding
425
+ ori_seq_len = inputs.shape[1]
426
+ ori_padding_mask = padding_mask
427
+ hidden_states, padding_mask = self._prepare_embedding(inputs, targets_mask, padding_mask)
428
+
429
+ scale_outputs = []
430
+ scale_padding_masks = []
431
+ all_hidden_states = []
432
+ reg_token_emb = None
433
+
434
+ for i in range(self.num_scales):
435
+
436
+ if i > 0:
437
+
438
+ # pooling
439
+ if i <= self.num_scales // 2:
440
+ scale_padding_masks.append(padding_mask)
441
+ hidden_states, padding_mask = self.downsamplers[i - 1](hidden_states, padding_mask)
442
+
443
+ # unpooling
444
+ else: # i > self.num_scales // 2
445
+ idx = i - self.num_scales // 2 - 1
446
+ hidden_states = self.upsamplers[idx](hidden_states, scale_outputs[self.num_scales - i - 1])
447
+ padding_mask = scale_padding_masks[self.num_scales - i - 1]
448
+
449
+ attention_mask = self._prepare_attn_mask(hidden_states, padding_mask)
450
+
451
+ hidden_states, _, _, reg_tokens = self.encoders[i](
452
+ hidden_states,
453
+ attention_mask=attention_mask
454
+ )
455
+
456
+ if i == self.num_scales - 2:
457
+ reg_token_emb = reg_tokens.mean(dim=1)
458
+
459
+ if return_all_hidden_states:
460
+ all_hidden_states.append(hidden_states)
461
+
462
+ if i < self.num_scales:
463
+ scale_outputs.append(hidden_states)
464
+
465
+ # [B, L, D] -> [B, L, Q]
466
+ quantile_preds = self.head(hidden_states)[:, :ori_seq_len, :]
467
+
468
+ loss = 0.0
469
+ # target and not nan
470
+ if targets is not None:
471
+ loss_mask = (targets_mask * ori_padding_mask).float()
472
+ quantiles = self.quantiles.view(1, 1, self.num_quantiles).to(quantile_preds.dtype)
473
+ loss = 2 * torch.abs((targets - quantile_preds)
474
+ * ((targets <= quantile_preds).float() - quantiles))
475
+ loss = loss * loss_mask
476
+ loss = loss.sum() / (loss_mask.sum() * self.num_quantiles)
477
+
478
+ return {
479
+ "prediction": quantile_preds,
480
+ "loss": loss,
481
+ "all_hidden_states": all_hidden_states,
482
+ "reg_token_emb": reg_token_emb,
483
+ }
484
+
485
+
486
+ class ZeusForPrediction(Zeus):
487
+
488
+ def __init__(self, config: ZeusConfig):
489
+ super().__init__(config)
490
+
491
+ def generate(
492
+ self,
493
+ context: torch.Tensor,
494
+ prediction_length: int,
495
+ context_mask: torch.Tensor = None,
496
+ use_norm: bool = True
497
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
498
+
499
+ context = context.to(self.device)
500
+
501
+ ndim = context.ndim
502
+ num_features = None
503
+ if ndim == 2:
504
+ context = context.unsqueeze(-1)
505
+ elif ndim == 3 and context.shape[2] > 1:
506
+ _, L, num_features = context.shape
507
+ context = context.transpose(1, 2).view(-1, L, 1)
508
+ elif ndim == 1:
509
+ context = context.unsqueeze(0).unsqueeze(2)
510
+
511
+ B, L, _ = context.shape
512
+ device = context.device
513
+
514
+ if use_norm:
515
+ mean = context.mean(dim=1, keepdim=True)
516
+ std = context.std(dim=1, keepdim=True)
517
+ context = (context - mean) / std
518
+ context = torch.arcsinh(context)
519
+
520
+ inputs = torch.cat(
521
+ [context, torch.zeros(B, prediction_length, 1, device=device)], dim=1)
522
+ if context_mask is None:
523
+ context_mask = torch.torch.ones(B, L, 1, device=device, dtype=torch.int32)
524
+ padding_mask = torch.cat(
525
+ [
526
+ context_mask,
527
+ torch.ones(B, prediction_length, 1, dtype=torch.int32, device=device)
528
+ ], dim=1
529
+ )
530
+ targets_mask = torch.cat(
531
+ [
532
+ torch.zeros_like(context, dtype=torch.int32),
533
+ torch.ones(B, prediction_length, 1, dtype=torch.int32, device=device)
534
+ ], dim=1
535
+ )
536
+
537
+ with torch.autocast("cuda", dtype=torch.bfloat16):
538
+ outputs = self.forward(
539
+ inputs,
540
+ padding_mask=padding_mask,
541
+ targets_mask=targets_mask,
542
+ )
543
+
544
+ # [B, L, Q]
545
+ quantile_preds = outputs["prediction"][:, -prediction_length:, :]
546
+
547
+ if use_norm:
548
+ quantile_preds = torch.sinh(quantile_preds)
549
+ quantile_preds = quantile_preds * std + mean
550
+
551
+ # [B, L, 1]
552
+ prediction = quantile_preds.mean(dim=-1, keepdim=True)
553
+
554
+ if ndim == 2: # [B, L]
555
+ prediction = prediction.squeeze(-1)
556
+ elif ndim == 3 and num_features is not None:
557
+ # [B, L, N]
558
+ prediction = prediction.reshape(-1, num_features, prediction_length).transpose(1, 2)
559
+ prediction = quantile_preds.reshape(
560
+ -1, num_features, prediction_length, quantile_preds.shape[-1]
561
+ ).transpose(1, 2) # [B, L, N, Q]
562
+ elif ndim == 1:
563
+ prediction = prediction[0, :, 0] #[L,]
564
+ quantile_preds = quantile_preds[0] # [L, Q]
565
+
566
+ return prediction, quantile_preds
567
+
568
+ def predict(
569
+ self,
570
+ context,
571
+ prediction_length,
572
+ use_norm: bool = True,
573
+ max_pred_len: int = 4096
574
+ ):
575
+
576
+ B = len(context)
577
+
578
+ series = []
579
+ Ns = []
580
+ for x in context:
581
+ if x.ndim == 1: # [L] -> [1, L]
582
+ x = x[None, :]
583
+ else: # [L, N] -> [N, L]
584
+ x = x.T
585
+ series.append(x)
586
+ Ns.append(x.shape[0])
587
+
588
+ assert len(set(Ns)) == 1, "All arrays must have same N"
589
+ N = Ns[0]
590
+
591
+ padded = []
592
+ target_masks = []
593
+ for x in series: # x: [N, L]
594
+ N_, L = x.shape
595
+ pad = np.full((N_, prediction_length), np.nan)
596
+ padded.append(np.concatenate([x, pad], axis=1)) # [N, L+F]
597
+
598
+ m = np.zeros((N_, L + prediction_length), dtype=bool)
599
+ m[:, L:] = 1
600
+ target_masks.append(m)
601
+
602
+ batch = []
603
+ # pad_masks = []
604
+ tgt_masks = []
605
+
606
+ for x, tm in zip(padded, target_masks):
607
+ N_, Lf = x.shape
608
+ if Lf >= max_pred_len:
609
+ x = x[:, -max_pred_len:]
610
+ tm = tm[:, -max_pred_len:]
611
+ # pm = np.ones((N_, max_pred_len), dtype=bool)
612
+ else:
613
+ pad_len = max_pred_len - Lf
614
+ x = np.concatenate([x, np.full((N_, pad_len), np.nan)], axis=1)
615
+ tm = np.concatenate([tm, np.zeros((N_, pad_len), bool)], axis=1)
616
+ # pm = np.concatenate([np.ones((N_, Lf)), np.zeros((N_, pad_len))], axis=1)
617
+
618
+ batch.append(x)
619
+ tgt_masks.append(tm)
620
+ # pad_masks.append(pm)
621
+
622
+ # [B, N, T] -> [B*N, T]
623
+ batch = np.stack(batch).reshape(B * N, max_pred_len, 1)
624
+ tgt_masks = np.stack(tgt_masks).reshape(B * N, max_pred_len, 1)
625
+ # pad_masks = np.stack(pad_masks).reshape(B * N, max_pred_len, 1)
626
+ pad_masks = (
627
+ (~np.isnan(batch))
628
+ | (tgt_masks.astype(bool))
629
+ ).astype(np.int32)
630
+
631
+ if use_norm:
632
+ mean = np.nanmean(batch, axis=1, keepdims=True)
633
+ std = np.nanstd(batch, axis=1, keepdims=True)
634
+ mean[np.isnan(mean)] = 0.0
635
+ std[np.isnan(std)] = 1.0
636
+ std[std < 1e-3] = 1.0
637
+ batch_norm = (batch - mean) / std
638
+ batch_norm = np.nan_to_num(batch_norm, nan=0.0)
639
+ batch_norm = np.arcsinh(batch_norm)
640
+ else:
641
+ batch_norm = np.nan_to_num(batch, nan=0.0)
642
+
643
+ x = torch.from_numpy(batch_norm).to(self.device).float() # [B*N, T]
644
+ padding_mask = torch.from_numpy(pad_masks).int().to(self.device)
645
+ targets_mask = torch.from_numpy(tgt_masks).int().to(self.device)
646
+
647
+ # prediction: [B*N, T]
648
+ # quantile_prediction: [B*N, T, Q]
649
+ with torch.autocast("cuda", dtype=torch.bfloat16):
650
+ outputs = self.forward(
651
+ x,
652
+ padding_mask=padding_mask,
653
+ targets_mask=targets_mask,
654
+ )
655
+
656
+ quantile_preds = outputs["prediction"].float().detach().cpu().numpy() # [B*N, T, Q]
657
+ if use_norm:
658
+ quantile_preds = np.sinh(quantile_preds) * std + mean
659
+ quantile_preds = quantile_preds[tgt_masks.repeat(self.num_quantiles, axis=2)].reshape(B, N, prediction_length, self.num_quantiles)
660
+
661
+ preds = quantile_preds.mean(axis=-1)
662
+
663
+ if N == 1:
664
+ preds = preds[:, 0, :]
665
+ quantile_preds = quantile_preds[:, 0, :, :]
666
+
667
+ return preds, quantile_preds
668
+
669
+
670
+ class ZeusForImputation(Zeus):
671
+ def __init__(self, config: ZeusConfig):
672
+ super().__init__(config)
673
+
674
+ def generate(
675
+ self,
676
+ inputs: torch.Tensor,
677
+ targets_mask: torch.Tensor,
678
+ use_norm: bool = True
679
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
680
+
681
+ # transform inputs and targets_mask to [B * N, L, 1]
682
+ ndim = inputs.ndim
683
+ num_features = None
684
+ if ndim == 2:
685
+ inputs = inputs.unsqueeze(-1)
686
+ targets_mask = targets_mask.unsqueeze(-1)
687
+ elif ndim == 3 and inputs.shape[2] > 1:
688
+ _, L, num_features = inputs.shape
689
+ inputs = inputs.transpose(1, 2).reshape(-1, L, 1)
690
+ targets_mask = targets_mask.transpose(1, 2).reshape(-1, L, 1)
691
+ elif ndim == 1:
692
+ inputs = inputs.unsqueeze(0).unsqueeze(2)
693
+ targets_mask = targets_mask.unsqueeze(0).unsqueeze(2)
694
+
695
+ if use_norm:
696
+ inputs_mask = ~targets_mask # 1 for valid, 0 for invalid
697
+ valid_count = inputs_mask.sum(dim=1, keepdim=True).clamp_min(1)
698
+ mean = inputs.sum(dim=1, keepdim=True) / valid_count
699
+ inputs = (inputs - mean) * inputs_mask
700
+ std = torch.sqrt(
701
+ (inputs ** 2).sum(dim=1, keepdim=True) / valid_count + 1e-5)
702
+ inputs /= std
703
+ inputs = torch.arcsinh(inputs)
704
+
705
+ targets_mask = targets_mask.to(torch.int32)
706
+ with torch.autocast("cuda", dtype=torch.bfloat16):
707
+ outputs = self(inputs, targets_mask)
708
+ quantile_preds = outputs["prediction"]
709
+
710
+ if use_norm:
711
+ quantile_preds = torch.sinh(quantile_preds)
712
+ quantile_preds = quantile_preds * std + mean
713
+
714
+ if num_features is not None:
715
+ quantile_preds = quantile_preds.reshape(-1, num_features, L, self.config.quantiles).transpose(1, 2)
716
+
717
+ prediction = quantile_preds.mean(dim=-1, keepdim=True)
718
+ return prediction, quantile_preds
719
+
720
+
721
+ class ZeusForClassification(Zeus):
722
+ def __init__(self, config: ZeusConfig):
723
+ super().__init__(config)
724
+
725
+ def generate_one_sample(self, inputs: torch.Tensor, padding_mask: torch.Tensor = None, use_norm: bool = True):
726
+ # transform inputs and targets_mask to [B * N, L, 1]
727
+ B = inputs.shape[0]
728
+ ndim = inputs.ndim
729
+ num_features = None
730
+ if ndim == 2:
731
+ inputs = inputs.unsqueeze(-1)
732
+ elif ndim == 3 and inputs.shape[2] > 1:
733
+ _, L, num_features = inputs.shape
734
+ inputs = inputs.transpose(1, 2).view(-1, L, 1)
735
+ elif ndim == 1:
736
+ inputs = inputs.unsqueeze(0).unsqueeze(2)
737
+
738
+ if use_norm:
739
+ if padding_mask is None:
740
+ padding_mask = torch.ones_like(inputs, dtype=torch.int32)
741
+ valid_count = padding_mask.sum(dim=1, keepdim=True).clamp_min(1)
742
+ mean = inputs.sum(dim=1, keepdim=True) / valid_count
743
+ inputs = (inputs - mean) * padding_mask
744
+ std = torch.sqrt(
745
+ (inputs ** 2).sum(dim=1, keepdim=True) / valid_count + 1e-5)
746
+ inputs /= std
747
+ inputs = torch.arcsinh(inputs)
748
+
749
+ targets_mask = torch.zeros_like(inputs, dtype=torch.int32)
750
+ with torch.autocast(device_type="cuda", dtype=torch.bfloat16):
751
+ outputs = self(
752
+ inputs,
753
+ targets_mask=targets_mask,
754
+ padding_mask=padding_mask,
755
+ return_all_hidden_states=True
756
+ )
757
+ all_hidden_states = outputs["all_hidden_states"]
758
+
759
+ return all_hidden_states