cogforge-engine 1.0.7__tar.gz → 1.1.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: 1.0.7
3
+ Version: 1.1.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>
@@ -51,7 +51,7 @@ class Tensor:
51
51
  # if self.requires_grad:
52
52
  self.grad = None if backend.NO_GRAD else backend.np.zeros(self.shape,dtype=backend.np.float32 if typed == "compressed" else backend.np.float64)
53
53
  self._backwards = lambda:None
54
- self._children = set(children)
54
+ self._children = set() if backend.NO_GRAD else set(children)
55
55
  self.typed = typed
56
56
 
57
57
  def __getitem__(self, key):
@@ -59,6 +59,7 @@ class Tensor:
59
59
 
60
60
  out = Tensor(out_data,children=(self,))
61
61
 
62
+ if backend.NO_GRAD: return out_data
62
63
  def _backward():
63
64
  self.grad[key] += out.grad
64
65
  # backend.np.add.at(self.grad, key, out.grad)
@@ -73,7 +74,11 @@ class Tensor:
73
74
  Concatenates a sequence of Tensors along a specified axis.
74
75
  """
75
76
  arrays = tuple(t.data for t in tensors)
77
+ if backend.NO_GRAD: return Tensor(backend.np.concatenate(arrays, axis=axis))
78
+
76
79
  out = Tensor(backend.np.concatenate(arrays,axis=axis),children=tensors)
80
+
81
+
77
82
  sizes = [a.shape[axis] for a in arrays[:-1]]
78
83
  split_indices = numpy.cumsum(sizes).tolist()
79
84
 
@@ -95,6 +100,8 @@ class Tensor:
95
100
  other = other if isinstance(other, Tensor) else Tensor(other)
96
101
  out_data = self.data + other.data
97
102
  out = Tensor(out_data, (self, other))
103
+
104
+ if backend.NO_GRAD: return Tensor(out_data)
98
105
 
99
106
  def _backward():
100
107
  if self.shape != out_data.shape:
@@ -129,6 +136,8 @@ class Tensor:
129
136
  other = other if isinstance(other, Tensor) else Tensor(other)
130
137
  out_data = self.data * other.data
131
138
 
139
+ if backend.NO_GRAD: return Tensor(out_data)
140
+
132
141
  out = Tensor(out_data, children=(self, other))
133
142
 
134
143
  def _backward():
@@ -177,6 +186,9 @@ class Tensor:
177
186
  return grad
178
187
 
179
188
  def __matmul__(self, other):
189
+
190
+ if backend.NO_GRAD: return Tensor(self.data@other.data)
191
+
180
192
  out = Tensor(self.data @ other.data, children=(self, other))
181
193
  def _backward():
182
194
  gs = out.grad @ backend.np.swapaxes(other.data, -1, -2)
@@ -189,6 +201,8 @@ class Tensor:
189
201
  def relu(self):
190
202
  out_data = backend.np.maximum(0,self.data)
191
203
 
204
+ if backend.NO_GRAD: return Tensor(out_data)
205
+
192
206
  out = Tensor(out_data, children=(self,))
193
207
 
194
208
  def _backward():
@@ -208,6 +222,10 @@ class Tensor:
208
222
  arr = self.data
209
223
 
210
224
  out_data = arr.reshape(shape)
225
+
226
+ if backend.NO_GRAD: return Tensor(out_data)
227
+
228
+
211
229
  out = Tensor(out_data, children=(self,))
212
230
 
213
231
  def _backward():
@@ -222,6 +240,9 @@ class Tensor:
222
240
 
223
241
  def sigmoid(self):
224
242
  out_data = 1 / (1 + backend.np.exp(-self.data))
243
+
244
+ if backend.NO_GRAD: return Tensor(out_data)
245
+
225
246
  out = Tensor(out_data, children=(self,))
226
247
  def _backward():
227
248
  local_derivative = out_data * (1 - out_data)
@@ -233,6 +254,7 @@ class Tensor:
233
254
 
234
255
  def tanh(self):
235
256
  out_data = backend.np.tanh(self.data)
257
+ if backend.NO_GRAD: return Tensor(out_data)
236
258
  out = Tensor(out_data,children=(self,))
237
259
  def _backward():
238
260
  dervitive = 1-(out_data*out_data)
@@ -246,6 +268,7 @@ class Tensor:
246
268
  expVal = backend.np.exp(self.data-maxVal)
247
269
 
248
270
  out_data = expVal/backend.np.sum(expVal,axis=axis,keepdims=True)
271
+ if backend.NO_GRAD: return Tensor(out_data)
249
272
  out=Tensor(out_data,(self,))
250
273
 
251
274
  def _backward():
@@ -263,6 +286,7 @@ class Tensor:
263
286
  batch_size = predictions.shape[0]
264
287
 
265
288
  loss_data = - backend.np.sum(targets * backend.np.log(probabilities)) / batch_size
289
+ if backend.NO_GRAD: return cls(loss_data)
266
290
  loss = Tensor(loss_data, children=(predictions,))
267
291
 
268
292
  def _backward():
@@ -325,6 +349,8 @@ class Tensor:
325
349
  batch_size = self.shape[0]
326
350
  out_data = self.data.reshape(batch_size, -1)
327
351
 
352
+ if backend.NO_GRAD: return Tensor(out_data)
353
+
328
354
  out = Tensor(out_data, children=(self,))
329
355
  def _backward():
330
356
  self.grad += out.grad.reshape(self.shape)
@@ -346,6 +372,8 @@ class Tensor:
346
372
 
347
373
  out_data = self.data.reshape(B,T//num,C*num)
348
374
 
375
+ if backend.NO_GRAD: return Tensor(out_data)
376
+
349
377
  out = Tensor(out_data, children=(self,))
350
378
 
351
379
  def _backward():
@@ -369,6 +397,8 @@ class Tensor:
369
397
 
370
398
  # only real rows contribute to the loss value
371
399
  loss_data = -backend.np.sum(mask * targets * backend.np.log(probs)) / n_real
400
+
401
+ if backend.NO_GRAD: return cls(loss_data)
372
402
  loss = cls(loss_data, children=(predictions,))
373
403
 
374
404
  def _backward():
@@ -388,7 +418,14 @@ class Tensor:
388
418
  p = e / e.sum(axis=-1, keepdims=True)
389
419
  N = int(numpy.prod(scores.shape[:-1]))
390
420
  flat, idx, rows = p.reshape(N, -1), target_ids.reshape(N), backend.np.arange(N)
391
- loss = cls(-backend.np.log(backend.np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N, children=(scores,))
421
+ # loss = cls(-backend.np.log(backend.np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N, children=(scores,))
422
+
423
+ loss_data = -backend.np.log(backend.np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N
424
+
425
+ if backend.NO_GRAD: return cls(loss_data)
426
+
427
+ loss = cls(loss_data, children=(scores,))
428
+
392
429
  def _backward():
393
430
  # g = p.reshape(N, -1).copy()
394
431
  g = p.reshape(N, -1)
@@ -402,7 +439,14 @@ class Tensor:
402
439
  p = _stable_softmax(scores.data)
403
440
  N = int(numpy.prod(scores.shape[:-1]))
404
441
  flat, idx, rows = p.reshape(N, -1), target_ids.reshape(N), backend.np.arange(N)
405
- loss = cls(-backend.np.log(backend.np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N, children=(scores,))
442
+ # loss = cls(-backend.np.log(backend.np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N, children=(scores,))
443
+
444
+ loss_data = -backend.np.log(backend.np.clip(flat[rows, idx], 1e-15, 1.0)).sum() / N
445
+
446
+ if backend.NO_GRAD: return cls(loss_data)
447
+
448
+ loss = cls(loss_data, children=(scores,))
449
+
406
450
  def _backward():
407
451
  g = p.reshape(N, -1)
408
452
  g[rows, idx] -= 1.0
@@ -420,8 +464,14 @@ class Tensor:
420
464
  p = e / e.sum(axis=1, keepdims=True) # softmax, computed privately
421
465
  B = scores.shape[0]
422
466
 
423
- loss = cls(-backend.np.sum(targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / B, children=(scores,))
467
+ # loss = cls(-backend.np.sum(targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / B, children=(scores,))
424
468
 
469
+ loss_data = -backend.np.sum(targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / B
470
+
471
+ if backend.NO_GRAD: return cls(loss_data)
472
+
473
+ loss = cls(loss_data, children=(scores,))
474
+
425
475
  def _backward():
426
476
  scores.grad += (p - targets) / B * loss.grad
427
477
  loss._backwards = _backward
@@ -434,7 +484,10 @@ class Tensor:
434
484
  e = backend.np.exp(z)
435
485
  p = e / e.sum(axis=-1, keepdims=True)
436
486
  N = numpy.prod(scores.shape[:-1]) # B for 2D, B*T for 3D
437
- loss = cls(-backend.np.sum(targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / N, children=(scores,))
487
+ # loss = cls(-backend.np.sum(targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / N, children=(scores,))
488
+ loss_data = -backend.np.sum(targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / N
489
+ if backend.NO_GRAD: return cls(loss_data)
490
+ loss = cls(loss_data, children=(scores,))
438
491
  def _backward():
439
492
  scores.grad += (p - targets) / N * loss.grad
440
493
  loss._backwards = _backward
@@ -452,8 +505,13 @@ class Tensor:
452
505
  n_real = mask.sum()
453
506
  n_real = n_real if n_real > 0 else 1.0
454
507
 
455
- loss = cls(-backend.np.sum(mask * targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / n_real, children=(scores,))
456
-
508
+ # loss = cls(-backend.np.sum(mask * targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / n_real, children=(scores,))
509
+ loss_data = -backend.np.sum(mask * targets * backend.np.log(backend.np.clip(p, 1e-15, 1.0))) / n_real
510
+
511
+ if backend.NO_GRAD: return cls(loss_data)
512
+
513
+ loss = cls(loss_data, children=(scores,))
514
+
457
515
  def _backward():
458
516
  grad = (p - targets) / n_real
459
517
  grad = grad * mask
@@ -462,6 +520,7 @@ class Tensor:
462
520
  return loss
463
521
 
464
522
  def transpose(self,axes):
523
+ if backend.NO_GRAD: return Tensor(backend.np.transpose(self.data,axes=axes))
465
524
  out = Tensor(backend.np.transpose(self.data,axes=axes),children=(self,))
466
525
  # inv = backend.np.argsort(axes)
467
526
  inv = tuple(int(i) for i in numpy.argsort(axes))
@@ -473,12 +532,49 @@ class Tensor:
473
532
 
474
533
  def masked_fill(self, mask, value):
475
534
  out_data = backend.np.where(mask, value, self.data)
535
+ if backend.NO_GRAD: return Tensor(out_data)
476
536
  out = Tensor(out_data, children=(self,))
477
537
  def _backward():
478
538
  self.grad += backend.np.where(mask, 0.0, 1.0) * out.grad
479
539
  out._backwards = _backward
480
540
  return out
481
-
541
+
542
+ def dropout(self,p=0.1,training=True):
543
+ if not training or p == 0.0:
544
+ return self
545
+
546
+ mask = (backend.np.random.rand(*self.shape)>p).astype(self.data.dtype)
547
+ scale = 1.0 / (1.0 - p)
548
+ out_data = self.data * mask * scale
549
+ if backend.NO_GRAD: return Tensor(out_data)
550
+
551
+ out = Tensor(out_data, children=(self,))
552
+
553
+ def _backward():
554
+ self.grad += (mask * scale) * out.grad
555
+
556
+ out._backwards = _backward
557
+ return out
558
+
559
+ def dropTheWholeNeuron(self,p=0.1,training=True,axis=-1,batch_ind = 0):
560
+ if not training or p == 0.0:
561
+ return self
562
+
563
+ N = self.shape[axis]
564
+ B = self.shape[batch_ind]
565
+ R = (1 for _ in range(len(self.shape)-2))
566
+
567
+ mask = (backend.np.random.rand(B,*R,N)>p).astype(self.self.data.dtype)
568
+ scale = 1.0 / (1.0 - p)
569
+ out_data = self.data * mask *scale
570
+ if backend.NO_GRAD: return Tensor(out_data)
571
+ out = Tensor(out_data, children=(self,))
572
+
573
+ def _backward():
574
+ self.grad += (mask * scale) * out.grad
575
+
576
+ out._backwards = _backward
577
+ return out
482
578
 
483
579
 
484
580
 
@@ -539,7 +635,7 @@ class Embedding:
539
635
  def __call__(self, input_indices):
540
636
  idx = backend.np.asarray(input_indices)
541
637
  out_data = self.weights.data[idx]
542
-
638
+ if backend.NO_GRAD: return Tensor(out_data)
543
639
  out = Tensor(out_data, children=(self.weights,))
544
640
 
545
641
  def _backward():
@@ -722,7 +818,7 @@ class BatchNorm1D:
722
818
  self.x_hat = (x.data-self.running_mean)/backend.np.sqrt(self.running_var + self.eps)
723
819
 
724
820
  out_data = self.gamma.data * self.x_hat + self.beta.data
725
-
821
+ if backend.NO_GRAD: return Tensor(out_data)
726
822
  out = Tensor(out_data, children=(x, self.gamma, self.beta))
727
823
 
728
824
  def _backward():
@@ -899,6 +995,7 @@ class LayerNorm:
899
995
  std_inv = 1.0 / backend.np.sqrt(var + self.eps)
900
996
  x_hat = (x.data - mu) * std_inv
901
997
  out_data = self.gamma.data * x_hat + self.beta.data
998
+ if backend.NO_GRAD: return Tensor(out_data)
902
999
  out = Tensor(out_data, children=(x, self.gamma, self.beta))
903
1000
 
904
1001
  D = x.data.shape[-1]
@@ -926,25 +1023,33 @@ class FeedForward:
926
1023
  self.fc1 = Linear(dmodel,dff)
927
1024
  self.fc2 = Linear(dff,dmodel)
928
1025
 
929
- def __call__(self, x):
930
- return self.fc2(self.fc1(x).relu())
1026
+ def __call__(self, x,is_training = False):
1027
+ hidden:Tensor = self.fc1(x).relu()
1028
+ hidden = hidden.dropout(p=0.15,training=is_training)
1029
+ return self.fc2(hidden)
931
1030
  def parameters(self):
932
1031
  return self.fc1.parameters() + self.fc2.parameters()
933
1032
 
934
1033
  class Transformer:
935
1034
  """The transformer block has no bridge. So demb = dmodel"""
936
1035
 
937
- def __init__(self, dmodel, n, dff = None,rope=None):
1036
+ def __init__(self, dmodel, n, dff = None,rope=None, is_training = False):
938
1037
  self.ln1 = LayerNorm(dmodel)
939
1038
  self.attn = MultiHeadAttention(dinp=dmodel,dmodel=dmodel,dout=dmodel,n=n,rope=rope)
940
1039
  self.ln2 = LayerNorm(dmodel)
941
1040
  self.ff = FeedForward(dmodel=dmodel,dff=dff)
1041
+ self.is_training = is_training
1042
+
1043
+ def train(self, enabled = True):
1044
+ self.is_training = enabled
1045
+ def infer(self, enabled = True):
1046
+ self.is_training = not enabled
942
1047
 
943
1048
  def __call__(self,x,mask=None):
944
1049
  a = self.ln1(x)
945
1050
  x = x + self.attn(a,a,a,mask=mask)
946
1051
  f = self.ln2(x)
947
- x = x+ self.ff(f)
1052
+ x = x+ self.ff(f,is_training=self.is_training)
948
1053
 
949
1054
  return x
950
1055
 
@@ -0,0 +1,114 @@
1
+ from . import backend
2
+ from .app import Embedding, PositionalEncoding,Transformer,LayerNorm,Linear,RotatoryPositionalEncoding,to_cpu,needGradientHence
3
+ import numpy
4
+
5
+
6
+ class GPTV1:
7
+ def __init__(self, vocab, d_model, n_heads, n_layers, max_len, d_ff=None):
8
+ self.tok = Embedding(vocab, d_model)
9
+ self.pos = PositionalEncoding(max_len, d_model)
10
+ self.blocks = [Transformer(dmodel=d_model,n=n_heads,dff=d_ff) for _ in range(n_layers)]
11
+ self.ln_f = LayerNorm(d_model)
12
+ self.head = Linear(d_model, vocab)
13
+ self.max_len = max_len
14
+
15
+ def __call__(self, idx):
16
+ T = idx.shape[1]
17
+ casual = backend.np.triu((backend.np.ones((T,T))),k=1).astype(bool)
18
+ x = self.pos(self.tok(idx))
19
+ for block in self.blocks:
20
+ x = block(x,mask=casual)
21
+
22
+ x = self.ln_f(x)
23
+ return self.head(x)
24
+
25
+ def parameters(self):
26
+ ps = self.tok.parameters() + self.ln_f.parameters() + self.head.parameters()
27
+ for b in self.blocks: ps += b.parameters()
28
+ return ps
29
+
30
+ def generate(self, idx, n_new, temperature=1.0, top_k=None):
31
+ idx = numpy.asarray(idx)
32
+ original_grad_state = not backend.NO_GRAD
33
+ needGradientHence(False)
34
+ try:
35
+ for _ in range(n_new):
36
+ cond = idx[:, -self.max_len:]
37
+ logits = to_cpu(self(cond).data)[:, -1, :] / temperature
38
+ if top_k is not None:
39
+ kth = numpy.sort(logits, axis=-1)[:, -top_k][:, None]
40
+ logits = numpy.where(logits < kth, -1e9, logits)
41
+ z = logits - logits.max(-1, keepdims=True)
42
+ p = numpy.exp(z).astype(numpy.float64); p /= p.sum(-1, keepdims=True)
43
+ nxt = numpy.array([[numpy.random.choice(len(pr), p=pr)] for pr in p])
44
+ idx = numpy.concatenate([idx, nxt], axis=1)
45
+ return idx
46
+ finally:
47
+ needGradientHence(original_grad_state)
48
+
49
+
50
+
51
+
52
+ class GPT2:
53
+ def __init__(self, vocab, d_model, n_heads, n_layers, max_len, d_ff=None, base=10000.0,training = False):
54
+ assert d_model % n_heads == 0
55
+ self.tok = Embedding(vocab, d_model)
56
+ self.rope = RotatoryPositionalEncoding(max_len, d_model // n_heads, base) # dim = d_k
57
+ self.blocks = [Transformer(d_model, n_heads, dff=d_ff, rope=self.rope,is_training=training)
58
+ for _ in range(n_layers)]
59
+ self.ln_f = LayerNorm(d_model)
60
+ self.head = Linear(d_model, vocab)
61
+ self.max_len = max_len
62
+ self.is_training = training
63
+
64
+ def train(self, enabled = True):
65
+ self.is_training = enabled
66
+ for block in self.blocks:
67
+ block.train(enabled=enabled)
68
+ def infer(self, enabled = True):
69
+ self.is_training = not enabled
70
+ for block in self.blocks:
71
+ block.infer(enabled=enabled)
72
+
73
+
74
+ def __call__(self, idx):
75
+ T = idx.shape[1]
76
+ causal = backend.np.triu(backend.np.ones((T, T)), k=1).astype(bool)
77
+ x = self.tok(idx) # straight from token embedding
78
+ for block in self.blocks:
79
+ x = block(x, mask=causal)
80
+ return self.head(self.ln_f(x))
81
+
82
+ def parameters(self):
83
+ ps = self.tok.parameters() + self.ln_f.parameters() + self.head.parameters()
84
+ for b in self.blocks: ps += b.parameters()
85
+ return ps
86
+
87
+ def generate(self, idx, n_new, temperature=1.0, top_k=None):
88
+ idx = numpy.asarray(idx)
89
+ was_training = self.is_training
90
+ self.infer()
91
+ original_grad_state = not backend.NO_GRAD
92
+ needGradientHence(False)
93
+
94
+ try:
95
+ for _ in range(n_new):
96
+ cond = idx[:, -self.max_len:]
97
+ logits = to_cpu(self(cond).data)[:, -1, :] / temperature
98
+ if top_k is not None:
99
+ kth = numpy.sort(logits, axis=-1)[:, -top_k][:, None]
100
+ logits = numpy.where(logits < kth, -1e9, logits)
101
+ z = logits - logits.max(-1, keepdims=True)
102
+ p = numpy.exp(z).astype(numpy.float64); p /= p.sum(-1, keepdims=True)
103
+ nxt = numpy.array([[numpy.random.choice(len(pr), p=pr)] for pr in p])
104
+ idx = numpy.concatenate([idx, nxt], axis=1)
105
+ # backend._cp.get_default_memory_pool().free_all_blocks() if backend.USE_GPU else None
106
+ return idx
107
+ finally:
108
+ if was_training:
109
+ self.train()
110
+ needGradientHence(original_grad_state)
111
+
112
+
113
+
114
+
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cogforge-engine"
7
- version = "1.0.7"
7
+ version = "1.1.0"
8
8
  authors = [
9
9
  { name="Avik Majumder", email="avikmjd2@gmail.com" },
10
10
  ]
@@ -1,85 +0,0 @@
1
- from . import backend
2
- from .app import Embedding, PositionalEncoding,Transformer,LayerNorm,Linear,RotatoryPositionalEncoding,to_cpu
3
- import numpy
4
-
5
-
6
- class GPTV1:
7
- def __init__(self, vocab, d_model, n_heads, n_layers, max_len, d_ff=None):
8
- self.tok = Embedding(vocab, d_model)
9
- self.pos = PositionalEncoding(max_len, d_model)
10
- self.blocks = [Transformer(dmodel=d_model,n=n_heads,dff=d_ff) for _ in range(n_layers)]
11
- self.ln_f = LayerNorm(d_model)
12
- self.head = Linear(d_model, vocab)
13
- self.max_len = max_len
14
-
15
- def __call__(self, idx):
16
- T = idx.shape[1]
17
- casual = backend.np.triu((backend.np.ones((T,T))),k=1).astype(bool)
18
- x = self.pos(self.tok(idx))
19
- for block in self.blocks:
20
- x = block(x,mask=casual)
21
-
22
- x = self.ln_f(x)
23
- return self.head(x)
24
-
25
- def parameters(self):
26
- ps = self.tok.parameters() + self.ln_f.parameters() + self.head.parameters()
27
- for b in self.blocks: ps += b.parameters()
28
- return ps
29
-
30
- def generate(self, idx, n_new, temperature=1.0, top_k=None):
31
- idx = numpy.asarray(idx)
32
- for _ in range(n_new):
33
- cond = idx[:, -self.max_len:]
34
- logits = to_cpu(self(cond).data)[:, -1, :] / temperature
35
- if top_k is not None:
36
- kth = numpy.sort(logits, axis=-1)[:, -top_k][:, None]
37
- logits = numpy.where(logits < kth, -1e9, logits)
38
- z = logits - logits.max(-1, keepdims=True)
39
- p = numpy.exp(z).astype(numpy.float64); p /= p.sum(-1, keepdims=True)
40
- nxt = numpy.array([[numpy.random.choice(len(pr), p=pr)] for pr in p])
41
- idx = numpy.concatenate([idx, nxt], axis=1)
42
- return idx # <-- was a bare `return`
43
-
44
-
45
-
46
-
47
- class GPT2:
48
- def __init__(self, vocab, d_model, n_heads, n_layers, max_len, d_ff=None, base=10000.0):
49
- assert d_model % n_heads == 0
50
- self.tok = Embedding(vocab, d_model)
51
- self.rope = RotatoryPositionalEncoding(max_len, d_model // n_heads, base) # dim = d_k
52
- self.blocks = [Transformer(d_model, n_heads, dff=d_ff, rope=self.rope)
53
- for _ in range(n_layers)]
54
- self.ln_f = LayerNorm(d_model)
55
- self.head = Linear(d_model, vocab)
56
- self.max_len = max_len
57
-
58
-
59
- def __call__(self, idx):
60
- T = idx.shape[1]
61
- causal = backend.np.triu(backend.np.ones((T, T)), k=1).astype(bool)
62
- x = self.tok(idx) # straight from token embedding
63
- for block in self.blocks:
64
- x = block(x, mask=causal)
65
- return self.head(self.ln_f(x))
66
-
67
- def parameters(self):
68
- ps = self.tok.parameters() + self.ln_f.parameters() + self.head.parameters()
69
- for b in self.blocks: ps += b.parameters()
70
- return ps
71
-
72
- def generate(self, idx, n_new, temperature=1.0, top_k=None):
73
- idx = numpy.asarray(idx) # token ids live on host
74
- for _ in range(n_new):
75
- cond = idx[:, -self.max_len:]
76
- logits = to_cpu(self(cond).data)[:, -1, :] / temperature # forward on GPU, logits to host
77
- if top_k is not None:
78
- kth = numpy.sort(logits, axis=-1)[:, -top_k][:, None]
79
- logits = numpy.where(logits < kth, -1e9, logits)
80
- z = logits - logits.max(-1, keepdims=True)
81
- p = numpy.exp(z).astype(numpy.float64); p /= p.sum(-1, keepdims=True)
82
- nxt = numpy.array([[numpy.random.choice(len(pr), p=pr)] for pr in p])
83
- idx = numpy.concatenate([idx, nxt], axis=1)
84
- # backend._cp.get_default_memory_pool().free_all_blocks() if backend.USE_GPU else None
85
- return idx
File without changes