AGofficial commited on
Commit
285857b
·
verified ·
1 Parent(s): 077c173

Upload 4 files

Browse files
Files changed (4) hide show
  1. aglm/config.json +12 -0
  2. aglm/model.pt +3 -0
  3. aglm/tokenizer.json +0 -0
  4. gpt_chat.py +141 -0
aglm/config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_name": "AgLM",
3
+ "block_size": 128,
4
+ "n_embd": 128,
5
+ "n_head": 4,
6
+ "n_layer": 4,
7
+ "vocab_size": 8000,
8
+ "batch_size": 8,
9
+ "grad_accum": 4,
10
+ "max_epochs": 3,
11
+ "end_token_id": 4
12
+ }
aglm/model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b3ce58b730f490c19b272866d043e0ff9eb64abb648a392d0a2eb35314211d5a
3
+ size 12512854
aglm/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
gpt_chat.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import json
3
+ from torch.nn import functional as F
4
+ from tokenizers import Tokenizer
5
+ from pathlib import Path
6
+ import os
7
+
8
+ # LightweightGPT Model
9
+ class LightweightGPT(torch.nn.Module):
10
+ """Compact GPT-like model with causal masking and positional encoding"""
11
+ def __init__(self, vocab_size, block_size, n_embd, n_head, n_layer):
12
+ super().__init__()
13
+ self.block_size = block_size
14
+ self.token_embedding = torch.nn.Embedding(vocab_size, n_embd)
15
+ self.position_embedding = torch.nn.Embedding(block_size, n_embd)
16
+
17
+ self.blocks = torch.nn.ModuleList([
18
+ torch.nn.TransformerDecoderLayer(
19
+ d_model=n_embd,
20
+ nhead=n_head,
21
+ dim_feedforward=4 * n_embd,
22
+ dropout=0.1,
23
+ activation='gelu',
24
+ batch_first=True,
25
+ norm_first=True
26
+ )
27
+ for _ in range(n_layer)
28
+ ])
29
+ self.ln_f = torch.nn.LayerNorm(n_embd)
30
+ self.lm_head = torch.nn.Linear(n_embd, vocab_size, bias=False)
31
+
32
+ def forward(self, idx, targets=None):
33
+ B, T = idx.shape
34
+ device = idx.device
35
+ causal_mask = torch.triu(torch.ones(T, T, device=device, dtype=torch.bool), diagonal=1)
36
+
37
+ token_emb = self.token_embedding(idx)
38
+ pos = torch.arange(0, T, dtype=torch.long, device=device)
39
+ pos_emb = self.position_embedding(pos)
40
+
41
+ x = token_emb + pos_emb
42
+
43
+ for block in self.blocks:
44
+ x = block(x, x, tgt_mask=causal_mask)
45
+
46
+ x = self.ln_f(x)
47
+ logits = self.lm_head(x)
48
+
49
+ loss = None
50
+ if targets is not None:
51
+ loss = F.cross_entropy(
52
+ logits.view(-1, logits.size(-1)),
53
+ targets.view(-1),
54
+ ignore_index=-1
55
+ )
56
+ return logits, loss
57
+
58
+ def generate(self, idx, max_new_tokens, temperature=0.8, top_k=50, stop_token=None):
59
+ """Generate text with context handling and positional encoding"""
60
+ for _ in range(max_new_tokens):
61
+ idx_cond = idx[:, -self.block_size:]
62
+ logits, _ = self(idx_cond)
63
+ logits = logits[:, -1, :]
64
+ logits = logits / temperature
65
+
66
+ if top_k is not None:
67
+ v, _ = torch.topk(logits, min(top_k, logits.size(-1)))
68
+ logits[logits < v[:, [-1]]] = -float('Inf')
69
+
70
+ probs = F.softmax(logits, dim=-1)
71
+ idx_next = torch.multinomial(probs, num_samples=1)
72
+
73
+ if stop_token is not None and idx_next.item() == stop_token:
74
+ break
75
+
76
+ idx = torch.cat((idx, idx_next), dim=1)
77
+
78
+ return idx
79
+
80
+ # Chat Interface
81
+ class ChatInterface:
82
+ def __init__(self, model_dir="/"):
83
+ self.model_dir = Path(model_dir)
84
+ self.device = "mps" if torch.backends.mps.is_available() else "cuda" if torch.cuda.is_available() else "cpu"
85
+ self.load_model()
86
+
87
+ def load_model(self):
88
+ with open(self.model_dir / "config.json", "r") as f:
89
+ self.config = json.load(f)
90
+
91
+ self.tokenizer = Tokenizer.from_file(str(self.model_dir / "tokenizer.json"))
92
+ self.end_token_id = self.config.get("end_token_id")
93
+
94
+ self.model = LightweightGPT(
95
+ vocab_size=self.config["vocab_size"],
96
+ block_size=self.config["block_size"],
97
+ n_embd=self.config["n_embd"],
98
+ n_head=self.config["n_head"],
99
+ n_layer=self.config["n_layer"]
100
+ ).to(self.device)
101
+
102
+ self.model.load_state_dict(torch.load(self.model_dir / "model.pt", map_location=self.device))
103
+ self.model.eval()
104
+ print("✅ Model loaded successfully!")
105
+
106
+ def chat(self):
107
+ print("\n===== AI Assistant Ready =====")
108
+ print("Type 'quit' or 'exit' to end the chat.\n")
109
+
110
+ while True:
111
+ user_input = input("user: ")
112
+ if user_input.lower() in ["quit", "exit"]:
113
+ break
114
+
115
+ prompt = f"user: {user_input}\nai:"
116
+ input_ids = self.tokenizer.encode(prompt).ids
117
+ input_tensor = torch.tensor([input_ids], dtype=torch.long, device=self.device)
118
+
119
+ with torch.no_grad():
120
+ output_ids = self.model.generate(
121
+ input_tensor,
122
+ max_new_tokens=150,
123
+ temperature=0.7,
124
+ top_k=40,
125
+ stop_token=self.end_token_id
126
+ )
127
+
128
+ response_ids = output_ids[0, len(input_ids):].tolist()
129
+ response = self.tokenizer.decode(response_ids)
130
+ response = response.replace("<|endoftext|>", "").strip()
131
+
132
+ print(f"ai: {response}")
133
+
134
+ # Main execution
135
+ if __name__ == "__main__":
136
+ model_folder = "aglm"
137
+ if os.path.exists(model_folder) and os.path.exists(os.path.join(model_folder, "model.pt")):
138
+ chat_bot = ChatInterface(model_dir=model_folder)
139
+ chat_bot.chat()
140
+ else:
141
+ print(f"\nERROR: Model directory '{model_folder}' not found. Please ensure the model is trained and the directory contains 'model.pt' and 'config.json'.")