@genai-fi/nanogpt 1.4.1 → 1.5.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 (75) hide show
  1. package/dist/api/beamer.d.ts +1 -0
  2. package/dist/api/beamer.js +15 -5
  3. package/dist/inference/Beamer.d.ts +14 -2
  4. package/dist/inference/Beamer.js +147 -89
  5. package/dist/inference/Generator.js +36 -22
  6. package/dist/inference/tokenisePrompt.d.ts +2 -1
  7. package/dist/inference/tokenisePrompt.js +10 -7
  8. package/dist/inference/types.d.ts +1 -0
  9. package/dist/layers/GQA.d.ts +44 -0
  10. package/dist/layers/{CausalSelfAttention.js → GQA.js} +21 -19
  11. package/dist/layers/HeadLayer.d.ts +12 -0
  12. package/dist/layers/HeadLayer.js +28 -0
  13. package/dist/layers/{CausalSelfAttention.d.ts → MHA.d.ts} +7 -3
  14. package/dist/layers/MHA.js +101 -0
  15. package/dist/layers/MLP.d.ts +5 -1
  16. package/dist/layers/MLP.js +25 -13
  17. package/dist/layers/RMSNorm.d.ts +2 -0
  18. package/dist/layers/RMSNorm.js +12 -8
  19. package/dist/layers/RoPECache.js +4 -3
  20. package/dist/layers/TransformerBlock.d.ts +2 -2
  21. package/dist/layers/TransformerBlock.js +4 -4
  22. package/dist/layers.d.ts +1 -1
  23. package/dist/layers.js +1 -1
  24. package/dist/loader/loadTransformers.js +17 -1
  25. package/dist/loader/save.js +18 -3
  26. package/dist/loader/types.d.ts +8 -2
  27. package/dist/main.js +2 -2
  28. package/dist/matMul16-CO1QhsRt.js +85 -0
  29. package/dist/models/Llama.d.ts +16 -0
  30. package/dist/models/Llama.js +89 -0
  31. package/dist/models/Qwen3.d.ts +16 -0
  32. package/dist/models/Qwen3.js +89 -0
  33. package/dist/models/config.d.ts +18 -1
  34. package/dist/models/config.js +1 -1
  35. package/dist/models/factory.js +11 -7
  36. package/dist/models/model.d.ts +1 -1
  37. package/dist/ops/dot16.js +1 -1
  38. package/dist/ops/globalNorm.js +12 -12
  39. package/dist/ops/grads/attentionMask.js +1 -1
  40. package/dist/ops/grads/matMul16.js +1 -1
  41. package/dist/ops/grads/qkv.js +1 -1
  42. package/dist/ops/grads/rope.js +1 -1
  43. package/dist/ops/grads/silu.d.ts +2 -0
  44. package/dist/ops/grads/silu.js +2 -0
  45. package/dist/ops/matMul16.d.ts +1 -1
  46. package/dist/ops/matMul16.js +1 -1
  47. package/dist/ops/normRMS.d.ts +1 -1
  48. package/dist/ops/normRMS.js +8 -8
  49. package/dist/ops/rope.d.ts +1 -1
  50. package/dist/ops/rope.js +1 -1
  51. package/dist/ops/silu.d.ts +3 -0
  52. package/dist/ops/silu.js +2 -0
  53. package/dist/ops/webgl/rope.js +6 -4
  54. package/dist/ops/webgpu/attentionMask.js +1 -1
  55. package/dist/ops/webgpu/index.js +1 -0
  56. package/dist/ops/webgpu/matMul16.js +50 -44
  57. package/dist/ops/webgpu/matMul16_program.d.ts +2 -2
  58. package/dist/ops/webgpu/matMul16_program.js +1 -1
  59. package/dist/ops/webgpu/normRMS.js +6 -6
  60. package/dist/ops/webgpu/normRMS16_program.d.ts +2 -1
  61. package/dist/ops/webgpu/normRMS16_program.js +4 -3
  62. package/dist/ops/webgpu/normRMS32_program.d.ts +2 -1
  63. package/dist/ops/webgpu/normRMS32_program.js +4 -3
  64. package/dist/ops/webgpu/qkv.js +1 -1
  65. package/dist/ops/webgpu/rope.js +99 -34
  66. package/dist/ops/webgpu/silu.d.ts +14 -0
  67. package/dist/ops/webgpu/silu.js +118 -0
  68. package/dist/{rope-C8EAiSGY.js → rope-BPu_uooz.js} +5 -4
  69. package/dist/silu-B6bvCgJ7.js +25 -0
  70. package/dist/training/Evaluator.js +4 -1
  71. package/dist/utilities/maxHeap.d.ts +16 -0
  72. package/dist/utilities/maxHeap.js +55 -0
  73. package/dist/utilities/parameters.js +33 -17
  74. package/package.json +1 -1
  75. package/dist/matMul16-DGtlziMn.js +0 -81
@@ -7,12 +7,12 @@ import s from "./normRMS32_program.js";
7
7
  import c from "./normRMS16_program.js";
8
8
  //#region lib/ops/webgpu/normRMS.ts
9
9
  function l(t) {
10
- let { x: l, gamma: u } = t.inputs, d = t.backend, f = o(d), p = n(l), m = u ? n(u) : !1, h = p || m, g = !h || p ? l : r(l), _ = u && (!h || m ? u : r(u)), v = _ ? [g, _] : [g], y = i(v, -1), b = h ? new c(f, y, !!u) : new s(f, y, !!u);
11
- if (_ && e(_.shape, [g.shape[g.shape.length - 1]], "Error in RMSNorm: "), l.shape.length !== 3) throw Error(`rmsNormGPU: input rank ${l.shape.length} not supported, only rank 3 is supported`);
12
- if (y.inSize !== g.shape[g.shape.length - 1]) throw Error(`rmsNormGPU: reduction size ${y.inSize} does not match expected size ${g.shape[g.shape.length - 1]}`);
13
- if (y.batchSize !== l.shape[0] * l.shape[1]) throw Error(`rmsNormGPU: batch size ${y.batchSize} does not match expected size ${l.shape[0] * l.shape[1]}`);
14
- let x = a(b, v, d);
15
- return h && !p && g.dispose(), h && !m && _ && _.dispose(), x;
10
+ let { x: l, gamma: u } = t.inputs, d = t.backend, f = t.attrs?.epsilon ?? 1e-8, p = o(d), m = n(l), h = u ? n(u) : !1, g = m || h, _ = !g || m ? l : r(l), v = u && (!g || h ? u : r(u)), y = v ? [_, v] : [_], b = i(y, -1), x = g ? new c(p, b, !!u, f) : new s(p, b, !!u, f);
11
+ if (v && e(v.shape, [_.shape[_.shape.length - 1]], "Error in RMSNorm: "), l.shape.length !== 3) throw Error(`rmsNormGPU: input rank ${l.shape.length} not supported, only rank 3 is supported`);
12
+ if (b.inSize !== _.shape[_.shape.length - 1]) throw Error(`rmsNormGPU: reduction size ${b.inSize} does not match expected size ${_.shape[_.shape.length - 1]}`);
13
+ if (b.batchSize !== l.shape[0] * l.shape[1]) throw Error(`rmsNormGPU: batch size ${b.batchSize} does not match expected size ${l.shape[0] * l.shape[1]}`);
14
+ let S = a(x, y, d);
15
+ return g && !m && _.dispose(), g && !h && v && v.dispose(), S;
16
16
  }
17
17
  t({
18
18
  kernelName: "RMSNorm",
@@ -2,8 +2,9 @@ import { backend_util } from '@tensorflow/tfjs-core';
2
2
  import { ReduceProgram } from './utils/reductions';
3
3
  import { DeviceInformation } from './utils/deviceInfo';
4
4
  export default class RMSProgram16 extends ReduceProgram {
5
+ private epsilon;
5
6
  private hasGamma;
6
- constructor(deviceInfo: DeviceInformation, reduceInfo: backend_util.ReduceInfo, hasGamma?: boolean);
7
+ constructor(deviceInfo: DeviceInformation, reduceInfo: backend_util.ReduceInfo, hasGamma?: boolean, epsilon?: number);
7
8
  getPreprocessSnippet(): string;
8
9
  getPostprocessSnippet(): string;
9
10
  getWriteSnippet(): string;
@@ -1,18 +1,19 @@
1
1
  import { ReduceProgram as e } from "./utils/reductions.js";
2
2
  //#region lib/ops/webgpu/normRMS16_program.ts
3
3
  var t = class extends e {
4
+ epsilon;
4
5
  hasGamma;
5
- constructor(e, t, n = !1) {
6
+ constructor(e, t, n = !1, r = 1e-8) {
6
7
  super(e, t, {
7
8
  reductionOp: "mean",
8
9
  elementwise: !0
9
- }, !0), this.shaderKey = "RMSNorm16", n && this.variableNames.push("gamma"), this.variableComponents = [1, 1], this.hasGamma = n;
10
+ }, !0), this.epsilon = r, this.shaderKey = `RMSNorm16_${n ? "Gamma" : "NoGamma"}_${this.epsilon}`, n && this.variableNames.push("gamma"), this.variableComponents = [1, 1], this.hasGamma = n;
10
11
  }
11
12
  getPreprocessSnippet() {
12
13
  return "candidate = candidate * candidate;";
13
14
  }
14
15
  getPostprocessSnippet() {
15
- return "bestValue = inverseSqrt(bestValue + 1e-8);";
16
+ return `bestValue = inverseSqrt(bestValue + ${this.epsilon});`;
16
17
  }
17
18
  getWriteSnippet() {
18
19
  return `
@@ -2,8 +2,9 @@ import { backend_util } from '@tensorflow/tfjs-core';
2
2
  import { ReduceProgram } from './utils/reductions';
3
3
  import { DeviceInformation } from './utils/deviceInfo';
4
4
  export default class RMSProgram32 extends ReduceProgram {
5
+ private epsilon;
5
6
  private hasGamma;
6
- constructor(deviceInfo: DeviceInformation, reduceInfo: backend_util.ReduceInfo, hasGamma?: boolean);
7
+ constructor(deviceInfo: DeviceInformation, reduceInfo: backend_util.ReduceInfo, hasGamma?: boolean, epsilon?: number);
7
8
  protected getPreprocessSnippet(): string;
8
9
  protected getPostprocessSnippet(): string;
9
10
  protected getWriteSnippet(): string;
@@ -1,18 +1,19 @@
1
1
  import { ReduceProgram as e } from "./utils/reductions.js";
2
2
  //#region lib/ops/webgpu/normRMS32_program.ts
3
3
  var t = class extends e {
4
+ epsilon;
4
5
  hasGamma;
5
- constructor(e, t, n = !1) {
6
+ constructor(e, t, n = !1, r = 1e-8) {
6
7
  super(e, t, {
7
8
  reductionOp: "mean",
8
9
  elementwise: !0
9
- }, !1), this.shaderKey = "RMSNorm32", n && this.variableNames.push("gamma"), this.variableComponents = [1, 1], this.hasGamma = n;
10
+ }, !1), this.epsilon = r, this.shaderKey = `RMSNorm32_${n ? "Gamma" : "NoGamma"}_${this.epsilon}`, n && this.variableNames.push("gamma"), this.variableComponents = [1, 1], this.hasGamma = n;
10
11
  }
11
12
  getPreprocessSnippet() {
12
13
  return "candidate = candidate * candidate;";
13
14
  }
14
15
  getPostprocessSnippet() {
15
- return "bestValue = inverseSqrt(bestValue + 1e-8);";
16
+ return `bestValue = inverseSqrt(bestValue + ${this.epsilon});`;
16
17
  }
17
18
  getWriteSnippet() {
18
19
  return `
@@ -1,6 +1,6 @@
1
1
  import { Fs as e, Ii as t } from "../../dist-Da20xy8E.js";
2
2
  import { isPackedTensor as n } from "../../utilities/packed.js";
3
- import { t as r } from "../../matMul16-DGtlziMn.js";
3
+ import { t as r } from "../../matMul16-CO1QhsRt.js";
4
4
  import { slice16 as i } from "../slice16.js";
5
5
  //#region lib/ops/webgpu/qkv.ts
6
6
  function a(t) {
@@ -20,13 +20,14 @@ var o = class {
20
20
  ];
21
21
  size = !0;
22
22
  uniforms = "pastLen: i32";
23
- constructor(e, t, n, a) {
24
- this.shaderKey = `Rope_${a}`, this.outputShape = [
23
+ interleaved;
24
+ constructor(e, t, n, a, o = !0) {
25
+ this.shaderKey = `Rope_${a}_${o ? "interleaved" : "split"}`, this.outputShape = [
25
26
  e,
26
27
  t,
27
28
  n,
28
29
  a
29
- ], this.dispatchLayout = r(this.outputShape), this.dispatch = i(this.dispatchLayout, this.outputShape, this.workgroupSize);
30
+ ], this.dispatchLayout = r(this.outputShape), this.dispatch = i(this.dispatchLayout, this.outputShape, this.workgroupSize), this.interleaved = o;
30
31
  }
31
32
  getUserCode() {
32
33
  let e = this.outputShape[3];
@@ -49,19 +50,19 @@ var o = class {
49
50
  d;
50
51
 
51
52
  if (d < rotaryDim) {
52
- let idx = (t + uniforms.pastLen) * uniforms.cosShape[1] + d / 2;
53
+ let half = rotaryDim / 2;
54
+ let idx = (t + uniforms.pastLen) * uniforms.cosShape[1] +
55
+ ${this.interleaved ? "d / 2" : "d % half"};
53
56
  let cos = cos[idx];
54
57
  let sin = sin[idx];
55
58
 
56
59
  let ownX = x[xIdx] * cos;
57
60
  var evenOdd = 0.0;
58
61
 
59
- if (d % 2 == 0) {
60
- // even index
61
- evenOdd = -x[xIdx + 1];
62
+ if (${this.interleaved ? "d % 2 == 0" : "d < half"}) {
63
+ evenOdd = -x[${this.interleaved ? "xIdx + 1" : "xIdx + half"}];
62
64
  } else {
63
- // odd index
64
- evenOdd = x[xIdx - 1];
65
+ evenOdd = x[${this.interleaved ? "xIdx - 1" : "xIdx - half"}];
65
66
  }
66
67
 
67
68
  outVal = fma(evenOdd, sin, ownX);
@@ -93,7 +94,7 @@ var o = class {
93
94
  size = !0;
94
95
  uniforms = "pastLen: i32";
95
96
  constructor(e, t, n, a) {
96
- this.shaderKey = `Rope_${a}`, this.outputShape = [
97
+ this.shaderKey = `Rope_${a}_interleaved_packed`, this.outputShape = [
97
98
  e,
98
99
  t,
99
100
  n,
@@ -117,21 +118,14 @@ var o = class {
117
118
  t * uniforms.outShapeStrides[2] +
118
119
  d;
119
120
 
120
- let idx = (t + uniforms.pastLen) * uniforms.cosShape[1] + d;
121
- let cos = cos[idx];
122
- let sin = sin[idx];
123
-
124
121
  let xPair = unpack2x16float(u32(x[xIdx]));
125
- let ownX = vec2<f32>(xPair.x * cos, xPair.y * cos);
126
-
127
- let evenOdd = vec2<f32>(
128
- -xPair.y,
129
- xPair.x
130
- );
122
+ let idx = (t + uniforms.pastLen) * uniforms.cosShape[1] + d;
123
+ let cosVal = cos[idx];
124
+ let sinVal = sin[idx];
131
125
 
132
126
  outVal = vec2<f32>(
133
- fma(evenOdd.x, sin, ownX.x),
134
- fma(evenOdd.y, sin, ownX.y)
127
+ fma(-xPair.y, sinVal, xPair.x * cosVal),
128
+ fma(xPair.x, sinVal, xPair.y * cosVal)
135
129
  );
136
130
 
137
131
  result[index] = i32(pack2x16float(outVal));
@@ -139,25 +133,96 @@ var o = class {
139
133
  }
140
134
  `;
141
135
  }
136
+ }, c = class {
137
+ variableNames = [
138
+ "x",
139
+ "sin",
140
+ "cos"
141
+ ];
142
+ outputShape;
143
+ shaderKey = "Rope";
144
+ dispatchLayout;
145
+ dispatch;
146
+ workPerThread = 2;
147
+ workgroupSize = [
148
+ 64,
149
+ 1,
150
+ 1
151
+ ];
152
+ size = !0;
153
+ uniforms = "pastLen: i32";
154
+ constructor(e, t, n, a) {
155
+ this.shaderKey = `Rope_${a}_split_packed`, this.outputShape = [
156
+ e,
157
+ t,
158
+ n,
159
+ a / 2
160
+ ], this.dispatchLayout = r(this.outputShape), this.dispatch = i(this.dispatchLayout, this.outputShape, this.workgroupSize, [
161
+ this.workPerThread,
162
+ 1,
163
+ 1
164
+ ]);
165
+ }
166
+ getUserCode() {
167
+ return `
168
+ ${a("index")} {
169
+ let halfPacked = uniforms.outShape[3] / 2;
170
+ for (var i = 0; i < ${this.workPerThread}; i = i + 1) {
171
+ let flatIndex = index * ${this.workPerThread} + i;
172
+ if (flatIndex < uniforms.size) {
173
+ let coords = getCoordsFromIndex(flatIndex); // [b, h, t, dPacked]
174
+ let d = coords[3];
175
+
176
+ if (d < halfPacked) {
177
+ let t = coords[2];
178
+ let xLow = unpack2x16float(u32(x[flatIndex]));
179
+ let xHigh = unpack2x16float(u32(x[flatIndex + halfPacked]));
180
+
181
+ let scalar0 = d * 2;
182
+ let scalar1 = scalar0 + 1;
183
+ let cacheOffset = (t + uniforms.pastLen) * uniforms.cosShape[1];
184
+
185
+ let cos0 = cos[cacheOffset + scalar0];
186
+ let sin0 = sin[cacheOffset + scalar0];
187
+ let cos1 = cos[cacheOffset + scalar1];
188
+ let sin1 = sin[cacheOffset + scalar1];
189
+
190
+ let outLow = vec2<f32>(
191
+ fma(-xHigh.x, sin0, xLow.x * cos0),
192
+ fma(-xHigh.y, sin1, xLow.y * cos1)
193
+ );
194
+ let outHigh = vec2<f32>(
195
+ fma(xLow.x, sin0, xHigh.x * cos0),
196
+ fma(xLow.y, sin1, xHigh.y * cos1)
197
+ );
198
+
199
+ result[flatIndex] = i32(pack2x16float(outLow));
200
+ result[flatIndex + halfPacked] = i32(pack2x16float(outHigh));
201
+ }
202
+ }
203
+ }
204
+ }
205
+ `;
206
+ }
142
207
  };
143
- function c(t) {
144
- let { x: r } = t.inputs, { pastLen: i, negSin: a, ropeCache: c } = t.attrs, l = t.backend, u = n(r), d = r.shape[0], f = r.shape[1], p = r.shape[2], m = u ? r.shape[3] * 2 : r.shape[3], h = a ? c.getNegSin() : c.getSin(), g = c.getCos();
145
- if (e(h.shape, g.shape, "Error in Rope: "), h.shape[0] < p + i) throw Error(`Sin tensor shape ${h.shape} is not compatible with seqLength ${p} and pastLen ${i}.`);
146
- if (h.shape[1] * 2 < m) throw Error(`Sin tensor shape ${h.shape} is not compatible with feature dimension ${m}.`);
147
- if (h.shape.length !== 3) throw Error(`Sin tensor must be 3-dimensional, but got shape ${h.shape}.`);
148
- let _ = u ? new s(d, f, p, m) : new o(d, f, p, m), v = [{
208
+ function l(t) {
209
+ let { x: r } = t.inputs, { pastLen: i, negSin: a, ropeCache: l, interleaved: u } = t.attrs, d = t.backend, f = n(r), p = r.shape[0], m = r.shape[1], h = r.shape[2], g = f ? r.shape[3] * 2 : r.shape[3], _ = a ? l.getNegSin() : l.getSin(), v = l.getCos();
210
+ if (e(_.shape, v.shape, "Error in Rope: "), _.shape[0] < h + i) throw Error(`Sin tensor shape ${_.shape} is not compatible with seqLength ${h} and pastLen ${i}.`);
211
+ if (_.shape[1] * 2 < g) throw Error(`Sin tensor shape ${_.shape} is not compatible with feature dimension ${g}.`);
212
+ if (_.shape.length !== 3) throw Error(`Sin tensor must be 3-dimensional, but got shape ${_.shape}.`);
213
+ let y = f ? u ? new s(p, m, h, g) : new c(p, m, h, g) : new o(p, m, h, g, u), b = [{
149
214
  type: "int32",
150
215
  data: [i]
151
- }], y = u ? "packedF16" : r.dtype;
152
- return l.runWebGPUProgram(_, [
216
+ }], x = f ? "packedF16" : r.dtype;
217
+ return d.runWebGPUProgram(y, [
153
218
  r,
154
- h,
155
- g
156
- ], y, v);
219
+ _,
220
+ v
221
+ ], x, b);
157
222
  }
158
223
  t({
159
224
  kernelName: "Rope",
160
225
  backendName: "webgpu",
161
- kernelFunc: c
226
+ kernelFunc: l
162
227
  });
163
228
  //#endregion
@@ -0,0 +1,14 @@
1
+ import { WebGPUProgram } from '@tensorflow/tfjs-backend-webgpu';
2
+ export declare class SiluProgram implements WebGPUProgram {
3
+ outputShape: number[];
4
+ shaderKey: string;
5
+ dispatchLayout: {
6
+ x: number[];
7
+ };
8
+ dispatch: [number, number, number];
9
+ variableNames: string[];
10
+ workgroupSize: [number, number, number];
11
+ size: boolean;
12
+ constructor(outputShape: number[]);
13
+ getUserCode(): string;
14
+ }
@@ -0,0 +1,118 @@
1
+ import { Ii as e } from "../../dist-Da20xy8E.js";
2
+ import { isPackedTensor as t } from "../../utilities/packed.js";
3
+ import { c as n, i as r } from "../../webgpu_util-DfODg6XI.js";
4
+ import { s as i } from "../../webgpu_program-B0PokuRJ.js";
5
+ //#region lib/ops/webgpu/silu.ts
6
+ var a = class {
7
+ outputShape;
8
+ shaderKey;
9
+ dispatchLayout;
10
+ dispatch;
11
+ variableNames = ["A"];
12
+ workgroupSize;
13
+ size = !0;
14
+ constructor(e) {
15
+ this.workgroupSize = [
16
+ 128,
17
+ 1,
18
+ 1
19
+ ], this.outputShape = e, this.dispatchLayout = n(this.outputShape), this.dispatch = r(this.dispatchLayout, this.outputShape, this.workgroupSize), this.shaderKey = "unary_silu";
20
+ }
21
+ getUserCode() {
22
+ return `
23
+ fn unaryOperation(x : f32) -> f32 {
24
+ return x / (1.0 + exp(-x));
25
+ }
26
+ ${i("index")} {
27
+ if (index < uniforms.size) {
28
+ let a = getAByOutputIndex(index);
29
+ setOutputAtIndex(index, unaryOperation(a));
30
+ }
31
+ }
32
+ `;
33
+ }
34
+ };
35
+ function o(e) {
36
+ let { x: t } = e.inputs, n = e.backend, r = new a(t.shape);
37
+ return n.runWebGPUProgram(r, [t], "float32");
38
+ }
39
+ e({
40
+ kernelName: "Silu",
41
+ backendName: "webgpu",
42
+ kernelFunc: o
43
+ });
44
+ var s = class {
45
+ variableNames = ["dy", "x"];
46
+ outputShape;
47
+ shaderKey = "SiluGrad16";
48
+ dispatchLayout;
49
+ dispatch;
50
+ workgroupSize = [
51
+ 128,
52
+ 1,
53
+ 1
54
+ ];
55
+ size = !0;
56
+ constructor(e) {
57
+ this.outputShape = e, this.dispatchLayout = n(this.outputShape), this.dispatch = r(this.dispatchLayout, this.outputShape, this.workgroupSize);
58
+ }
59
+ getUserCode() {
60
+ return `
61
+ fn activationGrad(dy: f32, X: f32) -> f32 {
62
+ let sigmoid = 1.0 / (1.0 + exp(-X));
63
+ return dy * (sigmoid + X * sigmoid * (1.0 - sigmoid));
64
+ }
65
+ ${i("index")} {
66
+ if (index < uniforms.size) {
67
+ let X = unpack2x16float(u32(x[index]));
68
+ let DY = unpack2x16float(u32(dy[index]));
69
+ let dsilu = vec2<f32>(
70
+ activationGrad(DY.x, X.x),
71
+ activationGrad(DY.y, X.y)
72
+ );
73
+ result[index] = i32(pack2x16float(dsilu));
74
+ }
75
+ }`;
76
+ }
77
+ }, c = class {
78
+ variableNames = ["dy", "x"];
79
+ outputShape;
80
+ shaderKey = "SiluGrad32";
81
+ dispatchLayout;
82
+ dispatch;
83
+ workgroupSize = [
84
+ 128,
85
+ 1,
86
+ 1
87
+ ];
88
+ size = !0;
89
+ constructor(e) {
90
+ this.outputShape = e, this.dispatchLayout = n(this.outputShape), this.dispatch = r(this.dispatchLayout, this.outputShape, this.workgroupSize);
91
+ }
92
+ getUserCode() {
93
+ return `
94
+ fn activationGrad(dy: f32, X: f32) -> f32 {
95
+ let sigmoid = 1.0 / (1.0 + exp(-X));
96
+ return dy * (sigmoid + X * sigmoid * (1.0 - sigmoid));
97
+ }
98
+ ${i("index")} {
99
+ if (index < uniforms.size) {
100
+ let X = getXByOutputIndex(index);
101
+ let DY = getDyByOutputIndex(index);
102
+ let dsilu = activationGrad(DY, X);
103
+ setOutputAtIndex(index, dsilu);
104
+ }
105
+ }`;
106
+ }
107
+ };
108
+ function l(e) {
109
+ let { dy: n, x: r } = e.inputs, i = e.backend, a = t(n), o = a ? new s(r.shape) : new c(r.shape);
110
+ return i.runWebGPUProgram(o, [n, r], a ? "packedF16" : "float32");
111
+ }
112
+ e({
113
+ kernelName: "SiluGrad",
114
+ backendName: "webgpu",
115
+ kernelFunc: l
116
+ });
117
+ //#endregion
118
+ export { a as SiluProgram };
@@ -7,18 +7,19 @@ var n = {
7
7
  inputsToSave: [],
8
8
  outputsToSave: [],
9
9
  gradFunc: (e, t, n) => {
10
- let { ropeCache: i } = n, a = r(e, i, 0, !0);
11
- return { x: () => a };
10
+ let { ropeCache: i, interleaved: a } = n, o = r(e, i, 0, !0, a ?? !0);
11
+ return { x: () => o };
12
12
  }
13
13
  };
14
14
  e(n);
15
15
  //#endregion
16
16
  //#region lib/ops/rope.ts
17
- function r(e, n, r, i = !1) {
17
+ function r(e, n, r, i = !1, a = !0) {
18
18
  return n.ensureRopeCache(e.shape[2] + r), t().runKernel("Rope", { x: e }, {
19
19
  pastLen: r,
20
20
  negSin: i,
21
- ropeCache: n
21
+ ropeCache: n,
22
+ interleaved: a
22
23
  });
23
24
  }
24
25
  //#endregion
@@ -0,0 +1,25 @@
1
+ import { Fi as e, ii as t } from "./dist-Da20xy8E.js";
2
+ //#region lib/ops/grads/silu.ts
3
+ var n = {
4
+ kernelName: "Silu",
5
+ inputsToSave: ["x"],
6
+ outputsToSave: [],
7
+ gradFunc: (e, t) => {
8
+ let [n] = t;
9
+ return { x: () => i(e, n) };
10
+ }
11
+ };
12
+ e(n);
13
+ //#endregion
14
+ //#region lib/ops/silu.ts
15
+ function r(e) {
16
+ return t().runKernel("Silu", { x: e });
17
+ }
18
+ function i(e, n) {
19
+ return t().runKernel("SiluGrad", {
20
+ dy: e,
21
+ x: n
22
+ });
23
+ }
24
+ //#endregion
25
+ export { r as n, n as r, i as t };
@@ -15,7 +15,10 @@ var r = class {
15
15
  }
16
16
  async calculateBatchLoss(r, i, a, o) {
17
17
  let [s, c] = e(() => {
18
- let e = this.model.forward({ training: !1 }, r), s = n(e, i, o, a), c = t(e, i);
18
+ let e = this.model.forward({
19
+ training: !1,
20
+ mixedPrecision: !0
21
+ }, r), s = n(e, i, o, a), c = t(e, i);
19
22
  return e.dispose(), [s, c];
20
23
  }), l = await s.array(), u = await c.array(), d = l, f = u;
21
24
  return c.dispose(), s.dispose(), Array.isArray(d) ? d.map((e) => ({
@@ -0,0 +1,16 @@
1
+ export default class MaxHeap<T> {
2
+ private readonly fn;
3
+ private readonly heap;
4
+ constructor(fn: (a: T) => number);
5
+ get length(): number;
6
+ get size(): number;
7
+ get values(): T[];
8
+ isEmpty(): boolean;
9
+ peek(): T | undefined;
10
+ push(item: T): void;
11
+ pop(): T | undefined;
12
+ clear(): void;
13
+ toArray(): T[];
14
+ private siftUp;
15
+ private siftDown;
16
+ }
@@ -0,0 +1,55 @@
1
+ //#region lib/utilities/maxHeap.ts
2
+ var e = class {
3
+ fn;
4
+ heap = [];
5
+ constructor(e) {
6
+ this.fn = e;
7
+ }
8
+ get length() {
9
+ return this.heap.length;
10
+ }
11
+ get size() {
12
+ return this.heap.length;
13
+ }
14
+ get values() {
15
+ return [...this.heap];
16
+ }
17
+ isEmpty() {
18
+ return this.heap.length === 0;
19
+ }
20
+ peek() {
21
+ return this.heap[0];
22
+ }
23
+ push(e) {
24
+ this.heap.push(e), this.siftUp(this.heap.length - 1);
25
+ }
26
+ pop() {
27
+ if (this.heap.length === 0) return;
28
+ let e = this.heap[0], t = this.heap.pop();
29
+ return this.heap.length > 0 && t !== void 0 && (this.heap[0] = t, this.siftDown(0)), e;
30
+ }
31
+ clear() {
32
+ this.heap.length = 0;
33
+ }
34
+ toArray() {
35
+ return [...this.heap];
36
+ }
37
+ siftUp(e) {
38
+ let t = e;
39
+ for (; t > 0;) {
40
+ let e = Math.floor((t - 1) / 2);
41
+ if (this.fn(this.heap[t]) <= this.fn(this.heap[e])) break;
42
+ [this.heap[t], this.heap[e]] = [this.heap[e], this.heap[t]], t = e;
43
+ }
44
+ }
45
+ siftDown(e) {
46
+ let t = e;
47
+ for (;;) {
48
+ let e = t * 2 + 1, n = t * 2 + 2, r = t;
49
+ if (e < this.heap.length && this.fn(this.heap[e]) > this.fn(this.heap[r]) && (r = e), n < this.heap.length && this.fn(this.heap[n]) > this.fn(this.heap[r]) && (r = n), r === t) break;
50
+ [this.heap[t], this.heap[r]] = [this.heap[r], this.heap[t]], t = r;
51
+ }
52
+ }
53
+ };
54
+ //#endregion
55
+ export { e as default };
@@ -1,27 +1,43 @@
1
+ import { swigluHidden as e } from "../layers/MLP.js";
1
2
  //#region lib/utilities/parameters.ts
2
- var e = 4;
3
- function t(e) {
4
- return 4 * e.nEmbed * e.nEmbed + (e.mlpFactor * e.nEmbed * e.nEmbed + e.nEmbed * e.mlpFactor * e.nEmbed);
3
+ var t = 4;
4
+ function n(t) {
5
+ let n;
6
+ switch (t.modelType) {
7
+ case "GenAI_NanoGPT_v1":
8
+ case "GenAI_NanoGPT_v2":
9
+ n = e(t.nEmbed, t.mlpFactor) * t.nEmbed * 2;
10
+ break;
11
+ case "llama":
12
+ case "qwen3":
13
+ n = Math.max(256, Math.ceil(t.nEmbed * (8 / 3) / 256) * 256) * t.nEmbed * 3;
14
+ break;
15
+ default: n = 0;
16
+ }
17
+ return n;
5
18
  }
6
- function n(e) {
7
- let t = e.vocabSize * e.nEmbed, n = e.nLayer * (4 * e.nEmbed * e.nEmbed), r = e.nLayer * (e.mlpFactor * e.nEmbed * e.nEmbed + e.nEmbed * e.mlpFactor * e.nEmbed);
8
- return t + n + r;
19
+ function r(e) {
20
+ return 4 * e.nEmbed * e.nEmbed + n(e);
9
21
  }
10
- function r(t) {
11
- return n(t) * e;
22
+ function i(e) {
23
+ let t = e.modelType === "llama" ? e.vocabSize * e.nEmbed * 2 : e.vocabSize * e.nEmbed, r = e.nLayer * (4 * e.nEmbed * e.nEmbed), i = n(e) * e.nLayer;
24
+ return t + r + i;
12
25
  }
13
- function i(t, n) {
14
- let i = r(t), a = i * 2, o = i * 2, s = n * t.blockSize * t.nEmbed * e;
15
- return i + a + o + s;
26
+ function a(e) {
27
+ return i(e) * t;
16
28
  }
17
- function a(e, t) {
29
+ function o(e, n) {
30
+ let r = a(e), i = r * 2, o = r * 2, s = n * e.blockSize * e.nEmbed * t;
31
+ return r + i + o + s;
32
+ }
33
+ function s(e, t) {
18
34
  return {
19
- numParams: n(e),
20
- modelMemoryMB: r(e) / (1024 * 1024),
21
- trainingMemoryMB: i(e, t) / (1024 * 1024)
35
+ numParams: i(e),
36
+ modelMemoryMB: a(e) / (1024 * 1024),
37
+ trainingMemoryMB: o(e, t) / (1024 * 1024)
22
38
  };
23
39
  }
24
- function o(e) {
40
+ function c(e) {
25
41
  if (e.nEmbed % e.nHead !== 0) throw Error("nEmbed_divisible_nHead");
26
42
  if (e.blockSize <= 0) throw Error("blockSize_positive");
27
43
  if (e.vocabSize <= 0) throw Error("vocabSize_positive");
@@ -35,4 +51,4 @@ function o(e) {
35
51
  if (!Number.isInteger(e.vocabSize)) throw Error("vocabSize_integer");
36
52
  }
37
53
  //#endregion
38
- export { t as estimateLayerParameters, r as estimateMemoryUsage, n as estimateParameterCount, a as estimateResources, i as estimateTrainingMemoryUsage, o as validateConfig };
54
+ export { r as estimateLayerParameters, a as estimateMemoryUsage, i as estimateParameterCount, s as estimateResources, o as estimateTrainingMemoryUsage, c as validateConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genai-fi/nanogpt",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",