cogforge-engine 1.1.0__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.1.0 → cogforge_engine-2.0.0}/PKG-INFO +1 -1
- cogforge_engine-2.0.0/TODO +7 -0
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/cogforge/app.py +79 -0
- cogforge_engine-2.0.0/cogforge/models.py +254 -0
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/pyproject.toml +1 -1
- cogforge_engine-1.1.0/cogforge/models.py +0 -114
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/.github/workflows/release.yml +0 -0
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/.gitignore +0 -0
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/LICENSE +0 -0
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/README.md +0 -0
- {cogforge_engine-1.1.0 → cogforge_engine-2.0.0}/cogforge/__init__.py +0 -0
- {cogforge_engine-1.1.0 → 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>
|
|
@@ -981,6 +981,47 @@ class MultiHeadAttention:
|
|
|
981
981
|
def parameters(self):
|
|
982
982
|
return (self.q.parameters() + self.k.parameters()
|
|
983
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())
|
|
984
1025
|
|
|
985
1026
|
|
|
986
1027
|
class LayerNorm:
|
|
@@ -1057,6 +1098,44 @@ class Transformer:
|
|
|
1057
1098
|
return (self.ln1.parameters() + self.attn.parameters()
|
|
1058
1099
|
+ self.ln2.parameters() + self.ff.parameters())
|
|
1059
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
|
+
|
|
1060
1139
|
|
|
1061
1140
|
class PositionalEncoding:
|
|
1062
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,114 +0,0 @@
|
|
|
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
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|