@imaduddin/fastbrain 1.1.1 → 2.0.1

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.
Files changed (115) hide show
  1. package/dist/Embedding/index.d.ts +24 -0
  2. package/dist/Embedding/index.js +93 -0
  3. package/dist/FFN/index.d.ts +20 -0
  4. package/dist/FFN/index.js +51 -0
  5. package/dist/Gelu/index.d.ts +15 -0
  6. package/dist/Gelu/index.js +58 -0
  7. package/dist/Linear/index.d.ts +31 -0
  8. package/dist/Linear/index.js +136 -0
  9. package/dist/RMSNorm/index.d.ts +16 -0
  10. package/dist/RMSNorm/index.js +63 -0
  11. package/dist/Relu/index.d.ts +15 -0
  12. package/dist/Relu/index.js +58 -0
  13. package/dist/SelfAttention/index.d.ts +47 -0
  14. package/dist/SelfAttention/index.js +186 -0
  15. package/dist/Softmax/index.d.ts +18 -0
  16. package/dist/Softmax/index.js +96 -0
  17. package/dist/Tokenizer/index.d.ts +15 -0
  18. package/dist/Tokenizer/index.js +58 -0
  19. package/dist/TransformerBlock/index.d.ts +21 -0
  20. package/dist/TransformerBlock/index.js +43 -0
  21. package/dist/fileManager.d.ts +6 -0
  22. package/dist/fileManager.js +34 -0
  23. package/dist/index.d.ts +10 -0
  24. package/dist/index.js +10 -0
  25. package/dist/residualConnection/index.d.ts +9 -0
  26. package/dist/residualConnection/index.js +25 -0
  27. package/package.json +20 -3
  28. package/shaders/add.wgsl +22 -0
  29. package/shaders/embedding/backward.wgsl +36 -0
  30. package/shaders/embedding/forward.wgsl +35 -0
  31. package/shaders/linear/ComputeDinput.wgsl +72 -0
  32. package/shaders/linear/forward.wgsl +63 -0
  33. package/shaders/linear/updateBias.wgsl +33 -0
  34. package/shaders/linear/updateWeights.wgsl +38 -0
  35. package/shaders/relu/backward.wgsl +43 -0
  36. package/shaders/relu/forward.wgsl +28 -0
  37. package/shaders/rmsnorm/backward.wgsl +54 -0
  38. package/shaders/rmsnorm/forward.wgsl +51 -0
  39. package/shaders/selfAttention/SB.wgsl +30 -0
  40. package/shaders/selfAttention/add3.wgsl +27 -0
  41. package/shaders/selfAttention/matMul.wgsl +63 -0
  42. package/shaders/selfAttention/qK.wgsl +66 -0
  43. package/shaders/selfAttention/transpose.wgsl +24 -0
  44. package/shaders/softmax/backward.wgsl +36 -0
  45. package/shaders/softmax/crossEntropy.wgsl +36 -0
  46. package/shaders/softmax/forward.wgsl +68 -0
  47. package/src/Embedding/index.ts +81 -0
  48. package/src/FFN/index.ts +47 -0
  49. package/src/Gelu/index.ts +53 -0
  50. package/src/Linear/index.ts +122 -0
  51. package/src/RMSNorm/index.ts +56 -0
  52. package/src/SelfAttention/index.ts +177 -0
  53. package/src/Softmax/index.ts +82 -0
  54. package/src/Tokenizer/index.ts +60 -0
  55. package/src/TransformerBlock/index.ts +41 -0
  56. package/src/fileManager.ts +46 -0
  57. package/src/index.ts +10 -0
  58. package/src/residualConnection/index.ts +24 -0
  59. package/tsconfig.json +27 -0
  60. package/index.js +0 -22
  61. package/src/Embedding/index.d.ts +0 -21
  62. package/src/Embedding/index.js +0 -140
  63. package/src/FFN/index.d.ts +0 -23
  64. package/src/FFN/index.js +0 -45
  65. package/src/Linear/index.d.ts +0 -31
  66. package/src/Linear/index.js +0 -196
  67. package/src/OperationManager.js +0 -169
  68. package/src/PositionEmbedding/index.d.ts +0 -30
  69. package/src/PositionEmbedding/index.js +0 -70
  70. package/src/RMSNorm/index.d.ts +0 -30
  71. package/src/RMSNorm/index.js +0 -91
  72. package/src/Relu/index.d.ts +0 -25
  73. package/src/Relu/index.js +0 -108
  74. package/src/SelfAttention/index.d.ts +0 -28
  75. package/src/SelfAttention/index.js +0 -138
  76. package/src/Softmax/index.d.ts +0 -26
  77. package/src/Softmax/index.js +0 -195
  78. package/src/Tokenizer/index.d.ts +0 -12
  79. package/src/Tokenizer/index.js +0 -164
  80. package/src/Tokenizer/vocabs.json +0 -19618
  81. package/src/TransformerBlock/index.d.ts +0 -28
  82. package/src/TransformerBlock/index.js +0 -78
  83. package/src/getVec.js +0 -30
  84. package/src/gpu.js +0 -0
  85. package/src/model/index.d.ts +0 -43
  86. package/src/model/index.js +0 -83
  87. package/src/residualConnection/index.js +0 -31
  88. package/src/shaders/CalculateAcc.wgsl +0 -50
  89. package/src/shaders/CalculateLoss.wgsl +0 -33
  90. package/src/shaders/ComputeDInput.wgsl +0 -46
  91. package/src/shaders/EB.wgsl +0 -33
  92. package/src/shaders/EF.wgsl +0 -25
  93. package/src/shaders/LB.wgsl +0 -71
  94. package/src/shaders/LF.wgsl +0 -60
  95. package/src/shaders/Norm/rmsBackward.wgsl +0 -65
  96. package/src/shaders/Norm/rmsForward.wgsl +0 -30
  97. package/src/shaders/Norm/sumSquare.wgsl +0 -38
  98. package/src/shaders/Norm/updateGamma.wgsl +0 -54
  99. package/src/shaders/PB.wgsl +0 -25
  100. package/src/shaders/PF.wgsl +0 -24
  101. package/src/shaders/RB.wgsl +0 -37
  102. package/src/shaders/RF.wgsl +0 -33
  103. package/src/shaders/ReductionFunction.wgsl +0 -28
  104. package/src/shaders/SB.wgsl +0 -41
  105. package/src/shaders/SF.wgsl +0 -75
  106. package/src/shaders/SoftmaxBackward.wgsl +0 -31
  107. package/src/shaders/add.wgsl +0 -30
  108. package/src/shaders/attentionShader/CompueFinalForwardOutput.wgsl +0 -29
  109. package/src/shaders/attentionShader/ComputeDA.wgsl +0 -30
  110. package/src/shaders/attentionShader/ComputeDV.wgsl +0 -37
  111. package/src/shaders/attentionShader/ComputeK.wgsl +0 -30
  112. package/src/shaders/attentionShader/ComputedQ.wgsl +0 -31
  113. package/src/shaders/attentionShader/attentionSocres.wgsl +0 -40
  114. package/src/shaders/attentionShader/sumGradient.wgsl +0 -24
  115. package/src/shaders/calculateTotal.wgsl +0 -26
@@ -0,0 +1,36 @@
1
+ struct Params{
2
+ vocabSize: u32,
3
+ tokenCount: u32
4
+ }
5
+
6
+
7
+ @group(0) @binding(0)
8
+
9
+ var <storage, read> probs: array<f32>;
10
+
11
+ @group(0) @binding(1)
12
+
13
+ var <storage, read> targetBuffer: array<u32>;
14
+
15
+
16
+ @group(0) @binding(2)
17
+
18
+ var <storage, read_write> loss: array<f32>;
19
+
20
+ @group(0) @binding(3)
21
+
22
+ var <uniform> params: Params;
23
+
24
+
25
+ @compute @workgroup_size(16)
26
+
27
+
28
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
29
+ let token = id.x;
30
+ if(token >= params.tokenCount){
31
+ return;
32
+ }
33
+ let targetToken = targetBuffer[token];
34
+ let index = token * params.vocabSize + targetToken;
35
+ loss[token] = - log(probs[index] + 1e-9);
36
+ }
@@ -0,0 +1,68 @@
1
+ struct Params {
2
+ vocabSize: u32,
3
+ tokenCount: u32,
4
+ };
5
+
6
+ @group(0) @binding(0)
7
+ var<storage, read> logits: array<f32>;
8
+
9
+ @group(0) @binding(1)
10
+ var<storage, read_write> probs: array<f32>;
11
+
12
+ @group(0) @binding(2)
13
+ var<uniform> params: Params;
14
+
15
+ var<workgroup> sharedMax: array<f32, 256>;
16
+ var<workgroup> sharedSum: array<f32, 256>;
17
+
18
+ @compute @workgroup_size(256, 1, 1)
19
+ fn main(@builtin(local_invocation_id) lid: vec3<u32>, @builtin(workgroup_id) wid: vec3<u32>) {
20
+ let lane = lid.x;
21
+ let token = wid.x;
22
+
23
+ if (token >= params.tokenCount) {
24
+ return;
25
+ }
26
+
27
+ let vocabSize = params.vocabSize;
28
+ let base = token * vocabSize;
29
+ var localMax = -3.402823466e+38;
30
+
31
+ for (var i = lane; i < vocabSize; i += 256u) {
32
+ localMax = max(localMax, logits[base + i]);
33
+ }
34
+
35
+ sharedMax[lane] = localMax;
36
+ workgroupBarrier();
37
+
38
+ for (var stride = 128u; stride > 0u; stride >>= 1u) {
39
+ if (lane < stride) {
40
+ sharedMax[lane] = max(
41
+ sharedMax[lane],
42
+ sharedMax[lane + stride]
43
+ );
44
+ }
45
+ workgroupBarrier();
46
+ }
47
+
48
+ let maxValue = sharedMax[0];
49
+ var localSum = 0.0;
50
+
51
+ for (var i = lane; i < vocabSize; i += 256u) {
52
+ localSum += exp(logits[base + i] - maxValue);
53
+ }
54
+
55
+ sharedSum[lane] = localSum;
56
+ workgroupBarrier();
57
+ for (var stride = 128u; stride > 0u; stride >>= 1u) {
58
+ if (lane < stride) {
59
+ sharedSum[lane] += sharedSum[lane + stride];
60
+ }
61
+ workgroupBarrier();
62
+ }
63
+ let denominator = sharedSum[0];
64
+
65
+ for (var i = lane; i < vocabSize; i += 256u) {
66
+ probs[base + i] = exp(logits[base + i] - maxValue) / denominator;
67
+ }
68
+ }
@@ -0,0 +1,81 @@
1
+ import { GetVectorsForFile, SaveFileVector, initRandomVector } from '../fileManager.js'
2
+ import { Buffer, GPUManager } from '@imaduddin/webgpu-manager';
3
+
4
+
5
+ export class Embedding {
6
+ vectors: Float32Array;
7
+ vectorsBuffer: Buffer | undefined;
8
+ gpu: GPUManager | undefined;
9
+ param: Buffer | undefined;
10
+ paramBackward: Buffer | undefined;
11
+ tokenBuffer: Buffer | undefined;
12
+ output: Buffer | undefined;
13
+ forwardShader: GPUComputePipeline | undefined;
14
+ backwardPipline: GPUComputePipeline | undefined;
15
+ constructor(public device: GPUDevice, public embeddingSize: number, public vocabSize: number, public configs: {
16
+ filename: string
17
+ }) {
18
+ if (!this.configs) {
19
+ this.vectors = initRandomVector(embeddingSize * vocabSize);
20
+ } else {
21
+ if (!this.configs.filename) {
22
+ this.vectors = initRandomVector(embeddingSize * vocabSize)
23
+ } else {
24
+ const fileVec = GetVectorsForFile(configs.filename, embeddingSize * vocabSize, false, embeddingSize, vocabSize);
25
+ if (!fileVec) {
26
+ this.vectors = initRandomVector(embeddingSize * vocabSize)
27
+ SaveFileVector(this.configs.filename, this.vectors)
28
+ } else {
29
+ this.vectors = fileVec;
30
+ }
31
+ }
32
+ }
33
+ this.gpu = new GPUManager(device, {
34
+ shaderDir: "./shaders"
35
+ })
36
+ }
37
+ async forward(input: number[], encoderShared: GPUCommandEncoder | undefined) {
38
+ let token = new Uint32Array(input)
39
+ let encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
40
+ if (!this.vectorsBuffer) {
41
+ this.vectorsBuffer = await this.gpu?.createBuffer(this.vectors, "storage")
42
+ this.forwardShader = await this.gpu?.getPiplineShader("embedding/forward.wgsl")
43
+ }
44
+ if (!this.param) this.param = await this.gpu?.createBuffer(new Uint32Array([this.embeddingSize, this.vocabSize]), "uniform");
45
+ if (!this.tokenBuffer) this.tokenBuffer = await this.gpu?.createBuffer(token, "storage")
46
+ if (this.tokenBuffer?.buffer.size !== token.byteLength) {
47
+ this.tokenBuffer?.destroy()
48
+ this.tokenBuffer = await this.gpu?.createBuffer(token, "storage")
49
+ }
50
+ this.tokenBuffer?.changeData(token)
51
+ if (!this.output) this.output = await this.gpu?.createBuffer(new Float32Array(this.embeddingSize * input.length), "storage");
52
+ if (this.output?.buffer.size !== input.length * this.embeddingSize * 4 || this.output.isDestroy()) {
53
+ this.output?.destroy();
54
+ this.output = await this.gpu?.createBuffer(new Float32Array(this.embeddingSize * input.length), "storage");
55
+ }
56
+ const bindGroup: any = await this.gpu?.createBindGroup(this.forwardShader!, [this.vectorsBuffer!, this.tokenBuffer!, this.output!, this.param!], 0)
57
+ await this.gpu?.RunPipline(encoder!, this.forwardShader!, bindGroup, Math.ceil(this.embeddingSize / 64), Math.ceil(input.length / 4))
58
+ if (!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
59
+ return this.output
60
+
61
+ }
62
+ async backward(dInput: Buffer, lr: number, encoderShared: GPUCommandEncoder | undefined) {
63
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
64
+ const tokenCount = dInput.buffer.size / (this.embeddingSize * 4)
65
+ if (!this.backwardPipline) {
66
+ this.backwardPipline = await this.gpu?.getPiplineShader("embedding/backward.wgsl")
67
+ }
68
+ if (!this.paramBackward) {
69
+ this.paramBackward = await this.gpu?.createBuffer(new Float32Array([this.embeddingSize, this.vocabSize, lr]), "uniform")
70
+ } else {
71
+ this.paramBackward.changeData(new Float32Array([this.embeddingSize, this.vocabSize, lr]))
72
+ }
73
+ const bindGroup = await this.gpu?.createBindGroup(this.backwardPipline!, [this.vectorsBuffer!, this.tokenBuffer!, dInput, this.paramBackward!], 0)
74
+ await this.gpu?.RunPipline(encoder!, this.backwardPipline!,bindGroup!, Math.ceil(this.embeddingSize / 64), Math.ceil(tokenCount / 4))
75
+ if(!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
76
+ }
77
+ async Save() {
78
+ let vec: any = await this.vectorsBuffer?.read()
79
+ await SaveFileVector(this.configs.filename, vec)
80
+ }
81
+ }
@@ -0,0 +1,47 @@
1
+ import { Linear } from "../Linear/index.js";
2
+ import { Gelu as Relu } from '../Gelu/index.js'
3
+ import { join } from "node:path";
4
+ import { Buffer, GPUManager } from '@imaduddin/webgpu-manager'
5
+ export class FFN {
6
+ linear1: Linear | undefined
7
+ linear2: Linear | undefined
8
+ activation: Relu | undefined
9
+ gpu: GPUManager | undefined
10
+ constructor(public device: GPUDevice, public dimSize: number, public configs: {
11
+ dirname: string
12
+ }) {
13
+ this.linear1 = new Linear(device, dimSize, dimSize * 4, {
14
+ filename: [join(configs.dirname, "LINEAR_EXPAND_FFN_WEIGHTS_1.bin"), join(configs.dirname, "LINEAR_EXPAND_FFN_BIAS_1.bin")]
15
+ })
16
+ this.linear2 = new Linear(device, dimSize * 4, dimSize, {
17
+ filename: [join(configs.dirname, "LINEAR_EXPAND_FFN_WEIGHTS_2.bin"), join(configs.dirname, "LINEAR_EXPAND_FFN_BIAS_2.bin")]
18
+ })
19
+ this.activation = new Relu(device, dimSize * 4)
20
+ this.gpu = new GPUManager(device, {
21
+ shaderDir: "./shaders"
22
+ })
23
+ }
24
+ async forward(input: Buffer, encoderShared: GPUCommandEncoder | undefined) {
25
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
26
+ const hidden1 = await this.linear1?.forward(input, encoder!)
27
+ const hiddenActivation = await this.activation?.forward(hidden1!, encoder!)
28
+ const hidden2 = await this.linear2?.forward(hiddenActivation!, encoder!)
29
+ if (!encoderShared) {
30
+ await this.gpu?.SumbitEncoder(encoder!)
31
+ }
32
+ return hidden2
33
+ }
34
+ async backward(outputGradient : Buffer, lr: number, encoderShared : GPUCommandEncoder | undefined){
35
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
36
+ const dActivation = await this.linear2?.backward(outputGradient, lr, encoder)
37
+ const dHidden2 = await this.activation?.backward(dActivation!, encoder)
38
+ const dHidden1 = await this.linear1?.backward(dHidden2!, lr, encoder)
39
+ await this.linear2?.updateParameter(outputGradient, lr, encoder)
40
+ await this.linear1?.updateParameter(dHidden2!, lr, encoder)
41
+ return dHidden1
42
+ }
43
+ async Save(){
44
+ await this.linear1?.Save()
45
+ await this.linear2?.Save()
46
+ }
47
+ }
@@ -0,0 +1,53 @@
1
+ import { Buffer, GPUManager } from "@imaduddin/webgpu-manager";
2
+
3
+
4
+ export class Gelu {
5
+ input: Buffer | undefined;
6
+ output: Buffer | undefined;
7
+ outputGrad: Buffer | undefined;
8
+ params: Buffer | undefined;
9
+ forwardShader: GPUComputePipeline | undefined;
10
+ backwardShader: GPUComputePipeline | undefined;
11
+ gpu: GPUManager | undefined;
12
+ constructor(public device: GPUDevice, public hiddenSize: number) {
13
+ this.gpu = new GPUManager(device, {
14
+ shaderDir: "./shaders/relu"
15
+ })
16
+ }
17
+ async forward(input: Buffer, encoderShared: GPUCommandEncoder | undefined) {
18
+ let tokenCount = input.buffer.size / (this.hiddenSize * 4)
19
+ this.input = input;
20
+ if (!this.output || this.output.buffer.size !== input.buffer.size) {
21
+ if (this.output) this.output.destroy()
22
+ this.output = await this.gpu?.createBuffer(new Float32Array(this.hiddenSize * tokenCount), "storage")
23
+ }
24
+ if (!this.forwardShader) {
25
+ this.forwardShader = await this.gpu?.getPiplineShader("forward.wgsl")
26
+ this.backwardShader = await this.gpu?.getPiplineShader("backward.wgsl")
27
+
28
+ }
29
+ if (!this.params) {
30
+ this.params = await this.gpu?.createBuffer(new Uint32Array([this.hiddenSize, tokenCount]), "uniform")
31
+ } else {
32
+ await this.params.changeData(new Uint32Array([this.hiddenSize, tokenCount]))
33
+ }
34
+ let encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
35
+ const bindGroup = await this.gpu?.createBindGroup(this.forwardShader!, [this.input!, this.output!, this.params!], 0)
36
+ await this.gpu?.RunPipline(encoder!, this.forwardShader!, bindGroup!, Math.ceil(this.hiddenSize / 16), Math.ceil(tokenCount / 16))
37
+ if (!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
38
+ return this.output
39
+ }
40
+ async backward(gradient: Buffer, encoderShared: GPUCommandEncoder | undefined) {
41
+ let tokenCount = gradient.buffer.size / (this.hiddenSize * 4)
42
+ let encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
43
+ if(!this.outputGrad || this.outputGrad.buffer.size !== gradient.buffer.size){
44
+ if(this.outputGrad) this.outputGrad.destroy()
45
+ this.outputGrad = await this.gpu?.createBuffer(new Float32Array(gradient.buffer.size / 4), "storage")
46
+ }
47
+ const bindGroup = await this.gpu?.createBindGroup(this.backwardShader!, [this.input!, this.outputGrad!, gradient!, this.params!], 0)
48
+ await this.gpu?.RunPipline(encoder!, this.backwardShader!, bindGroup!, Math.ceil(this.hiddenSize / 16), Math.ceil(tokenCount / 16))
49
+ if(!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
50
+ return this.outputGrad
51
+ }
52
+
53
+ }
@@ -0,0 +1,122 @@
1
+ import { GPUManager, Buffer } from "@imaduddin/webgpu-manager";
2
+ import { GetVectorsForFile, SaveFileVector, initRandomVector, getParameter } from '../fileManager.js'
3
+
4
+
5
+ export class Linear {
6
+ bias: Float32Array | undefined;
7
+ weights: Float32Array | undefined;
8
+ wBuffer: Buffer | undefined;
9
+ bBuffer: Buffer | undefined;
10
+ gpu: GPUManager | undefined;
11
+ paramsForward: Buffer | undefined;
12
+ paramsBackward: Buffer | undefined;
13
+ output: Buffer | undefined;
14
+ forwardPipline: GPUComputePipeline | undefined;
15
+ backwardPipline: GPUComputePipeline | undefined;
16
+ weightUpdate: GPUComputePipeline | undefined;
17
+ biasUpdate: GPUComputePipeline | undefined;
18
+ gradOut: Buffer | undefined;
19
+ input: Buffer | undefined
20
+ constructor(public device: GPUDevice, public embeddingSize: number, public vocabSize: number, public configs: {
21
+ filename: string[]
22
+ }) {
23
+ if (!this.configs) {
24
+ this.weights = initRandomVector(embeddingSize * vocabSize);
25
+ this.bias = initRandomVector(vocabSize);
26
+ } else {
27
+ if (!this.configs.filename) {
28
+ this.weights = initRandomVector(embeddingSize * vocabSize);
29
+ this.bias = initRandomVector(vocabSize);
30
+ } else {
31
+ const fileVec = GetVectorsForFile(configs.filename[0], embeddingSize * vocabSize, false, embeddingSize, vocabSize);
32
+ const fileBias = GetVectorsForFile(configs.filename[1], vocabSize, true, embeddingSize, vocabSize);
33
+ if (!fileVec) {
34
+ this.weights = initRandomVector(embeddingSize * vocabSize);
35
+ this.bias = initRandomVector(vocabSize);
36
+ SaveFileVector(this.configs.filename[0], this.weights)
37
+ SaveFileVector(this.configs.filename[1], this.bias)
38
+ } else {
39
+ this.weights = fileVec;
40
+ this.bias = fileBias!;
41
+ }
42
+ }
43
+ }
44
+ this.gpu = new GPUManager(device, {
45
+ shaderDir: "./shaders"
46
+ })
47
+ }
48
+ getParameter(){
49
+ getParameter()
50
+ }
51
+ async forward(input: Buffer, en: GPUCommandEncoder | undefined) {
52
+ const encoder = en ? en : await this.gpu?.CreateEncoder()
53
+ this.input = input;
54
+ if (!this.wBuffer || !this.bBuffer) {
55
+ this.wBuffer = await this.gpu?.createBuffer(this.weights!, "storage")
56
+ this.bBuffer = await this.gpu?.createBuffer(this.bias!, "storage")
57
+ this.forwardPipline = await this.gpu?.getPiplineShader("linear/forward.wgsl")
58
+ }
59
+ let tokenCount = input.buffer.size / (this.embeddingSize * 4)
60
+ if (!this.paramsForward) {
61
+ this.paramsForward = await this.gpu?.createBuffer(new Uint32Array([this.embeddingSize, this.vocabSize, tokenCount]), "uniform")
62
+ } else {
63
+ await this.paramsForward.changeData(new Uint32Array([this.embeddingSize, this.vocabSize, tokenCount]))
64
+ }
65
+ if (!this.output || this.output.buffer.size !== tokenCount * this.vocabSize * 4) {
66
+ if (this.output) this.output?.destroy();
67
+ this.output = await this.gpu?.createBuffer(new Float32Array(this.vocabSize * tokenCount), "storage")
68
+ }
69
+ const bindGroup = await this.gpu?.createBindGroup(this.forwardPipline!, [input, this.wBuffer!, this.bBuffer!, this.output!, this.paramsForward!], 0)
70
+ await this.gpu?.RunPipline(encoder, this.forwardPipline!, bindGroup!, this.vocabSize , tokenCount)
71
+ if (!en) await this.gpu?.SumbitEncoder(encoder!)
72
+ return this.output
73
+ }
74
+ async backward(outputGradient: Buffer, lr: number, encoderShared: GPUCommandEncoder | undefined) {
75
+ let tokenCount = outputGradient.buffer.size / (4 * this.vocabSize);
76
+ let encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
77
+ if (!this.weightUpdate) {
78
+ this.weightUpdate = await this.gpu?.getPiplineShader("linear/updateWeights.wgsl")
79
+ this.biasUpdate = await this.gpu?.getPiplineShader("linear/updateBias.wgsl")
80
+ this.backwardPipline = await this.gpu?.getPiplineShader("linear/ComputeDinput.wgsl")
81
+ }
82
+ if (!this.paramsBackward) {
83
+ this.paramsBackward = await this.gpu?.createBuffer(new Float32Array([this.embeddingSize, this.vocabSize, tokenCount, lr]), "uniform")
84
+ } else {
85
+ await this.paramsBackward.changeData(new Float32Array([this.embeddingSize, this.vocabSize, tokenCount, lr]))
86
+ }
87
+ if (!this.gradOut || this.gradOut.buffer.size !== tokenCount * this.embeddingSize * 4) {
88
+ if (this.gradOut) this.gradOut.destroy()
89
+ this.gradOut = await this.gpu?.createBuffer(new Float32Array(this.embeddingSize * tokenCount), "storage")
90
+ }
91
+ const bindGroup2 = await this.gpu?.createBindGroup(this.backwardPipline!, [this.wBuffer!, outputGradient, this.gradOut!, this.paramsBackward!], 0)
92
+ await this.gpu?.RunPipline(encoder!, this.backwardPipline!, bindGroup2!, tokenCount, this.embeddingSize)
93
+ if (!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
94
+ return this.gradOut
95
+ }
96
+ async updateParameter(outputGradient: Buffer, lr: number, encoderShared: GPUCommandEncoder | undefined) {
97
+ let tokenCount = outputGradient.buffer.size / (4 * this.vocabSize);
98
+ let encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
99
+ if (!this.weightUpdate) {
100
+ this.weightUpdate = await this.gpu?.getPiplineShader("linear/updateWeights.wgsl")
101
+ this.biasUpdate = await this.gpu?.getPiplineShader("linear/updateBias.wgsl")
102
+ }
103
+ if (!this.paramsBackward) {
104
+ this.paramsBackward = await this.gpu?.createBuffer(new Float32Array([this.embeddingSize, this.vocabSize, tokenCount, lr]), "uniform")
105
+ } else {
106
+ await this.paramsBackward.changeData(new Float32Array([this.embeddingSize, this.vocabSize, tokenCount, lr]))
107
+ }
108
+
109
+ const bindGroup = await this.gpu?.createBindGroup(this.weightUpdate!, [this.wBuffer!, outputGradient, this.paramsBackward!, this.input!], 0)
110
+ const bindGroup1 = await this.gpu?.createBindGroup(this.biasUpdate!, [this.bBuffer!, outputGradient, this.paramsBackward!], 0)
111
+ await this.gpu?.RunPipline(encoder!, this.weightUpdate!, bindGroup!, Math.ceil(this.embeddingSize / 16), Math.ceil(this.vocabSize / 32))
112
+ await this.gpu?.RunPipline(encoder!, this.biasUpdate!, bindGroup1!, Math.ceil(this.vocabSize / 32))
113
+ if (!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
114
+ return this.gradOut
115
+ }
116
+ async Save() {
117
+ const bias: any = await this.bBuffer?.read()
118
+ const weights: any = await this.wBuffer?.read()
119
+ SaveFileVector(this.configs.filename[0], weights!)
120
+ SaveFileVector(this.configs.filename[1], bias!)
121
+ }
122
+ }
@@ -0,0 +1,56 @@
1
+ import { GPUManager, Buffer } from "@imaduddin/webgpu-manager";
2
+
3
+
4
+ export class RMSNorm {
5
+ rms: Buffer | undefined
6
+ input: Buffer | undefined
7
+ dInput: Buffer | undefined
8
+ params: Buffer | undefined
9
+ output: Buffer | undefined
10
+ forwardShader: GPUComputePipeline | undefined
11
+ backwardShader: GPUComputePipeline | undefined
12
+ gpu: GPUManager | undefined
13
+ constructor(public device: GPUDevice, public embeddingSize: number) {
14
+ this.gpu = new GPUManager(device, {
15
+ shaderDir: "./shaders/rmsnorm"
16
+ })
17
+ }
18
+ async forward(input: Buffer, encoderShared: GPUCommandEncoder | undefined) {
19
+ this.input = input;
20
+ let tokenCount = input.buffer.size / (this.embeddingSize * 4)
21
+ if (!this.rms || this.rms.buffer.size !== tokenCount * 4) {
22
+ if (this.rms) this.rms.destroy();
23
+ this.rms = await this.gpu?.createBuffer(new Float32Array(tokenCount), "storage")
24
+ }
25
+ if(!this.output || this.output.buffer.size !== tokenCount * this.embeddingSize * 4){
26
+ if(this.output) this.output.destroy();
27
+ if(this.dInput) this.dInput.destroy();
28
+ this.output = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.embeddingSize), "storage")
29
+ this.dInput = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.embeddingSize), "storage")
30
+ }
31
+ if(!this.params){
32
+ this.params = await this.gpu?.createBuffer(new Uint32Array([this.embeddingSize, tokenCount,0 ]), "uniform")
33
+ }else{
34
+ await this.params.changeData(new Uint32Array([this.embeddingSize, tokenCount, 0]))
35
+ }
36
+ if(!this.forwardShader){
37
+ this.forwardShader = await this.gpu?.getPiplineShader("forward.wgsl")
38
+ this.backwardShader = await this.gpu?.getPiplineShader("backward.wgsl")
39
+ }
40
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
41
+ const bindGroup = await this.gpu?.createBindGroup(this.forwardShader!, [this.input!, this.output!, this.rms!, this.params!], 0)
42
+ await this.gpu?.RunPipline(encoder!, this.forwardShader!, bindGroup!, tokenCount);
43
+ if(!encoderShared){
44
+ this.gpu?.SumbitEncoder(encoder!)
45
+ }
46
+ return this.output
47
+ }
48
+ async backward(outputGradient : Buffer, encoderShared : GPUCommandEncoder | undefined){
49
+ const tokenCount = outputGradient.buffer.size / (this.embeddingSize * 4);
50
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder()
51
+ const bindGroup = await this.gpu?.createBindGroup(this.backwardShader!, [this.input!, this.rms!, outputGradient, this.dInput!, this.params!] , 0)
52
+ await this.gpu?.RunPipline(encoder!, this.backwardShader!, bindGroup!, tokenCount)
53
+ if(!encoderShared) await this.gpu?.SumbitEncoder(encoder!)
54
+ return this.dInput
55
+ }
56
+ }
@@ -0,0 +1,177 @@
1
+ import { join } from "node:path";
2
+ import { Linear } from "../Linear/index.js";
3
+ import { GPUManager, Buffer } from "@imaduddin/webgpu-manager";
4
+
5
+ export class SelfAttention {
6
+ query: Linear | undefined
7
+ value: Linear | undefined
8
+ key: Linear | undefined
9
+ v: Buffer | undefined
10
+ q: Buffer | undefined
11
+ weights: Buffer | undefined
12
+ k: Buffer | undefined
13
+ gpu: GPUManager | undefined
14
+ params: Buffer | undefined
15
+ Softparams: Buffer | undefined
16
+ Softbackparams: Buffer | undefined
17
+ Transparams: Buffer | undefined
18
+ matrixMat: GPUComputePipeline | undefined
19
+ transposeShader: GPUComputePipeline | undefined
20
+ addShader: GPUComputePipeline | undefined
21
+ softmaxShader: GPUComputePipeline | undefined
22
+ softmaxBackShader: GPUComputePipeline | undefined
23
+ qkT: Buffer | undefined
24
+ transPosedKey: Buffer | undefined
25
+ output: Buffer | undefined
26
+ qKTShader: GPUComputePipeline | undefined
27
+ dQ: Buffer | undefined
28
+ dK: Buffer | undefined
29
+ dV: Buffer | undefined
30
+ dWeights: Buffer | undefined
31
+ dScores: Buffer | undefined
32
+ dInput: Buffer | undefined
33
+ addParams: Buffer | undefined
34
+ constructor(public device: GPUDevice, public embeddingSize: number, public configs: {
35
+ dirname: string
36
+ }) {
37
+ this.query = new Linear(device, embeddingSize, embeddingSize, {
38
+ filename: [join(configs.dirname, "LINEAR_QUERY_WEIGHTS.bin"), join(configs.dirname, "LINEAR_QUERY_BIAS.bin")]
39
+ })
40
+ this.value = new Linear(device, embeddingSize, embeddingSize, {
41
+ filename: [join(configs.dirname, "LINEAR_VALUE_WEIGHTS.bin"), join(configs.dirname, "LINEAR_VALUE_BIAS.bin")]
42
+ })
43
+ this.key = new Linear(device, embeddingSize, embeddingSize, {
44
+ filename: [join(configs.dirname, "LINEAR_KEY_WEIGHTS.bin"), join(configs.dirname, "LINEAR_KEY_BIAS.bin")]
45
+ })
46
+ this.gpu = new GPUManager(device, {
47
+ shaderDir: "./shaders"
48
+ })
49
+ }
50
+ async softmaxBackward(weights: Buffer, dWeigths: Buffer, output: Buffer, tokenCount: number, enocder: GPUCommandEncoder) {
51
+ if (!this.Softbackparams) {
52
+ this.Softbackparams = await this.gpu?.createBuffer(new Uint32Array([tokenCount, this.embeddingSize, 0]), "uniform")
53
+ } else {
54
+ await this.Softbackparams.changeData(new Uint32Array([tokenCount, this.embeddingSize, 0]))
55
+ }
56
+ if (!this.softmaxBackShader) {
57
+ this.softmaxBackShader = await this.gpu?.getPiplineShader("selfAttention/SB.wgsl")
58
+ }
59
+ const bind = await this.gpu?.createBindGroup(this.softmaxBackShader!, [weights!, dWeigths!, output!, this.Softbackparams!], 0)
60
+ await this.gpu?.RunPipline(enocder, this.softmaxBackShader!, bind!, Math.ceil(tokenCount / 16), Math.ceil(tokenCount / 16))
61
+
62
+ }
63
+ async MatMut(a: Buffer, b: Buffer, output: Buffer, M: number, N: number, K: number, encoderS: GPUCommandEncoder, isqK: boolean) {
64
+ if (!this.params) {
65
+ this.params = await this.gpu?.createBuffer(new Uint32Array([M, N, K]), "uniform")
66
+ this.qKTShader = await this.gpu?.getPiplineShader("selfAttention/qK.wgsl")
67
+ this.matrixMat = await this.gpu?.getPiplineShader("selfAttention/matMul.wgsl")
68
+ } else {
69
+ this.params.changeData(new Uint32Array([M, N, K]))
70
+ }
71
+ const encoder = encoderS ? encoderS : await this.gpu?.CreateEncoder()
72
+ const bindGroup = await this.gpu?.createBindGroup(isqK ? this.qKTShader! : this.matrixMat!, [a!, b!, output!, this.params!], 0)
73
+ await this.gpu?.RunPipline(encoder, isqK ? this.qKTShader! : this.matrixMat!, bindGroup!, N, M)
74
+ }
75
+ async transpose(a: Buffer, output: Buffer, M: number, N: number, encoder: GPUCommandEncoder) {
76
+ if (!this.Transparams) {
77
+ this.Transparams = await this.gpu?.createBuffer(new Uint32Array([M, N, 0]), "uniform")
78
+ this.matrixMat = await this.gpu?.getPiplineShader("selfAttention/matMul.wgsl")
79
+ this.transposeShader = await this.gpu?.getPiplineShader("selfAttention/transpose.wgsl")
80
+ } else {
81
+ this.Transparams.changeData(new Uint32Array([M, N, 0]))
82
+ }
83
+ const bindGroup = await this.gpu?.createBindGroup(this.transposeShader!, [a!, output!, this.Transparams!], 0)
84
+ await this.gpu?.RunPipline(encoder!, this.transposeShader!, bindGroup!, N, M)
85
+
86
+ }
87
+ async forward(input: Buffer) {
88
+ let tokenCount = input.buffer.size / (this.embeddingSize * 4)
89
+ this.q = await this.query?.forward(input, undefined)
90
+ this.k = await this.key?.forward(input, undefined)
91
+ this.v = await this.value?.forward(input, undefined)
92
+ if (!this.softmaxShader) {
93
+ this.softmaxShader = await this.gpu?.getPiplineShader("softmax/forward.wgsl")
94
+ }
95
+ if (!this.qkT || this.qkT.buffer.size !== tokenCount * tokenCount * 4) {
96
+ if (this.qkT) this.qkT.destroy();
97
+ this.qkT = await this.gpu?.createBuffer(new Float32Array(tokenCount * tokenCount), "storage")
98
+ }
99
+ if (!this.transPosedKey || this.transPosedKey.buffer.size !== tokenCount * this.embeddingSize * 4) {
100
+ if (this.transPosedKey) this.transPosedKey.destroy();
101
+ this.transPosedKey = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.embeddingSize), "storage")
102
+ }
103
+ if (!this.weights || this.weights.buffer.size !== tokenCount * tokenCount * 4) {
104
+ if (this.weights) this.weights.destroy()
105
+ this.weights = await this.gpu?.createBuffer(new Float32Array(tokenCount * tokenCount), "storage")
106
+ }
107
+ if (!this.output || this.output.buffer.size !== tokenCount * this.embeddingSize * 4) {
108
+ if (this.output) this.output.destroy()
109
+ this.output = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.embeddingSize), "storage")
110
+ }
111
+ if (!this.Softparams) {
112
+ this.Softparams = await this.gpu?.createBuffer(new Uint32Array([tokenCount, tokenCount, 0]), "uniform")
113
+ } else {
114
+ this.Softparams.changeData(new Uint32Array([tokenCount, tokenCount, 0]))
115
+ }
116
+ const encoder = await this.gpu?.CreateEncoder()
117
+ await this.transpose(this.k!, this.transPosedKey!, this.embeddingSize, tokenCount, encoder!)
118
+ await this.MatMut(this.q!, this.transPosedKey!, this.qkT!, tokenCount, tokenCount, this.embeddingSize, encoder!, true)
119
+ const bindGroup = await this.gpu?.createBindGroup(this.softmaxShader!, [this.qkT!, this.weights!, this.Softparams!], 0)
120
+ await this.gpu?.RunPipline(encoder!, this.softmaxShader!, bindGroup!, tokenCount)
121
+ await this.MatMut(this.weights!, this.v!, this.output!, tokenCount, this.embeddingSize, tokenCount, encoder!, false)
122
+ await this.gpu?.SumbitEncoder(encoder!)
123
+ return this.output
124
+ }
125
+ async Save() {
126
+ await this.query?.Save()
127
+ await this.key?.Save()
128
+ await this.value?.Save()
129
+ }
130
+ async add3(a: Buffer, b: Buffer, c: Buffer, out: Buffer, size: number, encoder: GPUCommandEncoder) {
131
+ if (!this.addShader) {
132
+ this.addShader = await this.gpu!.getPiplineShader("selfAttention/add3.wgsl");
133
+ this.addParams = await this.gpu!.createBuffer(new Uint32Array([size]), "uniform");
134
+ } else {
135
+ await this.addParams!.changeData(new Uint32Array([size]));
136
+ }
137
+ const bindGroup = await this.gpu!.createBindGroup(this.addShader!, [a, b, c, out, this.addParams!], 0);
138
+ await this.gpu!.RunPipline(encoder, this.addShader!, bindGroup, Math.ceil(size / 256));
139
+ }
140
+ async backward(outputGradient: Buffer, lr: number) {
141
+ const D = this.embeddingSize;
142
+ const T = outputGradient.buffer.size / (D * 4);
143
+ if (!this.dV || this.dV.buffer.size !== T * D * 4) {
144
+ this.dV?.destroy();
145
+ this.dQ?.destroy();
146
+ this.dK?.destroy();
147
+ this.dWeights?.destroy();
148
+ this.dScores?.destroy();
149
+ this.dInput?.destroy();
150
+
151
+ this.dV = await this.gpu!.createBuffer(new Float32Array(T * D), "storage");
152
+ this.dQ = await this.gpu!.createBuffer(new Float32Array(T * D), "storage");
153
+ this.dK = await this.gpu!.createBuffer(new Float32Array(T * D), "storage");
154
+ this.dWeights = await this.gpu!.createBuffer(new Float32Array(T * T), "storage");
155
+ this.dScores = await this.gpu!.createBuffer(new Float32Array(T * T), "storage");
156
+ this.dInput = await this.gpu!.createBuffer(new Float32Array(T * D), "storage");
157
+ }
158
+ const encoder = await this.gpu!.CreateEncoder();
159
+ await this.transpose(this.weights!, this.qkT!, T, T, encoder);
160
+ await this.MatMut(this.qkT!, outputGradient, this.dV!, T, D, T, encoder, false);
161
+ await this.transpose(this.v!, this.transPosedKey!, D, T, encoder);
162
+ await this.MatMut(outputGradient, this.transPosedKey!, this.dWeights!, T, T, D, encoder, false);
163
+ await this.softmaxBackward(this.weights!, this.dWeights!, this.dScores!, T, encoder);
164
+ await this.MatMut(this.dScores!, this.k!, this.dQ!, T, D, T, encoder, false);
165
+ await this.transpose(this.dScores!, this.qkT!, T, T, encoder);
166
+ await this.MatMut(this.qkT!, this.q!, this.dK!, T, D, T, encoder, false);
167
+ const dInputQ = await this.query!.backward(this.dQ!, lr, encoder);
168
+ const dInputK = await this.key!.backward(this.dK!, lr, encoder);
169
+ const dInputV = await this.value!.backward(this.dV!, lr, encoder);
170
+ await this.add3(dInputQ!, dInputK!, dInputV!, this.dInput!, T * D, encoder);
171
+ await this.query!.updateParameter(this.dQ!, lr, encoder);
172
+ await this.key!.updateParameter(this.dK!, lr, encoder);
173
+ await this.value!.updateParameter(this.dV!, lr, encoder);
174
+ await this.gpu!.SumbitEncoder(encoder!);
175
+ return this.dInput;
176
+ }
177
+ }