@genai-fi/nanogpt 0.23.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.
- package/README.md +78 -281
- package/dist/{DatasetBuilder-C0iJT29K.js → DatasetBuilder-DU1G1OKX.js} +20 -23
- package/dist/{RealDiv-CNsvC4AU.js → RealDiv-CSnvtN2E.js} +20 -20
- package/dist/{Reshape-dnm9bO3B.js → Reshape-BlylqwWy.js} +12 -12
- package/dist/TeachableLLM.d.ts +10 -15
- package/dist/TeachableLLM.js +201 -2
- package/dist/api/responses.d.ts +81 -0
- package/dist/api/responses.js +169 -0
- package/dist/api/training.d.ts +70 -0
- package/dist/api/training.js +205 -0
- package/dist/data/docx.js +9 -3036
- package/dist/data/stream.d.ts +8 -8
- package/dist/data/stream.js +1 -1
- package/dist/data/textLoader.d.ts +1 -1
- package/dist/data/textLoader.js +2 -2
- package/dist/data.d.ts +3 -0
- package/dist/data.js +12 -0
- package/dist/{dist-BqAU9-yi.js → dist-CwK5S7Ls.js} +2168 -2168
- package/dist/{gpgpu_math-DBYEAAdI.js → gpgpu_math-20tPK8LM.js} +458 -458
- package/dist/{Generator.d.ts → inference/Generator.d.ts} +16 -44
- package/dist/inference/Generator.js +271 -0
- package/dist/inference/tokenisePrompt.d.ts +4 -0
- package/dist/inference/tokenisePrompt.js +13 -0
- package/dist/inference/types.d.ts +44 -8
- package/dist/inference/utilities.d.ts +9 -0
- package/dist/inference/utilities.js +20 -0
- package/dist/jszip.min-DKa1Rjyn.js +3033 -0
- package/dist/{kernel_funcs_utils-D-mATnGR.js → kernel_funcs_utils-ql8Y8qPn.js} +96 -93
- package/dist/layers/MLP.d.ts +1 -1
- package/dist/layers/PositionEmbedding.d.ts +2 -1
- package/dist/layers/PositionEmbedding.js +1 -1
- package/dist/layers/RMSNorm.d.ts +1 -1
- package/dist/layers/TiedEmbedding.js +1 -1
- package/dist/layers.d.ts +4 -0
- package/dist/layers.js +14 -0
- package/dist/loader/load.js +58 -2
- package/dist/loader/loadHF.d.ts +1 -1
- package/dist/loader/loadHF.js +17 -2
- package/dist/loader/loadTransformers.js +46 -2
- package/dist/loader/newZipLoad.js +25 -2
- package/dist/loader/oldZipLoad.d.ts +1 -1
- package/dist/loader/oldZipLoad.js +37 -2
- package/dist/loader/save.js +75 -2
- package/dist/loader/types.d.ts +3 -3
- package/dist/main.d.ts +34 -43
- package/dist/main.js +12327 -20
- package/dist/{matMulGelu-BAIgQaRx.js → matMulGelu-CBoqTZM7.js} +2 -2
- package/dist/models/NanoGPTV1.js +95 -2
- package/dist/models/NanoGPTV2.js +86 -2
- package/dist/models/factory.js +13 -2
- package/dist/models/model.js +76 -2
- package/dist/models.d.ts +4 -0
- package/dist/models.js +14 -0
- package/dist/ops/dot16.js +1 -1
- package/dist/ops/matMulGelu.js +1 -1
- package/dist/ops/webgl/adamAdjust.js +1 -1
- package/dist/ops/webgl/fusedSoftmax.js +2 -2
- package/dist/ops/webgl/gelu.js +2 -2
- package/dist/ops/webgl/log.js +5 -5
- package/dist/ops/webgl/matMulGelu.js +1 -1
- package/dist/ops/webgl/matMulMul.js +1 -1
- package/dist/{stream-BjdpSNqB.js → stream-BpAwcvHz.js} +565 -561
- package/dist/{tfjs_backend-CydPRQTc.js → tfjs_backend-h5weiy1O.js} +36 -36
- package/dist/tokenise.d.ts +4 -0
- package/dist/tokenise.js +15 -0
- package/dist/tokeniser/CharTokeniser.js +18 -20
- package/dist/tokeniser/bpe.js +18 -22
- package/dist/training/BasicTrainer.d.ts +5 -10
- package/dist/training/BasicTrainer.js +80 -88
- package/dist/training/DatasetBuilder.d.ts +4 -4
- package/dist/training/DatasetBuilder.js +1 -1
- package/dist/training/PreTrainer.js +1 -1
- package/dist/training/SFTTrainer.js +1 -1
- package/dist/training/configure.d.ts +3 -0
- package/dist/training/configure.js +32 -0
- package/dist/training/factory.d.ts +6 -0
- package/dist/training/factory.js +8 -0
- package/dist/training/prepareData.d.ts +22 -0
- package/dist/training/prepareData.js +49 -0
- package/dist/training/tasks/TokenStore.d.ts +2 -1
- package/dist/training/tasks/TokenStore.js +8 -5
- package/dist/training/tasks/tokenStream.d.ts +17 -0
- package/dist/training/tasks/tokenStream.js +46 -0
- package/dist/training/types.d.ts +14 -1
- package/dist/training/validateOptions.d.ts +2 -0
- package/dist/training/validateOptions.js +19 -0
- package/dist/training/validation.js +4 -2
- package/dist/utilities/arrayShape.d.ts +1 -0
- package/dist/utilities/arrayShape.js +8 -0
- package/dist/utilities/random.d.ts +1 -0
- package/dist/utilities/random.js +19 -0
- package/dist/utilities/waitForModel.d.ts +1 -1
- package/dist/v4-BK7K-jy_.js +30 -0
- package/package.json +8 -2
- package/dist/Generator.js +0 -2
- package/dist/Trainer-DBsyWJ4s.js +0 -228
- package/dist/Trainer.d.ts +0 -45
- package/dist/Trainer.js +0 -2
- package/dist/main-BSaDGH7I.js +0 -13274
- package/dist/training/tasks/ConversationTask.d.ts +0 -17
- package/dist/training/tasks/ConversationTask.js +0 -29
- package/dist/training/tasks/PretrainingTask.d.ts +0 -17
- package/dist/training/tasks/PretrainingTask.js +0 -42
- package/dist/training/tasks/StartSentenceTask.d.ts +0 -18
- package/dist/training/tasks/StartSentenceTask.js +0 -45
- package/dist/training/tasks/Task.d.ts +0 -29
- package/dist/training/tasks/Task.js +0 -50
- package/dist/training/tasks/splitter.d.ts +0 -5
- package/dist/training/tasks/splitter.js +0 -18
|
@@ -7,11 +7,11 @@ export declare function flattenTokensWithMask(textData: Conversation[][], tokeni
|
|
|
7
7
|
tokens: Uint16Array;
|
|
8
8
|
mask: Uint8Array;
|
|
9
9
|
};
|
|
10
|
-
export declare function shuffle(array: Uint32Array): Uint32Array;
|
|
10
|
+
export declare function shuffle(array: Uint32Array | Uint16Array): Uint32Array | Uint16Array;
|
|
11
11
|
export interface DatasetState {
|
|
12
|
-
shuffledShards:
|
|
13
|
-
shuffledIndexes:
|
|
14
|
-
lastShardIndexes:
|
|
12
|
+
shuffledShards: Uint16Array;
|
|
13
|
+
shuffledIndexes: Uint16Array;
|
|
14
|
+
lastShardIndexes: Uint16Array;
|
|
15
15
|
currentShard: Uint16Array | null;
|
|
16
16
|
nextShard: Uint16Array | null;
|
|
17
17
|
currentMask: Uint8Array | null;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, r, t as i } from "../DatasetBuilder-
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "../DatasetBuilder-DU1G1OKX.js";
|
|
2
2
|
export { i as DatasetBuilder, n as flattenTokens, r as flattenTokensWithMask, t as moveToNext, e as shuffle };
|
|
@@ -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,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 };
|
|
@@ -31,7 +31,8 @@ export declare class TokenStore {
|
|
|
31
31
|
getMask(index: number): Promise<Uint8Array | undefined>;
|
|
32
32
|
getShardCount(): number;
|
|
33
33
|
getTokenCount(): number;
|
|
34
|
-
|
|
34
|
+
finish(): Promise<void>;
|
|
35
|
+
appendShard(shard: Uint16Array, mask?: Uint8Array): void;
|
|
35
36
|
dispose(): Promise<void>;
|
|
36
37
|
clear(): Promise<void>;
|
|
37
38
|
}
|
|
@@ -7,12 +7,12 @@ var e = "llm-tokenstore", t = class {
|
|
|
7
7
|
masks;
|
|
8
8
|
shardCount = 0;
|
|
9
9
|
lastShardLength = -1;
|
|
10
|
-
_shardSize =
|
|
10
|
+
_shardSize = 8e3 * 1024;
|
|
11
11
|
dirHandle = null;
|
|
12
12
|
opfsAvailable = !1;
|
|
13
13
|
lru = /* @__PURE__ */ new Map();
|
|
14
14
|
maxCachedShards;
|
|
15
|
-
constructor(t, n, r, i =
|
|
15
|
+
constructor(t, n, r, i = 2, a = 8e3 * 1024) {
|
|
16
16
|
this.tokeniserId = t, this.datasetId = n, this.maxCachedShards = Math.max(1, Math.trunc(i)), this._shardSize = Math.max(1, Math.trunc(a)), this.name = r ?? e;
|
|
17
17
|
}
|
|
18
18
|
get shardSize() {
|
|
@@ -148,12 +148,15 @@ var e = "llm-tokenstore", t = class {
|
|
|
148
148
|
getTokenCount() {
|
|
149
149
|
return this.shardCount === 0 ? 0 : (this.shardCount - 1) * this._shardSize + this.lastShardLength;
|
|
150
150
|
}
|
|
151
|
-
async
|
|
151
|
+
async finish() {
|
|
152
|
+
await this.writeManifest();
|
|
153
|
+
}
|
|
154
|
+
appendShard(e, t) {
|
|
152
155
|
if (this.lastShardLength >= 0 && this.lastShardLength < this._shardSize) throw Error("Previous shard was not full");
|
|
153
156
|
let n = this.shards.length;
|
|
154
157
|
this.shards.push(e), !this.masks && t && (this.masks = Array(n).fill(null)), this.masks && this.masks.push(t ?? null), this.shardCount = this.shards.length, this.lastShardLength = e.length, this.touchLRU(n);
|
|
155
158
|
try {
|
|
156
|
-
this.opfsAvailable && this.dirHandle && (
|
|
159
|
+
this.opfsAvailable && this.dirHandle && (this.writeShardToOPFS(n, e), t && this.writeMaskToOPFS(n, t));
|
|
157
160
|
} catch (e) {
|
|
158
161
|
console.error(e), this.maxCachedShards = 2 ** 53 - 1;
|
|
159
162
|
}
|
|
@@ -208,7 +211,7 @@ async function a(e, r, i, a) {
|
|
|
208
211
|
let o = n.get(e);
|
|
209
212
|
if (o && o.tokeniserId === r && o.datasetId === i) return o;
|
|
210
213
|
o && (await o.dispose(), n.delete(e));
|
|
211
|
-
let s = new t(r, i, e, a?.maxCachedShards
|
|
214
|
+
let s = new t(r, i, e, a?.maxCachedShards, a?.shardSize);
|
|
212
215
|
return a?.noOPFS || await s.init(), n.set(e, s), s;
|
|
213
216
|
}
|
|
214
217
|
//#endregion
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ITokeniser } from '../../../tokeniser/type';
|
|
2
|
+
import { ConversationStream } from '../../../data/stream';
|
|
3
|
+
import { TokenStore } from './TokenStore';
|
|
4
|
+
interface TokensFromTasksOptions {
|
|
5
|
+
masking?: boolean;
|
|
6
|
+
maxCachedShards?: number;
|
|
7
|
+
noOPFS?: boolean;
|
|
8
|
+
shardSize?: number;
|
|
9
|
+
validationSplit?: number;
|
|
10
|
+
validationSeed?: string | number;
|
|
11
|
+
cb?: (tokens: number) => void;
|
|
12
|
+
}
|
|
13
|
+
export declare function tokensFromStreams(tasks: ConversationStream[], tokenizer: ITokeniser, options?: TokensFromTasksOptions): Promise<{
|
|
14
|
+
trainingTokens: TokenStore;
|
|
15
|
+
validationTokens?: TokenStore;
|
|
16
|
+
}>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createTokenStore as e, deleteTokenStore as t } from "./TokenStore.js";
|
|
2
|
+
import { seededRng as n } from "../../utilities/random.js";
|
|
3
|
+
//#region lib/training/tasks/tokenStream.ts
|
|
4
|
+
function r(e, t, n, r, i, a) {
|
|
5
|
+
let o = n.encodeConversation(e, !1, !!a);
|
|
6
|
+
if (o) {
|
|
7
|
+
let e = Array.isArray(o) ? o : o.tokens;
|
|
8
|
+
r.total += e.length;
|
|
9
|
+
let n = t[t.length - 1], s = a ? a[a.length - 1] : null;
|
|
10
|
+
if (r.offset + e.length > n.length) {
|
|
11
|
+
let c = n.length - r.offset;
|
|
12
|
+
n.set(e.slice(0, c), r.offset);
|
|
13
|
+
let l = e.length - c;
|
|
14
|
+
if (l > i) throw Error(`Estimated tokens (${i}) is too small for the next batch of tokens (${l}).`);
|
|
15
|
+
let u = new Uint16Array(i);
|
|
16
|
+
if (u.set(e.slice(c), 0), t.push(u), a && s && !Array.isArray(o)) {
|
|
17
|
+
s.set(o.mask.slice(0, c).map((e) => +!!e), r.offset);
|
|
18
|
+
let e = new Uint8Array(u.length);
|
|
19
|
+
e.set(o.mask.slice(c).map((e) => +!!e), 0), a.push(e);
|
|
20
|
+
}
|
|
21
|
+
r.offset = e.length - c;
|
|
22
|
+
} else n.set(e, r.offset), s && !Array.isArray(o) && s.set(o.mask.map((e) => +!!e), r.offset), r.offset += e.length;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function i(i, a, o) {
|
|
26
|
+
await t("training-tokens");
|
|
27
|
+
let s = await e("training-tokens", a.id, a.datasetID ?? "", o);
|
|
28
|
+
await t("validation-tokens");
|
|
29
|
+
let c = o?.validationSplit && o.validationSplit > 0 ? await e("validation-tokens", a.id, a.datasetID ?? "", o) : void 0, l = [new Uint16Array(s.shardSize)], u = o?.masking ? [new Uint8Array(s.shardSize)] : null, d = {
|
|
30
|
+
offset: 0,
|
|
31
|
+
total: 0
|
|
32
|
+
}, f = o?.validationSplit && o.validationSplit > 0 ? [new Uint16Array(c.shardSize)] : void 0, p = o?.masking && f ? [new Uint8Array(c.shardSize)] : null, m = {
|
|
33
|
+
offset: 0,
|
|
34
|
+
total: 0
|
|
35
|
+
}, h = 0, g = o?.cb, _ = o?.validationSeed === void 0 ? Math.random : n(o.validationSeed);
|
|
36
|
+
for (; h < i.length;) await i[h++].begin((e) => {
|
|
37
|
+
let t = o?.validationSplit && o.validationSplit > 0 && _() < o.validationSplit, n = t ? f : l, i = t ? m : d, h = t ? p : u, g = t ? c : s;
|
|
38
|
+
r(e, n, a, i, g.shardSize, h || void 0), n.length > 1 && (g.appendShard(n[0], h ? h[0] : void 0), n.shift(), h && h.shift());
|
|
39
|
+
}, g ? () => g(d.total) : void 0);
|
|
40
|
+
return l.length === 1 && (l[0] = l[0].subarray(0, d.offset), s.appendShard(l[0], u ? u[0].subarray(0, d.offset) : void 0)), f && f.length === 1 && (f[0] = f[0].subarray(0, m.offset), c.appendShard(f[0], p ? p[0].subarray(0, m.offset) : void 0)), await s.finish(), c && await c.finish(), {
|
|
41
|
+
trainingTokens: s,
|
|
42
|
+
validationTokens: f ? c : void 0
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { i as tokensFromStreams };
|
package/dist/training/types.d.ts
CHANGED
|
@@ -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,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 };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { TokenStore as e, createTokenStore as t } from "./tasks/TokenStore.js";
|
|
2
2
|
//#region lib/training/validation.ts
|
|
3
3
|
async function n(e, n) {
|
|
4
|
-
let r = await t("training-tokens", n.id, n.datasetID ?? "")
|
|
5
|
-
return
|
|
4
|
+
let r = await t("training-tokens", n.id, n.datasetID ?? "");
|
|
5
|
+
return e.forEach((e) => {
|
|
6
|
+
r.appendShard(e);
|
|
7
|
+
}), await r.finish(), r;
|
|
6
8
|
}
|
|
7
9
|
async function r(t, r, i, a, o) {
|
|
8
10
|
let s = t instanceof e ? t : await n(t, i), c = r instanceof e ? r : await n(r, i), l = s.getTokenCount(), { dataset: u, state: d } = await a.createTextDataset(s, { batchSize: o }), { dataset: f, state: p } = await a.createTextDataset(c, {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function arrayShape(arr: unknown[]): number[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function seededRng(seed: string | number): () => number;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region lib/utilities/random.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
let t = 1779033703 ^ e.length;
|
|
4
|
+
for (let n = 0; n < e.length; n++) t = Math.imul(t ^ e.charCodeAt(n), 3432918353), t = t << 13 | t >>> 19;
|
|
5
|
+
return () => (t = Math.imul(t ^ t >>> 16, 2246822507), t = Math.imul(t ^ t >>> 13, 3266489909), (t ^= t >>> 16) >>> 0);
|
|
6
|
+
}
|
|
7
|
+
function t(e) {
|
|
8
|
+
let t = e >>> 0;
|
|
9
|
+
return () => {
|
|
10
|
+
t += 1831565813;
|
|
11
|
+
let e = Math.imul(t ^ t >>> 15, t | 1);
|
|
12
|
+
return e ^= e + Math.imul(e ^ e >>> 7, e | 61), ((e ^ e >>> 14) >>> 0) / 4294967296;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function n(n) {
|
|
16
|
+
return t(typeof n == "number" ? n >>> 0 : e(n)());
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { n as seededRng };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { TeachableLLM } from '../../
|
|
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.
|
|
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": "^
|
|
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