@imaduddin/fastbrain 1.1.1-patch → 2.0.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/dist/Embedding/index.d.ts +24 -0
- package/dist/Embedding/index.js +93 -0
- package/dist/FFN/index.d.ts +20 -0
- package/dist/FFN/index.js +51 -0
- package/dist/Gelu/index.d.ts +15 -0
- package/dist/Gelu/index.js +58 -0
- package/dist/Linear/index.d.ts +31 -0
- package/dist/Linear/index.js +136 -0
- package/dist/RMSNorm/index.d.ts +16 -0
- package/dist/RMSNorm/index.js +63 -0
- package/dist/Relu/index.d.ts +15 -0
- package/dist/Relu/index.js +58 -0
- package/dist/SelfAttention/index.d.ts +47 -0
- package/dist/SelfAttention/index.js +186 -0
- package/dist/Softmax/index.d.ts +18 -0
- package/dist/Softmax/index.js +96 -0
- package/dist/Tokenizer/index.d.ts +15 -0
- package/dist/Tokenizer/index.js +58 -0
- package/dist/TransformerBlock/index.d.ts +21 -0
- package/dist/TransformerBlock/index.js +43 -0
- package/dist/fileManager.d.ts +6 -0
- package/dist/fileManager.js +34 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/residualConnection/index.d.ts +9 -0
- package/dist/residualConnection/index.js +25 -0
- package/package.json +14 -3
- package/shaders/add.wgsl +22 -0
- package/shaders/embedding/backward.wgsl +36 -0
- package/shaders/embedding/forward.wgsl +35 -0
- package/shaders/linear/ComputeDinput.wgsl +72 -0
- package/shaders/linear/forward.wgsl +63 -0
- package/shaders/linear/updateBias.wgsl +33 -0
- package/shaders/linear/updateWeights.wgsl +38 -0
- package/shaders/relu/backward.wgsl +43 -0
- package/shaders/relu/forward.wgsl +28 -0
- package/shaders/rmsnorm/backward.wgsl +54 -0
- package/shaders/rmsnorm/forward.wgsl +51 -0
- package/shaders/selfAttention/SB.wgsl +30 -0
- package/shaders/selfAttention/add3.wgsl +27 -0
- package/shaders/selfAttention/matMul.wgsl +63 -0
- package/shaders/selfAttention/qK.wgsl +66 -0
- package/shaders/selfAttention/transpose.wgsl +24 -0
- package/shaders/softmax/backward.wgsl +36 -0
- package/shaders/softmax/crossEntropy.wgsl +36 -0
- package/shaders/softmax/forward.wgsl +68 -0
- package/src/Embedding/index.ts +81 -0
- package/src/FFN/index.ts +47 -0
- package/src/Gelu/index.ts +53 -0
- package/src/Linear/index.ts +122 -0
- package/src/RMSNorm/index.ts +56 -0
- package/src/SelfAttention/index.ts +177 -0
- package/src/Softmax/index.ts +82 -0
- package/src/Tokenizer/index.ts +60 -0
- package/src/TransformerBlock/index.ts +41 -0
- package/src/fileManager.ts +46 -0
- package/src/index.ts +10 -0
- package/src/residualConnection/index.ts +24 -0
- package/tsconfig.json +27 -0
- package/index.js +0 -22
- package/src/Embedding/index.d.ts +0 -21
- package/src/Embedding/index.js +0 -140
- package/src/FFN/index.d.ts +0 -23
- package/src/FFN/index.js +0 -45
- package/src/Linear/index.d.ts +0 -31
- package/src/Linear/index.js +0 -196
- package/src/OperationManager.js +0 -169
- package/src/PositionEmbedding/index.d.ts +0 -30
- package/src/PositionEmbedding/index.js +0 -70
- package/src/RMSNorm/index.d.ts +0 -30
- package/src/RMSNorm/index.js +0 -91
- package/src/Relu/index.d.ts +0 -25
- package/src/Relu/index.js +0 -108
- package/src/SelfAttention/index.d.ts +0 -28
- package/src/SelfAttention/index.js +0 -138
- package/src/Softmax/index.d.ts +0 -26
- package/src/Softmax/index.js +0 -195
- package/src/Tokenizer/index.d.ts +0 -12
- package/src/Tokenizer/index.js +0 -164
- package/src/Tokenizer/vocabs.json +0 -19618
- package/src/TransformerBlock/index.d.ts +0 -28
- package/src/TransformerBlock/index.js +0 -78
- package/src/getVec.js +0 -30
- package/src/gpu.js +0 -0
- package/src/model/index.d.ts +0 -43
- package/src/model/index.js +0 -82
- package/src/residualConnection/index.js +0 -31
- package/src/shaders/CalculateAcc.wgsl +0 -50
- package/src/shaders/CalculateLoss.wgsl +0 -33
- package/src/shaders/ComputeDInput.wgsl +0 -46
- package/src/shaders/EB.wgsl +0 -33
- package/src/shaders/EF.wgsl +0 -25
- package/src/shaders/LB.wgsl +0 -71
- package/src/shaders/LF.wgsl +0 -60
- package/src/shaders/Norm/rmsBackward.wgsl +0 -65
- package/src/shaders/Norm/rmsForward.wgsl +0 -30
- package/src/shaders/Norm/sumSquare.wgsl +0 -38
- package/src/shaders/Norm/updateGamma.wgsl +0 -54
- package/src/shaders/PB.wgsl +0 -25
- package/src/shaders/PF.wgsl +0 -24
- package/src/shaders/RB.wgsl +0 -37
- package/src/shaders/RF.wgsl +0 -33
- package/src/shaders/ReductionFunction.wgsl +0 -28
- package/src/shaders/SB.wgsl +0 -41
- package/src/shaders/SF.wgsl +0 -75
- package/src/shaders/SoftmaxBackward.wgsl +0 -31
- package/src/shaders/add.wgsl +0 -30
- package/src/shaders/attentionShader/CompueFinalForwardOutput.wgsl +0 -29
- package/src/shaders/attentionShader/ComputeDA.wgsl +0 -30
- package/src/shaders/attentionShader/ComputeDV.wgsl +0 -37
- package/src/shaders/attentionShader/ComputeK.wgsl +0 -30
- package/src/shaders/attentionShader/ComputedQ.wgsl +0 -31
- package/src/shaders/attentionShader/attentionSocres.wgsl +0 -40
- package/src/shaders/attentionShader/sumGradient.wgsl +0 -24
- package/src/shaders/calculateTotal.wgsl +0 -26
package/src/Relu/index.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { OperationManager } from "../OperationManager.js";
|
|
2
|
-
|
|
3
|
-
export class Relu {
|
|
4
|
-
embeddingSize;
|
|
5
|
-
paramBuffer;
|
|
6
|
-
oldParam;
|
|
7
|
-
forwardPipline;
|
|
8
|
-
gpu;
|
|
9
|
-
backwardPipline;
|
|
10
|
-
input;
|
|
11
|
-
constructor(device, embeddingSize) {
|
|
12
|
-
this.embeddingSize = embeddingSize
|
|
13
|
-
this.gpu = new OperationManager(device);
|
|
14
|
-
this.device = device;
|
|
15
|
-
this.forwardPipline = this.gpu.getShaderPipline("./src/shaders/RF.wgsl")
|
|
16
|
-
this.backwardPipline = this.gpu.getShaderPipline("./src/shaders/RB.wgsl")
|
|
17
|
-
}
|
|
18
|
-
async forward(input, en) {
|
|
19
|
-
const encoder = en ? en : this.device.createCommandEncoder()
|
|
20
|
-
const tokenCount = input.mainBuffer.size / (this.embeddingSize * 4)
|
|
21
|
-
if (!this.oldParam) {
|
|
22
|
-
this.oldParam = new Uint32Array([0, 0, 0]);
|
|
23
|
-
this.paramBuffer = await this.gpu.createUniFormBuffer(4 * 3);
|
|
24
|
-
}
|
|
25
|
-
if (!this.output) this.output = await this.gpu.ManageBuffer(input.mainBuffer.size);
|
|
26
|
-
if (this.output.mainBuffer.size !== input.mainBuffer.size || this.output.isDestroyed() || this.output.size == 0) {
|
|
27
|
-
this.output.destroy()
|
|
28
|
-
this.output = await this.gpu.ManageBuffer(input.mainBuffer.size);
|
|
29
|
-
}
|
|
30
|
-
if (this.oldParam[1] !== tokenCount) {
|
|
31
|
-
this.oldParam = new Uint32Array([this.embeddingSize, tokenCount, 0])
|
|
32
|
-
await this.gpu.WriteBuffer(this.paramBuffer, this.oldParam)
|
|
33
|
-
}
|
|
34
|
-
const bind = await this.device.createBindGroup({
|
|
35
|
-
layout: await this.forwardPipline.getBindGroupLayout(0),
|
|
36
|
-
entries: [
|
|
37
|
-
{
|
|
38
|
-
binding: 0,
|
|
39
|
-
resource: {
|
|
40
|
-
buffer: input.mainBuffer
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
binding: 1,
|
|
45
|
-
resource: {
|
|
46
|
-
buffer: this.paramBuffer
|
|
47
|
-
}
|
|
48
|
-
}, {
|
|
49
|
-
binding: 2,
|
|
50
|
-
resource: {
|
|
51
|
-
buffer: this.output.mainBuffer
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
})
|
|
56
|
-
await this.gpu.RunPipline(encoder, this.forwardPipline, bind, Math.ceil((tokenCount * this.embeddingSize) / 256))
|
|
57
|
-
if(!en) this.device.queue.submit([encoder.finish()])
|
|
58
|
-
this.input = input
|
|
59
|
-
return this.output
|
|
60
|
-
}
|
|
61
|
-
async backward(inputGradient,en) {
|
|
62
|
-
const encoder = en ? en : this.device.createCommandEncoder()
|
|
63
|
-
const tokenCount = inputGradient.size / (this.embeddingSize * 4)
|
|
64
|
-
if (!this.oldParam) {
|
|
65
|
-
this.oldParam = new Uint32Array([0, 0, 0]);
|
|
66
|
-
this.paramBuffer = await this.gpu.createUniFormBuffer(4 * 3);
|
|
67
|
-
}
|
|
68
|
-
if(!this.gradOut) this.gradOut = await this.gpu.ManageBuffer(inputGradient.size);
|
|
69
|
-
if(this.gradOut.size !== inputGradient.size || this.gradOut.isDestroyed() || this.gradOut.size == 0){
|
|
70
|
-
this.gradOut.destroy();
|
|
71
|
-
this.gradOut = await this.gpu.ManageBuffer(inputGradient.size)
|
|
72
|
-
}
|
|
73
|
-
if (this.oldParam[1] !== tokenCount) {
|
|
74
|
-
this.oldParam = new Uint32Array([this.embeddingSize, tokenCount, 0])
|
|
75
|
-
await this.gpu.WriteBuffer(this.paramBuffer, this.oldParam)
|
|
76
|
-
}
|
|
77
|
-
const bind = await this.device.createBindGroup({
|
|
78
|
-
layout: await this.backwardPipline.getBindGroupLayout(0),
|
|
79
|
-
entries: [
|
|
80
|
-
{
|
|
81
|
-
binding: 0,
|
|
82
|
-
resource: {
|
|
83
|
-
buffer: this.input.mainBuffer
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
binding: 1,
|
|
88
|
-
resource: {
|
|
89
|
-
buffer: this.paramBuffer
|
|
90
|
-
}
|
|
91
|
-
}, {
|
|
92
|
-
binding: 2,
|
|
93
|
-
resource: {
|
|
94
|
-
buffer: this.gradOut.mainBuffer
|
|
95
|
-
}
|
|
96
|
-
}, {
|
|
97
|
-
binding: 3,
|
|
98
|
-
resource: {
|
|
99
|
-
buffer: inputGradient.mainBuffer
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
]
|
|
103
|
-
})
|
|
104
|
-
await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((tokenCount * this.embeddingSize) / 256))
|
|
105
|
-
if(!en) await this.device.queue.submit([encoder.finish()])
|
|
106
|
-
return this.gradOut
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export class SelfAttention {
|
|
2
|
-
constructor(device: GPUAdapter, embeddingSize: number, configs: {
|
|
3
|
-
dirname: string
|
|
4
|
-
})
|
|
5
|
-
async forward(vec: {
|
|
6
|
-
read: function(): Promise<Float32Array>,
|
|
7
|
-
mainBuffer: GPUBuffer,
|
|
8
|
-
isDestroyed: function(): Boolean,
|
|
9
|
-
destroy: function(): void
|
|
10
|
-
}): Promise<{
|
|
11
|
-
read: function(): Promise<Float32Array>,
|
|
12
|
-
mainBuffer: GPUBuffer,
|
|
13
|
-
isDestroyed: function(): Boolean,
|
|
14
|
-
destroy: function(): void
|
|
15
|
-
}>
|
|
16
|
-
async backward(dO: {
|
|
17
|
-
read: function(): Promise<Float32Array>,
|
|
18
|
-
mainBuffer: GPUBuffer,
|
|
19
|
-
isDestroyed: function(): Boolean,
|
|
20
|
-
destroy: function(): void
|
|
21
|
-
}, lr: number): Promise<{
|
|
22
|
-
read: function(): Promise<Float32Array>,
|
|
23
|
-
mainBuffer: GPUBuffer,
|
|
24
|
-
isDestroyed: function(): Boolean,
|
|
25
|
-
destroy: function(): void
|
|
26
|
-
}>
|
|
27
|
-
async Save(): Promise<void>
|
|
28
|
-
}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { Linear } from "../../index.js";
|
|
2
|
-
import { join } from 'path'
|
|
3
|
-
import { OperationManager } from "../OperationManager.js";
|
|
4
|
-
|
|
5
|
-
export class SelfAttention {
|
|
6
|
-
query;
|
|
7
|
-
value;
|
|
8
|
-
key;
|
|
9
|
-
q;
|
|
10
|
-
k;
|
|
11
|
-
v;
|
|
12
|
-
embeddingSize;
|
|
13
|
-
params;
|
|
14
|
-
attentionscoresShader;
|
|
15
|
-
softmaxForward;
|
|
16
|
-
gpu;
|
|
17
|
-
input;
|
|
18
|
-
constructor(device, embeddingSize, configs) {
|
|
19
|
-
this.embeddingSize = embeddingSize;
|
|
20
|
-
const dd = [1, 2, 3].map((e) => {
|
|
21
|
-
return {
|
|
22
|
-
save: {
|
|
23
|
-
filename: [join(configs.dirname, `SELF-W-${e}.bin`), join(configs.dirname, `SELF-B-${e}.bin`)]
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
this.q = new Linear(device, embeddingSize, embeddingSize, dd[0])
|
|
28
|
-
this.k = new Linear(device, embeddingSize, embeddingSize, dd[1])
|
|
29
|
-
this.v = new Linear(device, embeddingSize, embeddingSize, dd[2])
|
|
30
|
-
this.gpu = new OperationManager(device)
|
|
31
|
-
this.attentionscoresShader = this.gpu.getShaderPipline("./src/shaders/attentionShader/attentionSocres.wgsl")
|
|
32
|
-
this.softmaxForward = this.gpu.getShaderPipline("./src/shaders/SF.wgsl")
|
|
33
|
-
this.softmaxBackward = this.gpu.getShaderPipline("./src/shaders/SoftmaxBackward.wgsl")
|
|
34
|
-
this.outputForward = this.gpu.getShaderPipline("./src/shaders/attentionShader/CompueFinalForwardOutput.wgsl")
|
|
35
|
-
this.dVShader = this.gpu.getShaderPipline("./src/shaders/attentionShader/ComputeDV.wgsl")
|
|
36
|
-
this.dAshader = this.gpu.getShaderPipline("./src/shaders/attentionShader/ComputeDA.wgsl")
|
|
37
|
-
this.dQshader = this.gpu.getShaderPipline("./src/shaders/attentionShader/ComputedQ.wgsl")
|
|
38
|
-
this.dKShader = this.gpu.getShaderPipline("./src/shaders/attentionShader/ComputeK.wgsl")
|
|
39
|
-
this.sumShader = this.gpu.getShaderPipline("./src/shaders/attentionShader/sumGradient.wgsl")
|
|
40
|
-
}
|
|
41
|
-
async forward(vec, encoder2) {
|
|
42
|
-
this.input = vec.mainBuffer;
|
|
43
|
-
const tokenCount = vec.mainBuffer.size / (this.embeddingSize * 4)
|
|
44
|
-
if (!this.asParams) this.asParams = await this.gpu.createUniFormBuffer(4 * 3);
|
|
45
|
-
if (!this.softmaxParams) this.softmaxParams = await this.gpu.createUniFormBuffer(4 * 3);
|
|
46
|
-
const encoder = encoder2 ? encoder2 : await this.gpu.CreateEncoder()
|
|
47
|
-
if (!this.scroes) {
|
|
48
|
-
this.scroes = await this.gpu.createBuffer(tokenCount * tokenCount * 4)
|
|
49
|
-
}
|
|
50
|
-
if (this.scroes.size !== tokenCount * tokenCount * 4) {
|
|
51
|
-
this.scroes.destroy()
|
|
52
|
-
this.scroes = await this.gpu.createBuffer(tokenCount * tokenCount * 4)
|
|
53
|
-
}
|
|
54
|
-
await this.gpu.WriteBuffer(this.asParams, new Uint32Array([tokenCount, this.embeddingSize, 0]))
|
|
55
|
-
await this.gpu.WriteBuffer(this.softmaxParams, new Uint32Array([tokenCount, tokenCount, 0]))
|
|
56
|
-
this.query = await this.q.forward(vec, encoder)
|
|
57
|
-
this.key = await this.k.forward(vec, encoder)
|
|
58
|
-
this.value = await this.v.forward(vec, encoder)
|
|
59
|
-
const bindAttention = await this.gpu.createBindGroup(this.attentionscoresShader, 0, [this.query.mainBuffer, this.key.mainBuffer, this.scroes, this.asParams])
|
|
60
|
-
await this.gpu.RunPipline(encoder, this.attentionscoresShader, bindAttention, Math.ceil(tokenCount / 16), Math.ceil(tokenCount / 16))
|
|
61
|
-
if (this.weights) this.weights.destroy()
|
|
62
|
-
this.weights = await this.gpu.createBuffer(tokenCount * tokenCount * 4)
|
|
63
|
-
const bindSF = await this.gpu.createBindGroup(this.softmaxForward, 0, [this.scroes, this.weights, this.softmaxParams]);
|
|
64
|
-
await this.gpu.RunPipline(encoder, this.softmaxForward, bindSF, tokenCount)
|
|
65
|
-
if (!this.finalOutput) {
|
|
66
|
-
this.finalOutput = await this.gpu.ManageBuffer(tokenCount * this.embeddingSize * 4)
|
|
67
|
-
}
|
|
68
|
-
if (this.finalOutput.mainBuffer.size !== tokenCount * this.embeddingSize * 4 || this.finalOutput.size == 0 || this.finalOutput.isDestroyed()) {
|
|
69
|
-
this.finalOutput = await this.gpu.ManageBuffer(tokenCount * this.embeddingSize * 4)
|
|
70
|
-
}
|
|
71
|
-
await this.finalOutput.count()
|
|
72
|
-
const outputBind = await this.gpu.createBindGroup(this.outputForward, 0, [this.weights, this.value.mainBuffer, this.finalOutput.mainBuffer, this.asParams]);
|
|
73
|
-
await this.gpu.RunPipline(encoder, this.outputForward, outputBind, Math.ceil((tokenCount * this.embeddingSize) / 256))
|
|
74
|
-
if(!encoder2) await this.gpu.submitQueue(encoder)
|
|
75
|
-
return this.finalOutput
|
|
76
|
-
}
|
|
77
|
-
async backward(dO, lr,encoder2) {
|
|
78
|
-
const tokenCount = dO.size / (this.embeddingSize * 4);
|
|
79
|
-
const encoder = encoder2 ? encoder2 : await this.gpu.CreateEncoder();
|
|
80
|
-
if (!this.dV) this.dV = await this.gpu.createBuffer(dO.size);
|
|
81
|
-
if (!this.dA) this.dA = await this.gpu.createBuffer(tokenCount * tokenCount * 4);
|
|
82
|
-
if (!this.dS) this.dS = await this.gpu.createBuffer(tokenCount * tokenCount * 4);
|
|
83
|
-
if (!this.dQ) this.dQ = await this.gpu.createBuffer(tokenCount * this.embeddingSize * 4);
|
|
84
|
-
if (!this.dK) this.dK = await this.gpu.createBuffer(this.embeddingSize * tokenCount * 4)
|
|
85
|
-
if (this.dV.size !== dO.size || this.dV.size == 0) {
|
|
86
|
-
this.dV.destroy()
|
|
87
|
-
this.dV = await this.gpu.createBuffer(dO.size);
|
|
88
|
-
}
|
|
89
|
-
if (this.dA.size !== tokenCount * tokenCount * 4 || this.dA.size == 0) {
|
|
90
|
-
this.dA.destroy()
|
|
91
|
-
this.dA = await this.gpu.createBuffer(tokenCount * tokenCount * 4);
|
|
92
|
-
}
|
|
93
|
-
if (this.dS.size !== tokenCount * tokenCount * 4 || this.dS.size == 0) {
|
|
94
|
-
this.dS.destroy()
|
|
95
|
-
this.dS = await this.gpu.createBuffer(tokenCount * tokenCount * 4);
|
|
96
|
-
}
|
|
97
|
-
if (this.dQ.size !== tokenCount * this.embeddingSize * 4 || this.dQ.size == 0) {
|
|
98
|
-
this.dQ.destroy()
|
|
99
|
-
this.dQ = await this.gpu.createBuffer(tokenCount * this.embeddingSize * 4);
|
|
100
|
-
}
|
|
101
|
-
if (this.dK.size !== tokenCount * this.embeddingSize * 4 || this.dK.size == 0) {
|
|
102
|
-
this.dK.destroy()
|
|
103
|
-
this.dK = await this.gpu.createBuffer(tokenCount * this.embeddingSize * 4);
|
|
104
|
-
}
|
|
105
|
-
const DvBind = await this.gpu.createBindGroup(this.dVShader, 0, [this.weights, dO.mainBuffer, this.dV, this.asParams]);
|
|
106
|
-
await this.gpu.RunPipline(encoder, this.dVShader, DvBind, Math.ceil(tokenCount / 16), Math.ceil(this.embeddingSize / 16));
|
|
107
|
-
const DaBind = await this.gpu.createBindGroup(this.dAshader, 0, [dO.mainBuffer, this.value.mainBuffer, this.dA, this.asParams]);
|
|
108
|
-
await this.gpu.RunPipline(encoder, this.dAshader, DaBind, Math.ceil(tokenCount / 16), Math.ceil(tokenCount / 16))
|
|
109
|
-
const dSBind = await this.gpu.createBindGroup(this.softmaxBackward, 0, [this.weights, this.dA, this.dS, this.asParams])
|
|
110
|
-
await this.gpu.RunPipline(encoder, this.softmaxBackward, dSBind, Math.ceil((tokenCount * tokenCount) / 256))
|
|
111
|
-
const dQbind = await this.gpu.createBindGroup(this.dQshader, 0, [this.dS, this.key.mainBuffer, this.dQ, this.asParams]);
|
|
112
|
-
await this.gpu.RunPipline(encoder, this.dQshader, dQbind, Math.ceil(tokenCount / 16), Math.ceil(this.embeddingSize / 16))
|
|
113
|
-
const dKbind = await this.gpu.createBindGroup(this.dKShader, 0, [this.dS, this.query.mainBuffer, this.dK, this.asParams]);
|
|
114
|
-
await this.gpu.RunPipline(encoder, this.dKShader, dKbind, Math.ceil(tokenCount / 16), Math.ceil(this.embeddingSize / 16))
|
|
115
|
-
const dq = await this.q.backward({ mainBuffer: this.dQ, size: this.dQ.size}, lr, encoder)
|
|
116
|
-
const dk = await this.k.backward({ mainBuffer: this.dK, size: this.dK.size}, lr, encoder)
|
|
117
|
-
const dv = await this.v.backward({ mainBuffer: this.dV, size: this.dV.size}, lr, encoder)
|
|
118
|
-
if(!this.gradOut) this.gradOut = await this.gpu.ManageBuffer(tokenCount * this.embeddingSize * 4)
|
|
119
|
-
if(this.gradOut.size !== tokenCount * 4 * this.embeddingSize || this.gradOut.isDestroyed() || this.gradOut.size == 0){
|
|
120
|
-
this.gradOut.destroy()
|
|
121
|
-
this.gradOut = await this.gpu.ManageBuffer(tokenCount * 4 * this.embeddingSize)
|
|
122
|
-
}
|
|
123
|
-
await this.gradOut.count()
|
|
124
|
-
if(!dq || !dk || !dq || !this.gradOut){
|
|
125
|
-
throw new Error("Something is wrong!")
|
|
126
|
-
}
|
|
127
|
-
const outputBind = await this.gpu.createBindGroup(this.sumShader, 0, [dq.mainBuffer, dk.mainBuffer, dv.mainBuffer, this.gradOut.mainBuffer, this.asParams]);
|
|
128
|
-
await this.gpu.RunPipline(encoder, this.sumShader, outputBind, Math.ceil((tokenCount * this.embeddingSize / 256)));
|
|
129
|
-
if(!encoder2) await this.gpu.submitQueue(encoder)
|
|
130
|
-
return this.gradOut
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
async Save() {
|
|
134
|
-
await this.q.Save()
|
|
135
|
-
await this.k.Save()
|
|
136
|
-
await this.v.Save()
|
|
137
|
-
}
|
|
138
|
-
}
|
package/src/Softmax/index.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export class Softmax {
|
|
2
|
-
constructor(device: GPUAdapter, embeddingSize: number, vocabSize: number);
|
|
3
|
-
async forward(logit: {
|
|
4
|
-
read: function(): Promise<Float32Array>,
|
|
5
|
-
mainBuffer: GPUBuffer,
|
|
6
|
-
isDestroyed: function(): Boolean,
|
|
7
|
-
destroy: function(): void
|
|
8
|
-
}, isCpuReadBack): Promise<{
|
|
9
|
-
read: function(): Promise<Float32Array>,
|
|
10
|
-
mainBuffer: GPUBuffer,
|
|
11
|
-
isDestroyed: function(): Boolean,
|
|
12
|
-
destroy: function(): void
|
|
13
|
-
}>;
|
|
14
|
-
async backward(probs: {
|
|
15
|
-
read: function(): Promise<Float32Array>,
|
|
16
|
-
mainBuffer: GPUBuffer,
|
|
17
|
-
isDestroyed: function(): Boolean,
|
|
18
|
-
destroy: function(): void
|
|
19
|
-
}, target: number[]): Promise<{
|
|
20
|
-
read: function(): Promise<Float32Array>,
|
|
21
|
-
mainBuffer: GPUBuffer,
|
|
22
|
-
isDestroyed: function(): Boolean,
|
|
23
|
-
destroy: function(): void
|
|
24
|
-
}>
|
|
25
|
-
async crossEntropy(probs: GPUBuffer, target: number[]): Promise<{ loss: Function, acc: Function }>
|
|
26
|
-
}
|
package/src/Softmax/index.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { log } from 'console';
|
|
2
|
-
import { OperationManager } from '../OperationManager.js'
|
|
3
|
-
|
|
4
|
-
export class Softmax {
|
|
5
|
-
device;
|
|
6
|
-
vocabSize;
|
|
7
|
-
forwardPipline;
|
|
8
|
-
embeddingSize;
|
|
9
|
-
gpu;
|
|
10
|
-
paramsForward;
|
|
11
|
-
oldParam;
|
|
12
|
-
bp;
|
|
13
|
-
totalLoss;
|
|
14
|
-
totalAcc;
|
|
15
|
-
totalCalculate;
|
|
16
|
-
constructor(device, embeddingSize, vocabSize) {
|
|
17
|
-
this.vocabSize = vocabSize;
|
|
18
|
-
this.device = device;
|
|
19
|
-
this.embeddingSize = embeddingSize;
|
|
20
|
-
this.gpu = new OperationManager(device);
|
|
21
|
-
this.forwardPipline = this.gpu.getShaderPipline("./src/shaders/SF.wgsl")
|
|
22
|
-
this.backwardPipline = this.gpu.getShaderPipline("./src/shaders/SB.wgsl")
|
|
23
|
-
this.lossPipline = this.gpu.getShaderPipline("./src/shaders/CalculateLoss.wgsl")
|
|
24
|
-
this.accPipline = this.gpu.getShaderPipline("./src/shaders/CalculateAcc.wgsl")
|
|
25
|
-
this.battention = this.gpu.getShaderPipline("./src/shaders/SoftmaxBackward.wgsl")
|
|
26
|
-
this.reduceFn = this.gpu.getShaderPipline("./src/shaders/ReductionFunction.wgsl")
|
|
27
|
-
this.totalCalculate = this.gpu.getShaderPipline('./src/shaders/calculateTotal.wgsl')
|
|
28
|
-
}
|
|
29
|
-
async forward(logits, en) {
|
|
30
|
-
const encoder = en ? en : this.device.createCommandEncoder()
|
|
31
|
-
const tokenCount = logits.size / (this.vocabSize * 4)
|
|
32
|
-
if (!this.paramsForward) {
|
|
33
|
-
this.paramsForward = await this.gpu.createUniFormBuffer(4 * 3)
|
|
34
|
-
}
|
|
35
|
-
if (!this.oldParam) {
|
|
36
|
-
this.oldParam = new Uint32Array([this.vocabSize, 0, 0])
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (this.oldParam[1] !== tokenCount) { await this.gpu.WriteBuffer(this.paramsForward, new Uint32Array([this.vocabSize, tokenCount, 0])); this.oldParam = new Uint32Array([this.vocabSize, tokenCount, 0]); }
|
|
40
|
-
if (!this.output) this.output = await this.gpu.ManageBuffer(logits.size);
|
|
41
|
-
if (this.output.size !== 4 * tokenCount * this.vocabSize || this.output.isDestroyed()) {
|
|
42
|
-
this.output.destroy()
|
|
43
|
-
this.output = await this.gpu.ManageBuffer(logits.size)
|
|
44
|
-
}
|
|
45
|
-
const bind = await this.device.createBindGroup({
|
|
46
|
-
layout: await this.forwardPipline.getBindGroupLayout(0),
|
|
47
|
-
entries: [
|
|
48
|
-
{
|
|
49
|
-
binding: 0,
|
|
50
|
-
resource: {
|
|
51
|
-
buffer: logits.mainBuffer
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
binding: 1,
|
|
56
|
-
resource: {
|
|
57
|
-
buffer: this.output.mainBuffer
|
|
58
|
-
}
|
|
59
|
-
}, {
|
|
60
|
-
binding: 2,
|
|
61
|
-
resource: {
|
|
62
|
-
buffer: this.paramsForward
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
})
|
|
67
|
-
await this.gpu.RunPipline(encoder, this.forwardPipline, bind, tokenCount)
|
|
68
|
-
if(!en) await this.device.queue.submit([encoder.finish()])
|
|
69
|
-
|
|
70
|
-
return this.output
|
|
71
|
-
}
|
|
72
|
-
async backward(probs, target,encoder2) {
|
|
73
|
-
const encoder = encoder2 ? encoder2 : this.device.createCommandEncoder()
|
|
74
|
-
const tokenCount = probs.size / (this.vocabSize * 4)
|
|
75
|
-
if (!this.paramsForward) {
|
|
76
|
-
this.paramsForward = await this.gpu.createUniFormBuffer(4 * 3)
|
|
77
|
-
}
|
|
78
|
-
if (!this.oldParam) {
|
|
79
|
-
this.oldParam = new Uint32Array([this.vocabSize, 0, 0])
|
|
80
|
-
}
|
|
81
|
-
if (this.oldParam[1] !== tokenCount) {
|
|
82
|
-
await this.gpu.WriteBuffer(this.paramsForward, new Uint32Array([this.vocabSize, tokenCount, 0]));
|
|
83
|
-
this.oldParam = new Uint32Array([this.vocabSize, tokenCount, 0]);
|
|
84
|
-
}
|
|
85
|
-
if (!this.targetBuffer) this.targetBuffer = await this.gpu.createBuffer(target.length * Float32Array.BYTES_PER_ELEMENT);
|
|
86
|
-
if (this.targetBuffer.size !== target.length * 4) {
|
|
87
|
-
this.targetBuffer.destroy()
|
|
88
|
-
this.targetBuffer = await this.gpu.createBuffer(target.length * Float32Array.BYTES_PER_ELEMENT)
|
|
89
|
-
}
|
|
90
|
-
if (!this.dLogits) this.dLogits = await this.gpu.ManageBuffer(probs.size);
|
|
91
|
-
if (this.dLogits.size !== probs.size) {
|
|
92
|
-
this.dLogits.destroy()
|
|
93
|
-
this.dLogits = await this.gpu.ManageBuffer(probs.size);
|
|
94
|
-
}
|
|
95
|
-
await this.gpu.WriteBuffer(this.targetBuffer, new Float32Array(target))
|
|
96
|
-
const bind = await this.device.createBindGroup({
|
|
97
|
-
layout: await this.backwardPipline.getBindGroupLayout(0),
|
|
98
|
-
entries: [
|
|
99
|
-
{
|
|
100
|
-
binding: 0,
|
|
101
|
-
resource: {
|
|
102
|
-
buffer: probs.mainBuffer
|
|
103
|
-
}
|
|
104
|
-
}, {
|
|
105
|
-
binding: 2,
|
|
106
|
-
resource: {
|
|
107
|
-
buffer: this.targetBuffer
|
|
108
|
-
}
|
|
109
|
-
}, {
|
|
110
|
-
binding: 3,
|
|
111
|
-
resource: {
|
|
112
|
-
buffer: this.paramsForward
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
binding: 4,
|
|
117
|
-
resource: {
|
|
118
|
-
buffer: this.dLogits.mainBuffer
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
]
|
|
122
|
-
})
|
|
123
|
-
await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((tokenCount * this.vocabSize) / 256))
|
|
124
|
-
if(!encoder2) await this.gpu.submitQueue(encoder)
|
|
125
|
-
return this.dLogits
|
|
126
|
-
}
|
|
127
|
-
async crossEntropy(probs, target, encoderMain) {
|
|
128
|
-
const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder();
|
|
129
|
-
const tokenCount = probs.size / (this.vocabSize * Float32Array.BYTES_PER_ELEMENT);
|
|
130
|
-
if (!Number.isInteger(tokenCount) || tokenCount <= 0) {
|
|
131
|
-
throw new Error("Invalid probability buffer size or vocabulary size");
|
|
132
|
-
}
|
|
133
|
-
const targetBytes = target.length * Uint32Array.BYTES_PER_ELEMENT;
|
|
134
|
-
|
|
135
|
-
if (!this.targetBuffer || this.targetBuffer.size < targetBytes) {
|
|
136
|
-
this.targetBuffer =
|
|
137
|
-
await this.gpu.createBuffer(targetBytes);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (!this.loss || this.loss.size < tokenCount * 4) {
|
|
141
|
-
this.loss = await this.gpu.createBuffer(tokenCount * 4);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (!this.acc) {
|
|
145
|
-
this.acc = await this.gpu.createBuffer(4);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
await this.gpu.WriteBuffer(
|
|
149
|
-
this.targetBuffer,
|
|
150
|
-
new Uint32Array(target)
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
const bindGroup1 = await this.gpu.createBindGroup(
|
|
154
|
-
this.lossPipline,
|
|
155
|
-
0,
|
|
156
|
-
[probs.mainBuffer, this.targetBuffer, this.loss, this.paramsForward]
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const bindGroup2 = await this.gpu.createBindGroup(
|
|
160
|
-
this.accPipline,
|
|
161
|
-
0,
|
|
162
|
-
[this.paramsForward, probs.mainBuffer, this.acc, this.targetBuffer]
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
await this.gpu.RunPipline(
|
|
166
|
-
encoder,
|
|
167
|
-
this.lossPipline,
|
|
168
|
-
bindGroup1,
|
|
169
|
-
Math.ceil(tokenCount / 4)
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
await this.gpu.RunPipline(
|
|
173
|
-
encoder,
|
|
174
|
-
this.accPipline,
|
|
175
|
-
bindGroup2,
|
|
176
|
-
1
|
|
177
|
-
);
|
|
178
|
-
|
|
179
|
-
if (!encoderMain) {
|
|
180
|
-
await this.gpu.submitQueue(encoder);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
loss: async () =>
|
|
185
|
-
(await this.gpu.readBuffer(this.loss.size, this.loss)),
|
|
186
|
-
|
|
187
|
-
acc: async () =>
|
|
188
|
-
(await this.gpu.readBuffer(4, this.acc))[0],
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
package/src/Tokenizer/index.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export class Tokenizer{
|
|
2
|
-
vocabs : string[]
|
|
3
|
-
vocabSize: number
|
|
4
|
-
IdtoWord : Record<string, string>
|
|
5
|
-
WordtoID : Record<string , number>
|
|
6
|
-
encoder(text: string) : {
|
|
7
|
-
tokens: string[]
|
|
8
|
-
tokenIDs: number[]
|
|
9
|
-
}
|
|
10
|
-
decoder(tokens: number[] | number[][]) : string
|
|
11
|
-
trainTokenizer(text: string, mergeSize: number, filename: string) : void
|
|
12
|
-
}
|
package/src/Tokenizer/index.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import fs, { existsSync, readFileSync } from 'fs'
|
|
2
|
-
import { join, dirname, format } from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
|
|
5
|
-
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
6
|
-
export class Tokenizer {
|
|
7
|
-
vocabs = [];
|
|
8
|
-
vocabSize = 0;
|
|
9
|
-
IdtoWord = {};
|
|
10
|
-
WordtoID = {};
|
|
11
|
-
EOSToken = 2
|
|
12
|
-
constructor(filename = "") {
|
|
13
|
-
if (fs.existsSync(filename)) {
|
|
14
|
-
console.log("Warning: Tokenizer is loaded with a Custom Vocab File!")
|
|
15
|
-
console.log("")
|
|
16
|
-
this.vocabs = JSON.parse(readFileSync(filename, "utf-8"))
|
|
17
|
-
} else {
|
|
18
|
-
this.vocabs = JSON.parse(readFileSync(join(__dirname, "vocabs.json"), "utf-8"))
|
|
19
|
-
}
|
|
20
|
-
this.vocabSize = this.vocabs.length
|
|
21
|
-
this.IdtoWord = Object.fromEntries(this.vocabs.map((e, idx) => [idx, e]))
|
|
22
|
-
this.WordtoID = Object.fromEntries(this.vocabs.map((e, idx) => [e, idx]))
|
|
23
|
-
}
|
|
24
|
-
encoder(text = "") {
|
|
25
|
-
const AddSpaces = text.replaceAll(/<EOS>/gi, " <EOS> ").toLocaleLowerCase().replaceAll(/<eos>/g, " <EOS> ").replaceAll(/([,.;'{}!`~|":?])/g, " $1 ");
|
|
26
|
-
const splitedWords = AddSpaces.split(/\s+/).filter(e => e.length > 0)
|
|
27
|
-
const output = []
|
|
28
|
-
for (let a = 0; a < splitedWords.length; a++) {
|
|
29
|
-
const word = splitedWords[a]
|
|
30
|
-
if (typeof this.WordtoID[word] !== "undefined") {
|
|
31
|
-
output.push(word)
|
|
32
|
-
} else {
|
|
33
|
-
let max = word.length
|
|
34
|
-
output.push("$12")
|
|
35
|
-
while (true) {
|
|
36
|
-
const regPatten = new RegExp(`.{0,${max}}`, "g")
|
|
37
|
-
const wordsliced = word.match(regPatten).filter((e) => e.length > 0)
|
|
38
|
-
const matched = wordsliced.flatMap(e => {
|
|
39
|
-
if (this.WordtoID[e] !== undefined) {
|
|
40
|
-
return true
|
|
41
|
-
}
|
|
42
|
-
return false
|
|
43
|
-
|
|
44
|
-
}).reduce((prev, curr) => prev && curr, true)
|
|
45
|
-
if (wordsliced.length == 0) output.push("<unk>")
|
|
46
|
-
if (matched) {
|
|
47
|
-
wordsliced.map((e) => output.push(e))
|
|
48
|
-
output.push("$130")
|
|
49
|
-
break
|
|
50
|
-
} else {
|
|
51
|
-
max -= 1
|
|
52
|
-
// break
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return { tokens: output, tokenIDs: output.map((e) => this.WordtoID[e]) }
|
|
59
|
-
}
|
|
60
|
-
decoder(tokens = [1, 2, 3]) {
|
|
61
|
-
const output = []
|
|
62
|
-
let isSpace = false
|
|
63
|
-
// let index = 0
|
|
64
|
-
for (let token of tokens) {
|
|
65
|
-
const formated = this.IdtoWord[String(token)]
|
|
66
|
-
if (formated == "$12") {
|
|
67
|
-
output[output.length] = ""
|
|
68
|
-
isSpace = true
|
|
69
|
-
} else if (formated == "$130") {
|
|
70
|
-
isSpace = false
|
|
71
|
-
} else {
|
|
72
|
-
if (isSpace) {
|
|
73
|
-
output[output.length - 1] += formated
|
|
74
|
-
} else {
|
|
75
|
-
output.push(formated)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return output.filter(e => e.trim().length > 0).join(" ").replaceAll(/\s+([,.;'{}`!~\"?])/g, "$1")
|
|
80
|
-
}
|
|
81
|
-
trainTokenizer(text = "ejrnienieijr", mergeLength = 5, vocabFileName) {
|
|
82
|
-
console.log("Training The Tokenizer....")
|
|
83
|
-
const arrText = text.toLowerCase().replace(/\r\n|\n|\r/g, " <EOS> ").toLocaleLowerCase().replaceAll(/<eos>/g, " <EOS> ").replace(/([,.;'{}!`~|":><?])/g, " $1 ").split(/\s+/).map(e => e.trim()).filter(e => e.length > 0)
|
|
84
|
-
const reg = new RegExp(`.{0,${mergeLength}}`, "g")
|
|
85
|
-
const prevVocab = existsSync(vocabFileName) ? JSON.parse(readFileSync(vocabFileName, "utf-8")) : [];
|
|
86
|
-
const specal = ["<unk>",
|
|
87
|
-
"<PAD>",
|
|
88
|
-
"<EOS>",
|
|
89
|
-
"$12",
|
|
90
|
-
"$130",
|
|
91
|
-
"😀",
|
|
92
|
-
"😃",
|
|
93
|
-
"😄",
|
|
94
|
-
"😁",
|
|
95
|
-
"😆",
|
|
96
|
-
"😅",
|
|
97
|
-
"😂",
|
|
98
|
-
"🤣",
|
|
99
|
-
"😊",
|
|
100
|
-
"😎",
|
|
101
|
-
"❤️",
|
|
102
|
-
"👍",
|
|
103
|
-
"👎",
|
|
104
|
-
"🔥",
|
|
105
|
-
"💯",
|
|
106
|
-
"🎉",
|
|
107
|
-
"🚀",
|
|
108
|
-
"⭐",
|
|
109
|
-
"😭",
|
|
110
|
-
"😍",
|
|
111
|
-
"🥰",
|
|
112
|
-
"😡",
|
|
113
|
-
"🤔",
|
|
114
|
-
"😢",
|
|
115
|
-
"😮",
|
|
116
|
-
"👋",
|
|
117
|
-
"🙏",
|
|
118
|
-
"💀",
|
|
119
|
-
"🤖",
|
|
120
|
-
"👀",
|
|
121
|
-
"💕",
|
|
122
|
-
"💔",
|
|
123
|
-
"😂😂",
|
|
124
|
-
"😂😭",
|
|
125
|
-
"🔥🔥",
|
|
126
|
-
"❤️❤️",
|
|
127
|
-
"👍👍",
|
|
128
|
-
"<",
|
|
129
|
-
">",
|
|
130
|
-
".",
|
|
131
|
-
"{",
|
|
132
|
-
"}",
|
|
133
|
-
"?",
|
|
134
|
-
"!",
|
|
135
|
-
"@",
|
|
136
|
-
"$",
|
|
137
|
-
":",
|
|
138
|
-
"/",
|
|
139
|
-
"+",
|
|
140
|
-
"-",
|
|
141
|
-
"=",
|
|
142
|
-
"%",
|
|
143
|
-
"*",
|
|
144
|
-
"@"
|
|
145
|
-
]
|
|
146
|
-
const uniArr = [...new Set([...arrText, ...specal, ...prevVocab])];
|
|
147
|
-
const output = []
|
|
148
|
-
for (let a = 0; a < uniArr.length; a++) {
|
|
149
|
-
let text = uniArr[a].match(reg).filter((e) => e.length > 0);
|
|
150
|
-
output.push(...text)
|
|
151
|
-
}
|
|
152
|
-
let finalOutput = [...new Set([...output])]
|
|
153
|
-
fs.writeFileSync(vocabFileName, JSON.stringify(finalOutput, null, 2), "utf-8");
|
|
154
|
-
console.log("_________________________________")
|
|
155
|
-
console.log(`New VocabSize : ${finalOutput.length - prevVocab.length}`);
|
|
156
|
-
console.log("_________________________________")
|
|
157
|
-
console.log("Operation Completed!")
|
|
158
|
-
this.vocabs = finalOutput;
|
|
159
|
-
this.vocabSize = finalOutput.length;
|
|
160
|
-
this.IdtoWord = Object.fromEntries(this.vocabs.map((e, idx) => [idx, e]))
|
|
161
|
-
this.WordtoID = Object.fromEntries(this.vocabs.map((e, idx) => [e, idx]))
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
}
|