Download model/aether.py from yadavkapil7155/Aether: direct link, hf CLI and curl.
- Browser
- Download file 6.53 kB
-
https://huggingface.co/yadavkapil7155/Aether/resolve/main/model/aether.py
- Command line
-
hf download hf://yadavkapil7155/Aether/model/aether.py
-
curl -L -o aether.py https://huggingface.co/yadavkapil7155/Aether/resolve/main/model/aether.py
6.53 kB
| import math | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from torch.utils.checkpoint import checkpoint | |
| from .attention import GQAAttention | |
| from .rmsnorm import RMSNorm | |
| from .rope import rope_cache | |
| from .swiglu import SwiGLU | |
| class AETHERConfig: | |
| vocab_size = 32000 | |
| hidden_size = 768 | |
| num_hidden_layers = 12 | |
| num_attention_heads = 12 | |
| num_key_value_heads = 4 | |
| head_dim = 64 | |
| intermediate_size = 2048 | |
| max_position_embeddings = 2048 | |
| rope_theta = 10000.0 | |
| rms_norm_eps = 1e-6 | |
| tie_word_embeddings = True | |
| bias = False | |
| gradient_checkpointing = True | |
| dropout = 0.0 | |
| class AETHERBlock(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.input_layernorm = RMSNorm( | |
| config.hidden_size, | |
| config.rms_norm_eps, | |
| ) | |
| self.self_attn = GQAAttention( | |
| hidden_size=config.hidden_size, | |
| num_attention_heads=config.num_attention_heads, | |
| num_key_value_heads=config.num_key_value_heads, | |
| head_dim=config.head_dim, | |
| bias=config.bias, | |
| ) | |
| self.post_attention_layernorm = RMSNorm( | |
| config.hidden_size, | |
| config.rms_norm_eps, | |
| ) | |
| self.mlp = SwiGLU( | |
| hidden_size=config.hidden_size, | |
| intermediate_size=config.intermediate_size, | |
| bias=config.bias, | |
| ) | |
| def forward(self, x, cos, sin): | |
| x = x + self.self_attn( | |
| self.input_layernorm(x), | |
| cos, | |
| sin, | |
| ) | |
| x = x + self.mlp( | |
| self.post_attention_layernorm(x) | |
| ) | |
| return x | |
| class AETHER100M(nn.Module): | |
| def __init__(self, config=None): | |
| super().__init__() | |
| if config is None: | |
| config = AETHERConfig() | |
| self.config = config | |
| self.embed = nn.Embedding( | |
| config.vocab_size, | |
| config.hidden_size, | |
| ) | |
| self.layers = nn.ModuleList( | |
| [ | |
| AETHERBlock(config) | |
| for _ in range(config.num_hidden_layers) | |
| ] | |
| ) | |
| self.norm = RMSNorm( | |
| config.hidden_size, | |
| config.rms_norm_eps, | |
| ) | |
| self.lm_head = nn.Linear( | |
| config.hidden_size, | |
| config.vocab_size, | |
| bias=False, | |
| ) | |
| if config.tie_word_embeddings: | |
| self.lm_head.weight = self.embed.weight | |
| self._init_weights() | |
| def _init_weights(self): | |
| std = 0.02 | |
| nn.init.normal_( | |
| self.embed.weight, | |
| mean=0.0, | |
| std=std, | |
| ) | |
| for module in self.modules(): | |
| if isinstance(module, nn.Linear): | |
| if module.weight is self.embed.weight: | |
| continue | |
| nn.init.normal_( | |
| module.weight, | |
| mean=0.0, | |
| std=std, | |
| ) | |
| if module.bias is not None: | |
| nn.init.zeros_(module.bias) | |
| residual_scale = 1.0 / math.sqrt( | |
| 2 * self.config.num_hidden_layers | |
| ) | |
| for layer in self.layers: | |
| layer.self_attn.o_proj.weight.data.mul_( | |
| residual_scale | |
| ) | |
| layer.mlp.down_proj.weight.data.mul_( | |
| residual_scale | |
| ) | |
| def forward( | |
| self, | |
| input_ids, | |
| labels=None, | |
| ): | |
| B, T = input_ids.shape | |
| if T > self.config.max_position_embeddings: | |
| raise ValueError( | |
| f"Sequence length {T} exceeds " | |
| f"maximum {self.config.max_position_embeddings}" | |
| ) | |
| x = self.embed(input_ids) | |
| cos, sin = rope_cache( | |
| seq_len=T, | |
| head_dim=self.config.head_dim, | |
| theta=self.config.rope_theta, | |
| device=input_ids.device, | |
| ) | |
| for layer in self.layers: | |
| if ( | |
| self.config.gradient_checkpointing | |
| and self.training | |
| ): | |
| x = checkpoint( | |
| layer, | |
| x, | |
| cos, | |
| sin, | |
| use_reentrant=False, | |
| ) | |
| else: | |
| x = layer( | |
| x, | |
| cos, | |
| sin, | |
| ) | |
| x = self.norm(x) | |
| loss = None | |
| logits = None | |
| if labels is not None: | |
| shift_x = x[:, :-1, :].contiguous() | |
| shift_labels = labels[:, 1:].contiguous() | |
| B, T, H = shift_x.shape | |
| # Avoid creating the enormous | |
| # [B, T, vocab_size] tensor at once. | |
| chunk_tokens = 64 | |
| total_loss = torch.zeros( | |
| (), | |
| device=x.device, | |
| dtype=torch.float32, | |
| ) | |
| total_tokens = 0 | |
| flat_x = shift_x.view( | |
| -1, | |
| H, | |
| ) | |
| flat_labels = shift_labels.view( | |
| -1, | |
| ) | |
| for start in range( | |
| 0, | |
| B * T, | |
| chunk_tokens, | |
| ): | |
| end = min( | |
| start + chunk_tokens, | |
| B * T, | |
| ) | |
| hidden_chunk = flat_x[ | |
| start:end | |
| ] | |
| label_chunk = flat_labels[ | |
| start:end | |
| ] | |
| logits_chunk = self.lm_head( | |
| hidden_chunk | |
| ) | |
| chunk_loss = F.cross_entropy( | |
| logits_chunk, | |
| label_chunk, | |
| reduction="sum", | |
| ) | |
| total_loss += chunk_loss.float() | |
| total_tokens += label_chunk.numel() | |
| loss = ( | |
| total_loss / | |
| total_tokens | |
| ) | |
| else: | |
| logits = self.lm_head(x) | |
| return { | |
| "logits": logits, | |
| "loss": loss, | |
| } | |
| def count_parameters(model): | |
| return sum( | |
| p.numel() | |
| for p in model.parameters() | |
| ) |