helloboy91's picture
Release Alloy 312M 2K v0.1.0
f5f443b verified
Raw History Blame Contribute Delete
4.73 kB
from dataclasses import asdict, dataclass
import torch
from torch import nn
from torch.nn import functional as functional
from torch.utils.checkpoint import checkpoint
@dataclass
class ModelConfig:
vocab_size: int = 8192
context_length: int = 1024
layers: int = 8
hidden_size: int = 512
heads: int = 8
intermediate_size: int = 1408
def __post_init__(self):
if any(value <= 0 for value in asdict(self).values()):
raise ValueError("All model dimensions must be positive")
if self.hidden_size % self.heads or (self.hidden_size // self.heads) % 2:
raise ValueError("Head dimension must be an even integer")
class Attention(nn.Module):
def __init__(self, config):
super().__init__()
self.heads = config.heads
self.head_size = config.hidden_size // config.heads
self.qkv = nn.Linear(config.hidden_size, 3 * config.hidden_size, bias=False)
self.output = nn.Linear(config.hidden_size, config.hidden_size, bias=False)
frequencies = 1.0 / (10000 ** (torch.arange(0, self.head_size, 2).float() / self.head_size))
angles = torch.outer(torch.arange(config.context_length).float(), frequencies)
self.register_buffer("cosines", angles.cos(), persistent=False)
self.register_buffer("sines", angles.sin(), persistent=False)
def rotate(self, tensor):
length = tensor.size(-2)
cosines = self.cosines[:length].to(tensor.dtype)
sines = self.sines[:length].to(tensor.dtype)
even, odd = tensor[..., 0::2], tensor[..., 1::2]
return torch.stack((even * cosines - odd * sines, even * sines + odd * cosines), dim=-1).flatten(-2)
def forward(self, hidden):
batch_size, length, width = hidden.shape
query, key, value = self.qkv(hidden).reshape(batch_size, length, 3, self.heads, self.head_size).unbind(2)
attended = functional.scaled_dot_product_attention(
self.rotate(query.transpose(1, 2)),
self.rotate(key.transpose(1, 2)),
value.transpose(1, 2),
is_causal=True,
)
return self.output(attended.transpose(1, 2).contiguous().view(batch_size, length, width))
class Block(nn.Module):
def __init__(self, config):
super().__init__()
self.attention_norm = nn.RMSNorm(config.hidden_size, eps=1e-5)
self.attention = Attention(config)
self.ffn_norm = nn.RMSNorm(config.hidden_size, eps=1e-5)
self.gate = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
self.up = nn.Linear(config.hidden_size, config.intermediate_size, bias=False)
self.down = nn.Linear(config.intermediate_size, config.hidden_size, bias=False)
def forward(self, hidden):
hidden = hidden + self.attention(self.attention_norm(hidden))
normalized = self.ffn_norm(hidden)
return hidden + self.down(functional.silu(self.gate(normalized)) * self.up(normalized))
class LanguageModel(nn.Module):
def __init__(self, config):
super().__init__()
self.config = config
self.embedding = nn.Embedding(config.vocab_size, config.hidden_size)
self.blocks = nn.ModuleList([Block(config) for _ in range(config.layers)])
self.norm = nn.RMSNorm(config.hidden_size, eps=1e-5)
self.gradient_checkpointing = False
self.apply(self.initialize)
def set_gradient_checkpointing(self, enabled):
self.gradient_checkpointing = enabled
@staticmethod
def initialize(module):
if isinstance(module, (nn.Linear, nn.Embedding)):
nn.init.normal_(module.weight, mean=0.0, std=0.02)
def forward(self, tokens, targets=None, return_logits=False, logit_positions=None):
if tokens.size(1) > self.config.context_length:
raise ValueError("Input exceeds context length")
hidden = self.embedding(tokens)
for block in self.blocks:
if self.gradient_checkpointing and self.training and torch.is_grad_enabled():
hidden = checkpoint(block, hidden, use_reentrant=False)
else:
hidden = block(hidden)
hidden = self.norm(hidden)
if logit_positions is not None:
hidden = hidden[:, logit_positions, :]
if targets is None and not return_logits:
return functional.linear(hidden[:, -1:, :], self.embedding.weight)
logits = functional.linear(hidden, self.embedding.weight)
if targets is None:
return logits
return functional.cross_entropy(logits.reshape(-1, self.config.vocab_size), targets.reshape(-1))