cogforge-engine 1.0.7__tar.gz → 2.0.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-2.0.0}/PKG-INFO +1 -1
- cogforge_engine-2.0.0/TODO +7 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/cogforge/app.py +198 -14
- cogforge_engine-2.0.0/cogforge/models.py +254 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/pyproject.toml +1 -1
- cogforge_engine-1.0.7/cogforge/models.py +0 -85
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/.github/workflows/release.yml +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/.gitignore +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/LICENSE +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/README.md +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/cogforge/__init__.py +0 -0
- {cogforge_engine-1.0.7 → cogforge_engine-2.0.0}/cogforge/backend.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cogforge-engine
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.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():
|
|
@@ -885,6 +981,47 @@ class MultiHeadAttention:
|
|
|
885
981
|
def parameters(self):
|
|
886
982
|
return (self.q.parameters() + self.k.parameters()
|
|
887
983
|
+ self.v.parameters() + self.o.parameters())
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
class CrossAttention:
|
|
988
|
+
def __init__(self, dim_dec, dim_enc,d_out, dec_rope = None, enc_rope = None,d_k=None, h=None, d_model = None):
|
|
989
|
+
assert (d_k and h) or (d_model and h), "Model Parameters not defined"
|
|
990
|
+
self.d_model = d_model if d_model is not None else h*d_k
|
|
991
|
+
self.q = Linear(nin=dim_dec, nout=self.d_model)
|
|
992
|
+
self.k = Linear(nin=dim_enc, nout=self.d_model)
|
|
993
|
+
self.v = Linear(nin=dim_enc, nout=self.d_model)
|
|
994
|
+
self.d_out = d_out
|
|
995
|
+
self.o = Linear(nin=self.d_model, nout=d_out)
|
|
996
|
+
self.dk = d_k if d_k is not None else d_model//h
|
|
997
|
+
self.h = h
|
|
998
|
+
self.dec_rope = dec_rope
|
|
999
|
+
self.enc_rope = enc_rope
|
|
1000
|
+
self.attention = Attention(self.dk)
|
|
1001
|
+
|
|
1002
|
+
def split(self,x:Tensor):
|
|
1003
|
+
B,T,_ = x.data.shape
|
|
1004
|
+
return x.view((B,T,self.h,self.dk)).transpose((0,2,1,3)) #(B, h, T, d_k)
|
|
1005
|
+
|
|
1006
|
+
def merge(self,x:Tensor):
|
|
1007
|
+
B, h, T, d_k = x.data.shape
|
|
1008
|
+
return x.transpose((0, 2, 1, 3)).view((B, T, h * d_k))
|
|
1009
|
+
|
|
1010
|
+
def __call__(self, x_decod,x_encod, mask=None):
|
|
1011
|
+
Q = self.split(self.q(x_decod))
|
|
1012
|
+
K = self.split(self.k(x_encod))
|
|
1013
|
+
V = self.split(self.v(x_encod))
|
|
1014
|
+
if self.dec_rope is not None:
|
|
1015
|
+
Q = self.dec_rope(Q)
|
|
1016
|
+
if self.enc_rope is not None:
|
|
1017
|
+
K = self.enc_rope(K)
|
|
1018
|
+
|
|
1019
|
+
out = self.attention(Q=Q,K=K,V=V,mask=mask)
|
|
1020
|
+
return self.o(self.merge(out))
|
|
1021
|
+
|
|
1022
|
+
def parameters(self):
|
|
1023
|
+
return (self.q.parameters() + self.k.parameters()
|
|
1024
|
+
+ self.v.parameters() + self.o.parameters())
|
|
888
1025
|
|
|
889
1026
|
|
|
890
1027
|
class LayerNorm:
|
|
@@ -899,6 +1036,7 @@ class LayerNorm:
|
|
|
899
1036
|
std_inv = 1.0 / backend.np.sqrt(var + self.eps)
|
|
900
1037
|
x_hat = (x.data - mu) * std_inv
|
|
901
1038
|
out_data = self.gamma.data * x_hat + self.beta.data
|
|
1039
|
+
if backend.NO_GRAD: return Tensor(out_data)
|
|
902
1040
|
out = Tensor(out_data, children=(x, self.gamma, self.beta))
|
|
903
1041
|
|
|
904
1042
|
D = x.data.shape[-1]
|
|
@@ -926,25 +1064,33 @@ class FeedForward:
|
|
|
926
1064
|
self.fc1 = Linear(dmodel,dff)
|
|
927
1065
|
self.fc2 = Linear(dff,dmodel)
|
|
928
1066
|
|
|
929
|
-
def __call__(self, x):
|
|
930
|
-
|
|
1067
|
+
def __call__(self, x,is_training = False):
|
|
1068
|
+
hidden:Tensor = self.fc1(x).relu()
|
|
1069
|
+
hidden = hidden.dropout(p=0.15,training=is_training)
|
|
1070
|
+
return self.fc2(hidden)
|
|
931
1071
|
def parameters(self):
|
|
932
1072
|
return self.fc1.parameters() + self.fc2.parameters()
|
|
933
1073
|
|
|
934
1074
|
class Transformer:
|
|
935
1075
|
"""The transformer block has no bridge. So demb = dmodel"""
|
|
936
1076
|
|
|
937
|
-
def __init__(self, dmodel, n, dff = None,rope=None):
|
|
1077
|
+
def __init__(self, dmodel, n, dff = None,rope=None, is_training = False):
|
|
938
1078
|
self.ln1 = LayerNorm(dmodel)
|
|
939
1079
|
self.attn = MultiHeadAttention(dinp=dmodel,dmodel=dmodel,dout=dmodel,n=n,rope=rope)
|
|
940
1080
|
self.ln2 = LayerNorm(dmodel)
|
|
941
1081
|
self.ff = FeedForward(dmodel=dmodel,dff=dff)
|
|
1082
|
+
self.is_training = is_training
|
|
1083
|
+
|
|
1084
|
+
def train(self, enabled = True):
|
|
1085
|
+
self.is_training = enabled
|
|
1086
|
+
def infer(self, enabled = True):
|
|
1087
|
+
self.is_training = not enabled
|
|
942
1088
|
|
|
943
1089
|
def __call__(self,x,mask=None):
|
|
944
1090
|
a = self.ln1(x)
|
|
945
1091
|
x = x + self.attn(a,a,a,mask=mask)
|
|
946
1092
|
f = self.ln2(x)
|
|
947
|
-
x = x+ self.ff(f)
|
|
1093
|
+
x = x+ self.ff(f,is_training=self.is_training)
|
|
948
1094
|
|
|
949
1095
|
return x
|
|
950
1096
|
|
|
@@ -952,6 +1098,44 @@ class Transformer:
|
|
|
952
1098
|
return (self.ln1.parameters() + self.attn.parameters()
|
|
953
1099
|
+ self.ln2.parameters() + self.ff.parameters())
|
|
954
1100
|
|
|
1101
|
+
|
|
1102
|
+
class Decoder:
|
|
1103
|
+
"""The decoder block has no bridge. So demb = dmodel"""
|
|
1104
|
+
def __init__(self, d_model, n_heads, d_ff=None, is_training=False,dec_in_rope=None,enc_rope=None,dec_rope=None):
|
|
1105
|
+
self.ln1 = LayerNorm(d_model)
|
|
1106
|
+
self.self_attn = MultiHeadAttention(dinp=d_model,dmodel=d_model,dout=d_model,n=n_heads,rope=dec_in_rope)
|
|
1107
|
+
|
|
1108
|
+
self.ln2 = LayerNorm(d_model)
|
|
1109
|
+
self.cross_attn = CrossAttention(dim_dec=d_model,dim_enc=d_model,d_out=d_model,dec_rope=dec_rope,enc_rope=enc_rope,h=n_heads,d_k=d_model//n_heads)
|
|
1110
|
+
|
|
1111
|
+
self.ln3 = LayerNorm(d_model)
|
|
1112
|
+
self.ff = FeedForward(dmodel=d_model, dff=d_ff)
|
|
1113
|
+
|
|
1114
|
+
self.is_training = is_training
|
|
1115
|
+
|
|
1116
|
+
def __call__(self, x_dec, x_enc, mask=None,cross_mask=None):
|
|
1117
|
+
a = self.ln1(x_dec)
|
|
1118
|
+
x_dec = x_dec + self.self_attn(a,a,a,mask=mask)
|
|
1119
|
+
|
|
1120
|
+
c = self.ln2(x_dec)
|
|
1121
|
+
x_dec = x_dec + self.cross_attn(x_decod=c,x_encod=x_enc,mask=cross_mask)
|
|
1122
|
+
|
|
1123
|
+
f = self.ln3(x_dec)
|
|
1124
|
+
x_dec = x_dec + self.ff(f,self.is_training)
|
|
1125
|
+
|
|
1126
|
+
return x_dec
|
|
1127
|
+
|
|
1128
|
+
def train(self, enabled = True):
|
|
1129
|
+
self.is_training = enabled
|
|
1130
|
+
def infer(self, enabled = True):
|
|
1131
|
+
self.is_training = not enabled
|
|
1132
|
+
|
|
1133
|
+
def parameters(self):
|
|
1134
|
+
return (self.ln1.parameters() + self.self_attn.parameters() +
|
|
1135
|
+
self.ln2.parameters() + self.cross_attn.parameters() +
|
|
1136
|
+
self.ln3.parameters() + self.ff.parameters())
|
|
1137
|
+
|
|
1138
|
+
|
|
955
1139
|
|
|
956
1140
|
class PositionalEncoding:
|
|
957
1141
|
def __init__(self,max_len,dmodel):
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
from . import backend
|
|
2
|
+
from .app import Embedding, PositionalEncoding,Transformer,LayerNorm,Linear,RotatoryPositionalEncoding,to_cpu,needGradientHence,Decoder,Tensor
|
|
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
|
+
|
|
115
|
+
class Seq2Seq:
|
|
116
|
+
def __init__(self, enc_vocab, dec_vocab, d_model, n_heads, num_enc_layers, num_dec_layers, max_len, d_ff=None, training=False,shared_tok = False,pad_id=0,encoder_rope = None,dec_in_rope = None, dec_rope = None, enc_rope=None):
|
|
117
|
+
if enc_vocab==dec_vocab and shared_tok:
|
|
118
|
+
self.shared_tok = Embedding(enc_vocab, d_model)
|
|
119
|
+
self.shared_tok.weights.data *= (1.0 / backend.np.sqrt(d_model))
|
|
120
|
+
self.emb_scale = backend.np.sqrt(d_model)
|
|
121
|
+
|
|
122
|
+
self.enc_tok = self.dec_tok = self.shared_tok
|
|
123
|
+
self.tie_weights = True
|
|
124
|
+
self.head_b = Tensor(backend.np.zeros((dec_vocab,)))
|
|
125
|
+
else:
|
|
126
|
+
self.enc_tok = Embedding(enc_vocab, d_model)
|
|
127
|
+
self.dec_tok = Embedding(dec_vocab, d_model)
|
|
128
|
+
|
|
129
|
+
self.head = Linear(d_model, dec_vocab)
|
|
130
|
+
self.tie_weights = False
|
|
131
|
+
self.emb_scale = 1.0
|
|
132
|
+
|
|
133
|
+
self.pad_id = pad_id
|
|
134
|
+
|
|
135
|
+
self.rope = RotatoryPositionalEncoding(max_len, d_model // n_heads) if (dec_in_rope or dec_rope or enc_rope or encoder_rope) is not None else None
|
|
136
|
+
self.dec_in_rope = self.rope if dec_in_rope is not None else None
|
|
137
|
+
self.dec_rope = self.rope if dec_rope is not None else None
|
|
138
|
+
self.enc_rope = self.rope if enc_rope is not None else None
|
|
139
|
+
self.encoder_rope = self.rope if encoder_rope is not None else None
|
|
140
|
+
|
|
141
|
+
self.encoders = [Transformer(dmodel=d_model, n=n_heads, dff=d_ff, is_training=training, rope=self.encoder_rope) for _ in range(num_enc_layers)]
|
|
142
|
+
self.decoders = [
|
|
143
|
+
Decoder(d_model=d_model, n_heads=n_heads, d_ff=d_ff, is_training=training, dec_in_rope=self.dec_in_rope,dec_rope=self.dec_rope,enc_rope=self.enc_rope)
|
|
144
|
+
for _ in range(num_dec_layers)
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
self.ln_f = LayerNorm(d_model)
|
|
148
|
+
self.enc_ln = LayerNorm(d_model)
|
|
149
|
+
|
|
150
|
+
self.max_len = max_len
|
|
151
|
+
self.is_training = training
|
|
152
|
+
|
|
153
|
+
def train(self, enabled=True):
|
|
154
|
+
self.is_training = enabled
|
|
155
|
+
for block in self.encoders: block.train(enabled)
|
|
156
|
+
for block in self.decoders: block.train(enabled)
|
|
157
|
+
|
|
158
|
+
def infer(self, enabled=True):
|
|
159
|
+
self.is_training = not enabled
|
|
160
|
+
for block in self.encoders: block.infer(enabled)
|
|
161
|
+
for block in self.decoders: block.infer(enabled)
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def make_pad_mask(idx, pad_id):
|
|
165
|
+
# idx: (B, T) int -> (B, 1, 1, T) bool, True where padding
|
|
166
|
+
m = (backend.np.asarray(idx) == pad_id)
|
|
167
|
+
return m[:, None, None, :]
|
|
168
|
+
|
|
169
|
+
def __call__(self, enc_idx, dec_idx):
|
|
170
|
+
"""
|
|
171
|
+
enc_idx: Scrambled words, shape (B, T_enc)
|
|
172
|
+
dec_idx: Shifted target sentence starting with <SOS>, shape (B, T_dec)
|
|
173
|
+
"""
|
|
174
|
+
enc_pad = self.make_pad_mask(enc_idx, self.pad_id)
|
|
175
|
+
x_enc = self.enc_tok(enc_idx) * self.emb_scale
|
|
176
|
+
for block in self.encoders:
|
|
177
|
+
x_enc = block(x_enc, mask=enc_pad)
|
|
178
|
+
|
|
179
|
+
x_enc = self.enc_ln(x_enc)
|
|
180
|
+
|
|
181
|
+
T_dec = dec_idx.shape[1]
|
|
182
|
+
causal_mask = backend.np.triu(backend.np.ones((T_dec, T_dec)), k=1).astype(bool)
|
|
183
|
+
|
|
184
|
+
x_dec = self.dec_tok(dec_idx) * self.emb_scale
|
|
185
|
+
for block in self.decoders:
|
|
186
|
+
x_dec = block(x_dec=x_dec, x_enc=x_enc, mask=causal_mask,cross_mask=enc_pad)
|
|
187
|
+
|
|
188
|
+
x = self.ln_f(x_dec)
|
|
189
|
+
if self.tie_weights:
|
|
190
|
+
logits = x @ self.shared_tok.weights.transpose((1, 0)) + self.head_b
|
|
191
|
+
else:
|
|
192
|
+
logits = self.head(x)
|
|
193
|
+
return logits
|
|
194
|
+
|
|
195
|
+
def parameters(self):
|
|
196
|
+
seen, ps = set(), []
|
|
197
|
+
def add(lst):
|
|
198
|
+
for p in lst:
|
|
199
|
+
if id(p) not in seen:
|
|
200
|
+
seen.add(id(p)); ps.append(p)
|
|
201
|
+
add(self.enc_tok.parameters()); add(self.dec_tok.parameters())
|
|
202
|
+
add(self.ln_f.parameters()); add(self.enc_ln.parameters())
|
|
203
|
+
add([self.head_b] if self.tie_weights else self.head.parameters())
|
|
204
|
+
for b in self.encoders: add(b.parameters())
|
|
205
|
+
for b in self.decoders: add(b.parameters())
|
|
206
|
+
return ps
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def encode(self, enc_idx):
|
|
210
|
+
enc_pad = self.make_pad_mask(enc_idx, self.pad_id)
|
|
211
|
+
x_enc = self.enc_tok(enc_idx) * self.emb_scale
|
|
212
|
+
for block in self.encoders:
|
|
213
|
+
x_enc = block(x_enc, mask=enc_pad)
|
|
214
|
+
x_enc = self.enc_ln(x_enc)
|
|
215
|
+
return x_enc, enc_pad
|
|
216
|
+
|
|
217
|
+
def decode_step(self, dec_idx, x_enc, enc_pad):
|
|
218
|
+
T_dec = dec_idx.shape[1]
|
|
219
|
+
causal = backend.np.triu(backend.np.ones((T_dec, T_dec)), k=1).astype(bool)
|
|
220
|
+
x_dec = self.dec_tok(dec_idx) * self.emb_scale
|
|
221
|
+
for block in self.decoders:
|
|
222
|
+
x_dec = block(x_dec=x_dec, x_enc=x_enc, mask=causal, cross_mask=enc_pad)
|
|
223
|
+
x = self.ln_f(x_dec)
|
|
224
|
+
if self.tie_weights:
|
|
225
|
+
return x @ self.shared_tok.weights.transpose((1, 0)) + self.head_b
|
|
226
|
+
return self.head(x)
|
|
227
|
+
|
|
228
|
+
def generate(self, enc_idx, sos_id, eos_id=None, max_new=50, temperature=1.0, top_k=None):
|
|
229
|
+
enc_idx = numpy.asarray(enc_idx)
|
|
230
|
+
B = enc_idx.shape[0]
|
|
231
|
+
was_training = self.is_training
|
|
232
|
+
self.infer()
|
|
233
|
+
original_grad_state = not backend.NO_GRAD
|
|
234
|
+
needGradientHence(False)
|
|
235
|
+
try:
|
|
236
|
+
x_enc, enc_pad = self.encode(enc_idx) # encode once
|
|
237
|
+
dec_idx = numpy.full((B, 1), sos_id, dtype=numpy.int64)
|
|
238
|
+
for _ in range(max_new):
|
|
239
|
+
logits = to_cpu(self.decode_step(dec_idx, x_enc, enc_pad).data)[:, -1, :] / temperature
|
|
240
|
+
if top_k is not None:
|
|
241
|
+
kth = numpy.sort(logits, axis=-1)[:, -top_k][:, None]
|
|
242
|
+
logits = numpy.where(logits < kth, -1e9, logits)
|
|
243
|
+
z = logits - logits.max(-1, keepdims=True)
|
|
244
|
+
p = numpy.exp(z).astype(numpy.float64); p /= p.sum(-1, keepdims=True)
|
|
245
|
+
nxt = numpy.array([[numpy.random.choice(len(pr), p=pr)] for pr in p])
|
|
246
|
+
dec_idx = numpy.concatenate([dec_idx, nxt], axis=1)
|
|
247
|
+
if eos_id is not None and bool((nxt[:, 0] == eos_id).all()):
|
|
248
|
+
break
|
|
249
|
+
return dec_idx
|
|
250
|
+
finally:
|
|
251
|
+
if was_training:
|
|
252
|
+
self.train()
|
|
253
|
+
needGradientHence(original_grad_state)
|
|
254
|
+
|
|
@@ -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
|