@genai-fi/nanogpt 0.16.1 → 0.17.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/Generator.d.ts +5 -0
- package/dist/Generator.js +193 -168
- package/dist/Trainer.js +89 -40
- package/dist/layers/LoRA.d.ts +5 -3
- package/dist/layers/LoRA.js +38 -32
- package/dist/loader/load.js +39 -39
- package/dist/loader/loadTransformers.js +11 -10
- package/dist/loader/save.js +17 -16
- package/dist/loader/types.d.ts +2 -1
- package/dist/models/config.d.ts +2 -1
- package/dist/models/config.js +24 -17
- package/dist/models/model.d.ts +9 -2
- package/dist/models/model.js +57 -19
- package/dist/training/types.d.ts +1 -0
- package/package.json +3 -2
package/dist/Trainer.js
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
import { E as
|
|
2
|
-
import
|
|
3
|
-
import { createTrainValidationSplit as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
1
|
+
import { E as f } from "./index-DvYrXKkX.js";
|
|
2
|
+
import l from "./training/PreTrainer.js";
|
|
3
|
+
import { createTrainValidationSplit as p } from "./training/validation.js";
|
|
4
|
+
import g from "./training/SFTTrainer.js";
|
|
5
|
+
import m from "./training/tasks/splitter.js";
|
|
6
|
+
const n = [];
|
|
7
|
+
for (let a = 0; a < 256; ++a)
|
|
8
|
+
n.push((a + 256).toString(16).slice(1));
|
|
9
|
+
function u(a, t = 0) {
|
|
10
|
+
return (n[a[t + 0]] + n[a[t + 1]] + n[a[t + 2]] + n[a[t + 3]] + "-" + n[a[t + 4]] + n[a[t + 5]] + "-" + n[a[t + 6]] + n[a[t + 7]] + "-" + n[a[t + 8]] + n[a[t + 9]] + "-" + n[a[t + 10]] + n[a[t + 11]] + n[a[t + 12]] + n[a[t + 13]] + n[a[t + 14]] + n[a[t + 15]]).toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
const w = new Uint8Array(16);
|
|
13
|
+
function S() {
|
|
14
|
+
return crypto.getRandomValues(w);
|
|
15
|
+
}
|
|
16
|
+
function c(a, t, i) {
|
|
17
|
+
return crypto.randomUUID ? crypto.randomUUID() : D(a);
|
|
18
|
+
}
|
|
19
|
+
function D(a, t, i) {
|
|
20
|
+
a = a || {};
|
|
21
|
+
const e = a.random ?? a.rng?.() ?? S();
|
|
22
|
+
if (e.length < 16)
|
|
23
|
+
throw new Error("Random bytes length must be >= 16");
|
|
24
|
+
return e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128, u(e);
|
|
25
|
+
}
|
|
26
|
+
class d extends f {
|
|
7
27
|
trainer;
|
|
8
28
|
trainingType = "pretraining";
|
|
9
29
|
hasTrained = !1;
|
|
@@ -18,21 +38,21 @@ class l extends g {
|
|
|
18
38
|
logInterval: 10
|
|
19
39
|
};
|
|
20
40
|
tokenizer;
|
|
21
|
-
constructor(t, i, e = "pretraining",
|
|
22
|
-
if (super(), t instanceof
|
|
23
|
-
const
|
|
24
|
-
let
|
|
25
|
-
t.trainingType === "sft" &&
|
|
41
|
+
constructor(t, i, e = "pretraining", r) {
|
|
42
|
+
if (super(), t instanceof d) {
|
|
43
|
+
const s = i || t.options, h = t.options;
|
|
44
|
+
let o = !1;
|
|
45
|
+
t.trainingType === "sft" && s.sftMode !== h.sftMode && (o = !0), e !== t.trainingType && (o = !0), o ? (t.trainingType === "sft" ? this.trainer = new g(t.model, t.tokenizer, s) : this.trainer = new l(t.model, t.tokenizer, s), this.trainingType = e, this.options = s, this.tokenizer = t.tokenizer) : (this.trainer = t.trainer, this.trainingType = e, this.options = s, this.trainer.updateOptimizer(this.options), this.log = t.log, this.progress = t.progress, this.totalSamples = t.totalSamples, this.tokenizer = t.tokenizer, s.batchSize === h.batchSize && (this.trainDataset = t.trainDataset, this.validationDataset = t.validationDataset));
|
|
26
46
|
return;
|
|
27
47
|
}
|
|
28
48
|
if (!i)
|
|
29
49
|
throw new Error("Tokeniser must be provided when initializing Trainer with a model");
|
|
30
50
|
if (!t)
|
|
31
51
|
throw new Error("Model must be provided when initializing Trainer");
|
|
32
|
-
this.options =
|
|
52
|
+
this.options = r || {
|
|
33
53
|
batchSize: 32,
|
|
34
54
|
sftMode: "full"
|
|
35
|
-
}, e === "sft" ? this.trainer = new
|
|
55
|
+
}, e === "sft" ? this.trainer = new g(t, i, r) : this.trainer = new l(t, i, r), this.trainingType = e, this.tokenizer = i;
|
|
36
56
|
}
|
|
37
57
|
get model() {
|
|
38
58
|
return this.trainer.model;
|
|
@@ -81,41 +101,70 @@ class l extends g {
|
|
|
81
101
|
}
|
|
82
102
|
async prepare(t = []) {
|
|
83
103
|
const i = this.options;
|
|
84
|
-
if (this.trainingType === "pretraining" && this.trainer instanceof
|
|
85
|
-
const { trainDataset: e, validationDataset:
|
|
104
|
+
if (this.trainingType === "pretraining" && this.trainer instanceof l) {
|
|
105
|
+
const { trainDataset: e, validationDataset: r, size: s, trainState: h } = await p(
|
|
86
106
|
t,
|
|
87
107
|
this.trainer.tokenizer,
|
|
88
108
|
this.trainer.datasetBuilder,
|
|
89
109
|
i?.batchSize || 32,
|
|
90
110
|
i?.validationSplit || 0.1
|
|
91
|
-
),
|
|
92
|
-
this.trainDataset = e, this.validationDataset =
|
|
93
|
-
} else if (this.trainingType === "sft" && this.trainer instanceof
|
|
111
|
+
), o = s * (1 - (i?.validationSplit || 0));
|
|
112
|
+
this.trainDataset = e, this.validationDataset = r, this.totalSamples = o, this.options.epochSteps = Math.ceil(h.shuffledIndexes.length / (i?.batchSize || 32)), this.trainer.updateOptimizer(this.options);
|
|
113
|
+
} else if (this.trainingType === "sft" && this.trainer instanceof g) {
|
|
94
114
|
if (t instanceof Uint16Array)
|
|
95
115
|
throw new Error("SFT training requires Task[] input");
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
116
|
+
if (i?.validationSplit && i.validationSplit > 0) {
|
|
117
|
+
const e = m(t, i?.validationSplit), r = await this.trainer.datasetBuilder.createSFTDataset(
|
|
118
|
+
[e.training],
|
|
119
|
+
i?.batchSize || 32,
|
|
120
|
+
-100
|
|
121
|
+
), s = await this.trainer.datasetBuilder.createSFTDataset(
|
|
122
|
+
[e.validation],
|
|
123
|
+
i?.batchSize || 32,
|
|
124
|
+
-100
|
|
125
|
+
);
|
|
126
|
+
this.validationDataset = s, this.trainDataset = r;
|
|
127
|
+
} else {
|
|
128
|
+
const e = await this.trainer.datasetBuilder.createSFTDataset(
|
|
129
|
+
t,
|
|
130
|
+
i?.batchSize || 32,
|
|
131
|
+
-100
|
|
132
|
+
);
|
|
133
|
+
this.trainDataset = e;
|
|
134
|
+
}
|
|
135
|
+
this.totalSamples = t.reduce((e, r) => e + r.length, 0), this.options.epochSteps = Math.ceil(this.totalSamples / (i?.batchSize || 32)), this.trainer.updateOptimizer(this.options);
|
|
106
136
|
}
|
|
107
137
|
}
|
|
108
138
|
configureModel(t) {
|
|
109
139
|
const i = t?.sftMode || "full";
|
|
110
140
|
if (this.trainingType === "pretraining" && (this.trainer.model.hasLoRA() && this.trainer.model.detachLoRA(), this.trainer.model.weightStore.setTrainable(["*"])), this.trainingType === "sft") {
|
|
111
141
|
if (i === "lora") {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
142
|
+
const e = this.trainer.model;
|
|
143
|
+
if (t?.loraName)
|
|
144
|
+
if (e.hasLoRA(t.loraName)) {
|
|
145
|
+
if (e.attachLoRA(t.loraName), t.loraConfig) {
|
|
146
|
+
const r = e.lora;
|
|
147
|
+
(r.alpha !== t.loraConfig.alpha || r.rank !== t.loraConfig.rank) && (e.detachLoRA(), e.deleteLoRA(t.loraName), e.createLoRA(t.loraName, t.loraConfig), e.attachLoRA(t.loraName), console.warn("Resetting LoRA with new configuration."));
|
|
148
|
+
}
|
|
149
|
+
} else if (t.loraConfig)
|
|
150
|
+
e.createLoRA(t.loraName, t.loraConfig), e.attachLoRA(t.loraName);
|
|
151
|
+
else
|
|
152
|
+
throw new Error(
|
|
153
|
+
`LoRA configuration must be provided to create LoRA with name ${t.loraName}`
|
|
154
|
+
);
|
|
155
|
+
else if (t?.loraConfig)
|
|
156
|
+
if (e.hasLoRA()) {
|
|
157
|
+
const r = e.lora;
|
|
158
|
+
if (r.alpha !== t.loraConfig.alpha || r.rank !== t.loraConfig.rank) {
|
|
159
|
+
e.detachLoRA();
|
|
160
|
+
const s = t.loraName || c();
|
|
161
|
+
e.createLoRA(s, t.loraConfig), e.attachLoRA(s);
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
const r = t.loraName || c();
|
|
165
|
+
e.createLoRA(r, t.loraConfig), e.attachLoRA(r);
|
|
166
|
+
}
|
|
167
|
+
else if (!e.hasLoRA()) throw new Error("LoRA configuration must be provided for lora SFT mode");
|
|
119
168
|
} else
|
|
120
169
|
this.trainer.model.hasLoRA() && this.trainer.model.detachLoRA();
|
|
121
170
|
i === "last-layer" ? this.trainer.model.weightStore.setTrainable([
|
|
@@ -143,8 +192,8 @@ class l extends g {
|
|
|
143
192
|
)
|
|
144
193
|
};
|
|
145
194
|
const e = this.listeners("log");
|
|
146
|
-
for (const
|
|
147
|
-
await
|
|
195
|
+
for (const r of e)
|
|
196
|
+
await r(i, this.progress);
|
|
148
197
|
}
|
|
149
198
|
},
|
|
150
199
|
this.validationDataset
|
|
@@ -155,8 +204,8 @@ class l extends g {
|
|
|
155
204
|
throw new Error("Dataset not prepared");
|
|
156
205
|
this.hasTrained || this.trainer.setLearningRate(t?.learningRate || 1e-3), this.hasTrained = !0, this.emit("start");
|
|
157
206
|
const { log: i } = await this.trainer.stepDataset(this.trainDataset, t || {}, this.validationDataset), e = this.listeners("log");
|
|
158
|
-
for (const
|
|
159
|
-
await
|
|
207
|
+
for (const r of e)
|
|
208
|
+
await r(i, {
|
|
160
209
|
lastLog: i,
|
|
161
210
|
progress: i.totalSamples / this.totalSamples,
|
|
162
211
|
remaining: Math.max(0, (this.totalSamples - i.totalSamples) / i.totalSamples * i.duration)
|
|
@@ -174,5 +223,5 @@ class l extends g {
|
|
|
174
223
|
}
|
|
175
224
|
}
|
|
176
225
|
export {
|
|
177
|
-
|
|
226
|
+
d as default
|
|
178
227
|
};
|
package/dist/layers/LoRA.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ export default class LoRA {
|
|
|
3
3
|
private weightStore;
|
|
4
4
|
readonly alpha: number;
|
|
5
5
|
readonly rank: number;
|
|
6
|
-
|
|
6
|
+
readonly variables: Set<string>;
|
|
7
7
|
private scale;
|
|
8
|
-
|
|
8
|
+
readonly name: string;
|
|
9
|
+
constructor(name: string, weightStore: WeightStore, alpha: number, rank: number, variables: string[]);
|
|
10
|
+
attach(): void;
|
|
9
11
|
merge(): void;
|
|
10
|
-
detach(
|
|
12
|
+
detach(): void;
|
|
11
13
|
dispose(): void;
|
|
12
14
|
}
|
package/dist/layers/LoRA.js
CHANGED
|
@@ -1,52 +1,58 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as m, t as n } from "../index-CUXkjxiT.js";
|
|
2
2
|
import { p } from "../index-DmeWGGmS.js";
|
|
3
|
-
import { v as
|
|
3
|
+
import { v as g } from "../variable-Ck482e3n.js";
|
|
4
4
|
import { r as S } from "../random_normal-IBRrha8a.js";
|
|
5
|
-
import { z as
|
|
6
|
-
class
|
|
5
|
+
import { z as _ } from "../zeros-DvZpK8s6.js";
|
|
6
|
+
class B {
|
|
7
7
|
weightStore;
|
|
8
8
|
alpha;
|
|
9
9
|
rank;
|
|
10
10
|
variables;
|
|
11
11
|
scale;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
name;
|
|
13
|
+
constructor(t, e, a, s, r) {
|
|
14
|
+
this.name = t, this.weightStore = e, this.alpha = a, this.rank = s;
|
|
15
|
+
const c = p(r), w = e.variableNames.filter(
|
|
16
|
+
(i) => c(i) && !i.endsWith("_loraA") && !i.endsWith("_loraB")
|
|
17
|
+
);
|
|
18
|
+
this.variables = new Set(w), this.scale = m(a / s), this.variables.forEach((i) => {
|
|
19
|
+
const o = this.weightStore.getRawVariable(i), [d, b] = o.shape, h = `${i}_${this.name}_loraA`, l = `${i}_${this.name}_loraB`;
|
|
20
|
+
if (o.shape.length !== 2) {
|
|
20
21
|
console.warn(
|
|
21
|
-
`LoRA currently only supports 2D weight matrices. Variable ${
|
|
22
|
-
), this.variables.delete(
|
|
22
|
+
`LoRA currently only supports 2D weight matrices. Variable ${i} has shape ${o.shape}`
|
|
23
|
+
), this.variables.delete(i);
|
|
23
24
|
return;
|
|
24
25
|
}
|
|
25
|
-
this.weightStore.hasVariable(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
), this.weightStore.addVariable(
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
this.weightStore.hasVariable(h) || this.weightStore.hasVariable(l) || (this.weightStore.addVariable(
|
|
27
|
+
h,
|
|
28
|
+
g(S([d, this.rank], 0, 0.02), !0, h)
|
|
29
|
+
), this.weightStore.addVariable(l, g(_([this.rank, b]), !0, l)));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
attach() {
|
|
33
|
+
if (this.weightStore.onWeightRead)
|
|
34
|
+
throw new Error("LoRA cannot be applied to a WeightStore that already has a onWeightRead hook.");
|
|
35
|
+
this.weightStore.onWeightRead = (t, e) => this.variables.has(t) ? n(() => {
|
|
36
|
+
const a = this.weightStore.getRawVariable(`${t}_${this.name}_loraA`), s = this.weightStore.getRawVariable(`${t}_${this.name}_loraB`);
|
|
37
|
+
return e.add(a.matMul(s).mul(this.scale));
|
|
38
|
+
}) : e, this.weightStore.setTrainable([`*_${this.name}_loraA`, `*_${this.name}_loraB`]);
|
|
33
39
|
}
|
|
34
40
|
merge() {
|
|
35
|
-
this.variables.forEach((
|
|
36
|
-
const
|
|
37
|
-
|
|
41
|
+
this.variables.forEach((t) => {
|
|
42
|
+
const e = this.weightStore.getRawVariable(t), a = this.weightStore.getRawVariable(`${t}_${this.name}_loraA`), s = this.weightStore.getRawVariable(`${t}_${this.name}_loraB`), r = n(() => e.add(a.matMul(s).mul(this.scale)));
|
|
43
|
+
e.assign(r), r.dispose();
|
|
38
44
|
});
|
|
39
45
|
}
|
|
40
|
-
detach(
|
|
41
|
-
|
|
42
|
-
const i = `${a}_loraA`, r = `${a}_loraB`;
|
|
43
|
-
this.weightStore.getRawVariable(i).dispose(), this.weightStore.getRawVariable(r).dispose(), this.weightStore.deleteVariable(i), this.weightStore.deleteVariable(r);
|
|
44
|
-
}), this.weightStore.onWeightRead = void 0, this.weightStore.setTrainable(["*"]), this.variables.clear();
|
|
46
|
+
detach() {
|
|
47
|
+
this.weightStore.onWeightRead = void 0, this.weightStore.setTrainable(["*"]);
|
|
45
48
|
}
|
|
46
49
|
dispose() {
|
|
47
|
-
this.detach(), this.scale.dispose()
|
|
50
|
+
this.detach(), this.scale.dispose(), this.variables.forEach((t) => {
|
|
51
|
+
const e = `${t}_${this.name}_loraA`, a = `${t}_${this.name}_loraB`;
|
|
52
|
+
this.weightStore.getRawVariable(e).dispose(), this.weightStore.getRawVariable(a).dispose(), this.weightStore.deleteVariable(e), this.weightStore.deleteVariable(a);
|
|
53
|
+
}), this.variables.clear();
|
|
48
54
|
}
|
|
49
55
|
}
|
|
50
56
|
export {
|
|
51
|
-
|
|
57
|
+
B as default
|
|
52
58
|
};
|
package/dist/loader/load.js
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
1
|
import { z as i } from "../jszip.min-BZhlzntC.js";
|
|
2
2
|
import u from "./oldZipLoad.js";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import d from "./newZipLoad.js";
|
|
4
|
+
import w from "./loadHF.js";
|
|
5
5
|
import { loadZipMeta as s } from "./loadZipMeta.js";
|
|
6
|
-
import { load_safetensors as
|
|
6
|
+
import { load_safetensors as g } from "../utilities/safetensors.js";
|
|
7
7
|
const j = 2;
|
|
8
|
-
async function h(
|
|
9
|
-
const
|
|
10
|
-
if (!
|
|
11
|
-
throw new Error(`Failed to fetch ${
|
|
12
|
-
return
|
|
8
|
+
async function h(e) {
|
|
9
|
+
const t = await fetch(e);
|
|
10
|
+
if (!t.ok)
|
|
11
|
+
throw new Error(`Failed to fetch ${e}: ${t.statusText}`);
|
|
12
|
+
return t.arrayBuffer();
|
|
13
13
|
}
|
|
14
|
-
async function p(
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
14
|
+
async function p(e, t, o) {
|
|
15
|
+
const a = e.file("model.safetensors");
|
|
16
|
+
if (!a)
|
|
17
17
|
return;
|
|
18
|
-
const
|
|
19
|
-
for (const [l,
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const r = await a.async("arraybuffer"), c = await g(r), n = /* @__PURE__ */ new Map();
|
|
19
|
+
for (const [l, m] of Object.entries(c))
|
|
20
|
+
n.set(l, [m]);
|
|
21
|
+
t.weightStore.loadWeights(n, o);
|
|
22
22
|
}
|
|
23
|
-
async function y(
|
|
24
|
-
const o =
|
|
23
|
+
async function y(e, t) {
|
|
24
|
+
const o = e.file("config.json");
|
|
25
25
|
if (!o)
|
|
26
26
|
return;
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
29
|
-
if (
|
|
27
|
+
const a = await o.async("string"), r = JSON.parse(a);
|
|
28
|
+
if (r.loraName) {
|
|
29
|
+
if (t.hasLoRA())
|
|
30
30
|
throw new Error("Model already has LoRA attached");
|
|
31
|
-
|
|
31
|
+
t.attachLoRA(r.loraName);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
async function f(
|
|
35
|
-
if (
|
|
36
|
-
const o = await
|
|
37
|
-
return await p(
|
|
34
|
+
async function f(e, t) {
|
|
35
|
+
if (t.reference) {
|
|
36
|
+
const o = await L(t.reference);
|
|
37
|
+
return await p(e, o.model, !!t.url), await y(e, o.model), o.model.config.loraName && o.model.attachLoRA(o.model.config.loraName), {
|
|
38
38
|
...o,
|
|
39
39
|
metaData: {
|
|
40
40
|
...o.metaData,
|
|
41
|
-
...
|
|
41
|
+
...t
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
} else {
|
|
45
|
-
if (
|
|
46
|
-
return u(
|
|
45
|
+
if (e.file("manifest.json"))
|
|
46
|
+
return u(e, t);
|
|
47
47
|
{
|
|
48
|
-
const o = await
|
|
49
|
-
return o.model.config.
|
|
48
|
+
const o = await d(e, t);
|
|
49
|
+
return o.model.config.loraName && o.model.attachLoRA(o.model.config.loraName), o;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
async function
|
|
54
|
-
if (typeof
|
|
55
|
-
if (
|
|
56
|
-
const o = await h(
|
|
57
|
-
return
|
|
53
|
+
async function L(e, t) {
|
|
54
|
+
if (typeof e == "string")
|
|
55
|
+
if (e.startsWith("http://") || e.startsWith("https://")) {
|
|
56
|
+
const o = await h(e), a = await i.loadAsync(o), r = await s(a);
|
|
57
|
+
return r.url = e, f(a, r);
|
|
58
58
|
} else
|
|
59
|
-
return
|
|
59
|
+
return w(e);
|
|
60
60
|
else {
|
|
61
|
-
const o = await i.loadAsync(
|
|
62
|
-
return
|
|
61
|
+
const o = await i.loadAsync(e), a = await s(o);
|
|
62
|
+
return a.url = t?.sourceURL || void 0, f(o, a);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
export {
|
|
66
66
|
j as VERSION,
|
|
67
|
-
|
|
67
|
+
L as loadModel
|
|
68
68
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import p from "../tokeniser/CharTokeniser.js";
|
|
2
2
|
import _ from "../tokeniser/bpe.js";
|
|
3
|
-
import { load_safetensors as
|
|
4
|
-
import { aa as
|
|
5
|
-
import { dummyPassAsync as
|
|
3
|
+
import { load_safetensors as b } from "../utilities/safetensors.js";
|
|
4
|
+
import { aa as c } from "../index-CUXkjxiT.js";
|
|
5
|
+
import { dummyPassAsync as u } from "../utilities/dummy.js";
|
|
6
6
|
import y from "../models/factory.js";
|
|
7
7
|
function h(e) {
|
|
8
8
|
let o;
|
|
@@ -23,19 +23,20 @@ function h(e) {
|
|
|
23
23
|
nHead: e.num_attention_heads,
|
|
24
24
|
nEmbed: e.hidden_size,
|
|
25
25
|
mlpFactor: e.mlpFactor,
|
|
26
|
-
loraConfig: e.loraConfig,
|
|
26
|
+
loraConfig: e.loraConfig ? new Map(Object.entries(e.loraConfig)) : void 0,
|
|
27
|
+
loraName: e.loraName,
|
|
27
28
|
windowSize: e.windowSize
|
|
28
29
|
}, o;
|
|
29
30
|
}
|
|
30
|
-
async function
|
|
31
|
-
const n = h(e), m = (o.type ?? "char") === "char" ? new p(o.vocab) : new _(o.vocab, o.merges), i = await
|
|
31
|
+
async function S(e, o, r, s) {
|
|
32
|
+
const n = h(e), m = (o.type ?? "char") === "char" ? new p(o.vocab) : new _(o.vocab, o.merges), i = await b(s), t = /* @__PURE__ */ new Map();
|
|
32
33
|
for (const [l, d] of Object.entries(i))
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
t.set(l, [d]);
|
|
35
|
+
c();
|
|
35
36
|
const a = y(n);
|
|
36
|
-
return a.metaData = r, await
|
|
37
|
+
return a.metaData = r, await u(a), a.weightStore.loadWeights(t, !!r.url), { model: a, tokeniser: m, metaData: r };
|
|
37
38
|
}
|
|
38
39
|
export {
|
|
39
|
-
|
|
40
|
+
S as default,
|
|
40
41
|
h as mapTransformersConfigToGPTConfig
|
|
41
42
|
};
|
package/dist/loader/save.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { z as p } from "../jszip.min-BZhlzntC.js";
|
|
2
|
-
import
|
|
3
|
-
import { save_safetensors as
|
|
2
|
+
import l from "../tokeniser/CharTokeniser.js";
|
|
3
|
+
import { save_safetensors as _ } from "../utilities/safetensors.js";
|
|
4
4
|
import { VERSION as b } from "./load.js";
|
|
5
5
|
async function z(e, i, a) {
|
|
6
|
-
const
|
|
7
|
-
e.weightStore.saveWeights(
|
|
8
|
-
const n = new p(),
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const r = /* @__PURE__ */ new Map();
|
|
7
|
+
e.weightStore.saveWeights(r);
|
|
8
|
+
const n = new p(), s = {};
|
|
9
|
+
r.forEach((o, f) => {
|
|
10
|
+
o.length === 1 && (s[f] = o[0]);
|
|
11
11
|
});
|
|
12
|
-
const c = await
|
|
12
|
+
const c = await _(s);
|
|
13
13
|
n.file("model.safetensors", c, { binary: !0 });
|
|
14
14
|
const g = e.config.modelType;
|
|
15
|
-
let
|
|
16
|
-
if (g === "GenAI_NanoGPT_v1" ?
|
|
15
|
+
let t;
|
|
16
|
+
if (g === "GenAI_NanoGPT_v1" ? t = {
|
|
17
17
|
model_type: "GenAI_NanoGPT_v1",
|
|
18
18
|
vocab_size: i.getVocab().length,
|
|
19
19
|
hidden_size: e.config.nEmbed,
|
|
@@ -22,7 +22,7 @@ async function z(e, i, a) {
|
|
|
22
22
|
block_size: e.config.blockSize,
|
|
23
23
|
mlpFactor: e.config.mlpFactor,
|
|
24
24
|
useRope: e.config.useRope
|
|
25
|
-
} :
|
|
25
|
+
} : t = {
|
|
26
26
|
model_type: "GenAI_NanoGPT_v2",
|
|
27
27
|
vocab_size: i.getVocab().length,
|
|
28
28
|
hidden_size: e.config.nEmbed,
|
|
@@ -30,9 +30,10 @@ async function z(e, i, a) {
|
|
|
30
30
|
num_attention_heads: e.config.nHead,
|
|
31
31
|
block_size: e.config.blockSize,
|
|
32
32
|
mlpFactor: e.config.mlpFactor,
|
|
33
|
-
loraConfig: e.config.loraConfig,
|
|
33
|
+
loraConfig: e.config.loraConfig ? Object.fromEntries(e.config.loraConfig) : void 0,
|
|
34
|
+
loraName: e.config.loraName,
|
|
34
35
|
windowSize: e.config.windowSize
|
|
35
|
-
}, n.file("config.json", JSON.stringify(
|
|
36
|
+
}, n.file("config.json", JSON.stringify(t, void 0, 4), {
|
|
36
37
|
binary: !1
|
|
37
38
|
}), n.file(
|
|
38
39
|
"meta.json",
|
|
@@ -55,7 +56,7 @@ async function z(e, i, a) {
|
|
|
55
56
|
), n.file(
|
|
56
57
|
"tokeniser.json",
|
|
57
58
|
JSON.stringify({
|
|
58
|
-
type: i instanceof
|
|
59
|
+
type: i instanceof l ? "char" : "bpe",
|
|
59
60
|
vocab: i.getVocab(),
|
|
60
61
|
merges: await i.getMerges()
|
|
61
62
|
}),
|
|
@@ -63,8 +64,8 @@ async function z(e, i, a) {
|
|
|
63
64
|
binary: !1
|
|
64
65
|
}
|
|
65
66
|
), a?.files)
|
|
66
|
-
for (const [
|
|
67
|
-
n.file(
|
|
67
|
+
for (const [o, f] of Object.entries(a.files))
|
|
68
|
+
n.file(o, JSON.stringify(f), { binary: !1 });
|
|
68
69
|
return n.generateAsync({ type: "blob" });
|
|
69
70
|
}
|
|
70
71
|
export {
|
package/dist/loader/types.d.ts
CHANGED
|
@@ -8,7 +8,8 @@ export interface TransformersConfigBase {
|
|
|
8
8
|
num_attention_heads: number;
|
|
9
9
|
block_size: number;
|
|
10
10
|
mlpFactor: number;
|
|
11
|
-
loraConfig?: LoRAConfig
|
|
11
|
+
loraConfig?: Record<string, LoRAConfig>;
|
|
12
|
+
loraName?: string;
|
|
12
13
|
}
|
|
13
14
|
export interface TransformersConfigV1 extends TransformersConfigBase {
|
|
14
15
|
model_type: 'GenAI_NanoGPT_v1';
|
package/dist/models/config.d.ts
CHANGED
|
@@ -11,7 +11,8 @@ export interface GPTConfigBase {
|
|
|
11
11
|
nHead: number;
|
|
12
12
|
nEmbed: number;
|
|
13
13
|
mlpFactor: number;
|
|
14
|
-
loraConfig?: LoRAConfig
|
|
14
|
+
loraConfig?: Map<string, LoRAConfig>;
|
|
15
|
+
loraName?: string;
|
|
15
16
|
}
|
|
16
17
|
export interface GPTConfigV1 extends GPTConfigBase {
|
|
17
18
|
modelType: 'GenAI_NanoGPT_v1';
|
package/dist/models/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const t = {
|
|
2
2
|
modelType: "GenAI_NanoGPT_v2",
|
|
3
3
|
vocabSize: 2e3,
|
|
4
4
|
blockSize: 128,
|
|
@@ -11,33 +11,40 @@ const a = {
|
|
|
11
11
|
// Embedding dimension
|
|
12
12
|
mlpFactor: 4
|
|
13
13
|
};
|
|
14
|
-
function e
|
|
15
|
-
if (typeof
|
|
16
|
-
throw new Error(`Invalid config: "${
|
|
14
|
+
function n(e, a) {
|
|
15
|
+
if (typeof e[a] != "number" || Number.isNaN(e[a]))
|
|
16
|
+
throw new Error(`Invalid config: "${a}" must be a number.`);
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
const
|
|
20
|
-
if (!
|
|
18
|
+
function l(e) {
|
|
19
|
+
const a = (o) => typeof o == "object" && o !== null && !Array.isArray(o);
|
|
20
|
+
if (!a(e))
|
|
21
21
|
throw new Error("Invalid config: expected an object.");
|
|
22
|
-
if (e
|
|
23
|
-
if (!
|
|
22
|
+
if (n(e, "vocabSize"), n(e, "blockSize"), n(e, "nLayer"), n(e, "nHead"), n(e, "nEmbed"), n(e, "mlpFactor"), e.loraConfig !== void 0) {
|
|
23
|
+
if (!a(e.loraConfig))
|
|
24
24
|
throw new Error('Invalid config: "loraConfig" must be an object.');
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const o = Object.values(e.loraConfig);
|
|
26
|
+
if (!o.every((r) => a(r)))
|
|
27
|
+
throw new Error('Invalid config: each entry in "loraConfig" must be an object.');
|
|
28
|
+
if (!o.every((r) => "rank" in r && "alpha" in r && "variables" in r))
|
|
29
|
+
throw new Error('Invalid config: each LoRA config must have "rank", "alpha", and "variables" fields.');
|
|
30
|
+
o.forEach((r) => {
|
|
31
|
+
if (n(r, "rank"), n(r, "alpha"), !Array.isArray(r.variables) || !r.variables.every((i) => typeof i == "string"))
|
|
32
|
+
throw new Error('Invalid config: "variables" must be a string array.');
|
|
33
|
+
});
|
|
27
34
|
}
|
|
28
|
-
if (
|
|
29
|
-
if (typeof
|
|
35
|
+
if (e.modelType === "GenAI_NanoGPT_v1") {
|
|
36
|
+
if (typeof e.useRope != "boolean")
|
|
30
37
|
throw new Error('Invalid config: "useRope" must be a boolean for GenAI_NanoGPT_v1.');
|
|
31
38
|
return;
|
|
32
39
|
}
|
|
33
|
-
if (
|
|
34
|
-
if (
|
|
40
|
+
if (e.modelType === "GenAI_NanoGPT_v2") {
|
|
41
|
+
if (e.windowSize !== void 0 && typeof e.windowSize != "string")
|
|
35
42
|
throw new Error('Invalid config: "windowSize" must be a string for GenAI_NanoGPT_v2.');
|
|
36
43
|
return;
|
|
37
44
|
}
|
|
38
45
|
throw new Error('Invalid config: "modelType" must be "GenAI_NanoGPT_v1" or "GenAI_NanoGPT_v2".');
|
|
39
46
|
}
|
|
40
47
|
export {
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
t as defaultConfig,
|
|
49
|
+
l as validateConfig
|
|
43
50
|
};
|
package/dist/models/model.d.ts
CHANGED
|
@@ -21,9 +21,16 @@ export default abstract class Model<T extends ModelForwardAttributes, C extends
|
|
|
21
21
|
trainingState: TrainingState | null;
|
|
22
22
|
metaData: TransformersMetadata;
|
|
23
23
|
private loraLayer?;
|
|
24
|
-
|
|
24
|
+
private loraMap;
|
|
25
|
+
constructor(config: C);
|
|
26
|
+
createLoRA(name: string, loraConfig: LoRAConfig): void;
|
|
27
|
+
deleteLoRA(name: string): void;
|
|
28
|
+
renameLoRA(oldName: string, newName: string): void;
|
|
29
|
+
mergeLoRA(name: string): void;
|
|
30
|
+
attachLoRA(name: string): void;
|
|
25
31
|
detachLoRA(): void;
|
|
26
|
-
hasLoRA(): boolean;
|
|
32
|
+
hasLoRA(name?: string): boolean;
|
|
33
|
+
listLoRAs(): string[];
|
|
27
34
|
get lora(): LoRA | null;
|
|
28
35
|
abstract getClassName(): string;
|
|
29
36
|
abstract forward(attrs: T, idx: Tensor): Tensor;
|