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.
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/PKG-INFO +1 -1
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/cogforge/__init__.py +1 -1
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/cogforge/app.py +23 -7
- cogforge_engine-0.2.0/cogforge/models.py +44 -0
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/pyproject.toml +1 -1
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/.github/workflows/release.yml +0 -0
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/.gitignore +0 -0
- {cogforge_engine-0.1.0 → cogforge_engine-0.2.0}/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cogforge-engine
|
|
3
|
-
Version: 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,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=
|
|
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
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|