@genai-fi/nanogpt 0.21.0 → 0.23.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/dist/{DatasetBuilder-B9UGNQT5.js → DatasetBuilder-C0iJT29K.js} +122 -93
- package/dist/Generator.js +2 -2
- package/dist/TeachableLLM.d.ts +2 -1
- package/dist/TeachableLLM.js +1 -1
- package/dist/Trainer-DBsyWJ4s.js +228 -0
- package/dist/Trainer.d.ts +2 -1
- package/dist/Trainer.js +1 -1
- package/dist/data/stream.d.ts +24 -0
- package/dist/data/stream.js +2 -0
- package/dist/data/textLoader.d.ts +2 -2
- package/dist/data/textLoader.js +28 -67
- package/dist/{BaseTokeniser-C9TSv4th.js → eventemitter3-D_qV3Lof.js} +2 -132
- package/dist/loader/load.js +2 -2
- package/dist/loader/loadHF.js +1 -1
- package/dist/loader/loadTransformers.js +2 -2
- package/dist/loader/newZipLoad.js +1 -1
- package/dist/loader/oldZipLoad.js +1 -1
- package/dist/loader/save.js +1 -1
- package/dist/{main-DdsoTJAW.js → main-BSaDGH7I.js} +2686 -2912
- package/dist/main.d.ts +4 -0
- package/dist/main.js +20 -16
- package/dist/models/NanoGPTV1.js +1 -1
- package/dist/models/NanoGPTV2.js +1 -1
- package/dist/models/factory.js +1 -1
- package/dist/models/model.js +1 -1
- package/dist/stream-BjdpSNqB.js +2296 -0
- package/dist/tokeniser/BaseTokeniser.d.ts +2 -1
- package/dist/tokeniser/BaseTokeniser.js +135 -2
- package/dist/tokeniser/CharTokeniser.d.ts +2 -2
- package/dist/tokeniser/CharTokeniser.js +10 -14
- package/dist/tokeniser/bpe.d.ts +2 -2
- package/dist/tokeniser/bpe.js +23 -32
- package/dist/tokeniser/type.d.ts +3 -2
- package/dist/training/DatasetBuilder.d.ts +17 -1
- package/dist/training/DatasetBuilder.js +2 -2
- package/dist/training/PreTrainer.js +1 -1
- package/dist/training/SFTTrainer.js +1 -1
- package/dist/training/tasks/ConversationTask.d.ts +9 -10
- package/dist/training/tasks/ConversationTask.js +15 -24
- package/dist/training/tasks/PretrainingTask.d.ts +4 -4
- package/dist/training/tasks/PretrainingTask.js +2 -2
- package/dist/training/tasks/StartSentenceTask.d.ts +4 -4
- package/dist/training/tasks/StartSentenceTask.js +3 -3
- package/dist/training/tasks/Task.d.ts +19 -12
- package/dist/training/tasks/Task.js +25 -30
- package/dist/training/tasks/TokenStore.d.ts +46 -0
- package/dist/training/tasks/TokenStore.js +215 -0
- package/dist/training/tasks/splitter.d.ts +2 -2
- package/dist/training/tasks/splitter.js +11 -11
- package/dist/training/validation.d.ts +4 -2
- package/dist/training/validation.js +21 -2
- package/dist/utilities/tokens.d.ts +2 -0
- package/dist/utilities/tokens.js +40 -0
- package/dist/utilities/topP.js +6 -0
- package/package.json +2 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { yieldIfNeeded as e } from "../../utilities/yielder.js";
|
|
2
|
+
import { createTokenStore as t, deleteTokenStore as n } from "./TokenStore.js";
|
|
2
3
|
//#region lib/training/tasks/Task.ts
|
|
3
|
-
var
|
|
4
|
-
function
|
|
4
|
+
var r = class {};
|
|
5
|
+
async function i(e, t, n, r, i, a) {
|
|
5
6
|
for (let o of e) {
|
|
6
|
-
let e = o.nextTokens(n, a ? !0 : void 0);
|
|
7
|
+
let e = await o.nextTokens(n, a ? !0 : void 0);
|
|
7
8
|
if (e) {
|
|
8
9
|
let n = Array.isArray(e) ? e : e.tokens;
|
|
9
10
|
r.total += n.length;
|
|
@@ -11,7 +12,9 @@ function n(e, t, n, r, i, a) {
|
|
|
11
12
|
if (r.offset + n.length > o.length) {
|
|
12
13
|
let c = o.length - r.offset;
|
|
13
14
|
o.set(n.slice(0, c), r.offset);
|
|
14
|
-
let l = n.length - c
|
|
15
|
+
let l = n.length - c;
|
|
16
|
+
if (l > i) throw Error(`Estimated tokens (${i}) is too small for the next batch of tokens (${l}).`);
|
|
17
|
+
let u = new Uint16Array(i);
|
|
15
18
|
if (u.set(n.slice(c), 0), t.push(u), a && s && !Array.isArray(e)) {
|
|
16
19
|
s.set(e.mask.slice(0, c).map((e) => +!!e), r.offset);
|
|
17
20
|
let t = new Uint8Array(u.length);
|
|
@@ -22,34 +25,26 @@ function n(e, t, n, r, i, a) {
|
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
|
-
async function
|
|
26
|
-
|
|
28
|
+
async function a(r, a, o) {
|
|
29
|
+
await n("training-tokens");
|
|
30
|
+
let s = await t("training-tokens", a.id, a.datasetID ?? "", o);
|
|
31
|
+
await n("validation-tokens");
|
|
32
|
+
let c = o?.validationSplit && o.validationSplit > 0 ? await t("validation-tokens", a.id, a.datasetID ?? "", o) : void 0, l = [new Uint16Array(s.shardSize)], u = o?.masking ? [new Uint8Array(s.shardSize)] : null, d = {
|
|
27
33
|
offset: 0,
|
|
28
34
|
total: 0
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let t = s[e];
|
|
38
|
-
e === s.length - 1 ? (f.set(t.subarray(0, l.offset), p), p += l.offset) : (f.set(t, p), p += t.length);
|
|
39
|
-
}
|
|
40
|
-
if (c) {
|
|
41
|
-
let e = new Uint8Array(d);
|
|
42
|
-
p = 0;
|
|
43
|
-
for (let t = 0; t < c.length; t++) {
|
|
44
|
-
let n = c[t];
|
|
45
|
-
t === c.length - 1 ? (e.set(n.subarray(0, l.offset), p), p += l.offset) : (e.set(n, p), p += n.length);
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
tokens: f,
|
|
49
|
-
mask: e
|
|
50
|
-
};
|
|
35
|
+
}, f = o?.validationSplit && o.validationSplit > 0 ? [new Uint16Array(c.shardSize)] : void 0, p = o?.masking && f ? [new Uint8Array(c.shardSize)] : null, m = {
|
|
36
|
+
offset: 0,
|
|
37
|
+
total: 0
|
|
38
|
+
}, h = performance.now();
|
|
39
|
+
for (;;) {
|
|
40
|
+
let t = o?.validationSplit && o.validationSplit > 0 && Math.random() < o.validationSplit, n = t ? f : l, g = t ? m : d, _ = t ? p : u, v = t ? c : s;
|
|
41
|
+
if (await i(r, n, a, g, v.shardSize, _ || void 0), n.length > 1 && (v.appendShard(n[0], _ ? _[0] : void 0), n.shift(), _ && _.shift()), r.every((e) => !e.hasMoreConversations())) break;
|
|
42
|
+
h = await e(h, o?.cb, d.total);
|
|
51
43
|
}
|
|
52
|
-
return f
|
|
44
|
+
return l.length === 1 && (l[0] = l[0].subarray(0, d.offset), await 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), await c.appendShard(f[0], p ? p[0].subarray(0, m.offset) : void 0)), {
|
|
45
|
+
trainingTokens: s,
|
|
46
|
+
validationTokens: f ? c : void 0
|
|
47
|
+
};
|
|
53
48
|
}
|
|
54
49
|
//#endregion
|
|
55
|
-
export {
|
|
50
|
+
export { r as Task, a as tokensFromTasks };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare class TokenStore {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly tokeniserId: string;
|
|
4
|
+
readonly datasetId: string;
|
|
5
|
+
private shards;
|
|
6
|
+
private masks?;
|
|
7
|
+
private shardCount;
|
|
8
|
+
private lastShardLength;
|
|
9
|
+
private _shardSize;
|
|
10
|
+
private dirHandle;
|
|
11
|
+
private opfsAvailable;
|
|
12
|
+
private lru;
|
|
13
|
+
private maxCachedShards;
|
|
14
|
+
constructor(tokeniserId: string, datasetId: string, name?: string, maxCachedShards?: number, shardSize?: number);
|
|
15
|
+
get shardSize(): number;
|
|
16
|
+
hasMask(): boolean;
|
|
17
|
+
getShardLength(index: number): number;
|
|
18
|
+
slice(start: number, end: number): Promise<Uint16Array>;
|
|
19
|
+
init(): Promise<void>;
|
|
20
|
+
private writeManifest;
|
|
21
|
+
private readManifest;
|
|
22
|
+
private shardFilename;
|
|
23
|
+
private maskFilename;
|
|
24
|
+
private writeShardToOPFS;
|
|
25
|
+
private writeMaskToOPFS;
|
|
26
|
+
private readShardFromOPFS;
|
|
27
|
+
private readMaskFromOPFS;
|
|
28
|
+
private touchLRU;
|
|
29
|
+
private evictIfNeeded;
|
|
30
|
+
getShard(index: number): Promise<Uint16Array>;
|
|
31
|
+
getMask(index: number): Promise<Uint8Array | undefined>;
|
|
32
|
+
getShardCount(): number;
|
|
33
|
+
getTokenCount(): number;
|
|
34
|
+
appendShard(shard: Uint16Array, mask?: Uint8Array): Promise<void>;
|
|
35
|
+
dispose(): Promise<void>;
|
|
36
|
+
clear(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export declare function getTokenStore(name: string, tokeniserId: string, datasetId: string): TokenStore | null;
|
|
39
|
+
export declare function deleteTokenStore(name: string): Promise<void>;
|
|
40
|
+
interface TokenStoreOptions {
|
|
41
|
+
maxCachedShards?: number;
|
|
42
|
+
shardSize?: number;
|
|
43
|
+
noOPFS?: boolean;
|
|
44
|
+
}
|
|
45
|
+
export declare function createTokenStore(name: string, tokeniserId: string, datasetId: string, options?: TokenStoreOptions): Promise<TokenStore>;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
//#region lib/training/tasks/TokenStore.ts
|
|
2
|
+
var e = "llm-tokenstore", t = class {
|
|
3
|
+
name;
|
|
4
|
+
tokeniserId;
|
|
5
|
+
datasetId;
|
|
6
|
+
shards = [];
|
|
7
|
+
masks;
|
|
8
|
+
shardCount = 0;
|
|
9
|
+
lastShardLength = -1;
|
|
10
|
+
_shardSize = 4e3 * 1024;
|
|
11
|
+
dirHandle = null;
|
|
12
|
+
opfsAvailable = !1;
|
|
13
|
+
lru = /* @__PURE__ */ new Map();
|
|
14
|
+
maxCachedShards;
|
|
15
|
+
constructor(t, n, r, i = 8, a = 4e3 * 1024) {
|
|
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
|
+
}
|
|
18
|
+
get shardSize() {
|
|
19
|
+
return this._shardSize;
|
|
20
|
+
}
|
|
21
|
+
hasMask() {
|
|
22
|
+
return !!this.masks;
|
|
23
|
+
}
|
|
24
|
+
getShardLength(e) {
|
|
25
|
+
if (e < 0 || e >= this.shardCount) throw RangeError(`Shard index ${e} out of range`);
|
|
26
|
+
return e === this.shardCount - 1 ? this.lastShardLength : this._shardSize;
|
|
27
|
+
}
|
|
28
|
+
async slice(e, t) {
|
|
29
|
+
if (e < 0 || t > this.getTokenCount() || e >= t) throw RangeError(`Invalid slice range: ${e} to ${t}`);
|
|
30
|
+
let n = new Uint16Array(t - e), r = 0, i = Math.floor(e / this._shardSize), a = Math.floor((t - 1) / this._shardSize);
|
|
31
|
+
for (let o = i; o <= a; o++) {
|
|
32
|
+
let i = o * this._shardSize, a = i + this.getShardLength(o), s = Math.max(e, i), c = Math.min(t, a);
|
|
33
|
+
if (s < c) {
|
|
34
|
+
let e = await this.getShard(o), t = s - i, a = c - i;
|
|
35
|
+
n.set(e.subarray(t, a), r), r += a - t;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return n;
|
|
39
|
+
}
|
|
40
|
+
async init() {
|
|
41
|
+
try {
|
|
42
|
+
let e = globalThis.navigator;
|
|
43
|
+
if (!e?.storage?.getDirectory) {
|
|
44
|
+
this.opfsAvailable = !1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let t = await e.storage.getDirectory();
|
|
48
|
+
this.dirHandle = await t.getDirectoryHandle(this.name, { create: !0 }), this.opfsAvailable = !0;
|
|
49
|
+
try {
|
|
50
|
+
let e = await this.readManifest();
|
|
51
|
+
if (e && (e?.tokenizerId !== this.tokeniserId || e?.datasetId !== this.datasetId)) for await (let e of this.dirHandle.values()) {
|
|
52
|
+
let t = e.name;
|
|
53
|
+
if (t.startsWith("shard-") || t.startsWith("mask-") || t === "manifest.json") try {
|
|
54
|
+
await this.dirHandle.removeEntry(t);
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
else e && (this.shardCount = e.shardCount, this._shardSize = e.shardSize, this.lastShardLength = e.lastShardLength, this.shards = Array(this.shardCount).fill(null), e.maskExistsIndex && Array.isArray(e.maskExistsIndex) && (this.masks = Array(this.shardCount).fill(null)));
|
|
58
|
+
} catch {}
|
|
59
|
+
} catch {
|
|
60
|
+
this.opfsAvailable = !1, this.dirHandle = null, console.warn("TokenStore: OPFS initialization failed, falling back to memory-only storage");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async writeManifest() {
|
|
64
|
+
if (!this.opfsAvailable || !this.dirHandle) return;
|
|
65
|
+
let e = {
|
|
66
|
+
tokenizerId: this.tokeniserId,
|
|
67
|
+
datasetId: this.datasetId,
|
|
68
|
+
shardSize: this._shardSize,
|
|
69
|
+
shardCount: this.shardCount,
|
|
70
|
+
lastShardLength: this.lastShardLength,
|
|
71
|
+
maskExistsIndex: (this.masks || []).map((e) => !!e),
|
|
72
|
+
timestamp: Date.now()
|
|
73
|
+
}, t = await (await this.dirHandle.getFileHandle("manifest.json", { create: !0 })).createWritable({ keepExistingData: !1 });
|
|
74
|
+
await t.write(JSON.stringify(e)), await t.close();
|
|
75
|
+
}
|
|
76
|
+
async readManifest() {
|
|
77
|
+
if (!(!this.opfsAvailable || !this.dirHandle)) try {
|
|
78
|
+
let e = await (await (await this.dirHandle.getFileHandle("manifest.json")).getFile()).text();
|
|
79
|
+
return JSON.parse(e);
|
|
80
|
+
} catch {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
shardFilename(e) {
|
|
85
|
+
return `shard-${e}.bin`;
|
|
86
|
+
}
|
|
87
|
+
maskFilename(e) {
|
|
88
|
+
return `mask-${e}.bin`;
|
|
89
|
+
}
|
|
90
|
+
async writeShardToOPFS(e, t) {
|
|
91
|
+
if (!this.opfsAvailable || !this.dirHandle) return;
|
|
92
|
+
let n = this.shardFilename(e), r = await (await this.dirHandle.getFileHandle(n, { create: !0 })).createWritable();
|
|
93
|
+
await r.write(t.buffer), await r.close();
|
|
94
|
+
}
|
|
95
|
+
async writeMaskToOPFS(e, t) {
|
|
96
|
+
if (!this.opfsAvailable || !this.dirHandle) return;
|
|
97
|
+
let n = this.maskFilename(e), r = await (await this.dirHandle.getFileHandle(n, { create: !0 })).createWritable();
|
|
98
|
+
await r.write(t.buffer), await r.close();
|
|
99
|
+
}
|
|
100
|
+
async readShardFromOPFS(e) {
|
|
101
|
+
if (!(!this.opfsAvailable || !this.dirHandle)) try {
|
|
102
|
+
let t = await (await (await this.dirHandle.getFileHandle(this.shardFilename(e))).getFile()).arrayBuffer();
|
|
103
|
+
return new Uint16Array(t);
|
|
104
|
+
} catch {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async readMaskFromOPFS(e) {
|
|
109
|
+
if (!(!this.opfsAvailable || !this.dirHandle)) try {
|
|
110
|
+
let t = await (await (await this.dirHandle.getFileHandle(this.maskFilename(e))).getFile()).arrayBuffer();
|
|
111
|
+
return new Uint8Array(t);
|
|
112
|
+
} catch {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
touchLRU(e) {
|
|
117
|
+
this.lru.delete(e), this.lru.set(e, !0);
|
|
118
|
+
}
|
|
119
|
+
evictIfNeeded() {
|
|
120
|
+
if (!(this.maxCachedShards <= 0)) for (; this.lru.size > this.maxCachedShards;) {
|
|
121
|
+
let e = this.lru.keys().next().value;
|
|
122
|
+
if (e === void 0) break;
|
|
123
|
+
this.lru.delete(e), this.shards[e] && (this.shards[e] = null), this.masks?.[e] && (this.masks[e] = null);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async getShard(e) {
|
|
127
|
+
if (!Number.isInteger(e) || e < 0 || e >= this.shards.length) throw RangeError(`Shard index ${e} out of range`);
|
|
128
|
+
let t = this.shards[e];
|
|
129
|
+
if (t) return this.touchLRU(e), t;
|
|
130
|
+
if (this.opfsAvailable) {
|
|
131
|
+
let t = await this.readShardFromOPFS(e);
|
|
132
|
+
if (t) return this.shards[e] = t, this.touchLRU(e), this.evictIfNeeded(), t;
|
|
133
|
+
}
|
|
134
|
+
throw Error(`Shard ${e} not available in memory or OPFS`);
|
|
135
|
+
}
|
|
136
|
+
async getMask(e) {
|
|
137
|
+
if (!Number.isInteger(e) || e < 0 || e >= this.shardCount || !this.masks) return;
|
|
138
|
+
let t = this.masks[e];
|
|
139
|
+
if (t) return this.touchLRU(e), t;
|
|
140
|
+
if (this.opfsAvailable) {
|
|
141
|
+
let t = await this.readMaskFromOPFS(e);
|
|
142
|
+
if (t) return this.masks[e] = t, this.touchLRU(e), this.evictIfNeeded(), t;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
getShardCount() {
|
|
146
|
+
return this.shardCount;
|
|
147
|
+
}
|
|
148
|
+
getTokenCount() {
|
|
149
|
+
return this.shardCount === 0 ? 0 : (this.shardCount - 1) * this._shardSize + this.lastShardLength;
|
|
150
|
+
}
|
|
151
|
+
async appendShard(e, t) {
|
|
152
|
+
if (this.lastShardLength >= 0 && this.lastShardLength < this._shardSize) throw Error("Previous shard was not full");
|
|
153
|
+
let n = this.shards.length;
|
|
154
|
+
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
|
+
try {
|
|
156
|
+
this.opfsAvailable && this.dirHandle && (await this.writeShardToOPFS(n, e), t && await this.writeMaskToOPFS(n, t), await this.writeManifest());
|
|
157
|
+
} catch (e) {
|
|
158
|
+
console.error(e), this.maxCachedShards = 2 ** 53 - 1;
|
|
159
|
+
}
|
|
160
|
+
this.evictIfNeeded();
|
|
161
|
+
}
|
|
162
|
+
async dispose() {
|
|
163
|
+
if (this.opfsAvailable && this.dirHandle) try {
|
|
164
|
+
for await (let e of this.dirHandle.values()) {
|
|
165
|
+
let t = e.name;
|
|
166
|
+
try {
|
|
167
|
+
await this.dirHandle.removeEntry(t);
|
|
168
|
+
} catch {}
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
let e = globalThis.navigator;
|
|
172
|
+
if (e?.storage?.getDirectory) {
|
|
173
|
+
let t = await e.storage.getDirectory();
|
|
174
|
+
t.removeEntry && await t.removeEntry(this.name, { recursive: !0 });
|
|
175
|
+
}
|
|
176
|
+
} catch {}
|
|
177
|
+
} catch {}
|
|
178
|
+
this.shards = [], this.masks = [], this.shardCount = 0, this.lastShardLength = -1, this.lru.clear(), this.dirHandle = null, this.opfsAvailable = !1;
|
|
179
|
+
}
|
|
180
|
+
async clear() {
|
|
181
|
+
if (this.shards = [], this.masks = [], this.shardCount = 0, this.lastShardLength = -1, this.lru.clear(), this.opfsAvailable && this.dirHandle) try {
|
|
182
|
+
for await (let e of this.dirHandle.values()) {
|
|
183
|
+
let t = e.name;
|
|
184
|
+
try {
|
|
185
|
+
await this.dirHandle.removeEntry(t);
|
|
186
|
+
} catch {}
|
|
187
|
+
}
|
|
188
|
+
await this.writeManifest();
|
|
189
|
+
} catch {}
|
|
190
|
+
}
|
|
191
|
+
}, n = /* @__PURE__ */ new Map();
|
|
192
|
+
function r(e, t, r) {
|
|
193
|
+
let i = n.get(e);
|
|
194
|
+
return i && i.tokeniserId === t && i.datasetId === r ? i : null;
|
|
195
|
+
}
|
|
196
|
+
async function i(e) {
|
|
197
|
+
let t = n.get(e);
|
|
198
|
+
if (t) await t.dispose(), n.delete(e);
|
|
199
|
+
else try {
|
|
200
|
+
let t = globalThis.navigator;
|
|
201
|
+
if (t?.storage?.getDirectory) {
|
|
202
|
+
let n = await t.storage.getDirectory();
|
|
203
|
+
n.removeEntry && await n.removeEntry(e, { recursive: !0 });
|
|
204
|
+
}
|
|
205
|
+
} catch {}
|
|
206
|
+
}
|
|
207
|
+
async function a(e, r, i, a) {
|
|
208
|
+
let o = n.get(e);
|
|
209
|
+
if (o && o.tokeniserId === r && o.datasetId === i) return o;
|
|
210
|
+
o && (await o.dispose(), n.delete(e));
|
|
211
|
+
let s = new t(r, i, e, a?.maxCachedShards ?? 8, a?.shardSize ?? 4e3 * 1024);
|
|
212
|
+
return a?.noOPFS || await s.init(), n.set(e, s), s;
|
|
213
|
+
}
|
|
214
|
+
//#endregion
|
|
215
|
+
export { t as TokenStore, a as createTokenStore, i as deleteTokenStore, r as getTokenStore };
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import e from "
|
|
1
|
+
import { n as e } from "../../stream-BjdpSNqB.js";
|
|
2
|
+
import t from "./ConversationTask.js";
|
|
2
3
|
//#region lib/training/tasks/splitter.ts
|
|
3
|
-
function
|
|
4
|
-
if (
|
|
5
|
-
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
let t = e.nextConversation();
|
|
4
|
+
async function n(n, r) {
|
|
5
|
+
if (r <= 0 || r >= 1) throw Error("validationSplit must be between 0 and 1");
|
|
6
|
+
let i = [], a = [];
|
|
7
|
+
for (let e of n) for (; e.hasMoreConversations();) {
|
|
8
|
+
let t = await e.nextConversation();
|
|
9
9
|
if (!t) break;
|
|
10
|
-
Math.random() <
|
|
10
|
+
Math.random() < r ? a.push(t) : i.push(t);
|
|
11
11
|
}
|
|
12
12
|
return {
|
|
13
|
-
training: new e(
|
|
14
|
-
validation: new e(
|
|
13
|
+
training: new t([new e(i)]),
|
|
14
|
+
validation: new t([new e(a)])
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
//#endregion
|
|
18
|
-
export {
|
|
18
|
+
export { n as default };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { ITokeniser
|
|
1
|
+
import { ITokeniser } from '../../tokeniser/type';
|
|
2
2
|
import { Tensor } from '@tensorflow/tfjs-core';
|
|
3
3
|
import { Dataset } from '@tensorflow/tfjs-data';
|
|
4
4
|
import { DatasetBuilder, DatasetState } from './DatasetBuilder';
|
|
5
|
-
|
|
5
|
+
import { TokenStore } from './tasks/TokenStore';
|
|
6
|
+
export declare function storeFromArray(tokens: Uint16Array[], tokenizer: ITokeniser): Promise<TokenStore>;
|
|
7
|
+
export declare function createTrainValidationDatasets(trainingTokens: Uint16Array[] | TokenStore, validationTokens: Uint16Array[] | TokenStore, tokeniser: ITokeniser, datasetBuilder: DatasetBuilder, batchSize: number): Promise<{
|
|
6
8
|
trainDataset: Dataset<{
|
|
7
9
|
xs: Tensor;
|
|
8
10
|
ys: Tensor;
|
|
@@ -1,2 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { TokenStore as e, createTokenStore as t } from "./tasks/TokenStore.js";
|
|
2
|
+
//#region lib/training/validation.ts
|
|
3
|
+
async function n(e, n) {
|
|
4
|
+
let r = await t("training-tokens", n.id, n.datasetID ?? ""), i = e.map((e) => r.appendShard(e));
|
|
5
|
+
return await Promise.all(i), r;
|
|
6
|
+
}
|
|
7
|
+
async function r(t, r, i, a, o) {
|
|
8
|
+
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, {
|
|
9
|
+
batchSize: o,
|
|
10
|
+
shuffleFirst: !0
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
trainDataset: u,
|
|
14
|
+
validationDataset: f,
|
|
15
|
+
size: l,
|
|
16
|
+
validationState: p,
|
|
17
|
+
trainState: d
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { r as createTrainValidationDatasets, n as storeFromArray };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare function sliceUint16Shards(shards: readonly Uint16Array[], start: number, endExclusive: number, shardSize?: number): Uint16Array;
|
|
2
|
+
export declare function sliceUint8Shards(shards: readonly Uint8Array[], start: number, endExclusive: number, shardSize?: number): Uint8Array;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region lib/utilities/tokens.ts
|
|
2
|
+
function e(e, t, n, r = e[0]?.length ?? 0) {
|
|
3
|
+
if (e.length === 0) return new Uint16Array();
|
|
4
|
+
if (!Number.isInteger(t) || !Number.isInteger(n)) throw RangeError("start/endExclusive must be integers");
|
|
5
|
+
if (t < 0 || n < t) throw RangeError(`Invalid range [${t}, ${n})`);
|
|
6
|
+
if (r <= 0) throw RangeError("Invalid shardSize");
|
|
7
|
+
let i = e[e.length - 1], a = (e.length - 1) * r + i.length;
|
|
8
|
+
if (n > a) throw RangeError(`Slice end ${n} is out of bounds for total length ${a}`);
|
|
9
|
+
if (t === n) return new Uint16Array();
|
|
10
|
+
let o = new Uint16Array(n - t), s = 0, c = t;
|
|
11
|
+
for (; c < n;) {
|
|
12
|
+
let t = Math.floor(c / r), i = c - t * r, a = e[t], l = Math.min(n - c, a.length - i);
|
|
13
|
+
try {
|
|
14
|
+
o.set(a.subarray(i, i + l), s);
|
|
15
|
+
} catch (n) {
|
|
16
|
+
throw console.error(`Error slicing shards: shardIndex=${t}, shardOffset=${i}, take=${l}, writeOffset=${s}`), e.forEach((t, n) => {
|
|
17
|
+
t.length !== r && n !== e.length - 1 && console.error(`Shard ${n} has length ${t.length}, expected ${r}`);
|
|
18
|
+
}), n;
|
|
19
|
+
}
|
|
20
|
+
c += l, s += l;
|
|
21
|
+
}
|
|
22
|
+
return o;
|
|
23
|
+
}
|
|
24
|
+
function t(e, t, n, r = e[0]?.length ?? 0) {
|
|
25
|
+
if (e.length === 0) return new Uint8Array();
|
|
26
|
+
if (!Number.isInteger(t) || !Number.isInteger(n)) throw RangeError("start/endExclusive must be integers");
|
|
27
|
+
if (t < 0 || n < t) throw RangeError(`Invalid range [${t}, ${n})`);
|
|
28
|
+
if (r <= 0) throw RangeError("Invalid shardSize");
|
|
29
|
+
let i = e[e.length - 1], a = (e.length - 1) * r + i.length;
|
|
30
|
+
if (n > a) throw RangeError(`Slice end ${n} is out of bounds for total length ${a}`);
|
|
31
|
+
if (t === n) return new Uint8Array();
|
|
32
|
+
let o = new Uint8Array(n - t), s = 0, c = t;
|
|
33
|
+
for (; c < n;) {
|
|
34
|
+
let t = Math.floor(c / r), i = c - t * r, a = e[t], l = Math.min(n - c, a.length - i);
|
|
35
|
+
o.set(a.subarray(i, i + l), s), c += l, s += l;
|
|
36
|
+
}
|
|
37
|
+
return o;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { e as sliceUint16Shards, t as sliceUint8Shards };
|
package/dist/utilities/topP.js
CHANGED
|
@@ -6,6 +6,12 @@ function e(e, t) {
|
|
|
6
6
|
})).sort((e, t) => t.prob - e.prob), r = 0, i = Array(n.length).fill(0);
|
|
7
7
|
for (let e of n) if (r += e.prob, i[e.index] = e.prob, r >= t) break;
|
|
8
8
|
let a = i.reduce((e, t) => e + t, 0);
|
|
9
|
+
if (a === 0) {
|
|
10
|
+
let t = e[0], n = t.reduce((e, t) => e + t, 0);
|
|
11
|
+
if (n > 0) return t.map((e) => e / n);
|
|
12
|
+
let r = 1 / t.length;
|
|
13
|
+
return t.map(() => r);
|
|
14
|
+
}
|
|
9
15
|
return i.map((e) => e / a);
|
|
10
16
|
}
|
|
11
17
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genai-fi/nanogpt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"types": "dist/main.d.ts",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@tensorflow/tfjs": "^4.22.0",
|
|
54
54
|
"@tensorflow/tfjs-backend-webgpu": "^4.22.0",
|
|
55
|
+
"@zip.js/zip.js": "^2.8.34",
|
|
55
56
|
"eventemitter3": "^5.0.1",
|
|
56
57
|
"jszip": "^3.10.1",
|
|
57
58
|
"papaparse": "^5.5.3",
|