@mineproness/tensorloop 2.1.66 → 2.1.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -6,6 +6,9 @@ import { FFN as ffn } from "./src/FFN/index.js";
6
6
  import { Tokenizer as to } from './src/Tokenizer/index.js'
7
7
  import {SelfAttention as ST} from './src/SelfAttention/index.js'
8
8
  import {TransformerBlock as TT} from './src/TransformerBlock/index.js'
9
+ import { Model as m } from "./src/Model/index.js";
10
+ import {PositionEmbedding as PM } from './src/PositionEmbedding/index.js'
11
+ import { RMSNorm as RM } from "./src/RMSNorm/index.js";
9
12
  export const Embedding = E
10
13
  export const Linear = L
11
14
  export const Softmax = S;
@@ -13,4 +16,7 @@ export const RELU = r
13
16
  export const FFN = ffn
14
17
  export const Tokenizer = to;
15
18
  export const SelfAttention = ST
16
- export const TransformerBlock = TT;
19
+ export const TransformerBlock = TT;
20
+ export const Model = m;
21
+ export const PositionEmbedding = PM;
22
+ export const RMSNorm = RM
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mineproness/tensorloop",
3
- "version": "2.1.66",
3
+ "version": "2.1.69",
4
4
  "description": "Raw-JAVASCRIPT Based Matirx and AI LLM Package called Tensorloop.",
5
5
  "keywords": [
6
6
  "ai",
@@ -134,6 +134,7 @@ export class Embedding {
134
134
  await this.gpu.WriteBuffer(this.tokenBuffer, new Uint32Array(token));
135
135
  await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((this.embeddingSize * token.length) / 256))
136
136
  this.device.queue.submit([encoder.finish()])
137
- inputGradient.destroy()
137
+ if(this.prevGra) this.prevGra.destroy()
138
+ this.prevGra = inputGradient;
138
139
  }
139
140
  }
package/src/FFN/index.js CHANGED
@@ -29,10 +29,11 @@ export class FFN {
29
29
  return final
30
30
  }
31
31
  async backward(inputGradient, lr) {
32
+ if(this.prevOUTGR) await this.prevOUTGR.destroy()
33
+ this.prevOUTGR = inputGradient;
32
34
  const logit2 = await this.linear2.backward(inputGradient, lr)
33
35
  const hidden = await this.hiddenLayer.backward(logit2)
34
36
  const final = await this.linear1.backward(hidden, lr)
35
- inputGradient.destroy()
36
37
  return final
37
38
  }
38
39
  async Save(){
@@ -113,6 +113,8 @@ export class Linear {
113
113
  return outputBuffer
114
114
  }
115
115
  async backward(dOutput, learningRate) {
116
+ if(this.pdOutput) await this.pdOutput.destroy();
117
+ this.pdOutput = dOutput
116
118
  const encoder = this.device.createCommandEncoder()
117
119
  const tokenCount = dOutput.size / (this.vocabSize * 4)
118
120
  if (!this.oldParamb) {
@@ -173,7 +175,6 @@ export class Linear {
173
175
  await this.gpu.RunPipline(encoder, this.dInputBackward, bind2, Math.ceil((this.embeddingSize * tokenCount) / 256));
174
176
  await this.gpu.RunPipline(encoder, this.backwardPipline, bind, Math.ceil((this.vocabSize * tokenCount) / 256));
175
177
  await this.device.queue.submit([encoder.finish()])
176
- await dOutput.destroy()
177
178
  this.input.destroy()
178
179
  return outputBuffer
179
180
 
@@ -0,0 +1,15 @@
1
+ export class Model {
2
+ async forward(input: Number[], buffer: boolean): Promise<Float32Array | GPUBuffer>;
3
+ async backward(output: GPUBuffer, target: number[], lr: number): Promise<{ acc: number, loss: number }>
4
+ TrainTokenizer(dataset: string): void;
5
+ constructor(device :GPUAdapter, embeddingSize: number, configs: {
6
+ tokenizerName: string
7
+ blockSize: number,
8
+ dirname: string,
9
+ contextSize: number,
10
+ gpuName: string
11
+
12
+ })
13
+ async Save() : Promise<void>
14
+ async CreateContext()
15
+ }
@@ -0,0 +1,95 @@
1
+ import { Embedding, Linear, Softmax, TransformerBlock, Tokenizer, PositionEmbedding, RMSNorm } from '../../index.js'
2
+ import { join } from 'path'
3
+ import fs from 'fs'
4
+ import { OperationManager } from '../OperationManager.js'
5
+ export class Model {
6
+ embedding;
7
+ posEmbedding;
8
+ linear;
9
+ softmax;
10
+ blocks = [];
11
+ blockSize;
12
+ dimSize;
13
+ tokenizer;
14
+ device;
15
+ configs;
16
+ tokenizerName;
17
+ op;
18
+ tokens;
19
+ rmsnorm
20
+ constructor(device, embeddingSize = 64, configs) {
21
+ this.device = device;
22
+ this.dimSize = embeddingSize;
23
+ this.blockSize = configs.blockSize;
24
+ this.configs = configs
25
+ this.tokenizer = new Tokenizer(configs.tokenizerName)
26
+ this.tokenizerName = configs.tokenizerName
27
+ this.op = new OperationManager(device)
28
+ }
29
+ async CreateContext() {
30
+ this.embedding = new Embedding(this.device, this.dimSize, this.tokenizer.vocabSize, {
31
+ save: {
32
+ filename: join(this.configs.dirname, "./vec.bin")
33
+ }
34
+ })
35
+ this.linear = new Linear(this.device, this.dimSize, this.tokenizer.vocabSize, {
36
+ save: {
37
+ filename: [join(this.configs.dirname, "weights.bin"), join(this.configs.dirname, "bias.bin")]
38
+ }
39
+ })
40
+ this.softmax = new Softmax(this.device, this.dimSize, this.tokenizer.vocabSize);
41
+ for (let a = 0; a < this.blockSize; a++) {
42
+ console.log(`Load the Transfomer Block ${a + 1}...`)
43
+ if (!fs.existsSync(join(this.configs.dirname, `block-${a}`))) fs.mkdirSync(join(this.configs.dirname, `block-${a}`));
44
+ this.blocks[a] = new TransformerBlock(this.device, this.dimSize, {
45
+ dirname: join(this.configs.dirname, `block-${a}`)
46
+ })
47
+ }
48
+ this.posEmbedding = new PositionEmbedding(this.device, this.dimSize, this.configs.contextSize, {
49
+ save:{
50
+ filename: join(this.configs.dirname, "posVec.bin")
51
+ }
52
+ })
53
+ }
54
+ TrainTokenizer(text = "", mergeSize = 5) {
55
+ this.tokenizer.trainTokenizer(text, mergeSize, this.tokenizerName)
56
+ }
57
+ async ClearInputCache() {
58
+ await this.linear.ClearInputCache()
59
+ for (let a = 0; a < this.blockSize; a++) {
60
+ await this.blocks[a].ClearInputCache()
61
+ }
62
+ }
63
+ async forward(input, readBack) {
64
+ if(this.configs.contextSize < input.length) throw new Error("The Input is larger then contextSize")
65
+ this.tokens = input;
66
+ await this.ClearInputCache()
67
+ let vec = await this.embedding.forward(input)
68
+ vec = await this.posEmbedding.forward(vec)
69
+ for (let a = 0; a < this.blockSize; a++) {
70
+ vec = await this.blocks[a].forward(vec)
71
+ }
72
+ let logits = await this.linear.forward(vec);
73
+ let probs = await this.softmax.forward(logits, readBack)
74
+ return probs
75
+ }
76
+ async backward(outputGradient, target, lr = 0.02) {
77
+ const loss = await this.softmax.crossEntropy(outputGradient, target)
78
+ const dLogits = await this.softmax.backward(outputGradient, target);
79
+ let DInput = await this.linear.backward(dLogits, lr);
80
+ for (let a = this.blockSize - 1; a !== 0; a--) {
81
+ DInput = await this.blocks[a].backward(DInput, lr);
82
+ }
83
+ this.embedding.backward(this.tokens, DInput, lr);
84
+ this.posEmbedding.backward(DInput, lr)
85
+ return loss
86
+ }
87
+ async Save() {
88
+ await this.embedding.Save()
89
+ await this.linear.Save()
90
+ for (let a = this.blockSize - 1; a !== 0; a--) {
91
+ await this.blocks[a].Save();
92
+ }
93
+ await this.posEmbedding.Save()
94
+ }
95
+ }
@@ -8,9 +8,10 @@ export class OperationManager {
8
8
  device;
9
9
  matrixMatSHhaders;
10
10
  params;
11
- matrixParams;
11
+ addShader;
12
12
  constructor(device) {
13
13
  this.device = device;
14
+ this.addShader = this.getShaderPipline("./src/shaders/add.wgsl")
14
15
  }
15
16
  async createBuffer(size) {
16
17
  return this.device.createBuffer({
@@ -71,18 +72,21 @@ export class OperationManager {
71
72
  pass.end()
72
73
  }
73
74
 
74
- async MakeACopyBuffer(encoder, sourceBuffer) {
75
+ async MakeACopyBuffer(encoder2, sourceBuffer) {
76
+ const encoder = encoder2 ? encoder2 : await this.CreateEncoder()
75
77
  const buffer = this.device.createBuffer({
76
78
  size: sourceBuffer.size,
77
79
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC | GPUBufferUsage.STORAGE
78
80
  })
79
81
  encoder.copyBufferToBuffer(sourceBuffer, 0, buffer, 0, sourceBuffer.size);
82
+ if(!encoder2) await this.submitQueue(encoder)
80
83
  return buffer
81
84
  }
82
85
  CreateEncoder() {
83
86
  return this.device.createCommandEncoder()
84
87
  }
85
88
  createBindGroup(shader, groupNum, ent) {
89
+
86
90
  return this.device.createBindGroup({
87
91
  layout: shader.getBindGroupLayout(groupNum),
88
92
  entries: ent.map((e, x) => {
@@ -96,5 +100,20 @@ export class OperationManager {
96
100
  async submitQueue(encoder) {
97
101
  this.device.queue.submit([encoder.finish()])
98
102
  }
103
+ async add(a, b, size) {
104
+ if (!this.params) {
105
+ this.params = await this.createUniFormBuffer(4 * 4)
106
+
107
+ }
108
+ const encoder = await this.CreateEncoder()
109
+ const output = await this.createBuffer(a.size);
110
+ const bind = await this.createBindGroup(this.addShader, 0, [a, b, output, this.params]);
111
+ await this.WriteBuffer(this.params, new Uint32Array([size, 0]))
112
+ await this.RunPipline(encoder, this.addShader, bind, Math.ceil(size / 64));
113
+ await this.submitQueue(encoder)
114
+ // a.destroy()
115
+ // b.destroy()
116
+ return output
117
+ }
99
118
 
100
119
  }
@@ -0,0 +1,10 @@
1
+ export class PositionEmbedding{
2
+ constructor(device: GPUBuffer ,embedding : number, contextSize: number, config:{
3
+ save: {
4
+ filename: string
5
+ }
6
+ });
7
+ async forward(input: GPUBuffer) : Promise<GPUBuffer>
8
+ async Save() : Promise<GPUBuffer>
9
+ async backward(inputGradient: GPUBuffer, lr: number) : Promise<void>
10
+ }
@@ -0,0 +1,70 @@
1
+ import { OperationManager } from "../OperationManager.js"
2
+ import { getVector, SaveVector } from "../getVec.js"
3
+ function GenerateVectors(embeddingSize, contextSize) {
4
+ const vec = new Float32Array(embeddingSize * contextSize).map(() => (Math.random() * 2 - 1) * 0.02)
5
+ return vec
6
+ }
7
+
8
+ export class PositionEmbedding {
9
+ vectors;
10
+ vecBuffer;
11
+ gpu;
12
+ embeddingSize;
13
+ contextSize;
14
+ params;
15
+ forwardShader;
16
+ backwardShader;
17
+ configs;
18
+ constructor(device, embeddingSize, contextSize, configs) {
19
+ this.embeddingSize = embeddingSize;
20
+ const total = embeddingSize * contextSize;
21
+ this.configs = configs;
22
+ this.contextSize = contextSize;
23
+ if (configs && configs.save) {
24
+ const vec = getVector(configs.save.filename, total);
25
+ if (vec) {
26
+ this.vectors = vec;
27
+
28
+ } else {
29
+ this.vectors = GenerateVectors(embeddingSize, contextSize)
30
+ SaveVector(this.configs.save.filename, this.vectors)
31
+ }
32
+
33
+ } else {
34
+ this.vectors = GenerateVectors(embeddingSize, contextSize)
35
+
36
+ }
37
+ this.gpu = new OperationManager(device)
38
+ this.forwardShader = this.gpu.getShaderPipline("./src/shaders/PF.wgsl")
39
+ this.backwardShader = this.gpu.getShaderPipline("./src/shaders/PB.wgsl")
40
+ }
41
+ async forward(input) {
42
+ const encoder = this.gpu.CreateEncoder()
43
+ if (!this.params) this.params = await this.gpu.createUniFormBuffer(4 * 4)
44
+ if (!this.vecBuffer) {
45
+ this.vecBuffer = await this.gpu.createBuffer(Float32Array.BYTES_PER_ELEMENT * this.contextSize * this.embeddingSize);
46
+ await this.gpu.WriteBuffer(this.vecBuffer, this.vectors)
47
+ }
48
+ const output = await this.gpu.createBuffer(input.size);
49
+ const size = Math.ceil((input.size / 4) / 64);
50
+ const bindGroup = await this.gpu.createBindGroup(this.forwardShader, 0, [this.vecBuffer, input, output])
51
+ if (this.prevVec) this.prevVec.destroy();
52
+ this.prevVec = input;
53
+ await this.gpu.RunPipline(encoder, this.forwardShader, bindGroup, size);
54
+ await this.gpu.submitQueue(encoder);
55
+ return output
56
+ }
57
+ async backward(outputGradient, lr){
58
+ const encoder = await this.gpu.CreateEncoder()
59
+ await this.gpu.WriteBuffer(this.params, new Float32Array([lr,0]))
60
+ const bindGroup = await this.gpu.createBindGroup(this.backwardShader, 0, [this.vecBuffer, outputGradient, this.params])
61
+ if(this.prevGradient) await this.prevGradient.destroy()
62
+ this.prevGradient = outputGradient;
63
+ await this.gpu.RunPipline(encoder, this.backwardShader, bindGroup, Math.ceil((outputGradient.size / 4) / 64))
64
+ await this.gpu.submitQueue(encoder);
65
+ }
66
+ async Save() {
67
+ const vec = await this.gpu.readBuffer(Float32Array.BYTES_PER_ELEMENT * this.contextSize * this.embeddingSize, this.vecBuffer)
68
+ SaveVector(this.configs.save.filename, vec)
69
+ }
70
+ }
@@ -0,0 +1,5 @@
1
+ export class RMSNorm{
2
+ constructor(device : GPUAdapter, embeddingSize : number);
3
+ async forward(input : GPUBuffer) : Promise<GPUBuffer>
4
+ async backward(outputGradient : GPUBuffer) : Promise<GPUBuffer>
5
+ }
@@ -0,0 +1,45 @@
1
+ import { OperationManager } from '../OperationManager.js'
2
+ import fs from 'fs'
3
+
4
+ export class RMSNorm {
5
+ embeddingSize;
6
+ reductionShader;
7
+ forwardShader;
8
+ backwardShader;
9
+ op;
10
+ constructor(device, embeddingSize) {
11
+ this.op = new OperationManager(device);
12
+ this.embeddingSize = embeddingSize;
13
+ this.reductionShader = this.op.getShaderPipline("./src/shaders/Norm/sumSquare.wgsl")
14
+ this.forwardShader = this.op.getShaderPipline("./src/shaders/Norm/rmsForward.wgsl")
15
+ this.backwardShader = this.op.getShaderPipline("./src/shaders/Norm/rmsBackward.wgsl")
16
+ }
17
+ async forward(input) {
18
+ const outputReduce = await this.op.createBuffer(4 * 1);
19
+ const output = await this.op.createBuffer(input.size);
20
+ const bindGroup = await this.op.createBindGroup(this.reductionShader, 0, [input, outputReduce])
21
+ const encoder = await this.op.CreateEncoder()
22
+ await this.op.RunPipline(encoder, this.reductionShader, bindGroup, Math.ceil((input.size / 4) / 64))
23
+ const bindGroup1 = await this.op.createBindGroup(this.forwardShader, 0, [outputReduce, input, output])
24
+ await this.op.RunPipline(encoder, this.forwardShader, bindGroup1, Math.ceil((input.size / 4) / 64));
25
+ await this.op.submitQueue(encoder);
26
+ if (this.rms) this.rms.destroy()
27
+ this.rms = outputReduce
28
+ if (this.input) this.input.destroy()
29
+ this.input = input;
30
+ if (this.outputPre) this.outputPre.destroy()
31
+ this.outputPre = output
32
+ return output
33
+ }
34
+ async backward(outputGradient) {
35
+ const output = await this.op.createBuffer(outputGradient.size);
36
+ const bindGroup = await this.op.createBindGroup(this.backwardShader, 0, [this.input, outputGradient, this.rms, output]);
37
+ const encoder = await this.op.CreateEncoder()
38
+ await this.op.RunPipline(encoder, this.backwardShader, bindGroup, Math.ceil((this.input.size / 4) / 64))
39
+ await this.op.submitQueue(encoder)
40
+ if (this.prevOut) this.prevOut.destroy()
41
+ this.prevOut = outputGradient
42
+ return output
43
+ }
44
+
45
+ }
@@ -102,7 +102,8 @@ export class SelfAttention {
102
102
  dK.destroy()
103
103
  dQ.destroy()
104
104
  dV.destroy()
105
- dO.destroy()
105
+ if(this.prevdO) await this.prevdO.destroy()
106
+ this.prevdO = dO
106
107
  return output
107
108
 
108
109
  }
@@ -63,6 +63,7 @@ export class Softmax {
63
63
  }
64
64
  if (cpuReadBack) {
65
65
  const outputCPU = await this.gpu.readBuffer(output.size, output);
66
+ logits.destroy()
66
67
  return outputCPU
67
68
  }
68
69
  return output
@@ -9,7 +9,7 @@ export class Tokenizer {
9
9
  IdtoWord = {};
10
10
  WordtoID = {};
11
11
  EOSToken = 2
12
- constructor(filename="") {
12
+ constructor(filename = "") {
13
13
  if (fs.existsSync(filename)) {
14
14
  console.log("Warning: Tokenizer is loaded with a Custom Vocab File!")
15
15
  console.log("")
@@ -22,7 +22,7 @@ export class Tokenizer {
22
22
  this.WordtoID = Object.fromEntries(this.vocabs.map((e, idx) => [e, idx]))
23
23
  }
24
24
  encoder(text = "") {
25
- const AddSpaces = text.toLocaleLowerCase().replaceAll(/([,.;'{}!`~\|":><?])/g, " $1 ").replaceAll("<" , " < ")
25
+ const AddSpaces = text.toLocaleLowerCase().replaceAll(/([,.;'{}!`~\|":><?])/g, " $1 ").replaceAll("<", " < ")
26
26
  const splitedWords = AddSpaces.split(/\s+/).filter(e => e.length > 0)
27
27
  const output = []
28
28
  for (let a = 0; a < splitedWords.length; a++) {
@@ -145,8 +145,8 @@ export class Tokenizer {
145
145
  ]
146
146
  const uniArr = [...new Set([...arrText, ...specal, ...prevVocab])];
147
147
  const output = []
148
- for(let a = 0 ; a < uniArr.length; a++){
149
- let text = uniArr[a].match(reg).filter((e)=> e.length > 0);
148
+ for (let a = 0; a < uniArr.length; a++) {
149
+ let text = uniArr[a].match(reg).filter((e) => e.length > 0);
150
150
  output.push(...text)
151
151
  }
152
152
  let finalOutput = [...new Set([...output])]
@@ -155,6 +155,10 @@ export class Tokenizer {
155
155
  console.log(`New VocabSize : ${finalOutput.length - prevVocab.length}`);
156
156
  console.log("_________________________________")
157
157
  console.log("Operation Completed!")
158
-
158
+ this.vocabs = finalOutput;
159
+ this.vocabSize = finalOutput.length;
160
+ this.IdtoWord = Object.fromEntries(this.vocabs.map((e, idx) => [idx, e]))
161
+ this.WordtoID = Object.fromEntries(this.vocabs.map((e, idx) => [e, idx]))
162
+
159
163
  }
160
164
  }
@@ -1,31 +1,74 @@
1
- import {SelfAttention} from '../SelfAttention/index.js'
2
- import {FFN} from '../FFN/index.js'
3
- import {existsSync, mkdirSync} from 'fs'
4
1
 
5
- export class TransformerBlock{
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
+
8
+ export class TransformerBlock {
6
9
  attention;
7
10
  ffn;
8
- constructor(device, embeddingSize, configs){
9
- if(!existsSync(configs.dirname)) mkdirSync(configs.dirname);
10
- this.attention = new SelfAttention(device, embeddingSize, configs)
11
- this.ffn = new FFN(device, embeddingSize, configs)
11
+ gpu;
12
+ size;
13
+ rmsnorm;
14
+ rmsnorm2;
15
+
16
+ constructor(device, embeddingSize, configs) {
17
+ this.size = embeddingSize;
18
+
19
+ this.rmsnorm = new RMSNorm(device, embeddingSize);
20
+ this.rmsnorm2 = new RMSNorm(device, embeddingSize);
21
+
22
+ if (!existsSync(configs.dirname)) {
23
+ mkdirSync(configs.dirname, { recursive: true });
24
+ }
25
+
26
+ this.attention = new SelfAttention(
27
+ device, embeddingSize, configs
28
+ );
29
+
30
+ this.ffn = new FFN(device, embeddingSize, configs);
31
+ this.gpu = new OperationManager(device);
12
32
  }
13
- async forward(input){
14
- const xAtt = await this.attention.forward(input);
15
- const xFF = await this.ffn.forward(xAtt);
16
- return xFF
33
+
34
+ async forward(input) {
35
+ const count = input.size / 4;
36
+ const norm1 = await this.rmsnorm.forward(input);
37
+ const att = await this.attention.forward(norm1);
38
+ const h = await this.gpu.add(input, att, count);
39
+ const norm2 = await this.rmsnorm2.forward(h);
40
+ const f = await this.ffn.forward(norm2);
41
+ const y = await this.gpu.add(h, f, count);
42
+ norm1.destroy();
43
+ att.destroy();
44
+ f.destroy();
45
+ return y;
17
46
  }
18
- async backward(outGradient, lr){
19
- const dAtt = await this.ffn.backward(outGradient, lr);
20
- const dFF = await this.attention.backward(dAtt, lr)
21
- return dFF
47
+
48
+ async backward(outGradient, lr) {
49
+ const count = outGradient.size / 4;
50
+ const dNorm2 = await this.ffn.backward(outGradient, lr);
51
+ const dHFromFFN = await this.rmsnorm2.backward(dNorm2);
52
+ const dH = await this.gpu.add(outGradient, dHFromFFN, count);
53
+ const dNorm1 = await this.attention.backward(dH, lr);
54
+ const dInputFromAttention = await this.rmsnorm.backward(dNorm1);
55
+ const dInput = await this.gpu.add(dH, dInputFromAttention, count);
56
+ dNorm2.destroy();
57
+ dHFromFFN.destroy();
58
+ dH.destroy();
59
+ dNorm1.destroy();
60
+ dInputFromAttention.destroy();
61
+ dInputFromAttention.destroy();
62
+ return dInput;
22
63
  }
23
- async ClearInputCache(){
24
- await this.ffn.ClearInputCache()
25
- await this.attention.ClearInputCache()
64
+
65
+ async ClearInputCache() {
66
+ await this.ffn.ClearInputCache();
67
+ await this.attention.ClearInputCache();
26
68
  }
27
- async Save(){
28
- await this.ffn.Save()
29
- await this.attention.Save()
69
+
70
+ async Save() {
71
+ await this.ffn.Save();
72
+ await this.attention.Save();
30
73
  }
31
74
  }
package/src/gpu.js ADDED
File without changes
@@ -9,7 +9,7 @@ var <storage, read> probs : array<f32>;
9
9
 
10
10
  @group(0) @binding(1)
11
11
 
12
- var <storage, read> targetToken : array<f32>;
12
+ var <storage, read> targetToken : array<u32>;
13
13
 
14
14
  @group(0) @binding(2)
15
15
 
@@ -42,16 +42,16 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
42
42
  let inputValue = input[token * u32(params.inputSize) + inputIndex];
43
43
  let gradient = outGradient[token * u32(params.vocabSize) + outputIndex];
44
44
  let dW = inputValue * gradient;
45
- dWeights += f32(dW);
45
+ dWeights += dW;
46
46
  }
47
- let vClap = weight[index] - params.lr * max(- 15.0, min(15.0, dWeights));
47
+ let vClap = weight[index] - params.lr * dWeights;
48
48
  weight[index] = vClap;
49
49
  if (inputIndex == 0u) {
50
50
  var dBias = 0.0;
51
51
  for (var token = 0u; token < u32(params.tokenCount); token++) {
52
- dBias += f32(outGradient[token * u32(params.vocabSize) + outputIndex]);
52
+ dBias += outGradient[token * u32(params.vocabSize) + outputIndex];
53
53
  }
54
- bias[outputIndex] = bias[outputIndex] - params.lr * max(- 15.0, min(15.0, dBias));
54
+ bias[outputIndex] = bias[outputIndex] - params.lr * dBias;
55
55
 
56
56
  }
57
57
  }
@@ -0,0 +1,35 @@
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
+
8
+ @group(0) @binding(2)
9
+ var<storage, read> rms: array<f32>;
10
+
11
+ @group(0) @binding(3)
12
+ var<storage, read_write> gradInput: array<f32>;
13
+
14
+ var<workgroup> partial: array<f32, 64>;
15
+
16
+ @compute @workgroup_size(64)
17
+ fn main(@builtin(local_invocation_index) lid: u32) {
18
+ let D = arrayLength(&input);
19
+ partial[lid] = gradOutput[lid] * input[lid];
20
+ workgroupBarrier();
21
+ var stride = 32u;
22
+ loop {
23
+ if (stride == 0u) {
24
+ break;
25
+ }
26
+ if (lid < stride) {
27
+ partial[lid] += partial[lid + stride];
28
+ }
29
+ workgroupBarrier();
30
+ stride = stride / 2u;
31
+ }
32
+ let dot = partial[0];
33
+ let r = rms[0];
34
+ gradInput[lid] = gradOutput[lid] / r - input[lid] * dot / (f32(D) * r * r * r);
35
+ }
@@ -0,0 +1,19 @@
1
+ @group(0) @binding(0)
2
+
3
+ var <storage, read> reduce: array<f32>;
4
+
5
+ @group(0) @binding(1)
6
+
7
+ var <storage, read> vector: array<f32>;
8
+
9
+ @group(0) @binding(2)
10
+
11
+ var <storage, read_write> output : array<f32>;
12
+
13
+ @compute @workgroup_size(64)
14
+
15
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
16
+ let x = id.x;
17
+ let rms = sqrt(reduce[0u] / f32(arrayLength(&vector)) + 1e-6);
18
+ output[x] = vector[x] / rms;
19
+ }
@@ -0,0 +1,37 @@
1
+
2
+ @group(0) @binding(0)
3
+ var<storage, read> input: array<f32>;
4
+
5
+ @group(0) @binding(1)
6
+ var<storage, read_write> out: array<f32>;
7
+
8
+ var<workgroup> partial: array<f32, 64>;
9
+
10
+ @compute @workgroup_size(64)
11
+ fn main(@builtin(local_invocation_index) lid: u32) {
12
+ var sum = 0.0;
13
+ var i = lid;
14
+ while (i < arrayLength(&input)) {
15
+ sum += input[i] * input[i];
16
+ i += 64u;
17
+ }
18
+ partial[lid] = sum;
19
+ workgroupBarrier();
20
+ var stride = 32u;
21
+
22
+ loop {
23
+ if (stride == 0u) {
24
+ break;
25
+ }
26
+
27
+ if (lid < stride) {
28
+ partial[lid] += partial[lid + stride];
29
+ }
30
+
31
+ workgroupBarrier();
32
+ stride = stride / 2u;
33
+ }
34
+ if (lid == 0u) {
35
+ out[0] = partial[0];
36
+ }
37
+ }
@@ -0,0 +1,25 @@
1
+ struct Params{
2
+ lr : f32
3
+ }
4
+
5
+ @group(0) @binding(0)
6
+ var <storage, read_write> posVec: array<f32>;
7
+
8
+ @group(0) @binding(1)
9
+
10
+ var <storage, read> outputGradient : array<f32>;
11
+
12
+
13
+ @group(0) @binding(2)
14
+
15
+ var <uniform> params: Params;
16
+
17
+ @compute @workgroup_size(64)
18
+
19
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
20
+ let x = id.x;
21
+ if(x >= arrayLength(&outputGradient)){
22
+ return;
23
+ }
24
+ posVec[x] -= params.lr * outputGradient[x];
25
+ }
@@ -0,0 +1,21 @@
1
+ @group(0) @binding(0)
2
+ var <storage, read> posVec: array<f32>;
3
+
4
+ @group(0) @binding(1)
5
+
6
+ var <storage, read> vecs : array<f32>;
7
+
8
+ @group(0) @binding(2)
9
+
10
+ var <storage, read_write> output: array<f32>;
11
+
12
+
13
+ @compute @workgroup_size(64)
14
+
15
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
16
+ let x = id.x;
17
+ if(x >= arrayLength(&vecs)){
18
+ return;
19
+ }
20
+ output[x] = vecs[x] + posVec[x];
21
+ }
@@ -0,0 +1,30 @@
1
+ struct Params{
2
+ size: u32
3
+ }
4
+
5
+ @group(0) @binding(0)
6
+
7
+ var <storage, read> a : array<f32>;
8
+
9
+ @group(0) @binding(1)
10
+
11
+ var <storage, read> b : array<f32>;
12
+
13
+ @group(0) @binding(2)
14
+
15
+ var <storage, read_write> output : array<f32>;
16
+ @group(0) @binding(3)
17
+
18
+ var <uniform> params : Params;
19
+
20
+ @compute @workgroup_size(64)
21
+
22
+ fn main(@builtin(global_invocation_id) id : vec3<u32>){
23
+ let index = id.x;
24
+ if(index >= params.size){
25
+ return;
26
+ }
27
+ let mainOut = a[index] + b[index];
28
+ output[index] = mainOut;
29
+ }
30
+