| import numpy as np |
| import torch |
| from torch import nn |
| import math |
| from typing import Tuple, Optional |
| from transformers import PreTrainedModel |
| from .configuration_zeus import ZeusConfig |
| from basicts.modules import ACT2FN |
| from basicts.modules.transformer import DecoderOnlyLayer, MultiHeadAttention, RotaryPositionEmbedding, AutoRegressiveDecoder |
| from basicts.modules.norm import RMSNorm |
| from flash_attn import flash_attn_varlen_func |
| from flash_attn.bert_padding import unpad_input, pad_input |
|
|
|
|
| class ZeusFlashAttention(nn.Module): |
| """ |
| Encoder-only (BERT-style) Multi-Head Attention with FlashAttention v2 |
| """ |
| def __init__( |
| self, |
| hidden_size: int, |
| n_heads: int, |
| dropout: float = 0.0, |
| kv_heads: Optional[int] = None, |
| rope: Optional[torch.nn.Module] = None, |
| ): |
| super().__init__() |
| assert hidden_size % n_heads == 0 |
|
|
| self.hidden_size = hidden_size |
| self.n_heads = n_heads |
| self.head_size = hidden_size // n_heads |
|
|
| self.q_proj = nn.Linear(hidden_size, hidden_size) |
| self.k_proj = nn.Linear(hidden_size, hidden_size) |
| self.v_proj = nn.Linear(hidden_size, hidden_size) |
| self.out_proj = nn.Linear(hidden_size, hidden_size, bias=False) |
|
|
| self.dropout_p = dropout |
| self.rope = rope |
|
|
| def _shape(self, x: torch.Tensor, B: int, L: int) -> torch.Tensor: |
| |
| return x.view(B, L, self.n_heads, self.head_size) |
|
|
| def forward( |
| self, |
| hidden_states: torch.Tensor, |
| attention_mask: Optional[torch.Tensor] = None, |
| position_ids: Optional[torch.LongTensor] = None, |
| past_key_value: Optional[object] = None, |
| use_cache: bool = False, |
| output_attentions: bool = False, |
| layer_idx: Optional[int] = None, |
| ): |
| assert not output_attentions, \ |
| "FlashAttention v2 does not support returning attention weights efficiently." |
|
|
| B, L, _ = hidden_states.shape |
| device = hidden_states.device |
|
|
| q = self._shape(self.q_proj(hidden_states), B, L) |
| k = self._shape(self.k_proj(hidden_states), B, L) |
| v = self._shape(self.v_proj(hidden_states), B, L) |
|
|
| if attention_mask is None: |
| mask = torch.ones((B, L), device=device, dtype=torch.bool) |
|
|
| q_unpad, indices, cu_seqlens, max_seqlen, _ = unpad_input(q, attention_mask) |
| k_unpad, _, _, _, _ = unpad_input(k, attention_mask) |
| v_unpad, _, _, _, _ = unpad_input(v, attention_mask) |
|
|
| if self.rope is not None: |
| if position_ids is None: |
| position_ids = torch.arange(L, device=device).unsqueeze(0).expand(B, -1) |
| pos = position_ids.reshape(-1)[indices] |
| q_unpad, k_unpad = self.rope(q_unpad, k_unpad, pos) |
|
|
| dropout_p = self.dropout_p if self.training else 0.0 |
|
|
| attn_unpad = flash_attn_varlen_func( |
| q_unpad, |
| k_unpad, |
| v_unpad, |
| cu_seqlens_q=cu_seqlens, |
| cu_seqlens_k=cu_seqlens, |
| max_seqlen_q=max_seqlen, |
| max_seqlen_k=max_seqlen, |
| dropout_p=dropout_p, |
| causal=False, |
| ) |
|
|
| attn_unpad = attn_unpad.reshape(-1, self.hidden_size) |
| context = pad_input(attn_unpad, indices, B, L) |
|
|
| output = self.out_proj(context) |
|
|
| return output, None, past_key_value |
|
|
|
|
| class ZeusMLP(nn.Module): |
|
|
| def __init__(self, hidden_size: int, intermediate_size: int, hidden_act: str): |
| super().__init__() |
| self.hidden_size = hidden_size |
| self.intermediate_size = intermediate_size |
| self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) |
| self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) |
| self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) |
| self.act_fn = ACT2FN[hidden_act] |
|
|
| def forward(self, hidden_state): |
| return self.down_proj(self.act_fn(self.gate_proj(hidden_state)) * self.up_proj(hidden_state)) |
|
|
|
|
| class ZeusInputEmbedding(nn.Module): |
|
|
| def __init__(self, input_size: int, hidden_size: int, hidden_act: str = "gelu"): |
| super().__init__() |
| self.input_size = input_size |
| self.hidden_size = hidden_size |
| self.intermediate_size = 4 * self.hidden_size |
| self.res_proj = nn.Linear(self.input_size, self.hidden_size, bias=False) |
| self.gate_proj = nn.Linear(self.input_size, self.intermediate_size, bias=True) |
| self.up_proj = nn.Linear(self.input_size, self.intermediate_size, bias=True) |
| self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) |
| self.act_fn = ACT2FN[hidden_act] |
|
|
| def forward(self, x: torch.Tensor): |
| return self.res_proj(x) + \ |
| self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) |
|
|
|
|
| class EncoderLayer(DecoderOnlyLayer): |
| def __init__(self, config: ZeusConfig, stage: int): |
| |
| attn_cls = ZeusFlashAttention \ |
| if config.attn_implementation == "flash_attention_2" else MultiHeadAttention |
| |
| self_attn = attn_cls( |
| hidden_size=config.hidden_size[stage], |
| n_heads=config.n_heads[stage], |
| dropout=config.dropout, |
| rope=RotaryPositionEmbedding( |
| dim=config.hidden_size[stage] // config.n_heads[stage], |
| max_position_embeddings=4096 |
| ) |
| ) |
| ffn_layer = ZeusMLP( |
| config.hidden_size[stage], |
| config.intermediate_size[stage], |
| config.hidden_act |
| ) |
| super().__init__(self_attn, ffn_layer, (RMSNorm, config.hidden_size[stage])) |
|
|
|
|
| class ZeusEncoder(AutoRegressiveDecoder): |
| def __init__(self, config: ZeusConfig, stage: int): |
| |
| decoder_layers = nn.ModuleList( |
| [ |
| EncoderLayer(config, stage) |
| for _ in range(config.num_layers[stage]) |
| ] |
| ) |
|
|
| layer_norm = RMSNorm(config.hidden_size[stage]) |
| super().__init__(decoder_layers, layer_norm) |
|
|
| self.num_reg_tokens = config.num_reg_tokens |
|
|
| if self.num_reg_tokens > 0: |
| self.reg_tokens = nn.Parameter( |
| torch.randn( |
| 1, self.num_reg_tokens, config.hidden_size[stage] |
| ) * config.initializer_range |
| ) |
| |
| def forward( |
| self, |
| hidden_states: torch.Tensor, |
| attention_mask: torch.Tensor | None = None, |
| **kwargs |
| ): |
|
|
| B, L, _ = hidden_states.size() |
| position_ids = torch.arange( |
| L, |
| dtype=torch.long, |
| device=hidden_states.device |
| ).unsqueeze(0) |
|
|
| if self.num_reg_tokens > 0: |
| reg_tokens = self.reg_tokens.expand(B, -1, -1) |
| hidden_states = torch.cat( |
| [reg_tokens, hidden_states], dim=1 |
| ) |
| position_ids = torch.cat( |
| [torch.zeros( |
| 1, self.num_reg_tokens, |
| dtype=torch.long, |
| device=hidden_states.device |
| ), position_ids], dim=1 |
| ) |
|
|
| hidden_states, attn_weights, kv_cache = super().forward( |
| hidden_states=hidden_states, |
| attention_mask=attention_mask, |
| position_ids=position_ids.expand(B, -1), |
| **kwargs |
| ) |
| |
| reg_tokens = hidden_states[:, :self.num_reg_tokens] |
| hidden_states = hidden_states[:, self.num_reg_tokens:] |
| |
| return hidden_states, attn_weights, kv_cache, reg_tokens |
|
|
| class ZeusPoolingLayer(nn.Module): |
|
|
| def __init__(self, config: ZeusConfig, stage: int): |
| super().__init__() |
| self.stage = stage |
| self.config = config |
| self.factor = config.scales[stage] // config.scales[stage - 1] |
| self.proj = nn.Linear( |
| self.factor * config.hidden_size[stage - 1], |
| config.hidden_size[stage], |
| bias=False |
| ) |
| |
| def forward(self, hidden_states: torch.Tensor, padding_mask: torch.Tensor): |
| batch_size, _, hidden_size = hidden_states.size() |
| hidden_states = hidden_states.reshape(batch_size, -1, self.factor * hidden_size) |
| hidden_states = self.proj(hidden_states) |
| padding_mask = padding_mask.reshape(batch_size, -1, self.factor, 1).any(dim=2) |
| return hidden_states, padding_mask |
|
|
| class ZeusUnpoolingLayer(nn.Module): |
|
|
| def __init__(self, config: ZeusConfig, stage: int): |
| super().__init__() |
| self.stage = stage |
| self.config = config |
| self.factor = config.scales[stage - 1] // config.scales[stage] |
| self.proj = nn.Linear( |
| config.hidden_size[stage - 1], |
| self.factor * config.hidden_size[stage], |
| bias=False |
| ) |
| |
| def forward(self, hidden_states: torch.Tensor, skip_connection: torch.Tensor): |
| batch_size, _, hidden_size = skip_connection.size() |
| hidden_states = self.proj(hidden_states) |
| hidden_states = hidden_states.reshape(batch_size, -1, hidden_size) |
| hidden_states = hidden_states + skip_connection |
| return hidden_states |
|
|
| class ZeusPreTrainedModel(PreTrainedModel): |
| config_class = ZeusConfig |
|
|
| def _init_weights(self, module): |
| std = self.config.initializer_range |
| if isinstance(module, torch.nn.Linear): |
| module.weight.data.normal_(mean=0.0, std=std) |
| if module.bias is not None: |
| module.bias.data.zero_() |
| elif isinstance(module, torch.nn.Embedding): |
| module.weight.data.normal_(mean=0.0, std=std) |
| if module.padding_idx is not None: |
| module.weight.data[module.padding_idx].zero_() |
|
|
|
|
| class Zeus(ZeusPreTrainedModel): |
|
|
| _supports_flash_attn_2 = True |
| |
| def __init__(self, config: ZeusConfig): |
| super().__init__(config) |
| self.config = config |
| self.scales = config.scales |
| self.num_reg_tokens = config.num_reg_tokens |
| self.num_scales = len(self.scales) |
|
|
| self.input_mlp = ZeusInputEmbedding( |
| config.input_dim, |
| config.hidden_size[0], |
| config.hidden_act |
| ) |
|
|
| self.special_tokens = nn.Embedding(2, config.hidden_size[0]) |
| self.pad_token_id = 0 |
| self.mask_token_id = 1 |
|
|
| self.encoders = nn.ModuleList() |
| self.downsamplers = nn.ModuleList() |
| self.upsamplers = nn.ModuleList() |
|
|
| |
| self.encoders.append(ZeusEncoder(config, 0)) |
|
|
| |
| for i in range(1, self.num_scales // 2 + 1): |
| self.encoders.append(ZeusEncoder(config, i)) |
| self.downsamplers.append(ZeusPoolingLayer(config, i)) |
| |
| for i in range(self.num_scales // 2 + 1, self.num_scales): |
| self.encoders.append(ZeusEncoder(config, i)) |
| self.upsamplers.append(ZeusUnpoolingLayer(config, i)) |
|
|
| self.num_quantiles = len(config.quantiles) |
| quantiles = torch.tensor(config.quantiles) |
| self.register_buffer("quantiles", quantiles, persistent=False) |
| self.head = nn.Linear(config.hidden_size[-1], self.num_quantiles) |
|
|
| self.post_init() |
|
|
| def _prepare_embedding( |
| self, |
| inputs: torch.Tensor, |
| targets_mask: torch.Tensor, |
| padding_mask: torch.Tensor = None, |
| ): |
|
|
| B, L, _ = inputs.shape |
| input_embeds = self.input_mlp(inputs) |
| |
| is_target = targets_mask == 1 |
| input_embeds = torch.where( |
| is_target, |
| self.special_tokens( |
| torch.full_like(targets_mask.squeeze(-1), self.mask_token_id) |
| ), |
| input_embeds) |
| |
| if padding_mask is not None: |
| is_padding = padding_mask == 0 |
| input_embeds = torch.where( |
| is_padding, |
| self.special_tokens( |
| torch.full_like(padding_mask.squeeze(-1), self.pad_token_id) |
| ), |
| input_embeds) |
| if padding_mask is None: |
| padding_mask = torch.ones( |
| (B, L, 1), device=input_embeds.device, dtype=torch.long) |
| |
| |
| max_scale = max(self.scales) |
| pad_len = math.ceil(L / max_scale) * max_scale - L |
| if pad_len > 0: |
| pad_tokens = self.special_tokens( |
| torch.full( |
| (B, pad_len), |
| self.pad_token_id, |
| device=input_embeds.device |
| ) |
| ) |
| |
| input_embeds = torch.cat( |
| [input_embeds, pad_tokens],dim=1) |
| |
| padding_mask = torch.cat( |
| [ |
| padding_mask, |
| torch.zeros( |
| (B, pad_len, 1), |
| device=input_embeds.device, |
| dtype=padding_mask.dtype) |
| ], |
| dim=1 |
| ) |
| |
| return input_embeds, padding_mask |
| |
| def _prepare_attn_mask( |
| self, |
| hidden_states: torch.Tensor, |
| padding_mask: torch.Tensor = None, |
| ): |
| device = hidden_states.device |
| B, L, _ = hidden_states.shape |
| |
| if padding_mask is None: |
| padding_mask = torch.ones( |
| (B, L, 1), device=device, dtype=torch.long) |
|
|
| |
| if self.num_reg_tokens > 0: |
| attention_mask = torch.cat( |
| [ |
| torch.ones( |
| (B, self.num_reg_tokens, 1), |
| device=device, |
| dtype=padding_mask.dtype |
| ), |
| padding_mask |
| ], |
| dim=1 |
| ) |
| else: |
| attention_mask = padding_mask |
| |
| if self.config.attn_implementation == "eager": |
| attention_mask = attention_mask.view(B, 1, 1, -1) |
| attention_mask = (1 - attention_mask.float()) * torch.finfo(hidden_states.dtype).min |
| else: |
| attention_mask = attention_mask.squeeze(-1) |
| return attention_mask |
| |
| def forward( |
| self, |
| inputs: torch.Tensor, |
| targets_mask: Optional[torch.Tensor], |
| targets: Optional[torch.Tensor] = None, |
| padding_mask: Optional[torch.Tensor] = None, |
| return_all_hidden_states: bool = False |
| ): |
| """ |
| x: [B, L, 1] |
| padding_mask: [B, L, 1] (0 for padding, 1 for valid) |
| target_mask: [B, L, 1] (1 for target/predict, 0 for context) |
| """ |
|
|
| |
| ori_seq_len = inputs.shape[1] |
| ori_padding_mask = padding_mask |
| hidden_states, padding_mask = self._prepare_embedding(inputs, targets_mask, padding_mask) |
|
|
| scale_outputs = [] |
| scale_padding_masks = [] |
| all_hidden_states = [] |
| reg_token_emb = None |
| |
| for i in range(self.num_scales): |
| |
| if i > 0: |
| |
| |
| if i <= self.num_scales // 2: |
| scale_padding_masks.append(padding_mask) |
| hidden_states, padding_mask = self.downsamplers[i - 1](hidden_states, padding_mask) |
| |
| |
| else: |
| idx = i - self.num_scales // 2 - 1 |
| hidden_states = self.upsamplers[idx](hidden_states, scale_outputs[self.num_scales - i - 1]) |
| padding_mask = scale_padding_masks[self.num_scales - i - 1] |
| |
| attention_mask = self._prepare_attn_mask(hidden_states, padding_mask) |
|
|
| hidden_states, _, _, reg_tokens = self.encoders[i]( |
| hidden_states, |
| attention_mask=attention_mask |
| ) |
| |
| if i == self.num_scales - 2: |
| reg_token_emb = reg_tokens.mean(dim=1) |
| |
| if return_all_hidden_states: |
| all_hidden_states.append(hidden_states) |
|
|
| if i < self.num_scales: |
| scale_outputs.append(hidden_states) |
|
|
| |
| quantile_preds = self.head(hidden_states)[:, :ori_seq_len, :] |
|
|
| loss = 0.0 |
| |
| if targets is not None: |
| loss_mask = (targets_mask * ori_padding_mask).float() |
| quantiles = self.quantiles.view(1, 1, self.num_quantiles).to(quantile_preds.dtype) |
| loss = 2 * torch.abs((targets - quantile_preds) |
| * ((targets <= quantile_preds).float() - quantiles)) |
| loss = loss * loss_mask |
| loss = loss.sum() / (loss_mask.sum() * self.num_quantiles) |
|
|
| return { |
| "prediction": quantile_preds, |
| "loss": loss, |
| "all_hidden_states": all_hidden_states, |
| "reg_token_emb": reg_token_emb, |
| } |
|
|
|
|
| class ZeusForPrediction(Zeus): |
|
|
| def __init__(self, config: ZeusConfig): |
| super().__init__(config) |
|
|
| def generate( |
| self, |
| context: torch.Tensor, |
| prediction_length: int, |
| context_mask: torch.Tensor = None, |
| use_norm: bool = True |
| ) -> Tuple[torch.Tensor, torch.Tensor]: |
|
|
| context = context.to(self.device) |
| |
| ndim = context.ndim |
| num_features = None |
| if ndim == 2: |
| context = context.unsqueeze(-1) |
| elif ndim == 3 and context.shape[2] > 1: |
| _, L, num_features = context.shape |
| context = context.transpose(1, 2).view(-1, L, 1) |
| elif ndim == 1: |
| context = context.unsqueeze(0).unsqueeze(2) |
| |
| B, L, _ = context.shape |
| device = context.device |
|
|
| if use_norm: |
| mean = context.mean(dim=1, keepdim=True) |
| std = context.std(dim=1, keepdim=True) |
| context = (context - mean) / std |
| context = torch.arcsinh(context) |
| |
| inputs = torch.cat( |
| [context, torch.zeros(B, prediction_length, 1, device=device)], dim=1) |
| if context_mask is None: |
| context_mask = torch.torch.ones(B, L, 1, device=device, dtype=torch.int32) |
| padding_mask = torch.cat( |
| [ |
| context_mask, |
| torch.ones(B, prediction_length, 1, dtype=torch.int32, device=device) |
| ], dim=1 |
| ) |
| targets_mask = torch.cat( |
| [ |
| torch.zeros_like(context, dtype=torch.int32), |
| torch.ones(B, prediction_length, 1, dtype=torch.int32, device=device) |
| ], dim=1 |
| ) |
|
|
| with torch.autocast("cuda", dtype=torch.bfloat16): |
| outputs = self.forward( |
| inputs, |
| padding_mask=padding_mask, |
| targets_mask=targets_mask, |
| ) |
|
|
| |
| quantile_preds = outputs["prediction"][:, -prediction_length:, :] |
|
|
| if use_norm: |
| quantile_preds = torch.sinh(quantile_preds) |
| quantile_preds = quantile_preds * std + mean |
|
|
| |
| prediction = quantile_preds.mean(dim=-1, keepdim=True) |
|
|
| if ndim == 2: |
| prediction = prediction.squeeze(-1) |
| elif ndim == 3 and num_features is not None: |
| |
| prediction = prediction.reshape(-1, num_features, prediction_length).transpose(1, 2) |
| prediction = quantile_preds.reshape( |
| -1, num_features, prediction_length, quantile_preds.shape[-1] |
| ).transpose(1, 2) |
| elif ndim == 1: |
| prediction = prediction[0, :, 0] |
| quantile_preds = quantile_preds[0] |
|
|
| return prediction, quantile_preds |
| |
| def predict( |
| self, |
| context, |
| prediction_length, |
| use_norm: bool = True, |
| max_pred_len: int = 4096 |
| ): |
|
|
| B = len(context) |
|
|
| series = [] |
| Ns = [] |
| for x in context: |
| if x.ndim == 1: |
| x = x[None, :] |
| else: |
| x = x.T |
| series.append(x) |
| Ns.append(x.shape[0]) |
|
|
| assert len(set(Ns)) == 1, "All arrays must have same N" |
| N = Ns[0] |
|
|
| padded = [] |
| target_masks = [] |
| for x in series: |
| N_, L = x.shape |
| pad = np.full((N_, prediction_length), np.nan) |
| padded.append(np.concatenate([x, pad], axis=1)) |
|
|
| m = np.zeros((N_, L + prediction_length), dtype=bool) |
| m[:, L:] = 1 |
| target_masks.append(m) |
|
|
| batch = [] |
| |
| tgt_masks = [] |
|
|
| for x, tm in zip(padded, target_masks): |
| N_, Lf = x.shape |
| if Lf >= max_pred_len: |
| x = x[:, -max_pred_len:] |
| tm = tm[:, -max_pred_len:] |
| |
| else: |
| pad_len = max_pred_len - Lf |
| x = np.concatenate([x, np.full((N_, pad_len), np.nan)], axis=1) |
| tm = np.concatenate([tm, np.zeros((N_, pad_len), bool)], axis=1) |
| |
|
|
| batch.append(x) |
| tgt_masks.append(tm) |
| |
|
|
| |
| batch = np.stack(batch).reshape(B * N, max_pred_len, 1) |
| tgt_masks = np.stack(tgt_masks).reshape(B * N, max_pred_len, 1) |
| |
| pad_masks = ( |
| (~np.isnan(batch)) |
| | (tgt_masks.astype(bool)) |
| ).astype(np.int32) |
|
|
| if use_norm: |
| mean = np.nanmean(batch, axis=1, keepdims=True) |
| std = np.nanstd(batch, axis=1, keepdims=True) |
| mean[np.isnan(mean)] = 0.0 |
| std[np.isnan(std)] = 1.0 |
| std[std < 1e-3] = 1.0 |
| batch_norm = (batch - mean) / std |
| batch_norm = np.nan_to_num(batch_norm, nan=0.0) |
| batch_norm = np.arcsinh(batch_norm) |
| else: |
| batch_norm = np.nan_to_num(batch, nan=0.0) |
|
|
| x = torch.from_numpy(batch_norm).to(self.device).float() |
| padding_mask = torch.from_numpy(pad_masks).int().to(self.device) |
| targets_mask = torch.from_numpy(tgt_masks).int().to(self.device) |
|
|
| |
| |
| with torch.autocast("cuda", dtype=torch.bfloat16): |
| outputs = self.forward( |
| x, |
| padding_mask=padding_mask, |
| targets_mask=targets_mask, |
| ) |
| |
| quantile_preds = outputs["prediction"].float().detach().cpu().numpy() |
| if use_norm: |
| quantile_preds = np.sinh(quantile_preds) * std + mean |
| quantile_preds = quantile_preds[tgt_masks.repeat(self.num_quantiles, axis=2)].reshape(B, N, prediction_length, self.num_quantiles) |
|
|
| preds = quantile_preds.mean(axis=-1) |
|
|
| if N == 1: |
| preds = preds[:, 0, :] |
| quantile_preds = quantile_preds[:, 0, :, :] |
|
|
| return preds, quantile_preds |
|
|
|
|
| class ZeusForImputation(Zeus): |
| def __init__(self, config: ZeusConfig): |
| super().__init__(config) |
| |
| def generate( |
| self, |
| inputs: torch.Tensor, |
| targets_mask: torch.Tensor, |
| use_norm: bool = True |
| ) -> Tuple[torch.Tensor, torch.Tensor]: |
|
|
| |
| ndim = inputs.ndim |
| num_features = None |
| if ndim == 2: |
| inputs = inputs.unsqueeze(-1) |
| targets_mask = targets_mask.unsqueeze(-1) |
| elif ndim == 3 and inputs.shape[2] > 1: |
| _, L, num_features = inputs.shape |
| inputs = inputs.transpose(1, 2).reshape(-1, L, 1) |
| targets_mask = targets_mask.transpose(1, 2).reshape(-1, L, 1) |
| elif ndim == 1: |
| inputs = inputs.unsqueeze(0).unsqueeze(2) |
| targets_mask = targets_mask.unsqueeze(0).unsqueeze(2) |
| |
| if use_norm: |
| inputs_mask = ~targets_mask |
| valid_count = inputs_mask.sum(dim=1, keepdim=True).clamp_min(1) |
| mean = inputs.sum(dim=1, keepdim=True) / valid_count |
| inputs = (inputs - mean) * inputs_mask |
| std = torch.sqrt( |
| (inputs ** 2).sum(dim=1, keepdim=True) / valid_count + 1e-5) |
| inputs /= std |
| inputs = torch.arcsinh(inputs) |
|
|
| targets_mask = targets_mask.to(torch.int32) |
| with torch.autocast("cuda", dtype=torch.bfloat16): |
| outputs = self(inputs, targets_mask) |
| quantile_preds = outputs["prediction"] |
|
|
| if use_norm: |
| quantile_preds = torch.sinh(quantile_preds) |
| quantile_preds = quantile_preds * std + mean |
|
|
| if num_features is not None: |
| quantile_preds = quantile_preds.reshape(-1, num_features, L, self.config.quantiles).transpose(1, 2) |
|
|
| prediction = quantile_preds.mean(dim=-1, keepdim=True) |
| return prediction, quantile_preds |
|
|
|
|
| class ZeusForClassification(Zeus): |
| def __init__(self, config: ZeusConfig): |
| super().__init__(config) |
| |
| def generate_one_sample(self, inputs: torch.Tensor, padding_mask: torch.Tensor = None, use_norm: bool = True): |
| |
| B = inputs.shape[0] |
| ndim = inputs.ndim |
| num_features = None |
| if ndim == 2: |
| inputs = inputs.unsqueeze(-1) |
| elif ndim == 3 and inputs.shape[2] > 1: |
| _, L, num_features = inputs.shape |
| inputs = inputs.transpose(1, 2).view(-1, L, 1) |
| elif ndim == 1: |
| inputs = inputs.unsqueeze(0).unsqueeze(2) |
| |
| if use_norm: |
| if padding_mask is None: |
| padding_mask = torch.ones_like(inputs, dtype=torch.int32) |
| valid_count = padding_mask.sum(dim=1, keepdim=True).clamp_min(1) |
| mean = inputs.sum(dim=1, keepdim=True) / valid_count |
| inputs = (inputs - mean) * padding_mask |
| std = torch.sqrt( |
| (inputs ** 2).sum(dim=1, keepdim=True) / valid_count + 1e-5) |
| inputs /= std |
| inputs = torch.arcsinh(inputs) |
|
|
| targets_mask = torch.zeros_like(inputs, dtype=torch.int32) |
| with torch.autocast(device_type="cuda", dtype=torch.bfloat16): |
| outputs = self( |
| inputs, |
| targets_mask=targets_mask, |
| padding_mask=padding_mask, |
| return_all_hidden_states=True |
| ) |
| all_hidden_states = outputs["all_hidden_states"] |
|
|
| return all_hidden_states |
|
|