cogforge-engine 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cogforge-engine
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: A custom autograd engine and Transformer block built from scratch.
5
5
  Project-URL: Homepage, https://github.com/avikmjd2/cogforge
6
6
  Author-email: Avik Majumder <avikmjd2@gmail.com>
@@ -1,4 +1,4 @@
1
- __version__ = "0.1.0"
1
+ __version__ = "0.2.0"
2
2
 
3
3
  from .app import (
4
4
  Tensor,
@@ -1,14 +1,15 @@
1
1
  import numpy as np
2
2
 
3
3
  class Tensor:
4
- def __init__(self, array,children=(),requires_grad = True):
5
- self.data = np.asarray(array, dtype=float)
4
+ def __init__(self, array,children=(),requires_grad = True,typed="compressed"):
5
+ self.data = np.asarray(array, dtype=np.float32 if typed == "compressed" else np.float64)
6
6
  self.shape = self.data.shape
7
7
  self.requires_grad = requires_grad
8
8
  # if self.requires_grad:
9
- self.grad = np.zeros(self.shape)
9
+ self.grad = np.zeros(self.shape,dtype=np.float32 if typed == "compressed" else np.float64)
10
10
  self._backwards = lambda:None
11
11
  self._children = set(children)
12
+ self.typed = typed
12
13
 
13
14
  def __getitem__(self, key):
14
15
  out_data = self.data[key]
@@ -221,7 +222,7 @@ class Tensor:
221
222
 
222
223
  topoSort(self)
223
224
 
224
- self.grad = np.ones(self.shape)
225
+ self.grad = np.ones(self.shape,dtype=np.float32 if self.typed == "compressed" else np.float64)
225
226
 
226
227
  for node in reversed(topo):
227
228
  node._backwards()
@@ -244,7 +245,7 @@ class Tensor:
244
245
  for child in node._children:
245
246
  stack.append((child,False))
246
247
 
247
- self.grad = np.ones(self.shape)
248
+ self.grad = np.ones(self.shape,dtype=np.float32 if self.typed == "compressed" else np.float64)
248
249
 
249
250
  for node in reversed(topo):
250
251
  node._backwards()
@@ -308,6 +309,22 @@ class Tensor:
308
309
 
309
310
  loss._backwards = _backward
310
311
  return loss
312
+
313
+ @classmethod
314
+ def sparse_softmax_cross_entropy(cls, scores, target_ids):
315
+ """ scores: (B, T, V) logits ; target_ids: (B, T) int """
316
+ z = scores.data - scores.data.max(axis=-1, keepdims=True)
317
+ e = np.exp(z)
318
+ p = e / e.sum(axis=-1, keepdims=True)
319
+ N = int(np.prod(scores.shape[:-1]))
320
+ flat, idx, rows = p.reshape(N, -1), target_ids.reshape(N), np.arange(N)
321
+ loss = cls(-np.log(np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N, children=(scores,))
322
+ def _backward():
323
+ g = p.reshape(N, -1).copy()
324
+ g[rows, idx] -= 1.0 # (softmax - onehot)
325
+ scores.grad += (g.reshape(scores.shape) / N) * loss.grad
326
+ loss._backwards = _backward
327
+ return loss
311
328
 
312
329
  #Legacy
313
330
  @classmethod
@@ -860,5 +877,4 @@ class PositionalEncoding:
860
877
 
861
878
  def parameters(self):
862
879
  return []
863
-
864
-
880
+
@@ -0,0 +1,44 @@
1
+ import numpy as np
2
+ from app import Embedding, PositionalEncoding,Transformer,LayerNorm,Linear
3
+
4
+ class GPTV1:
5
+ def __init__(self, vocab, d_model, n_heads, n_layers, max_len, d_ff=None):
6
+ self.tok = Embedding(vocab, d_model)
7
+ self.pos = PositionalEncoding(max_len, d_model)
8
+ self.blocks = [Transformer(dmodel=d_model,n=n_heads,dff=d_ff) for _ in range(n_layers)]
9
+ self.ln_f = LayerNorm(d_model)
10
+ self.head = Linear(d_model, vocab)
11
+ self.max_len = max_len
12
+
13
+ def __call__(self, idx):
14
+ T = idx.shape[1]
15
+ casual = np.triu((np.ones((T,T))),k=1).astype(bool)
16
+ x = self.pos(self.tok(idx))
17
+ for block in self.blocks:
18
+ x = block(x,mask=casual)
19
+
20
+ x = self.ln_f(x)
21
+ return self.head(x)
22
+
23
+ def parameters(self):
24
+ ps = self.tok.parameters() + self.ln_f.parameters() + self.head.parameters()
25
+ for b in self.blocks: ps += b.parameters()
26
+ return ps
27
+
28
+ def generate(self, idx, n_new, temperature=1.0, top_k=None):
29
+ """
30
+ idx: (B, T) int array — the prompt (B is usually 1)
31
+ returns: (B, T + n_new) int array
32
+ """
33
+ for _ in range(n_new):
34
+ cond = idx[:, -self.max_len:] # crop to context window
35
+ logits = self(cond).data[:, -1, :] / temperature # (B, V) — last position only
36
+ if top_k is not None:
37
+ kth = np.sort(logits, axis=-1)[:, -top_k][:, None]
38
+ logits = np.where(logits < kth, -1e9, logits) # keep only top-k choices
39
+ z = logits - logits.max(-1, keepdims=True)
40
+ p = np.exp(z).astype(np.float64); p /= p.sum(-1, keepdims=True) # softmax → probabilities
41
+ nxt = np.array([[np.random.choice(len(pr), p=pr)] for pr in p]) # sample
42
+ idx = np.concatenate([idx, nxt], axis=1) # append, feed back in
43
+ return idx # <-- was a bare `return`
44
+
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cogforge-engine"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  authors = [
9
9
  { name="Avik Majumder", email="avikmjd2@gmail.com" },
10
10
  ]