import torch import torch.nn as nn import math from transformers import PreTrainedModel from transformers.modeling_outputs import CausalLMOutput try: from .configuration_rapnss import RapnssConfig except ImportError: from configuration_rapnss import RapnssConfig class RMSNorm(nn.Module): def __init__(self, dim, eps=1e-6): super().__init__() self.eps = eps self.weight = nn.Parameter(torch.ones(dim)) def _norm(self, x): return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) def forward(self, x): return self.weight * self._norm(x.float()).type_as(x) def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0): freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim)) t = torch.arange(end, device=freqs.device, dtype=torch.float32) freqs = torch.outer(t, freqs) freqs_cis = torch.polar(torch.ones_like(freqs), freqs) return freqs_cis def apply_rotary_emb(xq: torch.Tensor, xk: torch.Tensor, freqs_cis: torch.Tensor): xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2)) xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2)) freqs_cis = freqs_cis[:xq_.shape[1]].unsqueeze(0).unsqueeze(2) xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3) xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3) return xq_out.type_as(xq), xk_out.type_as(xk) class CausalSelfAttention(nn.Module): def __init__(self, config): super().__init__() assert config.d_model % config.n_heads == 0 self.c_attn = nn.Linear(config.d_model, 3 * config.d_model, bias=False) self.c_proj = nn.Linear(config.d_model, config.d_model, bias=False) self.n_heads = config.n_heads self.d_model = config.d_model self.register_buffer("bias", torch.tril(torch.ones(config.max_seq_len, config.max_seq_len)) .view(1, 1, config.max_seq_len, config.max_seq_len)) freqs_cis = precompute_freqs_cis(self.d_model // self.n_heads, config.max_seq_len) self.register_buffer("freqs_cis", freqs_cis, persistent=False) self.dropout = nn.Dropout(config.dropout) def forward(self, x): B, T, C = x.size() qkv = self.c_attn(x) q, k, v = qkv.split(self.d_model, dim=2) q = q.view(B, T, self.n_heads, C // self.n_heads) k = k.view(B, T, self.n_heads, C // self.n_heads) v = v.view(B, T, self.n_heads, C // self.n_heads) q, k = apply_rotary_emb(q, k, self.freqs_cis) q = q.transpose(1, 2) k = k.transpose(1, 2) v = v.transpose(1, 2) att = (q @ k.transpose(-2, -1)) * (1.0 / math.sqrt(k.size(-1))) att = att.masked_fill(self.bias[:,:,:T,:T] == 0, float('-inf')) att = torch.softmax(att, dim=-1) att = self.dropout(att) y = att @ v y = y.transpose(1, 2).contiguous().view(B, T, C) y = self.c_proj(y) return y class SwiGLU(nn.Module): def forward(self, x): x, gate = x.chunk(2, dim=-1) return torch.nn.functional.silu(gate) * x class FeedForward(nn.Module): def __init__(self, config): super().__init__() hidden_dim = int(2 * config.d_ff / 3) self.w1 = nn.Linear(config.d_model, hidden_dim * 2, bias=False) self.swiglu = SwiGLU() self.w2 = nn.Linear(hidden_dim, config.d_model, bias=False) self.dropout = nn.Dropout(config.dropout) def forward(self, x): x = self.w1(x) x = self.swiglu(x) x = self.w2(x) x = self.dropout(x) return x class RapnssTransformerBlock(nn.Module): def __init__(self, config): super().__init__() self.ln_1 = RMSNorm(config.d_model) self.attn = CausalSelfAttention(config) self.ln_2 = RMSNorm(config.d_model) self.mlp = FeedForward(config) def forward(self, x): x = x + self.attn(self.ln_1(x)) x = x + self.mlp(self.ln_2(x)) return x class RapnssPreTrainedModel(PreTrainedModel): config_class = RapnssConfig base_model_prefix = "transformer" supports_gradient_checkpointing = True def _init_weights(self, module): if isinstance(module, nn.Linear): torch.nn.init.normal_(module.weight, mean=0.0, std=0.02) elif isinstance(module, nn.Embedding): torch.nn.init.normal_(module.weight, mean=0.0, std=0.02) class RapnssForCausalLM(RapnssPreTrainedModel): def __init__(self, config): super().__init__(config) self.config = config self.wte = nn.Embedding(config.vocab_size, config.d_model) self.drop = nn.Dropout(config.dropout) self.h = nn.ModuleList([RapnssTransformerBlock(config) for _ in range(config.n_layers)]) self.ln_f = RMSNorm(config.d_model) self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False) self.wte.weight = nn.Parameter(self.lm_head.weight.clone()) self.post_init() def get_input_embeddings(self): return self.wte def set_input_embeddings(self, value): self.wte = value def get_output_embeddings(self): return self.lm_head def set_output_embeddings(self, new_embeddings): self.lm_head = new_embeddings def forward(self, input_ids=None, labels=None, **kwargs): tok_emb = self.wte(input_ids) x = self.drop(tok_emb) for block in self.h: x = block(x) x = self.ln_f(x) logits = self.lm_head(x) loss = None if labels is not None: shift_logits = logits[..., :-1, :].contiguous() shift_labels = labels[..., 1:].contiguous() loss_fct = nn.CrossEntropyLoss() loss = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1)) return CausalLMOutput(loss=loss, logits=logits) def prepare_inputs_for_generation(self, input_ids, **kwargs): return {"input_ids": input_ids}