@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,186 @@
1
+ import { join } from "node:path";
2
+ import { Linear } from "../Linear/index.js";
3
+ import { GPUManager } from "@imaduddin/webgpu-manager";
4
+ export class SelfAttention {
5
+ device;
6
+ embeddingSize;
7
+ configs;
8
+ query;
9
+ value;
10
+ key;
11
+ v;
12
+ q;
13
+ weights;
14
+ k;
15
+ gpu;
16
+ params;
17
+ Softparams;
18
+ Softbackparams;
19
+ Transparams;
20
+ matrixMat;
21
+ transposeShader;
22
+ addShader;
23
+ softmaxShader;
24
+ softmaxBackShader;
25
+ qkT;
26
+ transPosedKey;
27
+ output;
28
+ qKTShader;
29
+ dQ;
30
+ dK;
31
+ dV;
32
+ dWeights;
33
+ dScores;
34
+ dInput;
35
+ addParams;
36
+ constructor(device, embeddingSize, configs) {
37
+ this.device = device;
38
+ this.embeddingSize = embeddingSize;
39
+ this.configs = configs;
40
+ this.query = new Linear(device, embeddingSize, embeddingSize, {
41
+ filename: [join(configs.dirname, "LINEAR_QUERY_WEIGHTS.bin"), join(configs.dirname, "LINEAR_QUERY_BIAS.bin")]
42
+ });
43
+ this.value = new Linear(device, embeddingSize, embeddingSize, {
44
+ filename: [join(configs.dirname, "LINEAR_VALUE_WEIGHTS.bin"), join(configs.dirname, "LINEAR_VALUE_BIAS.bin")]
45
+ });
46
+ this.key = new Linear(device, embeddingSize, embeddingSize, {
47
+ filename: [join(configs.dirname, "LINEAR_KEY_WEIGHTS.bin"), join(configs.dirname, "LINEAR_KEY_BIAS.bin")]
48
+ });
49
+ this.gpu = new GPUManager(device, {
50
+ shaderDir: "./shaders"
51
+ });
52
+ }
53
+ async softmaxBackward(weights, dWeigths, output, tokenCount, enocder) {
54
+ if (!this.Softbackparams) {
55
+ this.Softbackparams = await this.gpu?.createBuffer(new Uint32Array([tokenCount, this.embeddingSize, 0]), "uniform");
56
+ }
57
+ else {
58
+ await this.Softbackparams.changeData(new Uint32Array([tokenCount, this.embeddingSize, 0]));
59
+ }
60
+ if (!this.softmaxBackShader) {
61
+ this.softmaxBackShader = await this.gpu?.getPiplineShader("selfAttention/SB.wgsl");
62
+ }
63
+ const bind = await this.gpu?.createBindGroup(this.softmaxBackShader, [weights, dWeigths, output, this.Softbackparams], 0);
64
+ await this.gpu?.RunPipline(enocder, this.softmaxBackShader, bind, Math.ceil(tokenCount / 16), Math.ceil(tokenCount / 16));
65
+ }
66
+ async MatMut(a, b, output, M, N, K, encoderS, isqK) {
67
+ if (!this.params) {
68
+ this.params = await this.gpu?.createBuffer(new Uint32Array([M, N, K]), "uniform");
69
+ this.qKTShader = await this.gpu?.getPiplineShader("selfAttention/qK.wgsl");
70
+ this.matrixMat = await this.gpu?.getPiplineShader("selfAttention/matMul.wgsl");
71
+ }
72
+ else {
73
+ this.params.changeData(new Uint32Array([M, N, K]));
74
+ }
75
+ const encoder = encoderS ? encoderS : await this.gpu?.CreateEncoder();
76
+ const bindGroup = await this.gpu?.createBindGroup(isqK ? this.qKTShader : this.matrixMat, [a, b, output, this.params], 0);
77
+ await this.gpu?.RunPipline(encoder, isqK ? this.qKTShader : this.matrixMat, bindGroup, N, M);
78
+ }
79
+ async transpose(a, output, M, N, encoder) {
80
+ if (!this.Transparams) {
81
+ this.Transparams = await this.gpu?.createBuffer(new Uint32Array([M, N, 0]), "uniform");
82
+ this.matrixMat = await this.gpu?.getPiplineShader("selfAttention/matMul.wgsl");
83
+ this.transposeShader = await this.gpu?.getPiplineShader("selfAttention/transpose.wgsl");
84
+ }
85
+ else {
86
+ this.Transparams.changeData(new Uint32Array([M, N, 0]));
87
+ }
88
+ const bindGroup = await this.gpu?.createBindGroup(this.transposeShader, [a, output, this.Transparams], 0);
89
+ await this.gpu?.RunPipline(encoder, this.transposeShader, bindGroup, N, M);
90
+ }
91
+ async forward(input) {
92
+ let tokenCount = input.buffer.size / (this.embeddingSize * 4);
93
+ this.q = await this.query?.forward(input, undefined);
94
+ this.k = await this.key?.forward(input, undefined);
95
+ this.v = await this.value?.forward(input, undefined);
96
+ if (!this.softmaxShader) {
97
+ this.softmaxShader = await this.gpu?.getPiplineShader("softmax/forward.wgsl");
98
+ }
99
+ if (!this.qkT || this.qkT.buffer.size !== tokenCount * tokenCount * 4) {
100
+ if (this.qkT)
101
+ this.qkT.destroy();
102
+ this.qkT = await this.gpu?.createBuffer(new Float32Array(tokenCount * tokenCount), "storage");
103
+ }
104
+ if (!this.transPosedKey || this.transPosedKey.buffer.size !== tokenCount * this.embeddingSize * 4) {
105
+ if (this.transPosedKey)
106
+ this.transPosedKey.destroy();
107
+ this.transPosedKey = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.embeddingSize), "storage");
108
+ }
109
+ if (!this.weights || this.weights.buffer.size !== tokenCount * tokenCount * 4) {
110
+ if (this.weights)
111
+ this.weights.destroy();
112
+ this.weights = await this.gpu?.createBuffer(new Float32Array(tokenCount * tokenCount), "storage");
113
+ }
114
+ if (!this.output || this.output.buffer.size !== tokenCount * this.embeddingSize * 4) {
115
+ if (this.output)
116
+ this.output.destroy();
117
+ this.output = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.embeddingSize), "storage");
118
+ }
119
+ if (!this.Softparams) {
120
+ this.Softparams = await this.gpu?.createBuffer(new Uint32Array([tokenCount, tokenCount, 0]), "uniform");
121
+ }
122
+ else {
123
+ this.Softparams.changeData(new Uint32Array([tokenCount, tokenCount, 0]));
124
+ }
125
+ const encoder = await this.gpu?.CreateEncoder();
126
+ await this.transpose(this.k, this.transPosedKey, this.embeddingSize, tokenCount, encoder);
127
+ await this.MatMut(this.q, this.transPosedKey, this.qkT, tokenCount, tokenCount, this.embeddingSize, encoder, true);
128
+ const bindGroup = await this.gpu?.createBindGroup(this.softmaxShader, [this.qkT, this.weights, this.Softparams], 0);
129
+ await this.gpu?.RunPipline(encoder, this.softmaxShader, bindGroup, tokenCount);
130
+ await this.MatMut(this.weights, this.v, this.output, tokenCount, this.embeddingSize, tokenCount, encoder, false);
131
+ await this.gpu?.SumbitEncoder(encoder);
132
+ return this.output;
133
+ }
134
+ async Save() {
135
+ await this.query?.Save();
136
+ await this.key?.Save();
137
+ await this.value?.Save();
138
+ }
139
+ async add3(a, b, c, out, size, encoder) {
140
+ if (!this.addShader) {
141
+ this.addShader = await this.gpu.getPiplineShader("selfAttention/add3.wgsl");
142
+ this.addParams = await this.gpu.createBuffer(new Uint32Array([size]), "uniform");
143
+ }
144
+ else {
145
+ await this.addParams.changeData(new Uint32Array([size]));
146
+ }
147
+ const bindGroup = await this.gpu.createBindGroup(this.addShader, [a, b, c, out, this.addParams], 0);
148
+ await this.gpu.RunPipline(encoder, this.addShader, bindGroup, Math.ceil(size / 256));
149
+ }
150
+ async backward(outputGradient, lr) {
151
+ const D = this.embeddingSize;
152
+ const T = outputGradient.buffer.size / (D * 4);
153
+ if (!this.dV || this.dV.buffer.size !== T * D * 4) {
154
+ this.dV?.destroy();
155
+ this.dQ?.destroy();
156
+ this.dK?.destroy();
157
+ this.dWeights?.destroy();
158
+ this.dScores?.destroy();
159
+ this.dInput?.destroy();
160
+ this.dV = await this.gpu.createBuffer(new Float32Array(T * D), "storage");
161
+ this.dQ = await this.gpu.createBuffer(new Float32Array(T * D), "storage");
162
+ this.dK = await this.gpu.createBuffer(new Float32Array(T * D), "storage");
163
+ this.dWeights = await this.gpu.createBuffer(new Float32Array(T * T), "storage");
164
+ this.dScores = await this.gpu.createBuffer(new Float32Array(T * T), "storage");
165
+ this.dInput = await this.gpu.createBuffer(new Float32Array(T * D), "storage");
166
+ }
167
+ const encoder = await this.gpu.CreateEncoder();
168
+ await this.transpose(this.weights, this.qkT, T, T, encoder);
169
+ await this.MatMut(this.qkT, outputGradient, this.dV, T, D, T, encoder, false);
170
+ await this.transpose(this.v, this.transPosedKey, D, T, encoder);
171
+ await this.MatMut(outputGradient, this.transPosedKey, this.dWeights, T, T, D, encoder, false);
172
+ await this.softmaxBackward(this.weights, this.dWeights, this.dScores, T, encoder);
173
+ await this.MatMut(this.dScores, this.k, this.dQ, T, D, T, encoder, false);
174
+ await this.transpose(this.dScores, this.qkT, T, T, encoder);
175
+ await this.MatMut(this.qkT, this.q, this.dK, T, D, T, encoder, false);
176
+ const dInputQ = await this.query.backward(this.dQ, lr, encoder);
177
+ const dInputK = await this.key.backward(this.dK, lr, encoder);
178
+ const dInputV = await this.value.backward(this.dV, lr, encoder);
179
+ await this.add3(dInputQ, dInputK, dInputV, this.dInput, T * D, encoder);
180
+ await this.query.updateParameter(this.dQ, lr, encoder);
181
+ await this.key.updateParameter(this.dK, lr, encoder);
182
+ await this.value.updateParameter(this.dV, lr, encoder);
183
+ await this.gpu.SumbitEncoder(encoder);
184
+ return this.dInput;
185
+ }
186
+ }
@@ -0,0 +1,18 @@
1
+ import { GPUManager, Buffer } from "@imaduddin/webgpu-manager";
2
+ export declare class Softmax {
3
+ device: GPUDevice;
4
+ VocabSize: number;
5
+ forwardShader: GPUComputePipeline | undefined;
6
+ lossShader: GPUComputePipeline | undefined;
7
+ backwardShader: GPUComputePipeline | undefined;
8
+ output: Buffer | undefined;
9
+ loss: Buffer | undefined;
10
+ gpu: GPUManager | undefined;
11
+ forwardParams: Buffer | undefined;
12
+ gradOutput: Buffer | undefined;
13
+ targetBuffer: Buffer | undefined;
14
+ constructor(device: GPUDevice, VocabSize: number);
15
+ forward(logit: Buffer | number[], encoderShared: GPUCommandEncoder | undefined): Promise<Buffer | undefined>;
16
+ backward(probs: Buffer, target: number[], encoderShared: GPUCommandEncoder | undefined): Promise<Buffer | undefined>;
17
+ crossEntropy(probs: Buffer, target: number[], encoderShared: GPUCommandEncoder | undefined): Promise<Buffer | undefined>;
18
+ }
@@ -0,0 +1,96 @@
1
+ import { GPUManager } from "@imaduddin/webgpu-manager";
2
+ import { isBufferOrNumber } from '../fileManager.js';
3
+ export class Softmax {
4
+ device;
5
+ VocabSize;
6
+ forwardShader;
7
+ lossShader;
8
+ backwardShader;
9
+ output;
10
+ loss;
11
+ gpu;
12
+ forwardParams;
13
+ gradOutput;
14
+ targetBuffer;
15
+ constructor(device, VocabSize) {
16
+ this.device = device;
17
+ this.VocabSize = VocabSize;
18
+ this.gpu = new GPUManager(device, {
19
+ shaderDir: './shaders/softmax'
20
+ });
21
+ }
22
+ async forward(logit, encoderShared) {
23
+ let logits = await isBufferOrNumber(logit, this.gpu);
24
+ const tokenCount = logits.buffer.size / (this.VocabSize * 4);
25
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder();
26
+ if (!this.forwardShader) {
27
+ this.forwardShader = await this.gpu?.getPiplineShader("forward.wgsl");
28
+ }
29
+ if (!this.output || this.output.buffer.size !== logits.buffer.size || this.output.isDestroy()) {
30
+ if (this.output)
31
+ this.output.destroy();
32
+ this.output = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.VocabSize), "storage");
33
+ }
34
+ if (!this.forwardParams) {
35
+ this.forwardParams = await this.gpu?.createBuffer(new Uint32Array([this.VocabSize, tokenCount]), "uniform");
36
+ }
37
+ else {
38
+ await this.forwardParams.changeData(new Uint32Array([this.VocabSize, tokenCount]));
39
+ }
40
+ const bindGroup = await this.gpu?.createBindGroup(this.forwardShader, [logits, this.output, this.forwardParams], 0);
41
+ await this.gpu?.RunPipline(encoder, this.forwardShader, bindGroup, tokenCount);
42
+ if (!encoderShared)
43
+ await this.gpu?.SumbitEncoder(encoder);
44
+ return this.output;
45
+ }
46
+ async backward(probs, target, encoderShared) {
47
+ let tokenCount = probs.buffer.size / (4 * this.VocabSize);
48
+ if (!this.backwardShader) {
49
+ this.backwardShader = await this.gpu?.getPiplineShader("backward.wgsl");
50
+ }
51
+ const encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder();
52
+ if (!this.gradOutput || this.gradOutput.buffer.size !== probs.buffer.size || this.gradOutput.isDestroy()) {
53
+ if (this.gradOutput)
54
+ this.gradOutput.destroy();
55
+ this.gradOutput = await this.gpu?.createBuffer(new Float32Array(tokenCount * this.VocabSize), "storage");
56
+ }
57
+ if (!this.targetBuffer || this.targetBuffer.buffer.size !== tokenCount * Uint32Array.BYTES_PER_ELEMENT) {
58
+ if (this.targetBuffer)
59
+ this.targetBuffer.destroy();
60
+ this.targetBuffer = await this.gpu?.createBuffer(new Uint32Array(target), "storage");
61
+ }
62
+ else {
63
+ this.targetBuffer.changeData(new Uint32Array(target));
64
+ }
65
+ const bindGroup = await this.gpu?.createBindGroup(this.backwardShader, [probs, this.gradOutput, this.targetBuffer, this.forwardParams], 0);
66
+ await this.gpu?.RunPipline(encoder, this.backwardShader, bindGroup, Math.ceil(this.VocabSize / 64), tokenCount);
67
+ if (!encoderShared)
68
+ await this.gpu?.SumbitEncoder(encoder);
69
+ return this.gradOutput;
70
+ }
71
+ async crossEntropy(probs, target, encoderShared) {
72
+ let encoder = encoderShared ? encoderShared : await this.gpu?.CreateEncoder();
73
+ let tokenCount = probs.buffer.size / (4 * this.VocabSize);
74
+ if (!this.targetBuffer || this.targetBuffer.buffer.size !== tokenCount * Uint32Array.BYTES_PER_ELEMENT) {
75
+ if (this.targetBuffer)
76
+ this.targetBuffer.destroy();
77
+ this.targetBuffer = await this.gpu?.createBuffer(new Uint32Array(target), "storage");
78
+ }
79
+ else {
80
+ this.targetBuffer.changeData(new Uint32Array(target));
81
+ }
82
+ if (!this.loss || this.loss.buffer.size !== tokenCount * 4) {
83
+ if (this.loss)
84
+ this.loss.destroy();
85
+ this.loss = await this.gpu?.createBuffer(new Float32Array(tokenCount), "storage");
86
+ }
87
+ if (!this.lossShader) {
88
+ this.lossShader = await this.gpu?.getPiplineShader("crossEntropy.wgsl");
89
+ }
90
+ const bindGroup = await this.gpu?.createBindGroup(this.lossShader, [probs, this.targetBuffer, this.loss, this.forwardParams], 0);
91
+ await this.gpu?.RunPipline(encoder, this.lossShader, bindGroup, Math.ceil(tokenCount / 16));
92
+ if (!encoderShared)
93
+ await this.gpu?.SumbitEncoder(encoder);
94
+ return this.loss;
95
+ }
96
+ }
@@ -0,0 +1,15 @@
1
+ export declare class Tokenizer {
2
+ configs: {
3
+ vocabFile: string;
4
+ };
5
+ vocabs: string[];
6
+ vocabSize: number | undefined;
7
+ idToString: Record<number, string>;
8
+ stringToID: Record<string, number>;
9
+ constructor(configs: {
10
+ vocabFile: string;
11
+ });
12
+ encode(text: string): number[] | [];
13
+ decode(token: number[]): string;
14
+ trainTokenizer(text: string, file: string): void;
15
+ }
@@ -0,0 +1,58 @@
1
+ import fs from 'fs';
2
+ export class Tokenizer {
3
+ configs;
4
+ vocabs = ["hi"];
5
+ vocabSize = 0;
6
+ idToString = { 12: "hi" };
7
+ stringToID = { "hi": 12 };
8
+ constructor(configs) {
9
+ this.configs = configs;
10
+ const isVocabExist = fs.existsSync(configs.vocabFile);
11
+ if (isVocabExist) {
12
+ console.log(`[LOG] Tokenizer is Loaded with ${configs.vocabFile}`);
13
+ this.vocabs = JSON.parse(fs.readFileSync(configs.vocabFile, "utf-8"));
14
+ this.vocabSize = this.vocabs?.length;
15
+ this.idToString = Object.fromEntries(this.vocabs?.map((e, idx) => [idx, e]));
16
+ this.stringToID = Object.fromEntries(this.vocabs?.map((e, idx) => [e, idx]));
17
+ }
18
+ else {
19
+ console.log(`[LOG] Tokenizer exited with error 1. No such File or Dir.`);
20
+ }
21
+ }
22
+ encode(text) {
23
+ const split = text.toLocaleLowerCase().split(/(\s+|[.:?,;!:'-()])/).filter(Boolean);
24
+ const tokens = [];
25
+ for (let a = 0; a < split.length; a++) {
26
+ const token = this.stringToID[split[a]];
27
+ if (token !== undefined) {
28
+ tokens.push(token);
29
+ }
30
+ else {
31
+ const unkToken = this.stringToID["<unk>"];
32
+ tokens.push(unkToken);
33
+ }
34
+ }
35
+ return tokens;
36
+ }
37
+ decode(token) {
38
+ let text = "";
39
+ for (let a = 0; a < token.length; a++) {
40
+ const string = this.idToString[token[a]];
41
+ if (string !== undefined) {
42
+ text += string;
43
+ }
44
+ else {
45
+ text += "<unk>";
46
+ }
47
+ }
48
+ return text;
49
+ }
50
+ trainTokenizer(text, file) {
51
+ let oldArray = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf-8')) : [];
52
+ const splitedText = text.toLocaleLowerCase().split(/\r\n|\r|\n/).filter((e) => e.trim().length > 0).map((e) => e.replaceAll("<eos>", "<eos>").split(/(\s+|[.:?,;:'!-()])/).filter(Boolean)).flat();
53
+ const uqiuneText = [...new Set([...splitedText, "<unk>", "_m", "_e", "<eos>", ...oldArray])];
54
+ console.log("Operation Completed!");
55
+ console.log("New Vocab Size", uqiuneText.length - oldArray.length);
56
+ fs.writeFileSync(file, JSON.stringify(uqiuneText));
57
+ }
58
+ }
@@ -0,0 +1,21 @@
1
+ import { FFN, RMSNorm, SelfAttention, residualConnection } from '../index.js';
2
+ import { Buffer } from '@imaduddin/webgpu-manager';
3
+ export declare class TransformerBlock {
4
+ device: GPUDevice;
5
+ embeddingSize: number;
6
+ configs: {
7
+ dirname: string;
8
+ };
9
+ ffn: FFN | undefined;
10
+ attention: SelfAttention | undefined;
11
+ norm: RMSNorm | undefined;
12
+ norm1: RMSNorm | undefined;
13
+ residualConnection1: residualConnection | undefined;
14
+ residualConnection2: residualConnection | undefined;
15
+ constructor(device: GPUDevice, embeddingSize: number, configs: {
16
+ dirname: string;
17
+ });
18
+ forward(input: Buffer): Promise<Buffer | undefined>;
19
+ backward(outGradient: Buffer, lr: number): Promise<Buffer | undefined>;
20
+ Save(): Promise<void>;
21
+ }
@@ -0,0 +1,43 @@
1
+ import { FFN, RMSNorm, SelfAttention, residualConnection } from '../index.js';
2
+ export class TransformerBlock {
3
+ device;
4
+ embeddingSize;
5
+ configs;
6
+ ffn;
7
+ attention;
8
+ norm;
9
+ norm1;
10
+ residualConnection1;
11
+ residualConnection2;
12
+ constructor(device, embeddingSize, configs) {
13
+ this.device = device;
14
+ this.embeddingSize = embeddingSize;
15
+ this.configs = configs;
16
+ this.ffn = new FFN(device, embeddingSize, configs);
17
+ this.norm = new RMSNorm(device, embeddingSize);
18
+ this.norm1 = new RMSNorm(device, embeddingSize);
19
+ this.attention = new SelfAttention(device, embeddingSize, configs);
20
+ this.residualConnection1 = new residualConnection(device);
21
+ this.residualConnection2 = new residualConnection(device);
22
+ }
23
+ async forward(input) {
24
+ const norm = await this.norm?.forward(input, undefined);
25
+ const att = await this.attention?.forward(norm);
26
+ const residual = await this.residualConnection1?.add(att, input);
27
+ const norm1 = await this.norm1?.forward(residual, undefined);
28
+ const ff = await this.ffn?.forward(norm1, undefined);
29
+ return await this.residualConnection2?.add(residual, ff);
30
+ }
31
+ async backward(outGradient, lr) {
32
+ const d_FFN = await this.ffn?.backward(outGradient, lr, undefined);
33
+ const d_norm1 = await this.norm1?.backward(d_FFN, undefined);
34
+ let d_residual2 = await this.residualConnection2?.add(outGradient, d_norm1);
35
+ const d_att = await this.attention?.backward(d_residual2, lr);
36
+ const d_norm2 = await this.norm?.backward(d_att, undefined);
37
+ return await this.residualConnection1?.add(outGradient, d_norm2);
38
+ }
39
+ async Save() {
40
+ await this.ffn?.Save();
41
+ await this.attention?.Save();
42
+ }
43
+ }
@@ -0,0 +1,6 @@
1
+ import { Buffer as WEBB, GPUManager } from '@imaduddin/webgpu-manager';
2
+ export declare function GetVectorsForFile(file: string, total: number, isBias: boolean | undefined, aSize: number, bSize: number): Float32Array<ArrayBuffer> | null;
3
+ export declare function SaveFileVector(file: string, vector: Float32Array): void;
4
+ export declare function initRandomVector(total: number): Float32Array<ArrayBuffer>;
5
+ export declare function isBufferOrNumber(f: WEBB | number[], gpu: GPUManager): Promise<WEBB>;
6
+ export declare function getParameter(): void;
@@ -0,0 +1,34 @@
1
+ import fs from 'fs';
2
+ import { join } from 'path';
3
+ import { Buffer as WEBB } from '@imaduddin/webgpu-manager';
4
+ process.stdout.write("\x1bc");
5
+ let totalParameter = 0;
6
+ export function GetVectorsForFile(file, total, isBias = false, aSize, bSize) {
7
+ if (!fs.existsSync(file))
8
+ return null;
9
+ totalParameter += total;
10
+ console.log(`Loading File ${join(file)} (${aSize}x${bSize})...`);
11
+ const rawBuffer = fs.readFileSync(file);
12
+ const vec = new Float32Array(rawBuffer.buffer, rawBuffer.byteOffset, rawBuffer.byteLength / 4);
13
+ if (total <= vec.length) {
14
+ return vec;
15
+ }
16
+ const expanded = new Float32Array(total);
17
+ expanded.set(vec);
18
+ for (let i = vec.length; i < total; i++) {
19
+ expanded[i] = isBias ? 0 : (Math.random() * 2 - 1) * 0.05;
20
+ }
21
+ return expanded;
22
+ }
23
+ export function SaveFileVector(file, vector) {
24
+ fs.writeFileSync(file, Buffer.from(vector.buffer, vector.byteOffset, vector.byteLength));
25
+ }
26
+ export function initRandomVector(total) {
27
+ return new Float32Array(total).map((e) => (Math.random() * 2 - 1) * 0.02);
28
+ }
29
+ export async function isBufferOrNumber(f, gpu) {
30
+ return f instanceof WEBB ? f : await gpu.createBuffer(new Float32Array(f), "storage");
31
+ }
32
+ export function getParameter() {
33
+ console.log(`Total Parameter ${(totalParameter / 1000000).toFixed(2)}M.`);
34
+ }
@@ -0,0 +1,10 @@
1
+ export * from './Embedding/index.js';
2
+ export * from './Linear/index.js';
3
+ export * from './Softmax/index.js';
4
+ export * from './Gelu/index.js';
5
+ export * from './FFN/index.js';
6
+ export * from './RMSNorm/index.js';
7
+ export * from './SelfAttention/index.js';
8
+ export * from './Tokenizer/index.js';
9
+ export * from './TransformerBlock/index.js';
10
+ export * from './residualConnection/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export * from './Embedding/index.js';
2
+ export * from './Linear/index.js';
3
+ export * from './Softmax/index.js';
4
+ export * from './Gelu/index.js';
5
+ export * from './FFN/index.js';
6
+ export * from './RMSNorm/index.js';
7
+ export * from './SelfAttention/index.js';
8
+ export * from './Tokenizer/index.js';
9
+ export * from './TransformerBlock/index.js';
10
+ export * from './residualConnection/index.js';
@@ -0,0 +1,9 @@
1
+ import { Buffer, GPUManager } from "@imaduddin/webgpu-manager";
2
+ export declare class residualConnection {
3
+ device: GPUDevice;
4
+ output: Buffer | undefined;
5
+ gpu: GPUManager | undefined;
6
+ addShader: GPUComputePipeline | undefined;
7
+ constructor(device: GPUDevice);
8
+ add(a: Buffer, b: Buffer): Promise<Buffer | undefined>;
9
+ }
@@ -0,0 +1,25 @@
1
+ import { GPUManager } from "@imaduddin/webgpu-manager";
2
+ export class residualConnection {
3
+ device;
4
+ output;
5
+ gpu;
6
+ addShader;
7
+ constructor(device) {
8
+ this.device = device;
9
+ this.gpu = new GPUManager(device, {
10
+ shaderDir: "./shaders"
11
+ });
12
+ }
13
+ async add(a, b) {
14
+ const encoder = await this.gpu?.CreateEncoder();
15
+ if (!this.output || this.output.buffer.size !== a.buffer.size / 4) {
16
+ if (this.output)
17
+ this.output.destroy();
18
+ this.output = await this.gpu?.createBuffer(new Float32Array(a.buffer.size / 4), "storage");
19
+ }
20
+ const bindGroup = await this.gpu?.createBindGroup(this.addShader, [a, b, this.output], 0);
21
+ await this.gpu?.RunPipline(encoder, this.addShader, bindGroup, Math.ceil((a.buffer.size / 4) / 64));
22
+ await this.gpu?.SumbitEncoder(encoder);
23
+ return this.output;
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imaduddin/fastbrain",
3
- "version": "1.1.1",
3
+ "version": "2.0.1",
4
4
  "description": "Raw-JAVASCRIPT Based Matirx and AI LLM Package called fastBrain.",
5
5
  "keywords": [
6
6
  "ai",
@@ -12,6 +12,12 @@
12
12
  "Language",
13
13
  "Model"
14
14
  ],
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
15
21
  "license": "MIT",
16
22
  "author": "mineproness",
17
23
  "type": "module",
@@ -20,10 +26,21 @@
20
26
  "type": "git",
21
27
  "url": "https://github.com/imaduddin/fastBrain.git"
22
28
  },
29
+ "scripts": {
30
+ "build": "tsc",
31
+ "test": "node test/test1.js",
32
+ "test1": "node test/test2.js"
33
+ },
23
34
  "dependencies": {
35
+ "@imaduddin/webgpu-manager": "^1.0.3",
24
36
  "webgpu": "^0.6.1"
25
37
  },
26
38
  "allowScripts": {
27
- "webgpu@0.6.0": true
39
+ "webgpu@0.6.2": true
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^26.6.5",
43
+ "@webgpu/types": "^0.1.74",
44
+ "typescript": "~5.8.3"
28
45
  }
29
- }
46
+ }
@@ -0,0 +1,22 @@
1
+ @group(0) @binding(0)
2
+
3
+ var <storage, read> input : array<f32>;
4
+
5
+ @group(0) @binding(1)
6
+
7
+ var <storage, read> a : array<f32>;
8
+
9
+
10
+ @group(0) @binding(1)
11
+
12
+ var <storage, read> out : array<f32>;
13
+
14
+ @compute @workgroup_size(64)
15
+
16
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
17
+ if(id.x >= arrayLength(&input)){
18
+ return ;
19
+ }
20
+ out[id.x] = input[id.x] + a[id.x];
21
+
22
+ }
@@ -0,0 +1,36 @@
1
+ struct Params{
2
+ embeddingSize: f32,
3
+ vocabSize: f32,
4
+ lr: f32
5
+ }
6
+
7
+ @group(0) @binding(0)
8
+
9
+ var <storage, read_write> vectors : array<f32>;
10
+
11
+ @group(0) @binding(1)
12
+ var <storage, read> input : array<u32>;
13
+
14
+ @group(0) @binding(2)
15
+
16
+ var <storage, read> dInput : array<f32>;
17
+
18
+ @group(0) @binding(3)
19
+
20
+ var <uniform> params : Params;
21
+
22
+ @compute @workgroup_size(64, 4)
23
+
24
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
25
+ let x = id.x;
26
+ let token = id.y;
27
+ if(x >= u32(params.embeddingSize)){
28
+ return;
29
+ }
30
+ if(token >= arrayLength(&input)){
31
+ return;
32
+ }
33
+ let tokenId = input[token];
34
+ vectors[tokenId * u32(params.embeddingSize) + x] -= params.lr * dInput[token * u32(params.embeddingSize) + x];
35
+
36
+ }