AlihIng commited on
Commit
7a7d768
·
verified ·
1 Parent(s): d299c4a

Upload model.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. model.py +114 -0
model.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ TaxiLM — Vanilla transformer for Hassaniya.
3
+ """
4
+
5
+ import math
6
+ import torch
7
+ import torch.nn as nn
8
+ import torch.nn.functional as F
9
+ from config import TaxiConfig
10
+
11
+
12
+ class Attention(nn.Module):
13
+ def __init__(self, config):
14
+ super().__init__()
15
+ self.n_heads = config.n_heads
16
+ self.head_dim = config.d_model // config.n_heads
17
+ self.qkv = nn.Linear(config.d_model, 3 * config.d_model)
18
+ self.out = nn.Linear(config.d_model, config.d_model)
19
+ self.dropout = nn.Dropout(config.dropout)
20
+
21
+ def forward(self, x, mask=None):
22
+ B, T, C = x.shape
23
+ qkv = self.qkv(x).reshape(B, T, 3, self.n_heads, self.head_dim).permute(2, 0, 3, 1, 4)
24
+ q, k, v = qkv[0], qkv[1], qkv[2]
25
+ attn = (q @ k.transpose(-2, -1)) / math.sqrt(self.head_dim)
26
+ if mask is not None:
27
+ attn = attn.masked_fill(mask == 0, float("-inf"))
28
+ attn = self.dropout(F.softmax(attn, dim=-1))
29
+ return self.out((attn @ v).transpose(1, 2).contiguous().view(B, T, C))
30
+
31
+
32
+ class FFN(nn.Module):
33
+ def __init__(self, config):
34
+ super().__init__()
35
+ self.up = nn.Linear(config.d_model, config.ffn_hidden)
36
+ self.down = nn.Linear(config.ffn_hidden, config.d_model)
37
+ self.dropout = nn.Dropout(config.dropout)
38
+
39
+ def forward(self, x):
40
+ return self.dropout(self.down(F.relu(self.up(x))))
41
+
42
+
43
+ class Block(nn.Module):
44
+ def __init__(self, config):
45
+ super().__init__()
46
+ self.norm1 = nn.LayerNorm(config.d_model)
47
+ self.attn = Attention(config)
48
+ self.norm2 = nn.LayerNorm(config.d_model)
49
+ self.ffn = FFN(config)
50
+
51
+ def forward(self, x, mask=None):
52
+ x = x + self.attn(self.norm1(x), mask)
53
+ x = x + self.ffn(self.norm2(x))
54
+ return x
55
+
56
+
57
+ class TaxiLM(nn.Module): # ← Changé
58
+ def __init__(self, config: TaxiConfig): # ← Changé
59
+ super().__init__()
60
+ self.config = config
61
+ self.tok_emb = nn.Embedding(config.vocab_size, config.d_model)
62
+ self.pos_emb = nn.Embedding(config.max_seq_len, config.d_model)
63
+ self.drop = nn.Dropout(config.dropout)
64
+ self.blocks = nn.ModuleList([Block(config) for _ in range(config.n_layers)])
65
+ self.norm = nn.LayerNorm(config.d_model)
66
+ self.lm_head = nn.Linear(config.d_model, config.vocab_size, bias=False)
67
+ self.lm_head.weight = self.tok_emb.weight
68
+ self.apply(self._init_weights)
69
+
70
+ def _init_weights(self, m):
71
+ if isinstance(m, nn.Linear):
72
+ nn.init.normal_(m.weight, mean=0.0, std=0.02)
73
+ if m.bias is not None:
74
+ nn.init.zeros_(m.bias)
75
+ elif isinstance(m, nn.Embedding):
76
+ nn.init.normal_(m.weight, mean=0.0, std=0.02)
77
+
78
+ def forward(self, idx, targets=None):
79
+ B, T = idx.shape
80
+ pos = torch.arange(T, device=idx.device)
81
+ x = self.drop(self.tok_emb(idx) + self.pos_emb(pos))
82
+ mask = torch.tril(torch.ones(T, T, device=idx.device)).unsqueeze(0).unsqueeze(0)
83
+ for block in self.blocks:
84
+ x = block(x, mask)
85
+ logits = self.lm_head(self.norm(x))
86
+ loss = None
87
+ if targets is not None:
88
+ loss = F.cross_entropy(logits.view(-1, self.config.vocab_size), targets.view(-1), ignore_index=0)
89
+ return logits, loss
90
+
91
+ @torch.no_grad()
92
+ def generate(self, idx, max_new_tokens=64, temperature=0.7, top_k=50, **kwargs):
93
+ self.eval()
94
+ for _ in range(max_new_tokens):
95
+ idx_cond = idx[:, -self.config.max_seq_len:]
96
+ logits, _ = self(idx_cond)
97
+ logits = logits[:, -1, :] / temperature
98
+ if top_k > 0:
99
+ v, _ = torch.topk(logits, min(top_k, logits.size(-1)))
100
+ logits[logits < v[:, [-1]]] = float("-inf")
101
+ probs = F.softmax(logits, dim=-1)
102
+ next_id = torch.multinomial(probs, num_samples=1)
103
+ idx = torch.cat([idx, next_id], dim=1)
104
+ if next_id.item() == self.config.eos_id:
105
+ break
106
+ return idx, []
107
+
108
+ def param_count(self):
109
+ total = sum(p.numel() for p in self.parameters())
110
+ return total, 0
111
+
112
+ def param_summary(self):
113
+ total, _ = self.param_count()
114
+ return f"TaxiLM: {total:,} params ({total/1e6:.1f}M)" # ← Changé