@mineproness/tensorloop 1.5.9 → 2.1.0
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.
- package/package.json +1 -1
- package/readme.md +4 -3
- package/src/Embedding/index.d.ts +1 -1
- package/src/Embedding/index.js +13 -19
- package/src/FFN/index.js +14 -18
- package/src/GELU/index.d.ts +2 -2
- package/src/GELU/index.js +19 -29
- package/src/Linear/index.d.ts +2 -2
- package/src/Linear/index.js +12 -14
- package/src/PositionEmbedding/index.d.ts +1 -1
- package/src/PositionEmbedding/index.js +5 -3
- package/src/ReLU/index.d.ts +1 -0
- package/src/ReLU/index.js +12 -9
- package/src/SelfAttention/index.js +15 -11
- package/src/Softmax/index.d.ts +1 -2
- package/src/Softmax/index.js +9 -11
- package/src/TransformerBlock/index.d.ts +2 -1
- package/src/TransformerBlock/index.js +3 -1
- package/src/gpiInit.js +604 -0
- package/src/GPU.js +0 -279
package/src/GPU.js
DELETED
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import { GPU } from "gpu.js";
|
|
2
|
-
|
|
3
|
-
const gpu = new GPU({
|
|
4
|
-
mode: "gpu"
|
|
5
|
-
})
|
|
6
|
-
const kernel = gpu.createKernel(function () {
|
|
7
|
-
return 1
|
|
8
|
-
}).setOutput([1])
|
|
9
|
-
|
|
10
|
-
kernel()
|
|
11
|
-
const gl = kernel.context
|
|
12
|
-
const maxSize = gl ? gl.getParameter(gl.MAX_TEXTURE_SIZE) : 1200
|
|
13
|
-
export function splitMatrix(matrix, chunksSizes = maxSize) {
|
|
14
|
-
const chunks = []
|
|
15
|
-
for (let a = 0; a < matrix.length; a += chunksSizes) {
|
|
16
|
-
chunks.push(matrix.slice(a, a + chunksSizes))
|
|
17
|
-
}
|
|
18
|
-
return { split: true, data: chunks }
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
let outputSizes = [];
|
|
22
|
-
let out = 0
|
|
23
|
-
export class GPULinear {
|
|
24
|
-
cacheLF = [];
|
|
25
|
-
cacheLBIas = [];
|
|
26
|
-
cacheLBWeights = [];
|
|
27
|
-
cacheLBInputGradent = [];
|
|
28
|
-
// texures
|
|
29
|
-
contextSize;
|
|
30
|
-
weightLength = 0;
|
|
31
|
-
Bias = [];
|
|
32
|
-
Weights = []
|
|
33
|
-
InitKernel(weights, bias, size, contextSize) {
|
|
34
|
-
const splitedWeights = splitMatrix(weights)
|
|
35
|
-
const splitedBias = splitMatrix(bias)
|
|
36
|
-
this.weightLength = weights.length
|
|
37
|
-
this.Weights = splitedWeights.data
|
|
38
|
-
out = weights.length
|
|
39
|
-
this.Bias = splitedBias.data
|
|
40
|
-
for (let a = 0; a < splitedWeights.data.length; a++) {
|
|
41
|
-
outputSizes.push(splitedWeights.data[a].length)
|
|
42
|
-
|
|
43
|
-
this.cacheLF[a] = gpu.createKernel(function (input, bias, weights) {
|
|
44
|
-
let sum = bias[this.thread.x]
|
|
45
|
-
for (let a = 0; a < this.constants.inputLength; a++) {
|
|
46
|
-
sum += input[this.thread.y][a] * weights[this.thread.x][a]
|
|
47
|
-
}
|
|
48
|
-
return sum
|
|
49
|
-
}).setConstants({
|
|
50
|
-
inputLength: splitedWeights.data[a][0].length
|
|
51
|
-
}).setArgumentTypes({
|
|
52
|
-
input: 'Array',
|
|
53
|
-
bias: 'Array',
|
|
54
|
-
weights: 'Array'
|
|
55
|
-
}).setOutput([splitedWeights.data[a].length, contextSize])
|
|
56
|
-
this.cacheLBIas[a] = gpu.createKernel(function (
|
|
57
|
-
bias,
|
|
58
|
-
outputGradient,
|
|
59
|
-
learningRate
|
|
60
|
-
) {
|
|
61
|
-
let grad = 0;
|
|
62
|
-
for (let a = 0; a < this.constants.contextSize; a++) {
|
|
63
|
-
const g = outputGradient[a][this.thread.x]
|
|
64
|
-
|
|
65
|
-
grad += g
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return bias[this.thread.x] - learningRate * grad
|
|
69
|
-
}, {
|
|
70
|
-
pipeline: true,
|
|
71
|
-
immutable: true,
|
|
72
|
-
output: [splitedWeights.data[a].length, contextSize],
|
|
73
|
-
constants: { contextSize }
|
|
74
|
-
})
|
|
75
|
-
this.cacheLBInputGradent[a] = gpu.createKernel(function (
|
|
76
|
-
weights,
|
|
77
|
-
outputGradient
|
|
78
|
-
) {
|
|
79
|
-
let sum = 0
|
|
80
|
-
|
|
81
|
-
for (let a = 0; a < this.constants.outputSize; a++) {
|
|
82
|
-
const grad = outputGradient[this.thread.y][a]
|
|
83
|
-
sum += grad * weights[a][this.thread.x]
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return sum
|
|
87
|
-
}, {
|
|
88
|
-
constants: { outputSize: splitedWeights.data[a].length },
|
|
89
|
-
output: [size, contextSize]
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
this.cacheLBWeights[a] = gpu.createKernel(function (
|
|
93
|
-
weights,
|
|
94
|
-
outputGradient,
|
|
95
|
-
input,
|
|
96
|
-
learningRate
|
|
97
|
-
) {
|
|
98
|
-
let grad = 0;
|
|
99
|
-
for (let a = 0; a < this.constants.contextSize; a++) {
|
|
100
|
-
grad += outputGradient[a][this.thread.y] * input[a][this.thread.x]
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return weights[this.thread.y][this.thread.x]
|
|
104
|
-
- learningRate * grad
|
|
105
|
-
}, {
|
|
106
|
-
pipeline: true,
|
|
107
|
-
immutable: true,
|
|
108
|
-
output: [size, splitedWeights.data[a].length],
|
|
109
|
-
constants: { contextSize }
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
this.contextSize = contextSize
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
CalculateLinearForward(input) {
|
|
117
|
-
const result = Array.from({ length: this.contextSize },
|
|
118
|
-
() => new Float32Array(this.weightLength)
|
|
119
|
-
)
|
|
120
|
-
let offset = 0;
|
|
121
|
-
for (let a = 0; a < this.Weights.length; a++) {
|
|
122
|
-
const output = this.cacheLF[a](input, this.Bias[a], this.Weights[a])
|
|
123
|
-
for (let y = 0; y < this.contextSize; y++) {
|
|
124
|
-
result[y].set(output[y], offset);
|
|
125
|
-
}
|
|
126
|
-
offset += this.Weights[a].length
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
return result
|
|
130
|
-
}
|
|
131
|
-
CalculateBackward(out, learningRate, input) {
|
|
132
|
-
let inputGradient = Array.from({ length: this.contextSize } , ()=> new Float32Array(input[0].length))
|
|
133
|
-
for (let a = 0; a < this.Weights.length; a++) {
|
|
134
|
-
const outGradient = this.cacheLBInputGradent[a](this.Weights[a], out)
|
|
135
|
-
for (let row = 0; row < this.contextSize; row++) {
|
|
136
|
-
for (let i = 0; i < input[0].length; i++) {
|
|
137
|
-
inputGradient[row][i] += outGradient[row][i];
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
const oldW = this.Weights[a]
|
|
141
|
-
const oldB = this.Bias[a]
|
|
142
|
-
this.Weights[a] = this.cacheLBWeights[a](this.Weights[a], out, input, learningRate)
|
|
143
|
-
this.Bias[a] = this.cacheLBIas[a](this.Bias[a], out, learningRate)
|
|
144
|
-
if (oldW && typeof oldW.delete === "function") {
|
|
145
|
-
oldW.delete()
|
|
146
|
-
}
|
|
147
|
-
if (oldB && typeof oldB.delete === "function") {
|
|
148
|
-
oldB.delete()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
return inputGradient
|
|
153
|
-
}
|
|
154
|
-
GetWeightsAndBias() {
|
|
155
|
-
const weight = []
|
|
156
|
-
const bias = []
|
|
157
|
-
this.Weights.map((e) => weight.push(...e.toArray()))
|
|
158
|
-
this.Bias.map((e) => bias.push(...e.toArray()))
|
|
159
|
-
return { weights: weight, bias: new Float32Array(bias) }
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export class gpuSoftmax {
|
|
164
|
-
cacheSF = [];
|
|
165
|
-
cacheSB = [];
|
|
166
|
-
contextSize;
|
|
167
|
-
Probs = [];
|
|
168
|
-
LossCalculate;
|
|
169
|
-
constructor(contextSize) {
|
|
170
|
-
this.contextSize = contextSize;
|
|
171
|
-
for (let a = 0; a < outputSizes.length; a++) {
|
|
172
|
-
this.cacheSF[a] = gpu.createKernel(function (logits) {
|
|
173
|
-
let maxLogits = logits[this.thread.y][0];
|
|
174
|
-
let sum = 0;
|
|
175
|
-
for (let a = 0; a < this.constants.outputSize; a++) {
|
|
176
|
-
if (logits[this.thread.y][a] > maxLogits) {
|
|
177
|
-
maxLogits = logits[this.thread.y][a]
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
for (let a = 0; a < this.constants.outputSize; a++) {
|
|
181
|
-
sum += Math.exp(logits[this.thread.y][a] - maxLogits)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return Math.exp(logits[this.thread.y][this.thread.x] - maxLogits) / sum
|
|
185
|
-
|
|
186
|
-
}, {
|
|
187
|
-
pipeline: true,
|
|
188
|
-
immutable: true,
|
|
189
|
-
output: [outputSizes[a], contextSize],
|
|
190
|
-
constants: { outputSize: outputSizes[a] }
|
|
191
|
-
})
|
|
192
|
-
this.cacheSB[a] = gpu.createKernel(function (probs, target) {
|
|
193
|
-
const p = probs[this.thread.y][this.thread.x]
|
|
194
|
-
if (this.thread.x == target[this.thread.y]) {
|
|
195
|
-
return p - 1.0
|
|
196
|
-
}
|
|
197
|
-
return p
|
|
198
|
-
}, {
|
|
199
|
-
output: [outputSizes[a], contextSize]
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
this.LossCalculate = gpu.createKernel(function (probs, target) {
|
|
203
|
-
const tar = target[this.thread.x]
|
|
204
|
-
return -Math.log((probs[this.thread.x][tar] + 1) + 1e-10)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}, {
|
|
208
|
-
output: [contextSize]
|
|
209
|
-
})
|
|
210
|
-
}
|
|
211
|
-
forwardSoftmax(logits) {
|
|
212
|
-
const splitedLogits = splitMatrix(logits)
|
|
213
|
-
for (let a = 0; a < splitedLogits.data.length; a++) {
|
|
214
|
-
const oldSoftmax = this.Probs[a]
|
|
215
|
-
this.Probs[a] = this.cacheSF[a](splitedLogits.data[a])
|
|
216
|
-
if (oldSoftmax && typeof oldSoftmax.delete == "function") {
|
|
217
|
-
oldSoftmax.delete()
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return "Completed"
|
|
221
|
-
}
|
|
222
|
-
getSoftmax() {
|
|
223
|
-
const result = Array.from({ length: this.contextSize }, () => new Float32Array(out))
|
|
224
|
-
let offset = 0;
|
|
225
|
-
for (let a = 0; a < this.Probs.length; a++) {
|
|
226
|
-
const outputofSoftmax = this.Probs[a].toArray()
|
|
227
|
-
for (let a = 0; a < this.contextSize; a++) {
|
|
228
|
-
result[a].set(outputofSoftmax[a], offset)
|
|
229
|
-
}
|
|
230
|
-
offset += outputofSoftmax[0].length
|
|
231
|
-
}
|
|
232
|
-
return result
|
|
233
|
-
}
|
|
234
|
-
softmaxBackward(target) {
|
|
235
|
-
const result = Array.from(
|
|
236
|
-
{ length: this.contextSize },
|
|
237
|
-
() => new Float32Array(out)
|
|
238
|
-
);
|
|
239
|
-
let offset = 0;
|
|
240
|
-
for (let chunk = 0; chunk < this.Probs.length; chunk++) {
|
|
241
|
-
const chunkSize = outputSizes[chunk];
|
|
242
|
-
const localTarget = new Int32Array(this.contextSize);
|
|
243
|
-
for (let row = 0; row < this.contextSize; row++) {
|
|
244
|
-
const globalTarget = target[row];
|
|
245
|
-
if (
|
|
246
|
-
globalTarget >= offset &&
|
|
247
|
-
globalTarget < offset + chunkSize
|
|
248
|
-
) {
|
|
249
|
-
localTarget[row] = globalTarget - offset;
|
|
250
|
-
} else {
|
|
251
|
-
localTarget[row] = -1;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
const gradient = this.cacheSB[chunk](
|
|
255
|
-
this.Probs[chunk],
|
|
256
|
-
localTarget
|
|
257
|
-
);
|
|
258
|
-
const data = gradient;
|
|
259
|
-
for (let row = 0; row < this.contextSize; row++) {
|
|
260
|
-
result[row].set(data[row], offset);
|
|
261
|
-
}
|
|
262
|
-
offset += chunkSize;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return result;
|
|
266
|
-
}
|
|
267
|
-
calculateLOSS(dLogits, target) {
|
|
268
|
-
const losses = this.LossCalculate(dLogits, target)
|
|
269
|
-
let loss = 0;
|
|
270
|
-
|
|
271
|
-
for (let i = 0; i < losses.length; i++) {
|
|
272
|
-
loss += losses[i];
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
loss /= losses.length;
|
|
276
|
-
return loss
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
}
|