QED-Base-v1 / model.py
Qarvexium's picture
Upload 3 files
ac276b6 verified
Raw
History Blame Contribute Delete
3.57 kB
import math, torch, torch.nn as nn, torch.nn.functional as F
import sentencepiece as spm
sp = spm.SentencePieceProcessor()
sp.load("tok.model")
VOCAB = sp.get_piece_size()
def encode(t):return sp.encode(t, out_type=int)
def rope(T, d, device):
inv = 1.0 / (10000 ** (torch.arange(0, d, 2, device=device).float() / d))
pos = torch.arange(T, device=device).float()
freqs = torch.outer(pos, inv)
cos = freqs.cos()[None, None, :, :]
sin = freqs.sin()[None, None, :, :]
return cos, sin
def apply_rope(x, cos, sin):
x1 = x[..., ::2]
x2 = x[..., 1::2]
out = torch.empty_like(x)
out[..., ::2] = x1 * cos - x2 * sin
out[..., 1::2] = x1 * sin + x2 * cos
return out
def causal_mask(T, device):
return torch.triu(torch.ones(T, T, device=device, dtype=torch.bool), diagonal=1)
class RMSNorm(nn.Module):
def __init__(self, d, eps=1e-6):
super().__init__()
self.w = nn.Parameter(torch.ones(d))
self.eps = eps
def forward(self, x):
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.w
class SwiGLU(nn.Module):
def __init__(self, d):
super().__init__()
self.fc = nn.Linear(d, d * 4 * 2)
self.out = nn.Linear(d * 4, d)
def forward(self, x):
a, b = self.fc(x).chunk(2, dim=-1)
return self.out(F.silu(a) * b)
class Attention(nn.Module):
def __init__(self, d, h):
super().__init__()
assert d % h == 0
self.h = h
self.dh = d // h
self.qkv = nn.Linear(d, d * 3)
self.out = nn.Linear(d, d)
def forward(self, x):
B, T, C = x.shape
q, k, v = self.qkv(x).chunk(3, dim=-1)
q = q.view(B, T, self.h, self.dh).transpose(1, 2)
k = k.view(B, T, self.h, self.dh).transpose(1, 2)
v = v.view(B, T, self.h, self.dh).transpose(1, 2)
cos, sin = rope(T, self.dh, x.device)
q = apply_rope(q, cos, sin)
k = apply_rope(k, cos, sin)
att = (q @ k.transpose(-2, -1)) / math.sqrt(self.dh)
mask = causal_mask(T, x.device)
att = att.masked_fill(mask, float("-inf"))
att = F.softmax(att, dim=-1)
y = att @ v
y = y.transpose(1, 2).contiguous().view(B, T, C)
return self.out(y)
class Block(nn.Module):
def __init__(self, d, h):
super().__init__()
self.n1 = RMSNorm(d)
self.attn = Attention(d, h)
self.n2 = RMSNorm(d)
self.mlp = SwiGLU(d)
def forward(self, x):
x = x + self.attn(self.n1(x))
x = x + self.mlp(self.n2(x))
return x
class GPT(nn.Module):
def __init__(self):
super().__init__()
d = 1024
L = 12
H = 16
self.emb = nn.Embedding(VOCAB, d)
self.blocks = nn.ModuleList([Block(d, H) for _ in range(L)])
self.norm = RMSNorm(d)
self.head = nn.Linear(d, VOCAB, bias=False)
self.head.weight = self.emb.weight
def forward(self, x):
x = self.emb(x)
for b in self.blocks:
x = b(x)
return self.head(self.norm(x))
Qdevice = "cuda" if torch.cuda.is_available() else "cpu"
def load_qed(path, device="cpu",dw=False):
package = torch.load(path,map_location=device)
model = GPT()
model.load_state_dict(package["state_dict"])
None if dw else print(f"Loading {package['model_name']} by {package['author']}")
model.to(device)
model.eval()
return model