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.
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/PKG-INFO +1 -1
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/cogforge/app.py +119 -14
- cogforge_engine-1.1.0/cogforge/models.py +114 -0
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/pyproject.toml +1 -1
- cogforge_engine-1.0.7/cogforge/models.py +0 -85
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/.github/workflows/release.yml +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/.gitignore +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/LICENSE +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/README.md +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/cogforge/__init__.py +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-1.1.0}/cogforge/backend.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cogforge-engine
|
|
3
|
-
Version: 1.0
|
|
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
|
-
|
|
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
|
+
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|