@mineproness/tensorloop 2.1.0 → 2.1.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mineproness/tensorloop",
3
- "version": "2.1.0",
3
+ "version": "2.1.11",
4
4
  "description": "Raw-JAVASCRIPT Based Matirx and AI LLM Package called Tensorloop.",
5
5
  "keywords": [
6
6
  "ai",
@@ -1,4 +1,5 @@
1
1
  import { Softmax } from '../../index.js';
2
+ import { GPUAttention } from '../gpiInit.js';
2
3
  import { Linear } from '../Linear/index.js'
3
4
 
4
5
  export class SelfAttention {
@@ -13,6 +14,7 @@ export class SelfAttention {
13
14
  score;
14
15
  softmax;
15
16
  weights;
17
+ gpu;
16
18
  constructor(embeddingSize, configs) {
17
19
  this.configs = configs
18
20
  this.softmax = new Softmax()
@@ -22,96 +24,29 @@ export class SelfAttention {
22
24
  this.value = new Linear(embeddingSize, embeddingSize, { save: { filename: [`${configs.dirname}/value.bin`, `${configs.dirname}/valueBias.bin`] } })
23
25
  }
24
26
  forward(vectors) {
27
+ if(!this.gpu) this.gpu = new GPUAttention(vectors[0].length, vectors.length);
25
28
  this.q = this.query.forward(vectors)
26
29
  this.v = this.value.forward(vectors)
27
30
  this.k = this.key.forward(vectors)
28
- const attentionSocres = []
29
- for (let i = 0; i < this.q.length; i++) {
30
- attentionSocres[i] = new Float32Array(this.k.length);
31
-
32
- for (let j = 0; j < this.k.length; j++) {
33
- if (j > i) {
34
- attentionSocres[i][j] = -1e9; // mask future
35
- continue;
36
- }
37
-
38
- let dot = 0;
39
-
40
- for (let d = 0; d < this.q[i].length; d++) {
41
- dot += this.q[i][d] * this.k[j][d];
42
- }
43
-
44
- attentionSocres[i][j] = dot / this.score;
45
- }
46
- }
47
-
31
+ const attentionSocres = this.gpu.attentionScores(this.q, this.k, this.score);
48
32
  const weights = this.softmax.forward(attentionSocres)
49
33
  this.weights = weights
50
- const output = [];
51
-
52
- for (let i = 0; i < weights.length; i++) {
53
- output[i] = new Float32Array(this.v[0].length);
54
-
55
- for (let j = 0; j < this.v.length; j++) {
56
- for (let d = 0; d < this.v[j].length; d++) {
57
- output[i][d] += weights[i][j] * this.v[j][d];
58
- }
59
- }
60
- }
61
-
34
+ const output = this.gpu.attentionOutput(weights, this.v)
62
35
  return output;
63
36
  }
64
- softmaxBack(probs, dOut) {
65
- const dIn = new Float32Array(probs.length);
66
37
 
67
- for (let i = 0; i < probs.length; i++) {
68
- let sum = 0;
69
- for (let j = 0; j < probs.length; j++) {
70
- const jacobian =
71
- i === j
72
- ? probs[i] * (1 - probs[i])
73
- : -probs[i] * probs[j];
74
-
75
- sum += jacobian * dOut[j];
76
- }
77
- dIn[i] = sum;
78
- }
79
-
80
- return dIn;
81
- }
82
38
  backward(dOutput, learningRate) {
83
- const dV = this.v.map((e) => new Float32Array(e.length));
84
- const dWeights = []
85
- for (let a = 0; a < this.weights.length; a++) {
86
- dWeights[a] = new Float32Array(this.weights[a].length)
87
- for (let j = 0; j < this.v.length; j++) {
88
- for (let r = 0; r < this.v[j].length; r++) {
89
- dWeights[a][j] += dOutput[a][r] * this.v[j][r]
90
- dV[j][r] += dOutput[a][r] * this.weights[a][j]
91
- }
92
- }
93
- }
94
- const dScores = []
95
- for (let t = 0; t < dWeights.length; t++) {
96
- dScores[t] = this.softmaxBack(this.weights[t], dWeights[t])
97
- }
98
- const dQ = this.q.map(q => new Float32Array(q.length));
99
- const dK = this.k.map(k => new Float32Array(k.length));
100
- for (let a = 0; a < this.q.length; a++) {
101
- for (let j = 0; j < this.k.length; j++) {
102
- if (j > a) continue;
103
- for (let r = 0; r < this.q[a].length; r++) {
104
- dQ[a][r] += dScores[a][j] * this.k[j][r] / this.score;
105
- dK[j][r] += dScores[a][j] * this.q[a][r] / this.score;
106
- }
107
- }
108
- }
39
+ const dWeights = this.gpu.dWeightsKernel(dOutput, this.v)
40
+ const dV = this.gpu.dVKernel(dOutput, this.weights);
41
+ const dScores = this.gpu.softmaxBackKernel(this.weights, dWeights)
42
+ const dQ = this.gpu.dQKernel(dScores, this.k, this.score)
43
+ const dK = this.gpu.dKKernel(dScores, this.q, this.score)
109
44
  const dInput = this.q.map(() => new Float32Array(this.q[0].length))
110
45
  const dq = this.query.backward(dQ, learningRate)
111
46
  const dk = this.key.backward(dK, learningRate)
112
47
  const dv = this.value.backward(dV, learningRate)
113
48
  for (let a = 0; a < this.q.length; a++) {
114
- for (let b = 0; b < dq.length; b++) {
49
+ for (let b = 0; b < dq[a].length; b++) {
115
50
  dInput[a][b] = dq[a][b] + dk[a][b] + dv[a][b]
116
51
  }
117
52
  }
package/src/gpiInit.js CHANGED
@@ -601,4 +601,121 @@ export class GELUGPU {
601
601
  backward(dOutput, input) {
602
602
  return this.cacheGB(input, dOutput)
603
603
  }
604
+ }
605
+
606
+ export class GPUAttention {
607
+ attentionScores;
608
+ attentionOutput;
609
+ dWeightsKernel;
610
+ dVKernel;
611
+ softmaxBackKernel;
612
+ dQKernel;
613
+ dKKernel;
614
+ constructor(embeddingSize, contextSize) {
615
+ this.attentionScores = gpu.createKernel(function (q, k, scale) {
616
+ const i = this.thread.y;
617
+ const j = this.thread.x;
618
+ if (j > i) {
619
+ return -1e9;
620
+ }
621
+ let sum = 0;
622
+ for (let d = 0; d < this.constants.D; d++) {
623
+ sum += q[i][d] * k[j][d];
624
+ }
625
+ return sum / scale;
626
+ }, {
627
+ output: [contextSize, contextSize],
628
+ constants: {
629
+ D: embeddingSize
630
+ }
631
+ });
632
+ this.attentionOutput = gpu.createKernel(function (weights, v) {
633
+ const i = this.thread.y;
634
+ const d = this.thread.x;
635
+ let sum = 0;
636
+ for (let j = 0; j < this.constants.CONTEXT; j++) {
637
+ sum += weights[i][j] * v[j][d];
638
+ }
639
+ return sum;
640
+ }, {
641
+ output: [embeddingSize, contextSize],
642
+ constants: {
643
+ CONTEXT: contextSize
644
+ },
645
+ });
646
+ this.dWeightsKernel = gpu.createKernel(function (dOutput, v) {
647
+ const a = this.thread.y;
648
+ const j = this.thread.x;
649
+ let sum = 0;
650
+ for (let r = 0; r < this.constants.D; r++) {
651
+ sum += dOutput[a][r] * v[j][r];
652
+ }
653
+ return sum;
654
+ }, {
655
+ output: [contextSize, contextSize],
656
+ pipeline: true,
657
+ immutable: true,
658
+ constants: {
659
+ D: embeddingSize
660
+ }
661
+ });
662
+ this.dVKernel = gpu.createKernel(function (dOutput, weights) {
663
+ const j = this.thread.y;
664
+ const r = this.thread.x;
665
+ let sum = 0;
666
+ for (let a = 0; a < this.constants.C; a++) {
667
+ sum += weights[a][j] * dOutput[a][r];
668
+ }
669
+ return sum;
670
+ }, {
671
+ output: [embeddingSize, contextSize],
672
+
673
+ constants: {
674
+ C: contextSize
675
+ }
676
+ });
677
+ this.softmaxBackKernel = gpu.createKernel(function (probs, dOut) {
678
+ const a = this.thread.y;
679
+ const i = this.thread.x;
680
+ let dot = 0;
681
+ for (let j = 0; j < this.constants.C; j++) {
682
+ dot += probs[a][j] * dOut[a][j];
683
+ }
684
+ return probs[a][i] * (dOut[a][i] - dot);
685
+ }, {
686
+ output: [contextSize, contextSize],
687
+ pipeline: true,
688
+ immutable: true,
689
+ constants: {
690
+ C: contextSize
691
+ }
692
+ });
693
+ this.dQKernel = gpu.createKernel(function (dScores, k, scale) {
694
+ const a = this.thread.y;
695
+ const r = this.thread.x;
696
+ let sum = 0;
697
+ for (let j = 0; j <= a; j++) {
698
+ sum += dScores[a][j] * k[j][r];
699
+ }
700
+ return sum / scale;
701
+ }, {
702
+ output: [embeddingSize, contextSize],
703
+
704
+ });
705
+ this.dKKernel = gpu.createKernel(function (dScores, q, scale) {
706
+ const j = this.thread.y;
707
+ const r = this.thread.x;
708
+ let sum = 0;
709
+ for (let a = j; a < this.constants.C; a++) {
710
+ sum += dScores[a][j] * q[a][r];
711
+ }
712
+ return sum / scale;
713
+ }, {
714
+ output: [embeddingSize, contextSize],
715
+
716
+ constants: {
717
+ C: contextSize
718
+ }
719
+ });
720
+ }
604
721
  }