@genai-fi/nanogpt 0.24.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +78 -281
  2. package/dist/{RealDiv-CNsvC4AU.js → RealDiv-CSnvtN2E.js} +20 -20
  3. package/dist/{Reshape-dnm9bO3B.js → Reshape-BlylqwWy.js} +12 -12
  4. package/dist/TeachableLLM.d.ts +10 -14
  5. package/dist/TeachableLLM.js +201 -2
  6. package/dist/api/responses.d.ts +81 -0
  7. package/dist/api/responses.js +169 -0
  8. package/dist/api/training.d.ts +70 -0
  9. package/dist/api/training.js +205 -0
  10. package/dist/data/docx.js +9 -3036
  11. package/dist/data/stream.d.ts +2 -2
  12. package/dist/data/textLoader.d.ts +1 -1
  13. package/dist/data/textLoader.js +1 -1
  14. package/dist/data.d.ts +3 -0
  15. package/dist/data.js +12 -0
  16. package/dist/{dist-BqAU9-yi.js → dist-CwK5S7Ls.js} +2168 -2168
  17. package/dist/{gpgpu_math-DBYEAAdI.js → gpgpu_math-20tPK8LM.js} +458 -458
  18. package/dist/{Generator.d.ts → inference/Generator.d.ts} +16 -44
  19. package/dist/inference/Generator.js +271 -0
  20. package/dist/inference/tokenisePrompt.d.ts +4 -0
  21. package/dist/inference/tokenisePrompt.js +13 -0
  22. package/dist/inference/types.d.ts +44 -8
  23. package/dist/inference/utilities.d.ts +9 -0
  24. package/dist/inference/utilities.js +20 -0
  25. package/dist/jszip.min-DKa1Rjyn.js +3033 -0
  26. package/dist/{kernel_funcs_utils-D-mATnGR.js → kernel_funcs_utils-ql8Y8qPn.js} +96 -93
  27. package/dist/layers/MLP.d.ts +1 -1
  28. package/dist/layers/PositionEmbedding.d.ts +2 -1
  29. package/dist/layers/PositionEmbedding.js +1 -1
  30. package/dist/layers/RMSNorm.d.ts +1 -1
  31. package/dist/layers/TiedEmbedding.js +1 -1
  32. package/dist/layers.d.ts +4 -0
  33. package/dist/layers.js +14 -0
  34. package/dist/loader/load.js +58 -2
  35. package/dist/loader/loadHF.d.ts +1 -1
  36. package/dist/loader/loadHF.js +17 -2
  37. package/dist/loader/loadTransformers.js +46 -2
  38. package/dist/loader/newZipLoad.js +25 -2
  39. package/dist/loader/oldZipLoad.d.ts +1 -1
  40. package/dist/loader/oldZipLoad.js +37 -2
  41. package/dist/loader/save.js +75 -2
  42. package/dist/loader/types.d.ts +3 -3
  43. package/dist/main.d.ts +34 -35
  44. package/dist/main.js +12327 -20
  45. package/dist/{matMulGelu-BAIgQaRx.js → matMulGelu-CBoqTZM7.js} +2 -2
  46. package/dist/models/NanoGPTV1.js +95 -2
  47. package/dist/models/NanoGPTV2.js +86 -2
  48. package/dist/models/factory.js +13 -2
  49. package/dist/models/model.js +76 -2
  50. package/dist/models.d.ts +4 -0
  51. package/dist/models.js +14 -0
  52. package/dist/ops/dot16.js +1 -1
  53. package/dist/ops/matMulGelu.js +1 -1
  54. package/dist/ops/webgl/adamAdjust.js +1 -1
  55. package/dist/ops/webgl/fusedSoftmax.js +2 -2
  56. package/dist/ops/webgl/gelu.js +2 -2
  57. package/dist/ops/webgl/log.js +5 -5
  58. package/dist/ops/webgl/matMulGelu.js +1 -1
  59. package/dist/ops/webgl/matMulMul.js +1 -1
  60. package/dist/{tfjs_backend-CydPRQTc.js → tfjs_backend-h5weiy1O.js} +36 -36
  61. package/dist/tokenise.d.ts +4 -0
  62. package/dist/tokenise.js +15 -0
  63. package/dist/training/BasicTrainer.d.ts +5 -10
  64. package/dist/training/BasicTrainer.js +80 -88
  65. package/dist/training/configure.d.ts +3 -0
  66. package/dist/training/configure.js +32 -0
  67. package/dist/training/factory.d.ts +6 -0
  68. package/dist/training/factory.js +8 -0
  69. package/dist/training/prepareData.d.ts +22 -0
  70. package/dist/training/prepareData.js +49 -0
  71. package/dist/training/tasks/tokenStream.d.ts +2 -1
  72. package/dist/training/types.d.ts +14 -1
  73. package/dist/training/validateOptions.d.ts +2 -0
  74. package/dist/training/validateOptions.js +19 -0
  75. package/dist/utilities/arrayShape.d.ts +1 -0
  76. package/dist/utilities/arrayShape.js +8 -0
  77. package/dist/utilities/waitForModel.d.ts +1 -1
  78. package/dist/v4-BK7K-jy_.js +30 -0
  79. package/package.json +8 -2
  80. package/dist/Generator.js +0 -2
  81. package/dist/Trainer-Cr7csbTD.js +0 -228
  82. package/dist/Trainer.d.ts +0 -45
  83. package/dist/Trainer.js +0 -2
  84. package/dist/main-Dz72vadm.js +0 -13267
@@ -1,16 +1,17 @@
1
1
  import { _n as e, di as t, kt as n, ni as r, oi as i, qt as a } from "../dist-Da20xy8E.js";
2
2
  import { AdamWOptimizer as o } from "./AdamW.js";
3
- import { calculateAccuracy as s, calculateLoss as c } from "./loss.js";
4
- import l from "./Evaluator.js";
5
- import u from "../utilities/profile.js";
3
+ import s from "../utilities/profile.js";
4
+ import { calculateAccuracy as c, calculateLoss as l } from "./loss.js";
5
+ import u from "./Evaluator.js";
6
6
  import { createTensorStatistics as d } from "../checks/weights.js";
7
+ import f from "./configure.js";
7
8
  //#region lib/training/BasicTrainer.ts
8
- var f = {
9
+ var p = {
9
10
  logInterval: 1,
10
11
  maxEpochs: 100,
11
- sftMode: "full",
12
+ method: { type: "pretraining" },
12
13
  batchSize: 32
13
- }, p = {
14
+ }, m = {
14
15
  learningRate: 3e-4,
15
16
  beta1: .9,
16
17
  beta2: .99,
@@ -21,10 +22,11 @@ var f = {
21
22
  epochSteps: 1e4,
22
23
  minLearningRate: 1e-5,
23
24
  lossScaling: 1
24
- }, m = class {
25
+ }, h = class {
25
26
  tokenizer;
26
27
  model;
27
28
  optimizer;
29
+ log = [];
28
30
  running = !1;
29
31
  lastState;
30
32
  _gradientCheckpointing = !1;
@@ -35,9 +37,10 @@ var f = {
35
37
  _labelSmoothing = 0;
36
38
  _layerDrop = 0;
37
39
  _dropout = 0;
40
+ _tokensProcessed = 0;
38
41
  constructor(e, t, n, r) {
39
42
  this.tokenizer = t, this.model = e, this.optimizerConfig = {
40
- ...p,
43
+ ...m,
41
44
  ...n,
42
45
  lossScaling: n?.lossScaling ?? e.lossScaling
43
46
  };
@@ -68,8 +71,11 @@ var f = {
68
71
  setMetrics(e) {
69
72
  this.metrics = new Set(e);
70
73
  }
74
+ configure(e) {
75
+ this.setGradientCheckpointing(e?.gradientCheckpointing || !1), this.setMixedPrecision(e?.mixedPrecision || !1), this.setLabelSmoothing(e?.labelSmoothing || 0), this.setDropout(e?.dropout || 0), this.setLayerDrop(e?.layerDrop || 0), this.lastState || this.setLearningRate(e?.learningRate || .001), f(this.model, e);
76
+ }
71
77
  reset() {
72
- this.lastState = void 0, this.running = !1;
78
+ this.lastState = void 0, this.running = !1, this.log = [];
73
79
  }
74
80
  stop() {
75
81
  this.running = !1;
@@ -77,6 +83,9 @@ var f = {
77
83
  get isRunning() {
78
84
  return this.running;
79
85
  }
86
+ get tokensProcessed() {
87
+ return this._tokensProcessed;
88
+ }
80
89
  getOptimizer() {
81
90
  return this.optimizer;
82
91
  }
@@ -97,7 +106,7 @@ var f = {
97
106
  trainingDuration: e.duration
98
107
  });
99
108
  }
100
- trainStep(n, o, l = !1, u = !1) {
109
+ trainStep(n, o, s = !1, u = !1) {
101
110
  return t(() => {
102
111
  this.model.getProfiler()?.startMemory();
103
112
  let { xs: t, ys: d } = o, { value: f, grads: p } = a(() => {
@@ -108,12 +117,12 @@ var f = {
108
117
  dropout: this._dropout,
109
118
  layerDrop: this._layerDrop,
110
119
  ropePositionOffset: 0
111
- }, t), a = c(r, d, this.maskedLoss, !1, this._labelSmoothing);
112
- this.metrics.has("accuracy") && (n.accuracy = s(r, d), i(n.accuracy)), r.dispose();
120
+ }, t), a = l(r, d, this.maskedLoss, !1, this._labelSmoothing);
121
+ this.metrics.has("accuracy") && (n.accuracy = c(r, d), i(n.accuracy)), r.dispose();
113
122
  let o = a.mul(e(this.optimizerConfig.lossScaling));
114
123
  return a.dispose(), o;
115
124
  });
116
- if (l) this.model.getProfiler()?.endMemory("Training");
125
+ if (s) this.model.getProfiler()?.endMemory("Training");
117
126
  else {
118
127
  let e = this.optimizer.applyGradients(p);
119
128
  this.metrics.has("gradientNorm") ? (n.gradientNorm = e, i(e)) : (n.gradientNorm = void 0, e.dispose());
@@ -152,76 +161,47 @@ var f = {
152
161
  ...this.lastState || {}
153
162
  };
154
163
  }
155
- async stepDataset(e, t, n) {
156
- let { logInterval: i = 10 } = {
157
- ...f,
158
- ...t
159
- };
160
- t.metrics && this.setMetrics(t.metrics);
161
- let a = Date.now(), o = this.createEmptyState();
162
- this.lastState = o, await this.dummyPass(), this.metrics.has("memoryUsage") && (this.model.getProfiler() || this.model.setProfiler(new u())), this.running = !0, o.logStartTime = a;
163
- let s = n ? new l(this.model, n, this.maskedLoss) : void 0, c = await e.iterator();
164
- try {
165
- for (; this.running;) {
166
- let e = await c.next();
167
- if (e.done) break;
168
- let n = e.value, r = this.trainStep(o, n, !1);
169
- if (t.debug) {
170
- let e = (await r.data())[0];
171
- if (isNaN(e) || !isFinite(e)) throw console.error("Invalid loss value:", e), console.error("Batch xs:", n.xs.toString()), console.error("Batch ys:", n.ys.toString()), console.error("State:", o), Error("Loss is NaN or Infinity");
172
- console.log(`Step ${o.step}: Loss = ${e}`);
173
- }
174
- n.xs.dispose(), n.ys.dispose(), o.step++, o.totalSteps++, o.step % i === 0 ? await this.performLogging(r, n.xs.shape[0], t, s) : (o.gradientNorm &&= (o.gradientNorm.dispose(), void 0), o.accuracy &&= (o.accuracy.dispose(), void 0)), r.dispose();
175
- }
176
- } catch (e) {
177
- throw console.error("Training error:", e), e;
178
- }
179
- throw this.model.trainingState = {
180
- steps: o.totalSteps,
181
- learningRate: this.optimizer.lr,
182
- batchSize: t.batchSize || 32,
183
- loss: o.lastLoss,
184
- tokensProcessed: o.totalSteps * (t.batchSize || 32) * this.model.config.blockSize,
185
- duration: o.trainingDuration
186
- }, r(), this.running = !1, Error("No log returned before training stopped.");
187
- }
188
164
  async performLogging(e, t, n, r) {
189
- let i = n?.onStep, a = this.metrics.has("gradientStatistics"), o = (await e.data())[0], s = this.lastState;
190
- s.lastLoss = o, s.trainingDuration += Date.now() - s.logStartTime;
191
- let c = s.totalSteps * t * this.model.config.blockSize, l = {
165
+ let i = this.metrics.has("gradientStatistics"), a = this.lastState, o = [];
166
+ o.push(e.data()), o.push(a.accuracy ? a.accuracy.data() : null), o.push(a.gradientNorm ? a.gradientNorm.data() : null);
167
+ let s = await Promise.all(o), c = s[0]?.[0] ?? 0, l = s[1] ? s[1][0] : void 0, u = s[2] ? s[2][1] : void 0;
168
+ a.lastLoss = c, a.trainingDuration += Date.now() - a.logStartTime;
169
+ let f = a.totalSteps * t * this.model.config.blockSize;
170
+ this._tokensProcessed = f;
171
+ let p = {
192
172
  trainingMetrics: {
193
- loss: s.lastLoss,
194
- perplexity: this.metrics.has("perplexity") ? Math.exp(s.lastLoss) : void 0,
195
- accuracy: s.accuracy ? (await s.accuracy.data())[0] : void 0
173
+ loss: a.lastLoss,
174
+ perplexity: this.metrics.has("perplexity") ? Math.exp(a.lastLoss) : void 0,
175
+ accuracy: l
196
176
  },
197
- step: s.step,
198
- time: Date.now() - s.logStartTime,
199
- gradientNorm: s.gradientNorm ? (await s.gradientNorm.data())[1] : void 0,
177
+ step: a.step,
178
+ time: Date.now() - a.logStartTime,
179
+ gradientNorm: u,
200
180
  batchSize: t,
201
181
  learningRate: this.metrics.has("learningRate") ? this.optimizer.lr : void 0,
202
- duration: s.trainingDuration,
203
- totalTokens: c,
204
- tokensPerSecond: c / (s.trainingDuration / 1e3),
182
+ duration: a.trainingDuration,
183
+ totalTokens: f,
184
+ tokensPerSecond: f / (a.trainingDuration / 1e3),
205
185
  memoryUsage: this.metrics.has("memoryUsage") ? this.model.getProfiler()?.getPeakMemory() || 0 : void 0
206
186
  };
207
- if (s.gradientNorm &&= (s.gradientNorm.dispose(), void 0), s.accuracy &&= (s.accuracy.dispose(), void 0), this.model.trainingState = {
208
- steps: s.totalSteps,
187
+ if (a.gradientNorm &&= (a.gradientNorm.dispose(), void 0), a.accuracy &&= (a.accuracy.dispose(), void 0), this.model.trainingState = {
188
+ steps: a.totalSteps,
209
189
  learningRate: this.optimizer.lr,
210
190
  batchSize: t,
211
- loss: s.lastLoss,
212
- tokensProcessed: c,
213
- duration: s.trainingDuration
214
- }, a && s.gradients) {
191
+ loss: a.lastLoss,
192
+ tokensProcessed: f,
193
+ duration: a.trainingDuration
194
+ }, i && a.gradients) {
215
195
  let e = /* @__PURE__ */ new Map();
216
- for (let [t, n] of Object.entries(s.gradients)) e.set(t, await d(n)), n.dispose();
217
- l.gradientMetrics = e;
196
+ for (let [t, n] of Object.entries(a.gradients)) e.set(t, await d(n)), n.dispose();
197
+ p.gradientMetrics = e;
218
198
  }
219
- if (r) try {
220
- let e = await r.evaluate(5);
221
- Array.isArray(e) ? l.validationMetrics = {
199
+ if (n) try {
200
+ let e = await n.evaluate(5);
201
+ Array.isArray(e) ? p.validationMetrics = {
222
202
  loss: e[0].loss,
223
203
  accuracy: e[0].accuracy
224
- } : (s.validationLosses.push(e.loss), l.validationMetrics = {
204
+ } : (a.validationLosses.push(e.loss), p.validationMetrics = {
225
205
  accuracy: e.accuracy,
226
206
  loss: e.loss,
227
207
  perplexity: this.metrics.has("perplexity") ? Math.exp(e.loss) : void 0
@@ -229,37 +209,49 @@ var f = {
229
209
  } catch (e) {
230
210
  console.error("Validation error:", e);
231
211
  }
232
- i && await i(l), s.logStartTime = Date.now();
212
+ this.log.push(p), r && r(p), a.logStartTime = Date.now();
233
213
  }
234
- async trainOnDataset(e, t, n) {
235
- let { logInterval: i = 10, maxEpochs: a = Infinity } = {
236
- ...f,
214
+ async trainOnDataset(e, t, n, i) {
215
+ let { logInterval: a = 10, maxEpochs: o = Infinity } = {
216
+ ...p,
237
217
  ...t
238
- }, o = a * (t?.epochSteps || 1e3);
218
+ };
219
+ this.log.length > 0 && this.resumeFromLog(this.log[this.log.length - 1]);
220
+ let c = o * (t?.epochSteps || 1e3);
239
221
  t.metrics && this.setMetrics(t.metrics);
240
- let s = Date.now(), c = this.createEmptyState();
241
- this.lastState = c, await this.dummyPass(), t?.metrics?.includes("memoryUsage") && (this.model.getProfiler() || this.model.setProfiler(new u())), this.running = !0, c.logStartTime = s;
242
- let d = n ? new l(this.model, n, this.maskedLoss) : void 0, p = await e.iterator();
222
+ let l = this.createEmptyState();
223
+ this.lastState = l, await this.dummyPass(), t?.metrics?.includes("memoryUsage") && (this.model.getProfiler() || this.model.setProfiler(new s()));
224
+ let d = Date.now();
225
+ this.running = !0, l.logStartTime = d;
226
+ let f = n ? new u(this.model, n, this.maskedLoss) : void 0, m = await e.iterator(), h = m.next();
243
227
  try {
244
228
  for (; this.running;) {
245
- let e = await p.next();
246
- if (e.done) break;
247
- let n = e.value, r = c.step % i === 0, a = (t?.metrics?.includes("gradientStatistics") || !1) && r, s = this.trainStep(c, n, !1, a);
229
+ let e = await h;
230
+ if (h = m.next(), e.done) break;
231
+ let n = e.value, r = l.step % a === 0, o = (t?.metrics?.includes("gradientStatistics") || !1) && r, s = this.trainStep(l, n, !1, o);
248
232
  if (t.debug) {
249
233
  let e = (await s.data())[0];
250
- if (isNaN(e) || !isFinite(e)) throw console.error("Invalid loss value:", e), console.error("Batch xs:", await n.xs.array()), console.error("Batch ys:", await n.ys.array()), console.error("State:", c), Error("Loss is NaN or Infinity");
251
- console.log(`Step ${c.step}: Loss = ${e}`);
234
+ if (isNaN(e) || !isFinite(e)) throw console.error("Invalid loss value:", e), console.error("Batch xs:", await n.xs.array()), console.error("Batch ys:", await n.ys.array()), console.error("State:", l), Error("Loss is NaN or Infinity");
235
+ console.log(`Step ${l.step}: Loss = ${e}`);
252
236
  }
253
- n.xs.dispose(), n.ys.dispose(), c.step++, c.totalSteps++, r ? await this.performLogging(s, n.xs.shape[0], t, d) : (c.gradientNorm &&= (c.gradientNorm.dispose(), void 0), c.accuracy &&= (c.accuracy.dispose(), void 0)), s.dispose(), c.step >= o && this.stop();
237
+ n.xs.dispose(), n.ys.dispose(), l.step++, l.totalSteps++, r ? await this.performLogging(s, n.xs.shape[0], f, i) : (l.gradientNorm &&= (l.gradientNorm.dispose(), void 0), l.accuracy &&= (l.accuracy.dispose(), void 0)), s.dispose(), l.step >= c && this.stop();
254
238
  }
255
239
  } catch (e) {
256
240
  throw console.error("Training error:", e), r(), e;
257
241
  }
258
- return r(), this.running = !1, {
259
- losses: c.losses,
260
- validationLosses: c.validationLosses
242
+ r(), this.running = !1, this.model.metaData.actionLog = this.model.metaData.actionLog || [];
243
+ let g = Date.now();
244
+ return this.model.metaData.actionLog.push({
245
+ action: "pretrain",
246
+ timestamp: g,
247
+ duration: g - d,
248
+ tokensProcessed: this.tokensProcessed,
249
+ options: t
250
+ }), {
251
+ losses: l.losses,
252
+ validationLosses: l.validationLosses
261
253
  };
262
254
  }
263
255
  };
264
256
  //#endregion
265
- export { m as default };
257
+ export { h as default };
@@ -0,0 +1,3 @@
1
+ import { TrainingOptions } from './types';
2
+ import { default as Model, ModelForwardAttributes } from '../../models/model';
3
+ export default function configureModel(model: Model<ModelForwardAttributes>, options?: TrainingOptions): void;
@@ -0,0 +1,32 @@
1
+ import { t as e } from "../v4-BK7K-jy_.js";
2
+ //#region lib/training/configure.ts
3
+ function t(t, n) {
4
+ let r = n?.method.supervised || "full", i = n?.method.type || "pretraining";
5
+ if (i === "pretraining" && (t.hasLoRA() && t.detachLoRA(), t.weightStore.setTrainable(["*"]), n && (t.metaData.pretrainingSettings = n)), i === "supervised") {
6
+ if (r === "lora") {
7
+ if (n?.loraName) {
8
+ if (!t.hasLoRA(n.loraName)) if (n.loraConfig) t.createLoRA(n.loraName, n.loraConfig), t.attachLoRA(n.loraName);
9
+ else throw Error(`LoRA configuration must be provided to create LoRA with name ${n.loraName}`);
10
+ else if (t.attachLoRA(n.loraName), n.loraConfig) {
11
+ let e = t.lora;
12
+ (e.alpha !== n.loraConfig.alpha || e.rank !== n.loraConfig.rank) && (t.detachLoRA(), t.deleteLoRA(n.loraName), t.createLoRA(n.loraName, n.loraConfig), t.attachLoRA(n.loraName), console.warn("Resetting LoRA with new configuration."));
13
+ }
14
+ } else if (n?.loraConfig) if (t.hasLoRA()) {
15
+ let r = t.lora;
16
+ if (r.alpha !== n.loraConfig.alpha || r.rank !== n.loraConfig.rank) {
17
+ t.detachLoRA();
18
+ let r = n.loraName || e();
19
+ t.createLoRA(r, n.loraConfig), t.attachLoRA(r);
20
+ }
21
+ } else {
22
+ let r = n.loraName || e();
23
+ t.createLoRA(r, n.loraConfig), t.attachLoRA(r);
24
+ }
25
+ else if (!t.hasLoRA()) throw Error("LoRA configuration must be provided for lora SFT mode");
26
+ } else t.hasLoRA() && t.detachLoRA();
27
+ r === "last-layer" ? t.weightStore.setTrainable([`block_${t.config.nLayer - 1}_*`, "token_embedding"]) : r === "full" && t.weightStore.setTrainable(["*"]);
28
+ }
29
+ n?.trainableWeights && t.weightStore.setTrainable(n.trainableWeights);
30
+ }
31
+ //#endregion
32
+ export { t as default };
@@ -0,0 +1,6 @@
1
+ import { ModelForwardAttributes, default as Model } from '../../models/model';
2
+ import { TrainingOptions } from '../../training/types';
3
+ import { default as BasicTrainer } from '../../training/BasicTrainer';
4
+ import { ITokeniser } from '../../tokeniser/type';
5
+ import { AdamWOptimizer } from './AdamW';
6
+ export default function createTrainer(model: Model<ModelForwardAttributes>, tokenizer: ITokeniser, options?: TrainingOptions, optimizer?: AdamWOptimizer): BasicTrainer;
@@ -0,0 +1,8 @@
1
+ import e from "./SFTTrainer.js";
2
+ import t from "./PreTrainer.js";
3
+ //#region lib/training/factory.ts
4
+ function n(n, r, i, a) {
5
+ return i?.method.type === "supervised" ? new e(n, r, i, a) : new t(n, r, i, a);
6
+ }
7
+ //#endregion
8
+ export { n as default };
@@ -0,0 +1,22 @@
1
+ import { default as Model, ModelForwardAttributes } from '../../models/model';
2
+ import { TrainingOptions } from './types';
3
+ import { TokenStore } from './tasks/TokenStore';
4
+ import { DatasetMetadata } from '../../loader/types';
5
+ import { ConversationStream } from '../../data/stream';
6
+ import { ITokeniser } from '../../tokeniser/type';
7
+ import { Dataset } from '@tensorflow/tfjs-data';
8
+ import { Tensor } from '@tensorflow/tfjs-core';
9
+ interface PrepareDataResult {
10
+ trainDataset: Dataset<{
11
+ xs: Tensor;
12
+ ys: Tensor;
13
+ }>;
14
+ validationDataset?: Dataset<{
15
+ xs: Tensor;
16
+ ys: Tensor;
17
+ }>;
18
+ totalTokens: number;
19
+ }
20
+ /** Take our training options, model, tokeniser, and tasks, and prepare the training and validation datasets in Tensorflow format. */
21
+ export default function prepareData(options: TrainingOptions, model: Model<ModelForwardAttributes>, tokeniser: ITokeniser, tasks: ConversationStream[] | Uint16Array[] | TokenStore, validation?: Uint16Array[] | TokenStore, datasets?: DatasetMetadata[]): Promise<PrepareDataResult>;
22
+ export {};
@@ -0,0 +1,49 @@
1
+ import { TokenStore as e } from "./tasks/TokenStore.js";
2
+ import { tokensFromStreams as t } from "./tasks/tokenStream.js";
3
+ import { t as n } from "../DatasetBuilder-DU1G1OKX.js";
4
+ import { createTrainValidationDatasets as r, storeFromArray as i } from "./validation.js";
5
+ //#region lib/training/prepareData.ts
6
+ async function a(a, o, s, c, l, u) {
7
+ let d = a.loraName || a.loraConfig;
8
+ if (u && d) throw Error("Cannot specify datasets when using LoRA fine-tuning");
9
+ if (!u && !d) throw Error("Must specify datasets for non-LoRA training");
10
+ if (u) {
11
+ let e = o.metaData.pretrainingData || [], t = [...e], n = !1;
12
+ for (let r of u) e.some((e) => e.id === r.id) || t.push({
13
+ id: r.id,
14
+ name: r.name,
15
+ conversational: r.conversational
16
+ }), r.conversational && (n = !0);
17
+ o.metaData.pretrainingData = t, n ? o.metaData.mode = "conversational" : o.metaData.mode !== "conversational" && (o.metaData.mode = "completion");
18
+ } else o.metaData.mode !== "conversational" && (o.metaData.mode = "completion");
19
+ let f = a.maskedLoss ?? a.method.type === "supervised", p, m = l;
20
+ if (Array.isArray(c)) if (c[0] instanceof Uint16Array) p = c;
21
+ else {
22
+ let e = await t(c, s, {
23
+ masking: f,
24
+ validationSplit: a.validationSplit
25
+ });
26
+ p = e.trainingTokens, l || (m = e.validationTokens);
27
+ }
28
+ else p = c;
29
+ let h = p instanceof e ? p.getTokenCount() : p.reduce((e, t) => e + t.length, 0);
30
+ a.epochSteps = Math.ceil(h / ((a?.batchSize || 32) * o.config.blockSize));
31
+ let g = new n(s, o.config.blockSize);
32
+ if (m) {
33
+ let { trainDataset: e, validationDataset: t } = await r(p, m, s, g, a?.batchSize || 32);
34
+ return {
35
+ trainDataset: e,
36
+ validationDataset: t,
37
+ totalTokens: h
38
+ };
39
+ } else {
40
+ let t = p instanceof e ? p : await i(p, s);
41
+ return {
42
+ trainDataset: (await g.createTextDataset(t, a)).dataset,
43
+ validationDataset: void 0,
44
+ totalTokens: h
45
+ };
46
+ }
47
+ }
48
+ //#endregion
49
+ export { a as default };
@@ -1,4 +1,5 @@
1
- import { ConversationStream, ITokeniser } from '../../../main';
1
+ import { ITokeniser } from '../../../tokeniser/type';
2
+ import { ConversationStream } from '../../../data/stream';
2
3
  import { TokenStore } from './TokenStore';
3
4
  interface TokensFromTasksOptions {
4
5
  masking?: boolean;
@@ -1,6 +1,9 @@
1
1
  import { TensorStatistics } from '../../checks/weights';
2
2
  import { LoRAConfig } from '../../models/config';
3
3
  import { NamedTensorMap, Tensor } from '@tensorflow/tfjs-core';
4
+ import { TokenStore } from './tasks/TokenStore';
5
+ import { ConversationStream } from '../../data/stream';
6
+ import { DatasetMetadata } from '../../loader/types';
4
7
  export interface Metrics {
5
8
  accuracy?: number;
6
9
  perplexity?: number;
@@ -43,7 +46,13 @@ export interface AdamWOptimizerConfig extends LRSchedulerConfig {
43
46
  orthoGrad?: boolean;
44
47
  }
45
48
  export type TrainingMetrics = 'accuracy' | 'perplexity' | 'gradientNorm' | 'gradientStatistics' | 'weightNorm' | 'weightStatistics' | 'memoryUsage' | 'tokensPerSecond' | 'learningRate';
49
+ export interface TrainingMethod {
50
+ type: 'pretraining' | 'supervised';
51
+ supervised?: 'full' | 'lora' | 'last-layer';
52
+ }
46
53
  export interface TrainingOptions extends Partial<AdamWOptimizerConfig> {
54
+ previous_job_id?: string;
55
+ method: TrainingMethod;
47
56
  batchSize: number;
48
57
  maxEpochs?: number;
49
58
  logInterval?: number;
@@ -54,7 +63,6 @@ export interface TrainingOptions extends Partial<AdamWOptimizerConfig> {
54
63
  trainableWeights?: string[];
55
64
  loraConfig?: LoRAConfig;
56
65
  loraName?: string;
57
- sftMode: 'full' | 'lora' | 'last-layer';
58
66
  maskedLoss?: boolean;
59
67
  metrics?: TrainingMetrics[];
60
68
  contextScaling?: number;
@@ -62,6 +70,11 @@ export interface TrainingOptions extends Partial<AdamWOptimizerConfig> {
62
70
  dropout?: number;
63
71
  layerDrop?: number;
64
72
  debug?: boolean;
73
+ }
74
+ export interface TrainingContext {
75
+ training_data: ConversationStream[] | Uint16Array[] | TokenStore;
76
+ validation_data?: Uint16Array[] | TokenStore;
77
+ datasets?: DatasetMetadata[];
65
78
  onStep?: (log: TrainingLogEntry) => void;
66
79
  }
67
80
  export interface TrainingState {
@@ -0,0 +1,2 @@
1
+ import { TrainingOptions } from './types';
2
+ export default function validateOptions(options: TrainingOptions, training: boolean, oldOptions?: TrainingOptions): TrainingOptions;
@@ -0,0 +1,19 @@
1
+ //#region lib/training/validateOptions.ts
2
+ function e(e, t, n) {
3
+ let r = new Set(Object.keys(e).filter((t) => e[t] !== n?.[t]));
4
+ if (t) {
5
+ if (r.has("batchSize")) throw Error("Cannot change batch size during training");
6
+ if (r.has("sftMode")) throw Error("Cannot change SFT mode during training");
7
+ if (r.has("loraConfig")) throw Error("Cannot change LoRA configuration during training");
8
+ if (r.has("validationSplit")) throw Error("Cannot change validation split during training");
9
+ if (r.has("trainableWeights")) throw Error("Cannot change trainable weights during training");
10
+ if (r.has("mixedPrecision")) throw Error("Cannot change mixed precision setting during training");
11
+ if (r.has("gradientCheckpointing")) throw Error("Cannot change gradient checkpointing setting during training");
12
+ }
13
+ return {
14
+ ...n,
15
+ ...e
16
+ };
17
+ }
18
+ //#endregion
19
+ export { e as default };
@@ -0,0 +1 @@
1
+ export default function arrayShape(arr: unknown[]): number[];
@@ -0,0 +1,8 @@
1
+ //#region lib/utilities/arrayShape.ts
2
+ function e(e) {
3
+ let t = [], n = e;
4
+ for (; Array.isArray(n);) t.push(n.length), n = n[n.length - 1];
5
+ return t;
6
+ }
7
+ //#endregion
8
+ export { e as default };
@@ -1,2 +1,2 @@
1
- import { TeachableLLM } from '../../main';
1
+ import { default as TeachableLLM } from '../../TeachableLLM';
2
2
  export default function waitForModel(model: TeachableLLM): Promise<void>;
@@ -0,0 +1,30 @@
1
+ //#region node_modules/uuid/dist/stringify.js
2
+ var e = [];
3
+ for (let t = 0; t < 256; ++t) e.push((t + 256).toString(16).slice(1));
4
+ function t(t, n = 0) {
5
+ return (e[t[n + 0]] + e[t[n + 1]] + e[t[n + 2]] + e[t[n + 3]] + "-" + e[t[n + 4]] + e[t[n + 5]] + "-" + e[t[n + 6]] + e[t[n + 7]] + "-" + e[t[n + 8]] + e[t[n + 9]] + "-" + e[t[n + 10]] + e[t[n + 11]] + e[t[n + 12]] + e[t[n + 13]] + e[t[n + 14]] + e[t[n + 15]]).toLowerCase();
6
+ }
7
+ //#endregion
8
+ //#region node_modules/uuid/dist/rng.js
9
+ var n = new Uint8Array(16);
10
+ function r() {
11
+ return crypto.getRandomValues(n);
12
+ }
13
+ //#endregion
14
+ //#region node_modules/uuid/dist/v4.js
15
+ function i(e, t, n) {
16
+ return !t && !e && crypto.randomUUID ? crypto.randomUUID() : a(e, t, n);
17
+ }
18
+ function a(e, n, i) {
19
+ e ||= {};
20
+ let a = e.random ?? e.rng?.() ?? r();
21
+ if (a.length < 16) throw Error("Random bytes length must be >= 16");
22
+ if (a[6] = a[6] & 15 | 64, a[8] = a[8] & 63 | 128, n) {
23
+ if (i ||= 0, i < 0 || i + 16 > n.length) throw RangeError(`UUID byte range ${i}:${i + 15} is out of buffer bounds`);
24
+ for (let e = 0; e < 16; ++e) n[i + e] = a[e];
25
+ return n;
26
+ }
27
+ return t(a);
28
+ }
29
+ //#endregion
30
+ export { i as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genai-fi/nanogpt",
3
- "version": "0.24.0",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "main": "dist/main.js",
6
6
  "types": "dist/main.d.ts",
@@ -29,7 +29,7 @@
29
29
  "devDependencies": {
30
30
  "@eslint/js": "^10.0.1",
31
31
  "@playwright/test": "^1.55.0",
32
- "@types/node": "^22.13.14",
32
+ "@types/node": "^26.2.0",
33
33
  "@types/papaparse": "^5.3.16",
34
34
  "@types/picomatch": "^4.0.2",
35
35
  "@types/yargs": "^17.0.33",
@@ -60,5 +60,11 @@
60
60
  "pdfjs-dist": "^5.4.149",
61
61
  "picomatch": "^4.0.3",
62
62
  "uuid": "^14.0.0"
63
+ },
64
+ "allowScripts": {
65
+ "webgpu@0.4.0": true,
66
+ "esbuild@0.28.1": true,
67
+ "core-js@3.29.1": true,
68
+ "patch-package@8.0.1": true
63
69
  }
64
70
  }
package/dist/Generator.js DELETED
@@ -1,2 +0,0 @@
1
- import { a as e, i as t } from "./main-Dz72vadm.js";
2
- export { t as default, e as isConversation };