@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
@@ -20,6 +20,7 @@ export default class BeamAPI {
20
20
  off<E extends keyof BeamEvents>(event: E, listener: BeamEvents[E]): void;
21
21
  cancel(id?: string): void;
22
22
  private startJob;
23
+ more(id: string): string | undefined;
23
24
  create(conversation: Conversation[], options: BeamerOptions): string;
24
25
  }
25
26
  export {};
@@ -25,10 +25,10 @@ var r = class {
25
25
  } else for (let e of this._jobs.values()) e.canceled = !0, e.beamer.cancel();
26
26
  }
27
27
  startJob(e) {
28
- this._busyCount++, this.ee.emit("status", "busy"), e.beamer.beam(e.conversation, e.options, (t) => {
28
+ this._busyCount++, this.ee.emit("status", "busy"), e.beamer.beam((t) => {
29
29
  this.ee.emit("progress", e.id, t);
30
30
  }).then((t) => {
31
- this._busyCount--, this._busyCount === 0 && this.ee.emit("status", "ready"), this.ee.emit("done", e.id, t), this._jobs.delete(e.id);
31
+ this._busyCount--, this._busyCount === 0 && this.ee.emit("status", "ready"), this.ee.emit("done", e.id, t);
32
32
  let n = this._queue.shift();
33
33
  n && this.startJob(n);
34
34
  }).catch((t) => {
@@ -37,15 +37,25 @@ var r = class {
37
37
  n && this.startJob(n);
38
38
  });
39
39
  }
40
+ more(e) {
41
+ let t = this._jobs.get(e);
42
+ if (t) {
43
+ if (this._busyCount > 0) return this._queue.push(t), e;
44
+ this.startJob(t);
45
+ }
46
+ }
40
47
  create(e, r) {
41
- let i = t(), a = {
48
+ let i = t(), a = new n(this._model, this._tokeniser);
49
+ a.begin(e, r);
50
+ let o = {
42
51
  id: i,
43
- beamer: new n(this._model, this._tokeniser),
52
+ beamer: a,
44
53
  canceled: !1,
45
54
  conversation: e,
46
55
  options: r
47
56
  };
48
- return this._jobs.set(i, a), this._busyCount > 0 ? (this._queue.push(a), i) : (this.startJob(a), i);
57
+ for (let [e, t] of this._jobs.entries()) t.beamer.dispose(), this._jobs.delete(e);
58
+ return this._jobs.set(i, o), this._busyCount > 0 ? (this._queue.push(o), i) : (this.startJob(o), i);
49
59
  }
50
60
  };
51
61
  //#endregion
@@ -6,13 +6,25 @@ export default class Beamer {
6
6
  private readonly tokeniser;
7
7
  private actualTokeniser;
8
8
  private active;
9
+ private options;
10
+ private conversation;
11
+ private heap;
12
+ private hasRoot;
13
+ private totalCandidates;
14
+ private seen;
9
15
  constructor(model: Model<ModelForwardAttributes>, tokeniser: ITokeniser);
10
16
  private shouldTerminate;
11
17
  private initialise;
12
18
  private tokeniseConversation;
13
19
  private createInitialContext;
14
20
  private appendTokenToContext;
15
- private batchedNextProbabilities;
16
21
  cancel(): void;
17
- beam(conversation: Conversation[], options: BeamerOptions, onStep?: (beams: IBeam[]) => void): Promise<IBeam[]>;
22
+ begin(conversation: Conversation[], options: BeamerOptions): void;
23
+ private expand;
24
+ private pushNextChild;
25
+ private entryToBeam;
26
+ next(): Promise<IBeam | null>;
27
+ private _next;
28
+ beam(onStep?: (beams: IBeam[]) => void): Promise<IBeam[]>;
29
+ dispose(): void;
18
30
  }
@@ -2,18 +2,26 @@ import e from "../tokeniser/CharTokeniser.js";
2
2
  import { L as t, V as n, Y as r, _n as i, _r as a, di as o, xt as s } from "../dist-Da20xy8E.js";
3
3
  import c from "../utilities/topP.js";
4
4
  import { CHARS as l, padArray as u } from "./utilities.js";
5
+ import d from "../utilities/maxHeap.js";
5
6
  //#region lib/inference/Beamer.ts
6
- function d(e, t) {
7
- return e.map((e, t) => ({
7
+ function f(e, t) {
8
+ let n = e.map((e, t) => ({
8
9
  token: t,
9
10
  prob: e
10
- })).filter((e) => e.prob > 0).sort((e, t) => t.prob - e.prob).slice(0, Math.max(1, t));
11
+ })).filter((e) => e.prob > 0).sort((e, t) => t.prob - e.prob);
12
+ return t === void 0 ? n : n.slice(0, Math.max(1, t));
11
13
  }
12
- var f = class {
14
+ var p = class {
13
15
  model;
14
16
  tokeniser;
15
17
  actualTokeniser;
16
18
  active = !1;
19
+ options = null;
20
+ conversation = [];
21
+ heap = new d((e) => e.score);
22
+ hasRoot = !1;
23
+ totalCandidates = 0;
24
+ seen = /* @__PURE__ */ new Set();
17
25
  constructor(e, t) {
18
26
  this.model = e, this.tokeniser = t, this.actualTokeniser = t;
19
27
  }
@@ -51,100 +59,150 @@ var f = class {
51
59
  contextLength: c
52
60
  };
53
61
  }
54
- async batchedNextProbabilities(e, t, i) {
55
- if (e.length === 0) return [];
56
- let a = e[0], l = e.slice();
57
- for (; l.length < t;) l.push(a);
58
- let u = n(l.map((e) => e.context)), d = this.model.forward({
62
+ cancel() {
63
+ this.active = !1;
64
+ }
65
+ begin(e, t) {
66
+ if (!(!t || t.beams < 1 || t.maxBeamLength < 1)) {
67
+ if (this.options) throw Error("Beamer has already been initialized.");
68
+ this.conversation = e, this.options = t, this.initialise(t);
69
+ }
70
+ }
71
+ async expand(e, t) {
72
+ if (e.length === 0) return;
73
+ if (e.length > t) throw Error(`Number of nodes (${e.length}) exceeds fixed batch size (${t}).`);
74
+ let i = [...e];
75
+ if (e.length < t) for (; i.length < t;) i.push(e[e.length - 1]);
76
+ let a = n(i.map((e) => e.context)), l = this.model.forward({
59
77
  training: !1,
60
78
  mixedPrecision: !0
61
- }, u), f = l.map((e) => Math.max(0, e.contextLength - 1)), p = o(() => {
62
- let e = s(f, this.model.config.blockSize).expandDims(2);
63
- return r(d.mul(e).sum(1));
64
- }), m = e.length, h = m < t ? p.slice([0, 0], [m, this.model.config.vocabSize]) : p, g = await h.array();
65
- h !== p && h.dispose(), p.dispose(), d.dispose(), u.dispose();
66
- let _ = i.topP ?? 1;
67
- return g.map((e) => c(e, _));
79
+ }, a), u = i.map((e) => Math.max(0, e.contextLength - 1)), d = o(() => {
80
+ let e = s(u, this.model.config.blockSize).expandDims(2);
81
+ return r(l.mul(e).sum(1));
82
+ }), p = e.length, m = p < t ? d.slice([0, 0], [p, this.model.config.vocabSize]) : d, h = await m.array();
83
+ m !== d && m.dispose(), d.dispose(), l.dispose(), a.dispose();
84
+ let g = this.options?.topP ?? 1, _ = h.map((e) => f(c(e, g), this.options?.topK));
85
+ for (let t = 0; t < e.length; t++) e[t].sortedChildren = _[t], this.totalCandidates += _[t].length - 1;
68
86
  }
69
- cancel() {
70
- this.active = !1;
87
+ pushNextChild(e) {
88
+ if (!e.sortedChildren || e.nextChild >= e.sortedChildren.length) return;
89
+ let t = e.nextChild++, n = e.sortedChildren[t].token, r = e.sortedChildren[t].prob, i = this.options.maxBeamLength, a = this.shouldTerminate(this.options.allowSpecial ?? !1, n), o = this.actualTokeniser.decode([n]), s = e.tokens.length + 1 > i, c = this.options.endOnWhiteSpace === !0 && s && /\s/.test(o), l = this.options.endOnWhiteSpace ? e.tokens.length + 1 >= i + 10 : e.tokens.length + 1 >= i;
90
+ this.heap.push({
91
+ score: e.score * r,
92
+ parent: e,
93
+ idx: t,
94
+ tokenId: n,
95
+ tokenText: o,
96
+ probability: r,
97
+ terminated: a || c || l,
98
+ reason: a ? "token" : c ? "whitespace" : l ? "length" : void 0
99
+ });
71
100
  }
72
- async beam(e, t, n) {
73
- if (!t || t.beams < 1 || t.maxBeamLength < 1) return [];
74
- let r = Math.max(8, t.beams);
75
- this.initialise(t), this.active = !0;
76
- let i = await this.tokeniseConversation(e), a = this.createInitialContext(i), o = [{
77
- tokens: [],
78
- score: 1,
79
- text: "",
80
- terminated: !1,
81
- context: a.context,
82
- contextLength: a.contextLength,
83
- candidates: 0
84
- }], s = t.maxBeamLength, c = t.endOnWhiteSpace === !0 ? Math.max(s, t.maxLength ?? s + this.model.config.blockSize) : s, l = Date.now(), u = 0;
85
- for (let e = 0; e < c && this.active; e++) {
86
- let e = o.filter((e) => !e.terminated);
87
- if (e.length === 0) break;
88
- let i = await this.batchedNextProbabilities(e, r, t), a = [];
89
- for (let n = 0; n < e.length; n++) {
90
- let o = e[n], c = i[n], l = d(c, t.topK ? Math.min(t.topK, r) : Math.max(1, r));
91
- for (let e of l) {
92
- let n = this.actualTokeniser.decode([e.token]), r = this.shouldTerminate(t.allowSpecial ?? !1, e.token), i = o.tokens.length + 1 > s, c = t.endOnWhiteSpace === !0 && i && /\s/.test(n), l = c && o.tokens.length > 0 && /^\s/.test(n);
93
- a.push({
94
- parent: o,
95
- token: e.token,
96
- tokenText: n,
97
- score: o.score * e.prob,
98
- terminatedByToken: r,
99
- terminatedByWhitespace: c,
100
- dropLeadingWhitespaceTerminator: l
101
- });
102
- }
101
+ entryToBeam(e) {
102
+ let t = e.reason === "whitespace" && e.parent.tokens.length > 0 && /^\s/.test(e.tokenText), n = e.parent.tokens.map((t, n) => ({
103
+ token: t,
104
+ score: e.parent.probabilities[n],
105
+ text: this.actualTokeniser.decode([t]),
106
+ terminated: e.terminated,
107
+ confidence: null,
108
+ logits: null,
109
+ scores: null,
110
+ hiddenStates: null,
111
+ attention: null,
112
+ loss: null,
113
+ multinomialRand: null
114
+ }));
115
+ n.push({
116
+ token: e.tokenId,
117
+ score: e.probability,
118
+ text: e.tokenText,
119
+ terminated: e.terminated,
120
+ confidence: null,
121
+ logits: null,
122
+ scores: null,
123
+ hiddenStates: null,
124
+ attention: null,
125
+ loss: null,
126
+ multinomialRand: null
127
+ });
128
+ let r = {
129
+ tokens: t ? e.parent.tokens.slice() : [...e.parent.tokens, e.tokenId],
130
+ score: e.score,
131
+ text: t ? e.parent.text : e.parent.text + e.tokenText,
132
+ candidates: this.totalCandidates,
133
+ _output: n
134
+ };
135
+ if (!this.options?.keepDuplicates) {
136
+ if (this.seen.has(r.text.trim())) return this.totalCandidates--, null;
137
+ this.seen.add(r.text.trim());
138
+ }
139
+ return r;
140
+ }
141
+ async next() {
142
+ this.active = !0;
143
+ let e = await this._next();
144
+ return this.active = !1, e;
145
+ }
146
+ async _next() {
147
+ if (!this.options || !this.conversation) throw Error("Beamer not properly initialized with options and conversation.");
148
+ if (!this.hasRoot) {
149
+ let e = await this.tokeniseConversation(this.conversation), t = this.createInitialContext(e), n = {
150
+ tokens: [],
151
+ text: "",
152
+ score: 1,
153
+ context: t.context,
154
+ contextLength: t.contextLength,
155
+ terminated: !1,
156
+ nextChild: 0,
157
+ sortedChildren: void 0,
158
+ probabilities: []
159
+ };
160
+ this.totalCandidates = 1, await this.expand([n], 8), this.pushNextChild(n), this.hasRoot = !0;
161
+ }
162
+ for (; this.heap.size && this.active;) {
163
+ if (this.heap.peek().terminated) {
164
+ let e = this.heap.pop();
165
+ this.pushNextChild(e.parent);
166
+ let t = this.entryToBeam(e);
167
+ if (!t) continue;
168
+ return t;
103
169
  }
104
- let c = o.filter((e) => e.terminated), f = c.slice();
105
- a.sort((e, t) => t.score - e.score);
106
- for (let e of a) {
107
- if (f.length >= r) break;
108
- let t = e.terminatedByToken || e.terminatedByWhitespace, n = !e.dropLeadingWhitespaceTerminator, i = n ? e.parent.tokens.concat(e.token) : e.parent.tokens.slice(), a = e.terminatedByToken || e.dropLeadingWhitespaceTerminator ? e.parent.text : e.parent.text + e.tokenText, o = n ? this.appendTokenToContext(e.parent.context, e.parent.contextLength, e.token) : {
109
- context: e.parent.context.clone(),
110
- contextLength: e.parent.contextLength
111
- }, s = e.parent._output?.slice() ?? [];
112
- n && s.push({
113
- token: e.token,
114
- score: e.score,
115
- text: e.tokenText,
116
- terminated: t,
117
- confidence: null,
118
- logits: null,
119
- scores: null,
120
- hiddenStates: null,
121
- attention: null,
122
- loss: null,
123
- multinomialRand: null
124
- }), f.push({
125
- tokens: i,
126
- score: e.score,
127
- text: a,
128
- terminated: t,
129
- context: o.context,
130
- contextLength: o.contextLength,
131
- _output: s,
132
- candidates: u
170
+ let e = [];
171
+ for (; e.length < 8 && this.heap.size && !this.heap.peek().terminated;) {
172
+ let t = this.heap.pop();
173
+ this.pushNextChild(t.parent), e.push({
174
+ text: t.parent.text + t.tokenText,
175
+ tokens: [...t.parent.tokens, t.tokenId],
176
+ score: t.score,
177
+ ...this.appendTokenToContext(t.parent.context, t.parent.contextLength, t.tokenId),
178
+ terminated: t.terminated,
179
+ nextChild: 0,
180
+ sortedChildren: void 0,
181
+ probabilities: [...t.parent.probabilities, t.probability]
133
182
  });
134
183
  }
135
- if (u += a.length - f.length + c.length, o.forEach((e) => e.context.dispose()), f.length === 0) break;
136
- o = f, n && Date.now() - l >= 40 && (n(o.slice(0, t.beams)), l = Date.now());
184
+ await this.expand(e, 8);
185
+ for (let t of e) this.pushNextChild(t);
137
186
  }
138
- this.active = !1, u += o.length;
139
- let f = o.slice().sort((e, t) => t.score - e.score), p = [], m = /* @__PURE__ */ new Set();
140
- for (let e of f) {
141
- let n = e.text.trim();
142
- if (m.has(n) || (m.add(n), p.push(e)), p.length >= t.beams) break;
187
+ return null;
188
+ }
189
+ async beam(e) {
190
+ this.active = !0;
191
+ let t = [];
192
+ for (; t.length < (this.options?.beams ?? 8);) {
193
+ let n = await this._next();
194
+ if (!n) break;
195
+ t.push(n), e?.(t);
143
196
  }
144
- return o.forEach((e) => {
145
- e.context.dispose(), e.candidates = u;
146
- }), p;
197
+ return this.active = !1, t.forEach((e) => {
198
+ e.candidates = this.totalCandidates;
199
+ }), t;
200
+ }
201
+ dispose() {
202
+ this.active = !1, this.heap.values.forEach((e) => {
203
+ e.parent.context.dispose();
204
+ }), this.heap.clear();
147
205
  }
148
206
  };
149
207
  //#endregion
150
- export { f as default };
208
+ export { p as default };
@@ -4,13 +4,13 @@ import { A as n, Ct as r, I as i, Y as a, _r as o, an as s, di as c, oi as l, yt
4
4
  import d from "../utilities/multinomialCPU.js";
5
5
  import f from "../utilities/topP.js";
6
6
  import { sparseSoftmaxCrossEntropy as p } from "../training/sparseCrossEntropy.js";
7
- import m from "./tokenisePrompt.js";
8
- import { CHARS as h, getTokenConfidence as g, padArray as _ } from "./utilities.js";
7
+ import m, { tensorFromTokens as h } from "./tokenisePrompt.js";
8
+ import { CHARS as g, getTokenConfidence as _, padArray as v } from "./utilities.js";
9
9
  //#region lib/inference/Generator.ts
10
- function v(e) {
10
+ function y(e) {
11
11
  return Array.isArray(e);
12
12
  }
13
- var y = class extends e {
13
+ var b = class extends e {
14
14
  model;
15
15
  tokeniser;
16
16
  active = !1;
@@ -34,7 +34,7 @@ var y = class extends e {
34
34
  return t === this.actualTokeniser.eosToken || t === n;
35
35
  }
36
36
  async _generateToken(e, t, o) {
37
- let m = o?.temperature ?? 1, h = o?.topK, _ = o?.topP, v = o?.usePadding ?? !1, y = {
37
+ let m = o?.temperature ?? 1, h = o?.topK, g = o?.topP, v = o?.usePadding ?? !1, y = {
38
38
  training: !1,
39
39
  attentionScores: o?.outputAttention ? { attentionOut: [] } : void 0,
40
40
  cache: t,
@@ -68,10 +68,10 @@ var y = class extends e {
68
68
  ])), e.dispose());
69
69
  }), c.dispose(), [f.div(m).squeeze([1]), h];
70
70
  }), S, C, w, T = Math.random();
71
- if (_) {
71
+ if (g) {
72
72
  let e = a(b), t = await e.array();
73
73
  e.dispose();
74
- let n = f(t, _);
74
+ let n = f(t, g);
75
75
  (o?.outputScores || o?.outputConfidence) && (C = t), S = d(n, T);
76
76
  } else if (h) {
77
77
  let { values: e, indices: t } = n(b, h), i = r(e, 1);
@@ -129,7 +129,7 @@ var y = class extends e {
129
129
  outputTensor: S,
130
130
  token: D,
131
131
  text: O,
132
- confidence: o?.outputConfidence && C ? g(C[0]) : null,
132
+ confidence: o?.outputConfidence && C ? _(C[0]) : null,
133
133
  score: o?.outputScore && C ? C[0][D] : null,
134
134
  logits: o?.outputLogits ? (await b.array())[0] : null,
135
135
  scores: o?.outputScores && C ? C[0] : null,
@@ -152,28 +152,42 @@ var y = class extends e {
152
152
  content: "",
153
153
  _timestamp: Date.now()
154
154
  }), n = !0, this.resetCache(!e?.noCache)) : (this.lastToken < 0 || t) && this.resetCache(!e?.noCache);
155
- let r = this.lastToken >= 0 && this.cache ? i([this.lastToken], [1, 1], "int32") : await m(this.actualTokeniser, this.model.config.blockSize, t ? n ? this.outputConversation.slice(0, -1) : this.outputConversation : void 0, n ? e : {
155
+ let r = this.outputConversation[this.outputConversation.length - 1];
156
+ r.content.length > 0 && (!r._output || r._output.length === 0) && (r._output = this.actualTokeniser.encode(r.content).map((e) => ({
157
+ token: e,
158
+ text: this.actualTokeniser.decode([e]),
159
+ confidence: 1,
160
+ score: 1,
161
+ logits: null,
162
+ hiddenStates: null,
163
+ scores: null,
164
+ attention: null,
165
+ loss: null,
166
+ multinomialRand: null,
167
+ terminated: !1
168
+ })));
169
+ let a = this.lastToken >= 0 && this.cache ? i([this.lastToken], [1, 1], "int32") : h(await m(this.actualTokeniser, this.model.config.blockSize, t ? n ? this.outputConversation.slice(0, -1) : this.outputConversation : void 0, n ? e : {
156
170
  ...e,
157
171
  continuation: !0
158
- }), a = e?.maxLength ?? 1e3;
159
- for (let t = 0; t < a && this.active; t++) {
160
- let n = await this._generateToken(r, this.cache ? this.cache : void 0, {
172
+ })), s = e?.maxLength ?? 1e3;
173
+ for (let t = 0; t < s && this.active; t++) {
174
+ let n = await this._generateToken(a, this.cache ? this.cache : void 0, {
161
175
  ...e,
162
176
  usePadding: !this.cache
163
177
  });
164
- if (this.cache) r.dispose(), r = n.outputTensor;
178
+ if (this.cache) a.dispose(), a = n.outputTensor;
165
179
  else {
166
- let e = r;
167
- r = o([r, n.outputTensor], 1), e.dispose();
180
+ let e = a;
181
+ a = o([a, n.outputTensor], 1), e.dispose();
168
182
  }
169
- let i = this.outputConversation[this.outputConversation.length - 1];
183
+ let r = this.outputConversation[this.outputConversation.length - 1];
170
184
  if (this.cache || n.outputTensor.dispose(), n.terminated) {
171
- i._completed = !0;
185
+ r._completed = !0;
172
186
  break;
173
187
  }
174
- t === a - 1 && a > 1 && (i._completed = !0, n.terminated = !0), i.content += n.text, i._output ||= [], i._output.push(n);
188
+ t === s - 1 && s > 1 && (r._completed = !0, n.terminated = !0), r.content += n.text, r._output ||= [], r._output.push(n);
175
189
  }
176
- return r.dispose(), this.outputConversation;
190
+ return a.dispose(), this.outputConversation;
177
191
  }
178
192
  resetCache(e) {
179
193
  this.cache && (this.cache.forEach((e) => {
@@ -199,7 +213,7 @@ var y = class extends e {
199
213
  };
200
214
  this.cache = e, this.lastToken = -1;
201
215
  }
202
- let r = this.tokeniser.trained ? this.tokeniser : new t(_(h, this.tokeniser.vocabSize));
216
+ let r = this.tokeniser.trained ? this.tokeniser : new t(v(g, this.tokeniser.vocabSize));
203
217
  this.actualTokeniser = r, n?.loraName ? this.model.attachLoRA(n.loraName) : this.model.hasLoRA() && this.model.detachLoRA();
204
218
  }
205
219
  async step(e, t) {
@@ -207,7 +221,7 @@ var y = class extends e {
207
221
  ...t,
208
222
  maxLength: 1
209
223
  };
210
- return v(e) ? this.generate(e, n) : this.generate({
224
+ return y(e) ? this.generate(e, n) : this.generate({
211
225
  ...e,
212
226
  ...n
213
227
  });
@@ -256,4 +270,4 @@ var y = class extends e {
256
270
  }
257
271
  };
258
272
  //#endregion
259
- export { y as default, v as isConversation };
273
+ export { b as default, y as isConversation };
@@ -1,4 +1,5 @@
1
1
  import { Conversation, ITokeniser } from '../tokeniser/type';
2
2
  import { IGenerateOptions } from './types';
3
3
  import { Tensor } from '@tensorflow/tfjs-core';
4
- export default function tokenisePrompt(tokeniser: ITokeniser, blockSize: number, prompt?: Conversation[], options?: IGenerateOptions): Promise<Tensor>;
4
+ export declare function tensorFromTokens(tokens: number[]): Tensor;
5
+ export default function tokenisePrompt(tokeniser: ITokeniser, blockSize: number, prompt?: Conversation[], options?: IGenerateOptions): Promise<number[]>;
@@ -1,13 +1,16 @@
1
1
  import { I as e } from "../dist-Da20xy8E.js";
2
2
  //#region lib/inference/tokenisePrompt.ts
3
- async function t(t, n, r, i) {
4
- if (r) {
5
- let a = r.length > 0 && (r[r.length - 1].role === "text" || r[r.length - 1].role === "assistant"), o;
6
- return i?.nonConversational ? o = a && i?.continuation ? [t.bosToken, ...t.encode(r[r.length - 1].content)] : t.encodeAsSequence(r, !0) : a && i?.continuation ? (o = t.encodeConversation(r, !0), o[o.length - 1] === t.getSpecialTokenIndex("<|assistant_start|>") && o[o.length - 2] === t.getSpecialTokenIndex("<|assistant_end|>") && (o.pop(), o.pop())) : o = t.encodeConversation(r, !0), o.length > n && (o = o.slice(-n)), i?.debug && console.log("Tokenised prompt:", t.decode(o)), e([o], [1, o.length], "int32");
3
+ function t(t) {
4
+ return e([t], [1, t.length], "int32");
5
+ }
6
+ async function n(e, t, n, r) {
7
+ if (n) {
8
+ let i = n.length > 0 && (n[n.length - 1].role === "text" || n[n.length - 1].role === "assistant"), a;
9
+ return r?.nonConversational ? a = i && r?.continuation ? [e.bosToken, ...e.encode(n[n.length - 1].content)] : e.encodeAsSequence(n, !0) : i && r?.continuation ? (a = e.encodeConversation(n, !0), a[a.length - 1] === e.getSpecialTokenIndex("<|assistant_start|>") && a[a.length - 2] === e.getSpecialTokenIndex("<|assistant_end|>") && (a.pop(), a.pop())) : a = e.encodeConversation(n, !0), a.length > t && (a = a.slice(-t)), r?.debug && console.log("Tokenised prompt:", e.decode(a)), a;
7
10
  } else {
8
- let n = i?.nonConversational ? void 0 : t.getSpecialTokenIndex("<|assistant_start|>"), r = n === void 0 ? [t.bosToken] : [t.bosToken, n];
9
- return e([r], [1, r.length], "int32");
11
+ let t = r?.nonConversational ? void 0 : e.getSpecialTokenIndex("<|assistant_start|>");
12
+ return t === void 0 ? [e.bosToken] : [e.bosToken, t];
10
13
  }
11
14
  }
12
15
  //#endregion
13
- export { t as default };
16
+ export { n as default, t as tensorFromTokens };
@@ -58,6 +58,7 @@ export interface BeamerOptions extends IGenerateOptions {
58
58
  maxBeamLength: number;
59
59
  beams: number;
60
60
  endOnWhiteSpace?: boolean;
61
+ keepDuplicates?: boolean;
61
62
  }
62
63
  export interface IBeam {
63
64
  tokens: number[];
@@ -0,0 +1,44 @@
1
+ import { default as BaseLayer, ForwardAttributes } from './BaseLayer';
2
+ import { Tensor } from '@tensorflow/tfjs-core';
3
+ import { GPTConfig } from '../../models/config';
4
+ import { RMSNormConfig } from './RMSNorm';
5
+ export interface KVCache {
6
+ k?: Tensor;
7
+ v?: Tensor;
8
+ length: number;
9
+ cumulativeLength: number;
10
+ }
11
+ export interface AttentionScores {
12
+ meanOfHeads?: boolean;
13
+ attentionOut?: Tensor[];
14
+ }
15
+ interface AttentionForwardAttributes extends ForwardAttributes {
16
+ attentionScores?: AttentionScores;
17
+ pastKV?: KVCache;
18
+ seed?: number;
19
+ ropePositionOffset?: number;
20
+ }
21
+ export interface GQAConfig extends RMSNormConfig {
22
+ useQKNorm?: boolean;
23
+ ropeInterleaved?: boolean;
24
+ kvHeads?: number;
25
+ }
26
+ export default class GQA extends BaseLayer<AttentionForwardAttributes> {
27
+ private readonly attentionConfig;
28
+ private divisor;
29
+ private index;
30
+ private units;
31
+ private projUnits;
32
+ private ATTN;
33
+ private PROJ;
34
+ private qNorm;
35
+ private kNorm;
36
+ constructor(index: number, config: GPTConfig, attentionConfig: GQAConfig, parent?: BaseLayer);
37
+ protected build(): void;
38
+ private getAttentionScores;
39
+ private getQKV;
40
+ private getOutputProjection;
41
+ private updateCache;
42
+ forward(attr: AttentionForwardAttributes, x: Tensor): Tensor;
43
+ }
44
+ export {};
@@ -2,18 +2,18 @@ import { T as e, di as t, oi as n, pt as r } from "../dist-Da20xy8E.js";
2
2
  import { isPackedTensor as i } from "../utilities/packed.js";
3
3
  import { transpose16 as a } from "../ops/transpose16.js";
4
4
  import { reshape16 as o } from "../ops/reshape16.js";
5
- import { t as s } from "../matMul16-DGtlziMn.js";
5
+ import { t as s } from "../matMul16-CO1QhsRt.js";
6
6
  import { t as c } from "../pack16-BhuXNUS7.js";
7
7
  import { attentionMask as l } from "../ops/attentionMask.js";
8
8
  import u from "./BaseLayer.js";
9
- import { t as d } from "../rope-C8EAiSGY.js";
9
+ import { t as d } from "../rope-BPu_uooz.js";
10
10
  import { appendCache as f } from "../ops/appendCache.js";
11
11
  import { softmax16 as p } from "../ops/softmax16.js";
12
12
  import { dot16 as m } from "../ops/dot16.js";
13
13
  import { qkv as h } from "../ops/qkv.js";
14
- import { normRMS as g } from "../ops/normRMS.js";
15
- import { dropout16 as _ } from "../ops/dropout16.js";
16
- //#region lib/layers/CausalSelfAttention.ts
14
+ import { dropout16 as g } from "../ops/dropout16.js";
15
+ import _ from "./RMSNorm.js";
16
+ //#region lib/layers/GQA.ts
17
17
  var v = class extends u {
18
18
  attentionConfig;
19
19
  divisor;
@@ -22,8 +22,10 @@ var v = class extends u {
22
22
  projUnits;
23
23
  ATTN;
24
24
  PROJ;
25
+ qNorm = null;
26
+ kNorm = null;
25
27
  constructor(e, t, n, r) {
26
- super(t, r), this.attentionConfig = n, this.index = e, this.units = t.nEmbed * 3, this.projUnits = t.nEmbed, this.ATTN = `block_${this.index}_cAttn`, this.PROJ = `block_${this.index}_cProj`, this.addVariable(this.ATTN), this.addVariable(this.PROJ), this.divisor = 1 / Math.sqrt(t.nEmbed / t.nHead);
28
+ super(t, r), this.attentionConfig = n, this.index = e, this.units = t.nEmbed * 3, this.projUnits = t.nEmbed, this.ATTN = `block_${this.index}_cAttn`, this.PROJ = `block_${this.index}_cProj`, this.addVariable(this.ATTN), this.addVariable(this.PROJ), this.divisor = 1 / Math.sqrt(t.nEmbed / t.nHead), (this.attentionConfig.useQKNorm ?? !1) && (this.qNorm = new _(t, n, `block_${this.index}_qNorm`, this), this.kNorm = new _(t, n, `block_${this.index}_kNorm`, this));
27
29
  }
28
30
  build() {
29
31
  this.hasVariable(this.ATTN) === !1 && this.setVariable(this.ATTN, e(r([this.config.nEmbed, this.units], 0, .02), !0, this.ATTN)), this.hasVariable(this.PROJ) === !1 && this.setVariable(this.PROJ, e(r([this.projUnits, this.config.nEmbed], 0, .02), !0, this.PROJ));
@@ -62,20 +64,20 @@ var v = class extends u {
62
64
  forward(e, r) {
63
65
  return t(() => {
64
66
  this.startMemory();
65
- let [t, i, a] = this.getQKV(r), o = e.pastKV ? e.pastKV.cumulativeLength : e.ropePositionOffset || 0, c = e.ropeCache, l = c ? d(t, c, o) : t, u = c ? d(i, c, o) : i, f = this.attentionConfig.useQKNorm ?? !1, p = f ? g(l) : l;
66
- f && l.dispose();
67
- let m = f ? g(u) : u;
68
- f && u.dispose(), c && (t.dispose(), i.dispose());
67
+ let [t, i, a] = this.getQKV(r), o = e.pastKV ? e.pastKV.cumulativeLength : e.ropePositionOffset || 0, c = e.ropeCache, l = this.attentionConfig.ropeInterleaved ?? !0, u = c ? d(t, c, o, !1, l) : t, f = c ? d(i, c, o, !1, l) : i, p = this.qNorm ? this.qNorm.call(e, u) : u;
68
+ this.qNorm && u.dispose();
69
+ let m = this.kNorm ? this.kNorm.call(e, f) : f;
70
+ this.kNorm && f.dispose(), c && (t.dispose(), i.dispose());
69
71
  let h = e.pastKV ? e.pastKV.length : 0;
70
72
  e.pastKV && !e.training && this.updateCache(m, a, e.pastKV);
71
- let v = e.pastKV?.k ? e.pastKV.k : m, y = e.pastKV?.v ? e.pastKV.v : a, b;
72
- b = h > 0 ? this.getAttentionScores(p, v, h) : this.getAttentionScores(p, v), p.dispose(), e.pastKV || v.dispose();
73
- let x = s(b, y), S = e.attentionScores !== void 0 && e.attentionScores.attentionOut !== void 0;
74
- S || b.dispose(), e.pastKV || y.dispose();
75
- let C = this.getOutputProjection(x);
76
- if (x.dispose(), S && e.attentionScores && e.attentionScores.attentionOut !== void 0) {
77
- let t = b.shape[1], r = b.shape[2];
78
- e.attentionScores.attentionOut?.push(n(b.slice([
73
+ let _ = e.pastKV?.k ? e.pastKV.k : m, v = e.pastKV?.v ? e.pastKV.v : a, y;
74
+ y = h > 0 ? this.getAttentionScores(p, _, h) : this.getAttentionScores(p, _), p.dispose(), e.pastKV || _.dispose();
75
+ let b = s(y, v), x = e.attentionScores !== void 0 && e.attentionScores.attentionOut !== void 0;
76
+ x || y.dispose(), e.pastKV || v.dispose();
77
+ let S = this.getOutputProjection(b);
78
+ if (b.dispose(), x && e.attentionScores && e.attentionScores.attentionOut !== void 0) {
79
+ let t = y.shape[1], r = y.shape[2];
80
+ e.attentionScores.attentionOut?.push(n(y.slice([
79
81
  0,
80
82
  0,
81
83
  0,
@@ -91,7 +93,7 @@ var v = class extends u {
91
93
  -1
92
94
  ])));
93
95
  }
94
- return this.endMemory("CausalSelfAttention"), e.dropout && e.dropout > 0 ? _(C, e.dropout) : C;
96
+ return this.endMemory("CausalSelfAttention"), e.dropout && e.dropout > 0 ? g(S, e.dropout) : S;
95
97
  });
96
98
  }
97
99
  };
@@ -0,0 +1,12 @@
1
+ import { Tensor } from '@tensorflow/tfjs-core';
2
+ import { default as BaseLayer, ForwardAttributes } from './BaseLayer';
3
+ import { GPTConfig } from '../../models/config';
4
+ export default class HeadLayer extends BaseLayer {
5
+ private vocabSize;
6
+ private embedDim;
7
+ private initializer;
8
+ private WEIGHTS;
9
+ constructor(config: GPTConfig, name: string, parent?: BaseLayer);
10
+ project(inputs: Tensor): Tensor;
11
+ forward(_: ForwardAttributes, x: Tensor): Tensor;
12
+ }