| Property | Value |
|---|---|
| Parameters | 353.6M |
| Architecture | GPT (decoder-only transformer) |
| Layers | 24 |
| Attention heads | 16 |
| Hidden size | 1024 |
| Context length | 2048 tokens |
| Vocabulary | 50,304 (GPT-2 tokenizer, padded to multiple of 64) |
| Normalization | RMSNorm |
| Attention | Flash Attention (scaled dot-product) |
| Positional encoding | Learned positional embeddings |
| Weight tying | Input embedding ↔ output projection |
| Property | Value |
|---|---|
| Dataset | FineWeb-Edu (sample-10BT) |
| Tokens trained | 6.83 billion |
| Steps | 6,314 |
| Batch size | 512 sequences × 2048 tokens = ~1M tokens/step |
| Optimizer | AdamW (fused), β₁=0.9, β₂=0.95, weight decay=0.1 |
| Learning rate | 3e-4 → 3e-5 (cosine decay with linear warmup) |
| Precision | BF16 |
| Hardware | NVIDIA A100 SXM 80GB |
| Final val loss | ~3.04 |
| Final perplexity | ~20.9 |
| Property | Value |
|---|---|
| Dataset | OpenHermes 2.5 |
| Samples | 746,250 instruction-response pairs |
| Tokens | 288M |
| Steps | 8,000 |
| Learning rate | 1e-5 → 1e-6 (cosine) |
| Format | ### Human: {question}\n### Assistant: {answer}<|endoftext|> |
| Property | Value |
|---|---|
| Dataset | Custom identity dataset |
| Examples | ~936 |
| Tokens | ~172K |
| Purpose | Teach model information about Islam Kathat and personal projects |
| Learning Rate | 1e-6 |
| Steps | 200 |
Prompt: what is Machine Learning?
Model: Machine learning is a subset of artificial intelligence with the objective of improving, verifying or optimizing systems for specific tasks using algorithms that generate unstructured, meaningful output.Prompt: what is the future of AI?
Model: The future of AI is uncertain. We are seeing great advances in machine learning, artificial intelligence, robotics, and personalized medicine. And we will continue to learn, innovate, and adapt as our skills improve, but I don�t want to tell you that AI isn�t here yet — because it has been around for a long time.1# ============================================================
2# Load and Run Islam Kathat's 350M LLM from Hugging Face
3# (with live token streaming)
4# ============================================================
5
6# !pip install -q torch tiktoken huggingface_hub
7
8import torch
9import torch.nn as nn
10import torch.nn.functional as F
11import tiktoken
12from huggingface_hub import hf_hub_download
13
14# Download checkpoint from Hugging Face
15MODEL_PATH = hf_hub_download(
16 repo_id="FazeFlynn/my-350M-LLM",
17 filename="llm-350m.pt"
18)
19
20# Device
21device = "cuda" if torch.cuda.is_available() else "cpu"
22
23# Load checkpoint
24ckpt = torch.load(
25 MODEL_PATH,
26 map_location=device,
27 weights_only=False
28)
29
30print("Checkpoint Keys:")
31print(ckpt.keys())
32
33config = ckpt["model_config"]
34
35# Model Definition
36class RMSNorm(nn.Module):
37 def __init__(self, dim, eps=1e-6):
38 super().__init__()
39 self.eps = eps
40 self.weight = nn.Parameter(torch.ones(dim))
41
42 def forward(self, x):
43 return x * torch.rsqrt(
44 x.pow(2).mean(-1, keepdim=True) + self.eps
45 ) * self.weight
46
47
48class CausalSelfAttention(nn.Module):
49 def __init__(self, config):
50 super().__init__()
51
52 self.n_head = config["n_head"]
53 self.n_embd = config["n_embd"]
54 self.head_dim = self.n_embd // self.n_head
55
56 self.c_attn = nn.Linear(
57 self.n_embd,
58 3 * self.n_embd,
59 bias=config["bias"]
60 )
61
62 self.c_proj = nn.Linear(
63 self.n_embd,
64 self.n_embd,
65 bias=config["bias"]
66 )
67
68 def forward(self, x):
69 B, T, C = x.shape
70
71 q, k, v = self.c_attn(x).split(
72 self.n_embd,
73 dim=2
74 )
75
76 q = q.view(
77 B, T, self.n_head, self.head_dim
78 ).transpose(1, 2)
79
80 k = k.view(
81 B, T, self.n_head, self.head_dim
82 ).transpose(1, 2)
83
84 v = v.view(
85 B, T, self.n_head, self.head_dim
86 ).transpose(1, 2)
87
88 y = F.scaled_dot_product_attention(
89 q,
90 k,
91 v,
92 is_causal=True
93 )
94
95 y = (
96 y.transpose(1, 2)
97 .contiguous()
98 .view(B, T, C)
99 )
100
101 return self.c_proj(y)
102
103
104class MLP(nn.Module):
105 def __init__(self, config):
106 super().__init__()
107
108 self.c_fc = nn.Linear(
109 config["n_embd"],
110 4 * config["n_embd"],
111 bias=config["bias"]
112 )
113
114 self.c_proj = nn.Linear(
115 4 * config["n_embd"],
116 config["n_embd"],
117 bias=config["bias"]
118 )
119
120 self.act = nn.GELU()
121
122 def forward(self, x):
123 return self.c_proj(
124 self.act(self.c_fc(x))
125 )
126
127
128class Block(nn.Module):
129 def __init__(self, config):
130 super().__init__()
131
132 self.ln1 = RMSNorm(config["n_embd"])
133 self.attn = CausalSelfAttention(config)
134
135 self.ln2 = RMSNorm(config["n_embd"])
136 self.mlp = MLP(config)
137
138 def forward(self, x):
139 x = x + self.attn(self.ln1(x))
140 x = x + self.mlp(self.ln2(x))
141 return x
142
143
144class GPT(nn.Module):
145 def __init__(self, config):
146 super().__init__()
147
148 self.wte = nn.Embedding(
149 config["vocab_size"],
150 config["n_embd"]
151 )
152
153 self.wpe = nn.Embedding(
154 config["block_size"],
155 config["n_embd"]
156 )
157
158 self.blocks = nn.ModuleList([
159 Block(config)
160 for _ in range(config["n_layer"])
161 ])
162
163 self.ln_f = RMSNorm(config["n_embd"])
164
165 self.lm_head = nn.Linear(
166 config["n_embd"],
167 config["vocab_size"],
168 bias=False
169 )
170
171 self.wte.weight = self.lm_head.weight
172
173 def forward(self, idx):
174 B, T = idx.shape
175
176 pos = torch.arange(
177 T,
178 device=idx.device
179 )
180
181 x = self.wte(idx) + self.wpe(pos)
182
183 for block in self.blocks:
184 x = block(x)
185
186 x = self.ln_f(x)
187
188 logits = self.lm_head(x)
189
190 return logits
191
192
193# Create model
194model = GPT(config).to(device)
195
196# Load weights
197if "model_state_dict" in ckpt:
198 model.load_state_dict(ckpt["model_state_dict"])
199
200elif "model" in ckpt:
201 model.load_state_dict(ckpt["model"])
202
203else:
204 raise ValueError(
205 f"Unknown checkpoint keys: {ckpt.keys()}"
206 )
207
208model.eval()
209
210# Tokenizer
211enc = tiktoken.get_encoding("gpt2")
212
213# Streaming Generate Function
214@torch.no_grad()
215def generate(
216 prompt,
217 max_new_tokens=200,
218 temperature=0.8,
219 top_k=50
220):
221 """
222 Generates text token-by-token and prints each piece live
223 as it's produced (like ChatGPT-style streaming).
224 """
225
226 formatted = (
227 f"### Human: {prompt}\n"
228 f"### Assistant:"
229 )
230
231 ids = enc.encode(formatted)
232
233 x = torch.tensor(
234 [ids],
235 dtype=torch.long,
236 device=device
237 )
238
239 prev_text = "" # tracks decoded text so far, to print only new chars
240
241 for _ in range(max_new_tokens):
242
243 logits = model(x[:, -2048:])
244
245 logits = logits[:, -1, :] / temperature
246
247 v, _ = torch.topk(logits, top_k)
248
249 logits[
250 logits < v[:, [-1]]
251 ] = float("-inf")
252
253 probs = F.softmax(
254 logits,
255 dim=-1
256 )
257
258 next_token = torch.multinomial(
259 probs,
260 num_samples=1
261 )
262
263 x = torch.cat(
264 [x, next_token],
265 dim=1
266 )
267
268 if next_token.item() == enc.eot_token:
269 break
270
271 full_text = enc.decode(x[0].tolist())
272 assistant_text = full_text.split("### Assistant:")[-1]
273
274 new_piece = assistant_text[len(prev_text):]
275 print(new_piece, end="", flush=True)
276 prev_text = assistant_text
277
278 print() # final newline after generation finishes
279
280 # The return part is commented to avoid 2 responses in notebooks
281 # return prev_text.strip()
282
283
284# Generate
285generate("What is Machine Learning?")1class RMSNorm(nn.Module):
2 """RMSNorm instead of LayerNorm — faster, no mean subtraction."""
3 def __init__(self, dim, eps=1e-6):
4 super().__init__()
5 self.eps = eps
6 self.weight = nn.Parameter(torch.ones(dim))
7 def forward(self, x):
8 return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.weight
9
10class CausalSelfAttention(nn.Module):
11 def __init__(self, config):
12 super().__init__()
13 self.n_head = config["n_head"]
14 self.n_embd = config["n_embd"]
15 self.head_dim = self.n_embd // self.n_head
16 self.c_attn = nn.Linear(self.n_embd, 3 * self.n_embd, bias=config["bias"])
17 self.c_proj = nn.Linear(self.n_embd, self.n_embd, bias=config["bias"])
18 def forward(self, x):
19 B, T, C = x.shape
20 q, k, v = self.c_attn(x).split(self.n_embd, dim=2)
21 q = q.view(B, T, self.n_head, self.head_dim).transpose(1, 2)
22 k = k.view(B, T, self.n_head, self.head_dim).transpose(1, 2)
23 v = v.view(B, T, self.n_head, self.head_dim).transpose(1, 2)
24 y = F.scaled_dot_product_attention(q, k, v, is_causal=True)
25 return self.c_proj(y.transpose(1, 2).contiguous().view(B, T, C))
26
27class MLP(nn.Module):
28 def __init__(self, config):
29 super().__init__()
30 self.c_fc = nn.Linear(config["n_embd"], 4 * config["n_embd"], bias=config["bias"])
31 self.c_proj = nn.Linear(4 * config["n_embd"], config["n_embd"], bias=config["bias"])
32 self.act = nn.GELU()
33 def forward(self, x):
34 return self.c_proj(self.act(self.c_fc(x)))
35
36class Block(nn.Module):
37 def __init__(self, config):
38 super().__init__()
39 self.ln1 = RMSNorm(config["n_embd"])
40 self.attn = CausalSelfAttention(config)
41 self.ln2 = RMSNorm(config["n_embd"])
42 self.mlp = MLP(config)
43 def forward(self, x):
44 x = x + self.attn(self.ln1(x))
45 x = x + self.mlp(self.ln2(x))
46 return x
47
48class GPT(nn.Module):
49 def __init__(self, config):
50 super().__init__()
51 self.config = config
52 self.wte = nn.Embedding(config["vocab_size"], config["n_embd"])
53 self.wpe = nn.Embedding(config["block_size"], config["n_embd"])
54 self.blocks = nn.ModuleList([Block(config) for _ in range(config["n_layer"])])
55 self.ln_f = RMSNorm(config["n_embd"])
56 self.lm_head = nn.Linear(config["n_embd"], config["vocab_size"], bias=False)
57 self.wte.weight = self.lm_head.weight # weight tying
58 def forward(self, idx, targets=None):
59 B, T = idx.shape
60 pos = torch.arange(T, device=idx.device)
61 x = self.wte(idx) + self.wpe(pos)
62 for block in self.blocks:
63 x = block(x)
64 x = self.ln_f(x)
65 logits = self.lm_head(x)
66 loss = None
67 if targets is not None:
68 loss = F.cross_entropy(logits.view(-1, logits.size(-1)), targets.view(-1), ignore_index=-100)
69 return logits, loss.pt file is a standard PyTorch checkpoint:1{
2 "model_state_dict": ..., # model weights
3 "optimizer_state_dict": ..., # AdamW states
4 "model_config": {
5 "vocab_size": 50304,
6 "n_layer": 24,
7 "n_head": 16,
8 "n_embd": 1024,
9 "block_size": 2048,
10 "dropout": 0.0,
11 "bias": False,
12 },
13 "step": ...,
14 "best_val_loss": ...,
15}1@misc{kathat2026llm350m,
2 author = {Islam Kathat},
3 title = {350M Parameter GPT Language Model},
4 year = {2026},
5 publisher = {HuggingFace},
6 url = {https://huggingface.co/FazeFlynn/my-350M-LLM}
7}