@imaduddin/fastbrain 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +14 -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
@@ -1,28 +0,0 @@
1
- export class TransformerBlock{
2
- constructor(device: GPUAdapter, embeddingSize: number, configs: {
3
- dirname: string
4
- })
5
- async forward(input : {
6
- read: function(): Promise<Float32Array>,
7
- mainBuffer: GPUBuffer,
8
- isDestroyed: function(): Boolean,
9
- destroy: function(): void
10
- }) : Promise<{
11
- read: function(): Promise<Float32Array>,
12
- mainBuffer: GPUBuffer,
13
- isDestroyed: function(): Boolean,
14
- destroy: function(): void
15
- }>
16
- async backward(outInput : {
17
- read: function(): Promise<Float32Array>,
18
- mainBuffer: GPUBuffer,
19
- isDestroyed: function(): Boolean,
20
- destroy: function(): void
21
- }, lr : number) : Promise<{
22
- read: function(): Promise<Float32Array>,
23
- mainBuffer: GPUBuffer,
24
- isDestroyed: function(): Boolean,
25
- destroy: function(): void
26
- }>
27
- async Save() : Promise<void>
28
- }
@@ -1,78 +0,0 @@
1
-
2
- import { SelfAttention } from '../SelfAttention/index.js';
3
- import { FFN } from '../FFN/index.js';
4
- import { existsSync, mkdirSync } from 'fs';
5
- import { RMSNorm } from '../../index.js';
6
- import { OperationManager } from '../OperationManager.js';
7
- import path, { join } from 'path';
8
- import { residualConnection } from '../residualConnection/index.js'
9
-
10
- export class TransformerBlock {
11
- attention;
12
- ffn;
13
- gpu;
14
- size;
15
- rmsnorm;
16
- rmsnorm2;
17
-
18
- constructor(device, embeddingSize, configs) {
19
- this.size = embeddingSize;
20
- if (!existsSync(configs.dirname)) {
21
- mkdirSync(configs.dirname, { recursive: true });
22
- }
23
- this.rmsnorm = new RMSNorm(device, embeddingSize, {
24
- save: {
25
- filename: join(configs.dirname, "LAYERNORM-1.bin")
26
- }
27
- });
28
- this.rmsnorm2 = new RMSNorm(device, embeddingSize, {
29
- save: {
30
- filename: join(configs.dirname, "LAYERNORM-2.bin")
31
- }
32
- });
33
-
34
-
35
- this.attention = new SelfAttention(
36
- device, embeddingSize, configs
37
- );
38
- this.rFor1 = new residualConnection(device)
39
- this.rFor2 = new residualConnection(device)
40
- this.rback1 = new residualConnection(device)
41
- this.rback2 = new residualConnection(device)
42
- this.ffn = new FFN(device, embeddingSize, configs);
43
- this.gpu = new OperationManager(device);
44
- }
45
-
46
- async forward(input, encoderMain) {
47
- const count = input.size / 4;
48
- const norm1 = await this.rmsnorm.forward(input, encoderMain);
49
- const att = await this.attention.forward(norm1, encoderMain)
50
- const residual1 = await this.rFor1.add(att, input, encoderMain)
51
- const norm2 = await this.rmsnorm2.forward(residual1, encoderMain)
52
- const f = await this.ffn.forward(norm2, encoderMain)
53
- const residual2 = await this.rFor2.add(f, residual1, encoderMain)
54
- return residual2;
55
- }
56
-
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
- return dResidual2;
65
- }
66
-
67
- async ClearInputCache() {
68
- await this.ffn.ClearInputCache();
69
- await this.attention.ClearInputCache();
70
- }
71
-
72
- async Save() {
73
- await this.ffn.Save();
74
- await this.attention.Save();
75
- await this.rmsnorm.Save()
76
- await this.rmsnorm2.Save()
77
- }
78
- }
package/src/getVec.js DELETED
@@ -1,30 +0,0 @@
1
- import fs from 'fs'
2
-
3
-
4
- export function getVector(filename, size, bias) {
5
- if (!fs.existsSync(filename)) {
6
- return null;
7
- }
8
- const buffer = fs.readFileSync(filename);
9
- const r = new Float32Array(
10
- buffer.buffer,
11
- buffer.byteOffset,
12
- buffer.byteLength / 4
13
- );
14
- if (r.length >= size) {
15
- return r;
16
- }
17
- const output = new Float32Array(size);
18
- output.set(r);
19
- if (!bias) {
20
- for (let i = r.length; i < size; i++) {
21
- output[i] = (Math.random() * 2 - 1) * 0.02;
22
- }
23
- }
24
- return output;
25
- }
26
-
27
- export function SaveVector(filename, vectors) {
28
- const buffer = Buffer.from(vectors.buffer)
29
- fs.writeFileSync(filename, buffer)
30
- }
package/src/gpu.js DELETED
File without changes
@@ -1,43 +0,0 @@
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
- getLoss : Function
28
- getAcc: Function
29
- clearLoss : Function
30
- async forward(input: number[]): Promise<{
31
- read: function(): Promise<Float32Array>,
32
- mainBuffer: GPUBuffer,
33
- isDestroyed: function(): Boolean,
34
- destroy: function(): void
35
- }>
36
- async backward(x: {
37
- read: function(): Promise<Float32Array>,
38
- mainBuffer: GPUBuffer,
39
- isDestroyed: function(): Boolean,
40
- destroy: function(): void
41
- }, target: number[], lr : number)
42
- async Save() : Promise<{ loss: Function, acc: Function }>
43
- }
@@ -1,83 +0,0 @@
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) {
50
- if (input.length > this.contextSize) throw new Error("The input get large then ContextSize")
51
- let vec = await this.embedding.forward(input)
52
- vec = await this.PosEmbedding.forward(vec)
53
- for (let i = 0; i < this.blocks.length; i++) {
54
- vec = await this.blocks[i].forward(vec)
55
- }
56
-
57
- let logits = await this.linear.forward(vec)
58
- let probs = await this.softmax.forward(logits)
59
-
60
- return probs
61
- }
62
- async backward(x, target, lr) {
63
- const { acc, loss } = await this.softmax.crossEntropy(x, target)
64
- let dLogits = await this.softmax.backward(x, target)
65
- let dInput = await this.linear.backward(dLogits, lr)
66
- for (let i = this.blocks.length - 1; i >= 0; i--) {
67
- dInput = await this.blocks[i].backward(dInput, lr)
68
- };
69
- await this.embedding.backward(dInput, lr)
70
- await this.PosEmbedding.backward(dInput, lr)
71
- await this.op.submitQueue(encoder)
72
- return { acc, loss }
73
-
74
- }
75
- async Save() {
76
- await this.PosEmbedding.Save()
77
- await this.embedding.Save()
78
- await this.linear.Save()
79
- for (let i = this.blocks.length - 1; i >= 0; i--) {
80
- await this.blocks[i].Save()
81
- };
82
- }
83
- }
@@ -1,31 +0,0 @@
1
- import { OperationManager } from "../OperationManager.js";
2
-
3
- export class residualConnection {
4
- gpu;
5
- addShader;
6
- a;
7
- b;
8
- output;
9
- constructor(device) {
10
- this.gpu = new OperationManager(device)
11
- this.addShader = this.gpu.getShaderPipline("./src/shaders/add.wgsl")
12
- }
13
- async add(a, b, en) {
14
- if (!this.params) {
15
- this.params = await this.gpu.createUniFormBuffer(4 * 4)
16
- }
17
- const encoder = en ? en : await this.gpu.CreateEncoder()
18
- if (!this.output) {
19
- this.output = await this.gpu.ManageBuffer(a.size);
20
- }
21
- if (this.output.size !== a.size || this.output.size == 0 || this.output.isDestroyed()) {
22
- this.output.destroy()
23
- this.output = await this.gpu.ManageBuffer(a.size);
24
- }
25
- const bind = await this.gpu.createBindGroup(this.addShader, 0, [a.mainBuffer, b.mainBuffer, this.output.mainBuffer, this.params]);
26
- await this.gpu.WriteBuffer(this.params, new Uint32Array([(a.size / 4), 0]))
27
- await this.gpu.RunPipline(encoder, this.addShader, bind, Math.ceil((a.size / 4) / 64));
28
- if(!en) await this.gpu.submitQueue(encoder)
29
- return this.output
30
- }
31
- }
@@ -1,50 +0,0 @@
1
- struct Params{
2
- vocabSize: u32,
3
- tokenCount: u32
4
- }
5
-
6
- @group(0) @binding(0)
7
-
8
- var <uniform> params : Params;
9
-
10
-
11
- @group(0) @binding(1)
12
-
13
- var <storage, read_write> probs : array<f32>;
14
-
15
- @group(0) @binding(3)
16
-
17
- var <storage, read_write> tToken : array<u32>;
18
-
19
- @group(0) @binding(2)
20
-
21
-
22
- var <storage, read_write> result : array<f32>;
23
-
24
-
25
- @compute @workgroup_size(1)
26
-
27
- fn main(@builtin(global_invocation_id) id : vec3<u32>){
28
- let x = id.x;
29
-
30
- var correct = 0.0;
31
- for(var a = 0u; a < params.tokenCount; a++){
32
- var bestVal = - 3.402823e38;
33
- var maxToken = 0u;
34
- var start = a * params.vocabSize;
35
- let end = start + params.vocabSize;
36
- for(var t = start; t < end; t++){
37
- let val = probs[t];
38
- if(bestVal < val){
39
- bestVal = val;
40
- maxToken = t - start;
41
- }
42
- }
43
- if(maxToken == tToken[a]){
44
- correct += 1.0;
45
- }
46
-
47
- }
48
- correct /= f32(params.tokenCount);
49
- result[x] = correct;
50
- }
@@ -1,33 +0,0 @@
1
- struct Params {
2
- vocabSize: u32,
3
- tokenCount: u32,
4
- }
5
-
6
- @group(0) @binding(0)
7
-
8
- var <storage, read> probs : array<f32>;
9
-
10
- @group(0) @binding(1)
11
-
12
- var <storage, read> targetToken : array<u32>;
13
-
14
- @group(0) @binding(2)
15
-
16
- var <storage, read_write> loss : array<f32>;
17
-
18
- @group(0) @binding(3)
19
-
20
- var <uniform> params: Params;
21
-
22
-
23
- @compute @workgroup_size(4)
24
-
25
- fn main(@builtin(global_invocation_id) id : vec3<u32>) {
26
- let index = id.x;
27
- if(index >= params.vocabSize){
28
- return;
29
- }
30
- var targetIndex = targetToken[index];
31
- let probalitils = probs[index * params.vocabSize + u32(targetIndex)];
32
- loss[index] = -log(probalitils + 1e-15);
33
- }
@@ -1,46 +0,0 @@
1
-
2
- struct Params {
3
- vocabSize: u32,
4
- tokenCount: u32,
5
- lr: f32,
6
- inputSize: u32,
7
- }
8
-
9
- @group(0) @binding(0)
10
- var<storage, read> weight: array<f32>;
11
-
12
- @group(0) @binding(1)
13
- var<storage, read> outGradient: array<f32>;
14
-
15
- @group(0) @binding(3)
16
- var<uniform> params: Params;
17
-
18
- @group(0) @binding(4)
19
- var<storage, read_write> dInput: array<f32>;
20
-
21
- @compute @workgroup_size(256)
22
- fn main(@builtin(global_invocation_id) id: vec3<u32>) {
23
- let index = id.x;
24
- let total = params.tokenCount * params.inputSize;
25
-
26
- if (index >= total) {
27
- return;
28
- }
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];
44
- }
45
- dInput[index] = sum / f32(params.tokenCount);
46
- }
@@ -1,33 +0,0 @@
1
- struct Params {
2
- lr: f32
3
- }
4
-
5
- @group(0) @binding(0)
6
-
7
- var<storage, read_write> embeddings: array<f32>;
8
-
9
- @group(0) @binding(1)
10
-
11
- var<storage, read_write> outputGradient: array<f32>;
12
-
13
- @group(0) @binding(2)
14
-
15
- var<storage, read_write> tokens: array<u32>;
16
-
17
- @group(0) @binding(3)
18
- var<uniform> params: Params;
19
-
20
- const embeddingSize = %embeddingSize%u;
21
-
22
- @compute @workgroup_size(256)
23
-
24
- fn main(@builtin(global_invocation_id) id: vec3<u32>) {
25
- let dim = id.x % embeddingSize;
26
- if (id.x >= arrayLength(&outputGradient)) {
27
- return;
28
- }
29
- let tokenIndex = id.x / embeddingSize;
30
- let tokenID = tokens[tokenIndex];
31
- let embeddingIDx = tokenID * embeddingSize + dim;
32
- embeddings[embeddingIDx] -= params.lr * outputGradient[id.x];
33
- }
@@ -1,25 +0,0 @@
1
- @group(0) @binding(0)
2
-
3
- var <storage, read_write> embeddings: array<f32>;
4
-
5
- @group(0) @binding(1)
6
-
7
- var <storage, read_write> output: array<f32>;
8
-
9
- @group(0) @binding(2)
10
-
11
- var <storage, read_write> tokens: array<u32>;
12
-
13
- const embeddingSize = %embeddingSize%u;
14
-
15
- @compute @workgroup_size(256)
16
-
17
- fn main(@builtin(global_invocation_id) id : vec3<u32>){
18
- let dim = id.x % embeddingSize;
19
- let tokenIndex = id.x / embeddingSize;
20
-
21
- let tokenID = tokens[tokenIndex];
22
-
23
- let embeddingIDx = tokenID * embeddingSize + dim;
24
- output[id.x] = embeddings[embeddingIDx];
25
- }
@@ -1,71 +0,0 @@
1
-
2
- struct Params {
3
- vocabSize: u32,
4
- tokenCount: u32,
5
- lr: f32,
6
- inputSize: u32,
7
- }
8
-
9
- @group(0) @binding(0)
10
- var<storage, read_write> bias: array<f32>;
11
-
12
- @group(0) @binding(1)
13
- var<storage, read_write> weight: array<f32>;
14
-
15
- @group(0) @binding(2)
16
- var<storage, read> outGradient: array<f32>;
17
-
18
- @group(0) @binding(3)
19
- var<storage, read> input: array<f32>;
20
-
21
- @group(0) @binding(4)
22
- var<uniform> params: Params;
23
-
24
- const WG_SIZE: u32 = 256u;
25
-
26
- var<workgroup> sharedBias: array<f32, 256>;
27
-
28
- @compute @workgroup_size(256)
29
- fn main(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {
30
- let outputIndex = wid.x;
31
- let tid = lid.x;
32
- let vocab = params.vocabSize;
33
- let tokens = params.tokenCount;
34
- let inputSize = params.inputSize;
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) {
41
- var grad = 0.0;
42
- for (var t = 0u; t < tokens; t++) {
43
- let inputIndex = t * inputSize + j;
44
- let outputGradIndex = t * vocab + gradBase;
45
- grad += input[inputIndex] * outGradient[outputGradIndex];
46
- }
47
-
48
- if (tokens > 0u) {
49
- let idx = weightBase + j;
50
- weight[idx] -= params.lr * (grad / f32(params.tokenCount));
51
- }
52
- }
53
-
54
- var biasGrad = 0.0;
55
- for (var t = tid; t < tokens; t += WG_SIZE) {
56
- biasGrad += outGradient[t * vocab + gradBase];
57
- }
58
-
59
- sharedBias[tid] = biasGrad;
60
- workgroupBarrier();
61
- for (var stride = WG_SIZE / 2u; stride > 0u; stride >>= 1u) {
62
- if (tid < stride) {
63
- sharedBias[tid] += sharedBias[tid + stride];
64
- }
65
- workgroupBarrier();
66
- }
67
-
68
- if (tid == 0u && tokens > 0u) {
69
- bias[outputIndex] -= params.lr * (sharedBias[0] / f32(params.tokenCount));
70
- }
71
- }
@@ -1,60 +0,0 @@
1
-
2
- struct Params {
3
- inputSize: u32,
4
- outputSize: u32,
5
- tokenCount: u32,
6
- }
7
-
8
- @group(0) @binding(0)
9
- var<storage, read> weights: array<f32>;
10
-
11
- @group(0) @binding(1)
12
- var<storage, read_write> output: array<f32>;
13
-
14
- @group(0) @binding(2)
15
- var<storage, read> input: array<f32>;
16
-
17
- @group(0) @binding(3)
18
- var<storage, read> bias: array<f32>;
19
-
20
- @group(0) @binding(4)
21
- var<uniform> params: Params;
22
-
23
- const TILE_OUT: u32 = 16u;
24
- const TILE_TOKEN: u32 = 4u;
25
- const TILE_K: u32 = 16u;
26
-
27
- var<workgroup> tileInput: array<f32, 64>;
28
- var<workgroup> tileWeights: array<f32, 256>;
29
-
30
- @compute @workgroup_size(64)
31
- fn main(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {
32
- let outFeature = wid.x * TILE_OUT + lid.x % TILE_OUT;
33
- let token = wid.y * TILE_TOKEN + lid.x / TILE_OUT;
34
- let localOut = lid.x % TILE_OUT;
35
- let localToken = lid.x / TILE_OUT;
36
- var sum = 0.0;
37
- for (var baseK = 0u; baseK < params.inputSize; baseK += TILE_K) {
38
- let loadIndex = lid.x;
39
- let inputToken = wid.y * TILE_TOKEN + loadIndex / TILE_K;
40
- let inputK = baseK + loadIndex % TILE_K;
41
- if (loadIndex < TILE_TOKEN * TILE_K && inputToken < params.tokenCount && inputK < params.inputSize) {
42
- tileInput[loadIndex] = input[inputToken * params.inputSize + inputK];
43
- }
44
- let weightFeature = wid.x * TILE_OUT + loadIndex / TILE_K;
45
- let weightK = baseK + loadIndex % TILE_K;
46
- if (loadIndex < TILE_OUT * TILE_K && weightFeature < params.outputSize && weightK < params.inputSize) {
47
- tileWeights[loadIndex] = weights[weightFeature * params.inputSize + weightK];
48
- }
49
- workgroupBarrier();
50
- for (var k = 0u; k < TILE_K; k++) {
51
- let a = tileInput[localToken * TILE_K + k];
52
- let b = tileWeights[localOut * TILE_K + k];
53
- sum += a * b;
54
- }
55
- workgroupBarrier();
56
- }
57
- if (token < params.tokenCount && outFeature < params.outputSize) {
58
- output[token * params.outputSize + outFeature] = sum + bias[outFeature];
59
- }
60
- }
@@ -1,65 +0,0 @@
1
-
2
- @group(0) @binding(0)
3
- var<storage, read> input: array<f32>;
4
-
5
- @group(0) @binding(1)
6
- var<storage, read> gradOutput: array<f32>;
7
- @group(0) @binding(2)
8
- var<storage, read> sumSquares: array<f32>;
9
-
10
- @group(0) @binding(3)
11
- var<storage, read> gamma: array<f32>;
12
-
13
- @group(0) @binding(4)
14
- var<storage, read_write> gradInput: array<f32>;
15
-
16
- var<workgroup> partial: array<f32, 64>;
17
-
18
- const D: u32 = %embeddingSize%u;
19
- const EPSILON: f32 = 1e-6;
20
- @compute @workgroup_size(64)
21
- fn main(@builtin(local_invocation_index) lid: u32, @builtin(workgroup_id) wid: vec3<u32>) {
22
- let token = wid.x;
23
- if (token >= arrayLength(&sumSquares)) {
24
- return;
25
- }
26
- let base = token * D;
27
- let r = sqrt(sumSquares[token] / f32(D) + EPSILON);
28
- var localSum = 0.0;
29
- var d = lid;
30
- while (d < D) {
31
- let idx = base + d;
32
- localSum += gradOutput[idx] * gamma[d] * input[idx];
33
- d += 64u;
34
- }
35
-
36
- partial[lid] = localSum;
37
- workgroupBarrier();
38
- var stride = 32u;
39
- loop {
40
- if (stride == 0u) {
41
- break;
42
- }
43
-
44
- if (lid < stride) {
45
- partial[lid] += partial[lid + stride];
46
- }
47
-
48
- workgroupBarrier();
49
- stride /= 2u;
50
- }
51
- let dot = partial[0];
52
- d = lid;
53
- while (d < D) {
54
- let idx = base + d;
55
- let x = input[idx];
56
- let dy = gradOutput[idx];
57
- let g = gamma[d];
58
-
59
- gradInput[idx] =
60
- (dy * g) / r
61
- - (x * dot) / (f32(D) * r * r * r);
62
-
63
- d += 64u;
64
- }
65
- }