@imaduddin/fastbrain 1.0.1 → 1.0.3

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/index.js CHANGED
@@ -8,6 +8,7 @@ import {SelfAttention as ST} from './src/SelfAttention/index.js'
8
8
  import {TransformerBlock as TT} from './src/TransformerBlock/index.js'
9
9
  import {PositionEmbedding as PM } from './src/PositionEmbedding/index.js'
10
10
  import { RMSNorm as RM } from "./src/RMSNorm/index.js";
11
+ import {model as M} from './src/model/index.js'
11
12
  export const Embedding = E
12
13
  export const Linear = L
13
14
  export const Softmax = S;
@@ -17,4 +18,5 @@ export const Tokenizer = to;
17
18
  export const SelfAttention = ST
18
19
  export const TransformerBlock = TT;
19
20
  export const PositionEmbedding = PM;
20
- export const RMSNorm = RM
21
+ export const RMSNorm = RM
22
+ export const model = M
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaduddin/fastbrain",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Raw-JAVASCRIPT Based Matirx and AI LLM Package called fastBrain.",
5
5
  "keywords": [
6
6
  "ai",
@@ -21,7 +21,7 @@
21
21
  "url": "https://github.com/imaduddin/fastBrain.git"
22
22
  },
23
23
  "dependencies": {
24
- "webgpu": "^0.6.0"
24
+ "webgpu": "^0.6.1"
25
25
  },
26
26
  "allowScripts": {
27
27
  "webgpu@0.6.0": true
@@ -45,8 +45,8 @@ export class Embedding {
45
45
  })
46
46
  SaveVector(this.configs.save.filename, this.vectors)
47
47
  }
48
- async forward(input, encoderMain) {
49
- const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder()
48
+ async forward(input, encoder2) {
49
+ const encoder = encoder2 ? encoder2 : this.device.createCommandEncoder()
50
50
  if (!this.vectorsBuffer) {
51
51
  this.vectorsBuffer = await this.gpu.createBuffer(Float32Array.BYTES_PER_ELEMENT * this.vocabSize * this.embeddingSize);
52
52
  await this.gpu.WriteBuffer(this.vectorsBuffer, this.vectors)
@@ -86,7 +86,7 @@ export class Embedding {
86
86
  ]
87
87
  })
88
88
  await this.gpu.RunPipline(encoder, this.forwardPipline, bind, Math.ceil((this.embeddingSize * input.length) / 256))
89
- if(!encoderMain) await this.device.queue.submit([encoder.finish()])
89
+ if(!encoder2) await this.device.queue.submit([encoder.finish()])
90
90
  return this.outputBuffer
91
91
 
92
92
  }
@@ -94,8 +94,8 @@ export class Embedding {
94
94
  const vec = await this.gpu.readBuffer(Float32Array.BYTES_PER_ELEMENT * this.vocabSize * this.embeddingSize, this.vectorsBuffer)
95
95
  SaveVector(this.configs.save.filename, vec)
96
96
  }
97
- async backward(inputGradient, lr, encoderMain) {
98
- const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder()
97
+ async backward(inputGradient, lr, en2) {
98
+ const encoder = en2 ? en2 : this.device.createCommandEncoder()
99
99
  if (!this.oldParam) {
100
100
  this.oldParam = new Float32Array([0, 0]);
101
101
  this.param = await this.gpu.createUniFormBuffer(this.oldParam.byteLength);
@@ -134,7 +134,7 @@ export class Embedding {
134
134
  ]
135
135
  })
136
136
  await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((this.embeddingSize * (this.tokenBuffer.size / 4)) / 256))
137
- if(!encoderMain) this.device.queue.submit([encoder.finish()])
137
+ if(!en2) this.device.queue.submit([encoder.finish()])
138
138
  }
139
139
 
140
140
  }
package/src/FFN/index.js CHANGED
@@ -28,10 +28,10 @@ export class FFN {
28
28
  const final = await this.linear2.forward(hidden, encoderMain)
29
29
  return final
30
30
  }
31
- async backward(inputGradient, lr, encoderMain) {
32
- const logit2 = await this.linear2.backward(inputGradient, lr, encoderMain)
33
- const hidden = await this.hiddenLayer.backward(logit2, encoderMain)
34
- const final = await this.linear1.backward(hidden, lr, encoderMain)
31
+ async backward(inputGradient, lr, encoder) {
32
+ const logit2 = await this.linear2.backward(inputGradient, lr, encoder)
33
+ const hidden = await this.hiddenLayer.backward(logit2,encoder)
34
+ const final = await this.linear1.backward(hidden, lr, encoder)
35
35
  return final
36
36
  }
37
37
  async Save() {
@@ -110,7 +110,7 @@ export class Linear {
110
110
  })
111
111
  await this.gpu.RunPipline(encoder, this.forwardPipline, bind, Math.ceil(this.vocabSize / 16), Math.ceil(tokenCount / 4))
112
112
 
113
- if (!encoderMain) this.device.queue.submit([encoder.finish()])
113
+ if(!encoderMain) this.device.queue.submit([encoder.finish()])
114
114
  this.input = vec;
115
115
  return this.outputBuffer
116
116
  }
@@ -179,10 +179,9 @@ export class Linear {
179
179
  }
180
180
  ]
181
181
  })
182
- // console.log((await this.gpu.readBuffer(this.input.size, this.input))[0])
183
- await this.gpu.RunPipline(encoder, this.dInputBackward, bind2, Math.ceil((this.embeddingSize * tokenCount) / 256));
184
- await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil(this.vocabSize));
185
- if (!encoderMain) await this.device.queue.submit([encoder.finish()])
182
+ await this.gpu.RunPipline(encoder, this.dInputBackward, bind2, Math.ceil((this.embeddingSize * tokenCount) / 64));
183
+ await this.gpu.RunPipline(encoder, this.backwardPipline, bind, this.vocabSize);
184
+ if(!encoderMain) await this.device.queue.submit([encoder.finish()])
186
185
  return this.gradientBuffer
187
186
 
188
187
  }
@@ -38,8 +38,8 @@ export class PositionEmbedding {
38
38
  this.forwardShader = this.gpu.getShaderPipline("./src/shaders/PF.wgsl")
39
39
  this.backwardShader = this.gpu.getShaderPipline("./src/shaders/PB.wgsl")
40
40
  }
41
- async forward(input, encoderMain) {
42
- const encoder = encoderMain ? encoderMain : this.gpu.CreateEncoder()
41
+ async forward(input, en2) {
42
+ const encoder = en2 ? en2 : this.gpu.CreateEncoder()
43
43
  if (!this.params) this.params = await this.gpu.createUniFormBuffer(4 * 4)
44
44
  if (!this.vecBuffer) {
45
45
  this.vecBuffer = await this.gpu.createBuffer(Float32Array.BYTES_PER_ELEMENT * this.contextSize * this.embeddingSize);
@@ -48,15 +48,15 @@ export class PositionEmbedding {
48
48
  const size = Math.ceil((input.size / 4) / 64);
49
49
  const bindGroup = await this.gpu.createBindGroup(this.forwardShader, 0, [this.vecBuffer, input.mainBuffer])
50
50
  await this.gpu.RunPipline(encoder, this.forwardShader, bindGroup, size);
51
- if(!encoderMain) await this.gpu.submitQueue(encoder);
51
+ if(!en2) await this.gpu.submitQueue(encoder);
52
52
  return input
53
53
  }
54
- async backward(outputGradient, lr, encoderMain){
55
- const encoder = encoderMain ? encoderMain : await this.gpu.CreateEncoder()
54
+ async backward(outputGradient, lr, en2){
55
+ const encoder = en2 ? en2 : await this.gpu.CreateEncoder()
56
56
  await this.gpu.WriteBuffer(this.params, new Float32Array([lr,0]))
57
57
  const bindGroup = await this.gpu.createBindGroup(this.backwardShader, 0, [this.vecBuffer, outputGradient.mainBuffer, this.params])
58
58
  await this.gpu.RunPipline(encoder, this.backwardShader, bindGroup, Math.ceil((outputGradient.size / 4) / 64))
59
- if(!encoderMain) await this.gpu.submitQueue(encoder);
59
+ if(!en2) await this.gpu.submitQueue(encoder);
60
60
  }
61
61
  async Save() {
62
62
  const vec = await this.gpu.readBuffer(Float32Array.BYTES_PER_ELEMENT * this.contextSize * this.embeddingSize, this.vecBuffer)
@@ -45,7 +45,7 @@ export class RMSNorm {
45
45
  this.gamma = new Float32Array(embeddingSize).fill(1)
46
46
  }
47
47
  }
48
- async forward(vec, encoderMain) {
48
+ async forward(vec, en) {
49
49
  if (!this.gammabuffer) {
50
50
  this.gammabuffer = await this.op.createBuffer(this.embeddingSize * 4);
51
51
  await this.op.WriteBuffer(this.gammabuffer, this.gamma);
@@ -57,34 +57,30 @@ export class RMSNorm {
57
57
  this.rmsReduction.destroy()
58
58
  this.rmsReduction = await this.op.createBuffer(4 * context)
59
59
  }
60
- if (this.output.size !== vec.size) {
61
- this.output.destroy()
62
- this.output = await this.op.ManageBuffer(vec.size)
63
- }
64
- const encoder = encoderMain ? encoderMain : await this.op.CreateEncoder()
60
+ if (this.output) this.output.destroy();
61
+ this.output = await this.op.ManageBuffer(vec.size)
62
+ const encoder = en ? en : await this.op.CreateEncoder()
65
63
  const bind1 = await this.op.createBindGroup(this.reductionShader, 0, [vec.mainBuffer, this.rmsReduction])
66
64
  const bind2 = await this.op.createBindGroup(this.forwardShader, 0, [this.rmsReduction, vec.mainBuffer, this.output.mainBuffer, this.gammabuffer])
67
65
  await this.op.RunPipline(encoder, this.reductionShader, bind1, context)
68
66
  await this.op.RunPipline(encoder, this.forwardShader, bind2, Math.ceil((this.embeddingSize * context) / 64))
69
- if (!encoderMain) await this.op.submitQueue(encoder);
67
+ if(!en) await this.op.submitQueue(encoder);
70
68
  this.input = vec;
71
69
  return this.output
72
70
 
73
71
  }
74
- async backward(outGradient, lr, encoderMain) {
72
+ async backward(outGradient, lr, en) {
75
73
  const contextSize = outGradient.size / (this.embeddingSize * 4);
76
- if (!this.gradientOutput) this.gradientOutput = await this.op.ManageBuffer(this.embeddingSize * 4 * contextSize)
77
- if (this.gradientOutput.size !== outGradient.size) {
78
- this.gradientOutput = await this.op.ManageBuffer(this.embeddingSize * 4 * contextSize)
79
- }
80
- if (!this.params) this.params = await this.op.createBuffer(4 * 2);
74
+ if (this.gradientOutput) this.gradientOutput.destroy()
75
+ this.gradientOutput = await this.op.ManageBuffer(this.embeddingSize * 4 * contextSize)
76
+ if (!this.params) this.params = await this.op.createUniFormBuffer(4 * 2);
81
77
  await this.op.WriteBuffer(this.params, new Float32Array([lr, 0]))
82
- const encoder = encoderMain ? encoderMain : this.op.CreateEncoder()
78
+ const encoder = en ? en : this.op.CreateEncoder()
83
79
  const bind1 = await this.op.createBindGroup(this.backwardShader, 0, [this.input.mainBuffer, outGradient.mainBuffer, this.rmsReduction, this.gammabuffer, this.gradientOutput.mainBuffer])
84
80
  await this.op.RunPipline(encoder, this.backwardShader, bind1, contextSize);
85
81
  const bind2 = await this.op.createBindGroup(this.updateGamma, 0, [this.input.mainBuffer, outGradient.mainBuffer, this.rmsReduction, this.gammabuffer, this.params])
86
82
  await this.op.RunPipline(encoder, this.updateGamma, bind2, this.embeddingSize);
87
- if (!encoderMain) this.op.submitQueue(encoder);
83
+ if(!en) this.op.submitQueue(encoder);
88
84
  return this.gradientOutput
89
85
  }
90
86
  async Save() {
package/src/Relu/index.js CHANGED
@@ -15,8 +15,8 @@ export class Relu {
15
15
  this.forwardPipline = this.gpu.getShaderPipline("./src/shaders/RF.wgsl")
16
16
  this.backwardPipline = this.gpu.getShaderPipline("./src/shaders/RB.wgsl")
17
17
  }
18
- async forward(input, encoderMain) {
19
- const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder()
18
+ async forward(input, en) {
19
+ const encoder = en ? en : this.device.createCommandEncoder()
20
20
  const tokenCount = input.mainBuffer.size / (this.embeddingSize * 4)
21
21
  if (!this.oldParam) {
22
22
  this.oldParam = new Uint32Array([0, 0, 0]);
@@ -54,12 +54,12 @@ export class Relu {
54
54
  ]
55
55
  })
56
56
  await this.gpu.RunPipline(encoder, this.forwardPipline, bind, Math.ceil((tokenCount * this.embeddingSize) / 256))
57
- if(!encoderMain) this.device.queue.submit([encoder.finish()])
57
+ if(!en) this.device.queue.submit([encoder.finish()])
58
58
  this.input = input
59
59
  return this.output
60
60
  }
61
- async backward(inputGradient, encoderMain) {
62
- const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder()
61
+ async backward(inputGradient,en) {
62
+ const encoder = en ? en : this.device.createCommandEncoder()
63
63
  const tokenCount = inputGradient.size / (this.embeddingSize * 4)
64
64
  if (!this.oldParam) {
65
65
  this.oldParam = new Uint32Array([0, 0, 0]);
@@ -102,7 +102,7 @@ export class Relu {
102
102
  ]
103
103
  })
104
104
  await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((tokenCount * this.embeddingSize) / 256))
105
- if(!encoderMain) await this.device.queue.submit([encoder.finish()])
105
+ if(!en) await this.device.queue.submit([encoder.finish()])
106
106
  return this.gradOut
107
107
  }
108
108
  }
@@ -38,12 +38,12 @@ export class SelfAttention {
38
38
  this.dKShader = this.gpu.getShaderPipline("./src/shaders/attentionShader/ComputeK.wgsl")
39
39
  this.sumShader = this.gpu.getShaderPipline("./src/shaders/attentionShader/sumGradient.wgsl")
40
40
  }
41
- async forward(vec, encoderMain) {
41
+ async forward(vec, encoder2) {
42
42
  this.input = vec.mainBuffer;
43
43
  const tokenCount = vec.mainBuffer.size / (this.embeddingSize * 4)
44
44
  if (!this.asParams) this.asParams = await this.gpu.createUniFormBuffer(4 * 3);
45
45
  if (!this.softmaxParams) this.softmaxParams = await this.gpu.createUniFormBuffer(4 * 3);
46
- const encoder = encoderMain ? encoderMain : await this.gpu.CreateEncoder()
46
+ const encoder = encoder2 ? encoder2 : await this.gpu.CreateEncoder()
47
47
  if (!this.scroes) {
48
48
  this.scroes = await this.gpu.createBuffer(tokenCount * tokenCount * 4)
49
49
  }
@@ -53,9 +53,9 @@ export class SelfAttention {
53
53
  }
54
54
  await this.gpu.WriteBuffer(this.asParams, new Uint32Array([tokenCount, this.embeddingSize, 0]))
55
55
  await this.gpu.WriteBuffer(this.softmaxParams, new Uint32Array([tokenCount, tokenCount, 0]))
56
- this.query = await this.q.forward(vec, encoderMain)
57
- this.key = await this.k.forward(vec, encoderMain)
58
- this.value = await this.v.forward(vec, encoderMain)
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
59
  const bindAttention = await this.gpu.createBindGroup(this.attentionscoresShader, 0, [this.query.mainBuffer, this.key.mainBuffer, this.scroes, this.asParams])
60
60
  await this.gpu.RunPipline(encoder, this.attentionscoresShader, bindAttention, Math.ceil(tokenCount / 16), Math.ceil(tokenCount / 16))
61
61
  if (this.weights) this.weights.destroy()
@@ -71,12 +71,12 @@ export class SelfAttention {
71
71
  await this.finalOutput.count()
72
72
  const outputBind = await this.gpu.createBindGroup(this.outputForward, 0, [this.weights, this.value.mainBuffer, this.finalOutput.mainBuffer, this.asParams]);
73
73
  await this.gpu.RunPipline(encoder, this.outputForward, outputBind, Math.ceil((tokenCount * this.embeddingSize) / 256))
74
- if(!encoderMain) await this.gpu.submitQueue(encoder)
74
+ if(!encoder2) await this.gpu.submitQueue(encoder)
75
75
  return this.finalOutput
76
76
  }
77
- async backward(dO, lr, encoderMain) {
77
+ async backward(dO, lr,encoder2) {
78
78
  const tokenCount = dO.size / (this.embeddingSize * 4);
79
- const encoder = encoderMain ? encoderMain : await this.gpu.CreateEncoder();
79
+ const encoder = encoder2 ? encoder2 : await this.gpu.CreateEncoder();
80
80
  if (!this.dV) this.dV = await this.gpu.createBuffer(dO.size);
81
81
  if (!this.dA) this.dA = await this.gpu.createBuffer(tokenCount * tokenCount * 4);
82
82
  if (!this.dS) this.dS = await this.gpu.createBuffer(tokenCount * tokenCount * 4);
@@ -112,9 +112,9 @@ export class SelfAttention {
112
112
  await this.gpu.RunPipline(encoder, this.dQshader, dQbind, Math.ceil(tokenCount / 16), Math.ceil(this.embeddingSize / 16))
113
113
  const dKbind = await this.gpu.createBindGroup(this.dKShader, 0, [this.dS, this.query.mainBuffer, this.dK, this.asParams]);
114
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, encoderMain)
116
- const dk = await this.k.backward({ mainBuffer: this.dK, size: this.dK.size}, lr, encoderMain)
117
- const dv = await this.v.backward({ mainBuffer: this.dV, size: this.dV.size}, lr, encoderMain)
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
118
  if(!this.gradOut) this.gradOut = await this.gpu.ManageBuffer(tokenCount * this.embeddingSize * 4)
119
119
  if(this.gradOut.size !== tokenCount * 4 * this.embeddingSize || this.gradOut.isDestroyed() || this.gradOut.size == 0){
120
120
  this.gradOut.destroy()
@@ -126,7 +126,7 @@ export class SelfAttention {
126
126
  }
127
127
  const outputBind = await this.gpu.createBindGroup(this.sumShader, 0, [dq.mainBuffer, dk.mainBuffer, dv.mainBuffer, this.gradOut.mainBuffer, this.asParams]);
128
128
  await this.gpu.RunPipline(encoder, this.sumShader, outputBind, Math.ceil((tokenCount * this.embeddingSize / 256)));
129
- if(!encoderMain) await this.gpu.submitQueue(encoder)
129
+ if(!encoder2) await this.gpu.submitQueue(encoder)
130
130
  return this.gradOut
131
131
 
132
132
  }
@@ -26,8 +26,8 @@ export class Softmax {
26
26
  this.reduceFn = this.gpu.getShaderPipline("./src/shaders/ReductionFunction.wgsl")
27
27
  this.totalCalculate = this.gpu.getShaderPipline('./src/shaders/calculateTotal.wgsl')
28
28
  }
29
- async forward(logits, encoderCPU) {
30
- const encoder = encoderCPU ? encoderCPU : this.device.createCommandEncoder()
29
+ async forward(logits, en) {
30
+ const encoder = en ? en : this.device.createCommandEncoder()
31
31
  const tokenCount = logits.size / (this.vocabSize * 4)
32
32
  if (!this.paramsForward) {
33
33
  this.paramsForward = await this.gpu.createUniFormBuffer(4 * 3)
@@ -65,13 +65,12 @@ export class Softmax {
65
65
  ]
66
66
  })
67
67
  await this.gpu.RunPipline(encoder, this.forwardPipline, bind, tokenCount)
68
- if (!encoderCPU) {
69
- await this.device.queue.submit([encoder.finish()])
70
- }
68
+ if(!en) await this.device.queue.submit([encoder.finish()])
69
+
71
70
  return this.output
72
71
  }
73
- async backward(probs, target, encoderMain) {
74
- const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder()
72
+ async backward(probs, target,encoder2) {
73
+ const encoder = encoder2 ? encoder2 : this.device.createCommandEncoder()
75
74
  const tokenCount = probs.size / (this.vocabSize * 4)
76
75
  if (!this.paramsForward) {
77
76
  this.paramsForward = await this.gpu.createUniFormBuffer(4 * 3)
@@ -88,6 +87,11 @@ export class Softmax {
88
87
  this.targetBuffer.destroy()
89
88
  this.targetBuffer = await this.gpu.createBuffer(target.length * Float32Array.BYTES_PER_ELEMENT)
90
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
+ }
91
95
  await this.gpu.WriteBuffer(this.targetBuffer, new Float32Array(target))
92
96
  const bind = await this.device.createBindGroup({
93
97
  layout: await this.backwardPipline.getBindGroupLayout(0),
@@ -107,12 +111,18 @@ export class Softmax {
107
111
  resource: {
108
112
  buffer: this.paramsForward
109
113
  }
114
+ },
115
+ {
116
+ binding: 4,
117
+ resource: {
118
+ buffer: this.dLogits.mainBuffer
119
+ }
110
120
  }
111
121
  ]
112
122
  })
113
123
  await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((tokenCount * this.vocabSize) / 256))
114
- if (!encoderMain) this.device.queue.submit([encoder.finish()])
115
- return probs
124
+ if(!encoder2) await this.gpu.submitQueue(encoder)
125
+ return this.dLogits
116
126
  }
117
127
  async crossEntropy(probs, target, encoderMain) {
118
128
  const encoder = encoderMain ? encoderMain : this.device.createCommandEncoder();
@@ -54,13 +54,13 @@ export class TransformerBlock {
54
54
  return residual2;
55
55
  }
56
56
 
57
- async backward(outGradient, lr, encoderMain) {
58
- const dAtt = await this.ffn.backward(outGradient, lr, encoderMain);
59
- const dNorm2 = await this.rmsnorm2.backward(dAtt, lr)
60
- const dResidual1 = await this.rback2.add(outGradient, dNorm2, encoderMain)
61
- const dFF = await this.attention.backward(dResidual1, lr, encoderMain)
62
- const dNorm = await this.rmsnorm.backward(dFF, lr)
63
- const dResidual2 = await this.rback1.add(dNorm, dResidual1, encoderMain)
57
+ async backward(outGradient, lr, encoder) {
58
+ const dAtt = await this.ffn.backward(outGradient, lr, encoder);
59
+ const dNorm2 = await this.rmsnorm2.backward(dAtt, lr, encoder)
60
+ const dResidual1 = await this.rback2.add(outGradient, dNorm2, encoder)
61
+ const dFF = await this.attention.backward(dResidual1, lr, encoder)
62
+ const dNorm = await this.rmsnorm.backward(dFF, lr, encoder)
63
+ const dResidual2 = await this.rback1.add(dNorm, dResidual1 ,encoder)
64
64
  return dResidual2;
65
65
  }
66
66
 
@@ -0,0 +1,39 @@
1
+ import { Embedding } from '../Embedding/index.ts'
2
+ import { Linear } from '../Linear/index.ts'
3
+ import { PositionEmbedding } from '../PositionEmbedding/index.ts'
4
+ import { TransformerBlock } from '../TransformerBlock/index.ts'
5
+ import { Softmax } from '../Softmax/index.ts'
6
+ import { Tokenizer } from '../Tokenizer/index.ts'
7
+
8
+
9
+
10
+ export class model {
11
+ tokenizer: Tokenizer
12
+ embedding: Embedding
13
+ linear: Linear
14
+ PosEmbedding: PositionEmbedding
15
+ blocks: TransformerBlock[]
16
+ softmax: Softmax
17
+ embeddingSize: number
18
+ loopSize: number
19
+ contextSize: number
20
+ constructor(device: GPUAdapter, configs: {
21
+ embeddingSize: number,
22
+ contextSize: number,
23
+ blockSize: number,
24
+ dirname: string,
25
+ vocabFile: string
26
+ })
27
+ async forward(input: number[], target: number[]): Promise<{
28
+ read: function(): Promise<Float32Array>,
29
+ mainBuffer: GPUBuffer,
30
+ isDestroyed: function(): Boolean,
31
+ destroy: function(): void
32
+ }>
33
+ async backward(x: {
34
+ read: function(): Promise<Float32Array>,
35
+ mainBuffer: GPUBuffer,
36
+ isDestroyed: function(): Boolean,
37
+ destroy: function(): void
38
+ }, target: number[], lr : number)
39
+ }
@@ -0,0 +1,79 @@
1
+ import { Embedding } from "../Embedding/index.js"
2
+ import { Linear } from "../Linear/index.js"
3
+ import { PositionEmbedding } from "../PositionEmbedding/index.js"
4
+ import { Softmax } from "../Softmax/index.js"
5
+ import { Tokenizer } from "../Tokenizer/index.js"
6
+ import { join } from 'path'
7
+ import { TransformerBlock } from "../TransformerBlock/index.js"
8
+ import {OperationManager} from '../OperationManager.js'
9
+ export class model {
10
+ tokenizer
11
+ embedding
12
+ linear
13
+ PosEmbedding
14
+ blocks = []
15
+ softmax
16
+ embeddingSize
17
+ contextSize
18
+ op;
19
+ clearLoss;
20
+ getLoss;
21
+ getAcc;
22
+ constructor(device, configs) {
23
+ this.contextSize = configs.contextSize
24
+ this.embeddingSize = configs.embeddingSize;
25
+ this.tokenizer = new Tokenizer(configs.vocabFile)
26
+ this.op = new OperationManager(device)
27
+ this.embedding = new Embedding(device, this.embeddingSize, this.tokenizer.vocabSize, {
28
+ save: {
29
+ filename: join(configs.dirname, "vec.bin")
30
+ }
31
+ })
32
+ this.softmax = new Softmax(device, this.embeddingSize, this.tokenizer.vocabSize);
33
+ this.PosEmbedding = new PositionEmbedding(device, this.embeddingSize, configs.contextSize, {
34
+ save: {
35
+ filename: join(configs.dirname, "posVec.bin")
36
+ }
37
+ })
38
+ this.linear = new Linear(device, this.embeddingSize, this.tokenizer.vocabSize, {
39
+ save: {
40
+ filename: [join(configs.dirname, "w.bin"), join(configs.dirname, "b.bin")]
41
+ }
42
+ })
43
+ for (let a = 0; a < configs.blockSize; a++) {
44
+ this.blocks[a] = new TransformerBlock(device, this.embeddingSize, {
45
+ dirname: join(configs.dirname, `block-${a + 1}`)
46
+ })
47
+ }
48
+ }
49
+ async forward(input, target) {
50
+ const encoder = await this.op.CreateEncoder()
51
+ if (input.length > this.contextSize) throw new Error("The input get large then ContextSize")
52
+ let vec = await this.embedding.forward(input, encoder)
53
+ vec = await this.PosEmbedding.forward(vec, encoder)
54
+ for (let i = 0; i < this.blocks.length; i++) {
55
+ vec = await this.blocks[i].forward(vec, encoder)
56
+ }
57
+
58
+ let logits = await this.linear.forward(vec, encoder)
59
+ let probs = await this.softmax.forward(logits, encoder)
60
+ await this.op.submitQueue(encoder)
61
+ const {acc,clear,loss} = await this.softmax.crossEntropy(probs, target)
62
+ this.getAcc = acc;
63
+ this.getLoss = loss;
64
+ this.clearLoss = clear;
65
+ return probs
66
+ }
67
+ async backward(x, target, lr){
68
+ const encoder = await this.op.CreateEncoder()
69
+ let dLogits = await this.softmax.backward(x, target, encoder)
70
+ let dInput = await this.linear.backward(dLogits, lr, encoder)
71
+ for (let i = this.blocks.length - 1; i >= 0; i--) {
72
+ dInput = await this.blocks[i].backward(dInput, lr, encoder)
73
+ };
74
+ await this.embedding.backward(dInput, lr)
75
+ await this.PosEmbedding.backward(dInput, lr)
76
+ await this.op.submitQueue(encoder)
77
+
78
+ }
79
+ }
@@ -10,11 +10,11 @@ export class residualConnection {
10
10
  this.gpu = new OperationManager(device)
11
11
  this.addShader = this.gpu.getShaderPipline("./src/shaders/add.wgsl")
12
12
  }
13
- async add(a, b, encoderMain) {
13
+ async add(a, b, en) {
14
14
  if (!this.params) {
15
15
  this.params = await this.gpu.createUniFormBuffer(4 * 4)
16
16
  }
17
- const encoder = encoderMain ? encoderMain : await this.gpu.CreateEncoder()
17
+ const encoder = en ? en : await this.gpu.CreateEncoder()
18
18
  if (!this.output) {
19
19
  this.output = await this.gpu.ManageBuffer(a.size);
20
20
  }
@@ -22,11 +22,10 @@ export class residualConnection {
22
22
  this.output.destroy()
23
23
  this.output = await this.gpu.ManageBuffer(a.size);
24
24
  }
25
- await this.output.count()
26
25
  const bind = await this.gpu.createBindGroup(this.addShader, 0, [a.mainBuffer, b.mainBuffer, this.output.mainBuffer, this.params]);
27
26
  await this.gpu.WriteBuffer(this.params, new Uint32Array([(a.size / 4), 0]))
28
27
  await this.gpu.RunPipline(encoder, this.addShader, bind, Math.ceil((a.size / 4) / 64));
29
- if(!encoderMain) await this.gpu.submitQueue(encoder)
28
+ if(!en) await this.gpu.submitQueue(encoder)
30
29
  return this.output
31
30
  }
32
31
  }
@@ -1,3 +1,4 @@
1
+
1
2
  struct Params {
2
3
  vocabSize: u32,
3
4
  tokenCount: u32,
@@ -6,27 +7,40 @@ struct Params {
6
7
  }
7
8
 
8
9
  @group(0) @binding(0)
9
- var<storage, read_write> weight: array<f32>;
10
+ var<storage, read> weight: array<f32>;
11
+
10
12
  @group(0) @binding(1)
11
13
  var<storage, read> outGradient: array<f32>;
14
+
12
15
  @group(0) @binding(3)
13
16
  var<uniform> params: Params;
17
+
14
18
  @group(0) @binding(4)
15
19
  var<storage, read_write> dInput: array<f32>;
20
+
16
21
  @compute @workgroup_size(256)
17
22
  fn main(@builtin(global_invocation_id) id: vec3<u32>) {
18
23
  let index = id.x;
19
24
  let total = params.tokenCount * params.inputSize;
20
- if (index >= u32(total)) {
25
+
26
+ if (index >= total) {
21
27
  return;
22
28
  }
23
- let token =index / u32(params.inputSize);
24
- let inputIndex = index % u32(params.inputSize);
25
- var gradInput = 0.0;
26
- for (var i = 0u; i < u32(params.vocabSize); i++) {
27
- let w = weight[i * u32(params.inputSize) + inputIndex];
28
- let grad = outGradient[token * u32(params.vocabSize) + i];
29
- gradInput += grad * w;
29
+
30
+ let inputSize = params.inputSize;
31
+ let vocabSize = params.vocabSize;
32
+
33
+ let token = index / inputSize;
34
+ let inputIndex = index % inputSize;
35
+
36
+ let weightBase = inputIndex;
37
+ let gradBase = token * vocabSize;
38
+ var sum = 0.0;
39
+
40
+ for (var i = 0u; i < vocabSize; i++) {
41
+ let wIndex = i * inputSize + weightBase;
42
+ let gIndex = gradBase + i;
43
+ sum += outGradient[gIndex] * weight[wIndex];
30
44
  }
31
- dInput[index] = gradInput;
32
- }
45
+ dInput[index] = sum;
46
+ }
@@ -1,3 +1,4 @@
1
+
1
2
  struct Params {
2
3
  vocabSize: u32,
3
4
  tokenCount: u32,
@@ -20,48 +21,44 @@ var<storage, read> input: array<f32>;
20
21
  @group(0) @binding(4)
21
22
  var<uniform> params: Params;
22
23
 
24
+ const WG_SIZE: u32 = 256u;
25
+
23
26
  var<workgroup> sharedBias: array<f32, 256>;
24
27
 
25
28
  @compute @workgroup_size(256)
26
- fn main(
27
- @builtin(workgroup_id) wid: vec3<u32>,
28
- @builtin(local_invocation_id) lid: vec3<u32>
29
- ) {
29
+ fn main(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {
30
30
  let outputIndex = wid.x;
31
31
  let tid = lid.x;
32
-
33
32
  let vocab = params.vocabSize;
34
33
  let tokens = params.tokenCount;
35
34
  let inputSize = params.inputSize;
36
-
37
- for (
38
- var inputIndex = tid;
39
- inputIndex < inputSize;
40
- inputIndex += 256u
41
- ) {
35
+ if (outputIndex >= vocab) {
36
+ return;
37
+ }
38
+ let gradBase = outputIndex;
39
+ let weightBase = outputIndex * inputSize;
40
+ for (var j = tid; j < inputSize; j += WG_SIZE) {
42
41
  var grad = 0.0;
43
-
44
42
  for (var t = 0u; t < tokens; t++) {
45
- grad += input[t * inputSize + inputIndex]
46
- * outGradient[t * vocab + outputIndex];
43
+ let inputIndex = t * inputSize + j;
44
+ let outputGradIndex = t * vocab + gradBase;
45
+ grad += input[inputIndex] * outGradient[outputGradIndex];
47
46
  }
48
47
 
49
48
  if (tokens > 0u) {
50
- weight[outputIndex * inputSize + inputIndex] -=
51
- params.lr * grad / f32(tokens);
49
+ let idx = weightBase + j;
50
+ weight[idx] -= params.lr * (grad / f32(tokens));
52
51
  }
53
52
  }
54
53
 
55
54
  var biasGrad = 0.0;
56
-
57
- for (var t = tid; t < tokens; t += 256u) {
58
- biasGrad += outGradient[t * vocab + outputIndex];
55
+ for (var t = tid; t < tokens; t += WG_SIZE) {
56
+ biasGrad += outGradient[t * vocab + gradBase];
59
57
  }
60
58
 
61
59
  sharedBias[tid] = biasGrad;
62
60
  workgroupBarrier();
63
-
64
- for (var stride = 128u; stride > 0u; stride >>= 1u) {
61
+ for (var stride = WG_SIZE / 2u; stride > 0u; stride >>= 1u) {
65
62
  if (tid < stride) {
66
63
  sharedBias[tid] += sharedBias[tid + stride];
67
64
  }
@@ -69,7 +66,6 @@ fn main(
69
66
  }
70
67
 
71
68
  if (tid == 0u && tokens > 0u) {
72
- bias[outputIndex] -=
73
- params.lr * sharedBias[0] / f32(tokens);
69
+ bias[outputIndex] -= params.lr * (sharedBias[0] / f32(tokens));
74
70
  }
75
- }
71
+ }
@@ -1,4 +1,6 @@
1
-
1
+ struct Params{
2
+ lr: f32
3
+ }
2
4
  @group(0) @binding(0)
3
5
  var<storage, read> input: array<f32>;
4
6
 
@@ -12,7 +14,7 @@ var<storage, read> sumSquares: array<f32>;
12
14
  var<storage, read_write> gamma: array<f32>;
13
15
 
14
16
  @group(0) @binding(4)
15
- var<storage, read> params: array<f32>;
17
+ var<uniform> params: Params;
16
18
 
17
19
  var<workgroup> partial: array<f32, 64>;
18
20
 
@@ -47,6 +49,6 @@ fn main(@builtin(local_invocation_index) lid: u32, @builtin(workgroup_id) wid: v
47
49
  stride /= 2u;
48
50
  }
49
51
  if (lid == 0u && dim < D) {
50
- gamma[dim] -= params[0] * partial[0];
52
+ gamma[dim] -= params.lr * partial[0];
51
53
  }
52
54
  }
@@ -16,6 +16,11 @@ var<storage, read_write> targetToken: array<f32>;
16
16
 
17
17
  var<uniform> params: Params;
18
18
 
19
+
20
+ @group(0) @binding(4)
21
+
22
+ var<storage, read_write> dLogits: array<f32>;
23
+
19
24
  @compute @workgroup_size(256)
20
25
 
21
26
  fn main(@builtin(global_invocation_id) id: vec3<u32>) {
@@ -29,8 +34,8 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
29
34
  return;
30
35
  }
31
36
  var targetIndex = targetToken[token];
32
- probs[index] = probs[index];
37
+ dLogits[index] = probs[index];
33
38
  if(vocabIndex == u32(targetIndex)){
34
- probs[index] -= 1;
39
+ dLogits[index] -= 1;
35
40
  }
36
41
  }