@seanhogg/builderforce-memory-engine 2026.9.34 → 2026.10.2
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/evermind/delta_wire.d.ts +26 -2
- package/dist/evermind/delta_wire.d.ts.map +1 -1
- package/dist/evermind/delta_wire.js +46 -4
- package/dist/evermind/delta_wire.js.map +1 -1
- package/dist/evermind/index.d.ts +5 -5
- package/dist/evermind/index.d.ts.map +1 -1
- package/dist/evermind/index.js +2 -2
- package/dist/evermind/index.js.map +1 -1
- package/dist/evermind/merge.d.ts +28 -0
- package/dist/evermind/merge.d.ts.map +1 -1
- package/dist/evermind/merge.js +33 -0
- package/dist/evermind/merge.js.map +1 -1
- package/dist/evermind/ml_head.d.ts +28 -0
- package/dist/evermind/ml_head.d.ts.map +1 -0
- package/dist/evermind/ml_head.js +47 -0
- package/dist/evermind/ml_head.js.map +1 -0
- package/dist/evermind/package.d.ts +9 -0
- package/dist/evermind/package.d.ts.map +1 -1
- package/dist/evermind/package.js +20 -0
- package/dist/evermind/package.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/limbic/index.d.ts +3 -0
- package/dist/limbic/index.d.ts.map +1 -1
- package/dist/limbic/index.js +3 -0
- package/dist/limbic/index.js.map +1 -1
- package/dist/limbic/limbic_model.d.ts.map +1 -1
- package/dist/limbic/limbic_model.js +1 -3
- package/dist/limbic/limbic_model.js.map +1 -1
- package/dist/limbic/limbic_task.d.ts +22 -0
- package/dist/limbic/limbic_task.d.ts.map +1 -0
- package/dist/limbic/limbic_task.js +45 -0
- package/dist/limbic/limbic_task.js.map +1 -0
- package/dist/limbic/limbic_trainer.d.ts +17 -30
- package/dist/limbic/limbic_trainer.d.ts.map +1 -1
- package/dist/limbic/limbic_trainer.js +38 -144
- package/dist/limbic/limbic_trainer.js.map +1 -1
- package/dist/ml/classical/anomaly_composite.d.ts +32 -0
- package/dist/ml/classical/anomaly_composite.d.ts.map +1 -0
- package/dist/ml/classical/anomaly_composite.js +29 -0
- package/dist/ml/classical/anomaly_composite.js.map +1 -0
- package/dist/ml/classical/ewma.d.ts +37 -0
- package/dist/ml/classical/ewma.d.ts.map +1 -0
- package/dist/ml/classical/ewma.js +48 -0
- package/dist/ml/classical/ewma.js.map +1 -0
- package/dist/ml/classical/gbm.d.ts +42 -0
- package/dist/ml/classical/gbm.d.ts.map +1 -0
- package/dist/ml/classical/gbm.js +117 -0
- package/dist/ml/classical/gbm.js.map +1 -0
- package/dist/ml/classical/index.d.ts +52 -0
- package/dist/ml/classical/index.d.ts.map +1 -0
- package/dist/ml/classical/index.js +49 -0
- package/dist/ml/classical/index.js.map +1 -0
- package/dist/ml/classical/isolation_forest.d.ts +37 -0
- package/dist/ml/classical/isolation_forest.d.ts.map +1 -0
- package/dist/ml/classical/isolation_forest.js +72 -0
- package/dist/ml/classical/isolation_forest.js.map +1 -0
- package/dist/ml/classical/kmeans.d.ts +31 -0
- package/dist/ml/classical/kmeans.d.ts.map +1 -0
- package/dist/ml/classical/kmeans.js +112 -0
- package/dist/ml/classical/kmeans.js.map +1 -0
- package/dist/ml/classical/knn.d.ts +51 -0
- package/dist/ml/classical/knn.d.ts.map +1 -0
- package/dist/ml/classical/knn.js +69 -0
- package/dist/ml/classical/knn.js.map +1 -0
- package/dist/ml/classical/linear.d.ts +29 -0
- package/dist/ml/classical/linear.d.ts.map +1 -0
- package/dist/ml/classical/linear.js +114 -0
- package/dist/ml/classical/linear.js.map +1 -0
- package/dist/ml/classical/logistic.d.ts +31 -0
- package/dist/ml/classical/logistic.d.ts.map +1 -0
- package/dist/ml/classical/logistic.js +111 -0
- package/dist/ml/classical/logistic.js.map +1 -0
- package/dist/ml/classical/math.d.ts +26 -0
- package/dist/ml/classical/math.d.ts.map +1 -0
- package/dist/ml/classical/math.js +90 -0
- package/dist/ml/classical/math.js.map +1 -0
- package/dist/ml/classical/naive_bayes.d.ts +28 -0
- package/dist/ml/classical/naive_bayes.d.ts.map +1 -0
- package/dist/ml/classical/naive_bayes.js +72 -0
- package/dist/ml/classical/naive_bayes.js.map +1 -0
- package/dist/ml/classical/robust_z.d.ts +38 -0
- package/dist/ml/classical/robust_z.d.ts.map +1 -0
- package/dist/ml/classical/robust_z.js +47 -0
- package/dist/ml/classical/robust_z.js.map +1 -0
- package/dist/ml/dense_head.d.ts +33 -0
- package/dist/ml/dense_head.d.ts.map +1 -0
- package/dist/ml/dense_head.js +140 -0
- package/dist/ml/dense_head.js.map +1 -0
- package/dist/ml/eval_loss.d.ts +15 -0
- package/dist/ml/eval_loss.d.ts.map +1 -0
- package/dist/ml/eval_loss.js +20 -0
- package/dist/ml/eval_loss.js.map +1 -0
- package/dist/ml/features.d.ts +25 -0
- package/dist/ml/features.d.ts.map +1 -0
- package/dist/ml/features.js +46 -0
- package/dist/ml/features.js.map +1 -0
- package/dist/ml/federate.d.ts +56 -0
- package/dist/ml/federate.d.ts.map +1 -0
- package/dist/ml/federate.js +99 -0
- package/dist/ml/federate.js.map +1 -0
- package/dist/ml/head_trainer.d.ts +78 -0
- package/dist/ml/head_trainer.d.ts.map +1 -0
- package/dist/ml/head_trainer.js +182 -0
- package/dist/ml/head_trainer.js.map +1 -0
- package/dist/ml/index.d.ts +23 -0
- package/dist/ml/index.d.ts.map +1 -0
- package/dist/ml/index.js +11 -0
- package/dist/ml/index.js.map +1 -0
- package/dist/ml/registry.d.ts +20 -0
- package/dist/ml/registry.d.ts.map +1 -0
- package/dist/ml/registry.js +43 -0
- package/dist/ml/registry.js.map +1 -0
- package/dist/ml/run.d.ts +103 -0
- package/dist/ml/run.d.ts.map +1 -0
- package/dist/ml/run.js +169 -0
- package/dist/ml/run.js.map +1 -0
- package/dist/ml/tasks/experience.d.ts +127 -0
- package/dist/ml/tasks/experience.d.ts.map +1 -0
- package/dist/ml/tasks/experience.js +213 -0
- package/dist/ml/tasks/experience.js.map +1 -0
- package/dist/ml/tasks/index.d.ts +10 -0
- package/dist/ml/tasks/index.d.ts.map +1 -0
- package/dist/ml/tasks/index.js +28 -0
- package/dist/ml/tasks/index.js.map +1 -0
- package/dist/ml/tasks/local_success.d.ts +55 -0
- package/dist/ml/tasks/local_success.d.ts.map +1 -0
- package/dist/ml/tasks/local_success.js +77 -0
- package/dist/ml/tasks/local_success.js.map +1 -0
- package/dist/ml/tasks/run_anomaly.d.ts +52 -0
- package/dist/ml/tasks/run_anomaly.d.ts.map +1 -0
- package/dist/ml/tasks/run_anomaly.js +50 -0
- package/dist/ml/tasks/run_anomaly.js.map +1 -0
- package/dist/ml/train.d.ts +59 -0
- package/dist/ml/train.d.ts.map +1 -0
- package/dist/ml/train.js +84 -0
- package/dist/ml/train.js.map +1 -0
- package/dist/ml/types.d.ts +115 -0
- package/dist/ml/types.d.ts.map +1 -0
- package/dist/ml/types.js +24 -0
- package/dist/ml/types.js.map +1 -0
- package/dist/moe/moe_model.d.ts.map +1 -1
- package/dist/moe/moe_model.js +1 -16
- package/dist/moe/moe_model.js.map +1 -1
- package/dist/training/cpu_ops.d.ts +2 -0
- package/dist/training/cpu_ops.d.ts.map +1 -1
- package/dist/training/cpu_ops.js +16 -0
- package/dist/training/cpu_ops.js.map +1 -1
- package/package.json +1 -1
- package/src/evermind/delta_wire.ts +63 -4
- package/src/evermind/index.ts +7 -3
- package/src/evermind/merge.ts +59 -0
- package/src/evermind/ml_head.ts +63 -0
- package/src/evermind/package.ts +24 -0
- package/src/index.ts +17 -1
- package/src/limbic/index.ts +5 -0
- package/src/limbic/limbic_model.ts +1 -4
- package/src/limbic/limbic_task.ts +62 -0
- package/src/limbic/limbic_trainer.ts +41 -208
- package/src/ml/classical/anomaly_composite.ts +46 -0
- package/src/ml/classical/ewma.ts +74 -0
- package/src/ml/classical/gbm.ts +144 -0
- package/src/ml/classical/index.ts +82 -0
- package/src/ml/classical/isolation_forest.ts +88 -0
- package/src/ml/classical/kmeans.ts +120 -0
- package/src/ml/classical/knn.ts +102 -0
- package/src/ml/classical/linear.ts +119 -0
- package/src/ml/classical/logistic.ts +125 -0
- package/src/ml/classical/math.ts +93 -0
- package/src/ml/classical/naive_bayes.ts +84 -0
- package/src/ml/classical/robust_z.ts +74 -0
- package/src/ml/dense_head.ts +157 -0
- package/src/ml/eval_loss.ts +27 -0
- package/src/ml/features.ts +61 -0
- package/src/ml/federate.ts +130 -0
- package/src/ml/head_trainer.ts +247 -0
- package/src/ml/index.ts +57 -0
- package/src/ml/registry.ts +44 -0
- package/src/ml/run.ts +222 -0
- package/src/ml/tasks/experience.ts +293 -0
- package/src/ml/tasks/index.ts +30 -0
- package/src/ml/tasks/local_success.ts +118 -0
- package/src/ml/tasks/run_anomaly.ts +84 -0
- package/src/ml/train.ts +120 -0
- package/src/ml/types.ts +135 -0
- package/src/moe/moe_model.ts +1 -13
- package/src/training/cpu_ops.ts +14 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml/federate.ts — trained ML heads federate like the model's own weights.
|
|
3
|
+
*
|
|
4
|
+
* A head's trained state is ONE flat f32 vector (`MlPredictor.exportParams`),
|
|
5
|
+
* stored as a CRC-trailed checkpoint so it is the same shape the delta pipeline
|
|
6
|
+
* already handles: a learner diffs its trained copy against the version it
|
|
7
|
+
* started from (`diffCheckpoints`), ships it on the existing delta wire with
|
|
8
|
+
* `target: "ml:<task>"`, and the writer folds N of them with the existing FedAvg
|
|
9
|
+
* (`mergeCheckpointDiffsGated` → `mergeCheckpointDiffs`), refusing a merge whose
|
|
10
|
+
* held-out loss regresses. No second wire, no second merge.
|
|
11
|
+
*
|
|
12
|
+
* The head's manifest entry and checkpoint format live with the artifact
|
|
13
|
+
* (`evermind/ml_head.ts`); this module only imports evermind/, never the reverse.
|
|
14
|
+
*/
|
|
15
|
+
import { type DeltaLearnPayload } from "../evermind/delta_wire.js";
|
|
16
|
+
import { type GatedMergeResult, type MergeGateOptions } from "../evermind/merge.js";
|
|
17
|
+
import { type EvermindMlHead } from "../evermind/ml_head.js";
|
|
18
|
+
import type { EvermindModelPackage } from "../evermind/package.js";
|
|
19
|
+
export { headCheckpoint, headParams, mlHeadUnusableReason } from "../evermind/ml_head.js";
|
|
20
|
+
export type { EvermindMlHead } from "../evermind/ml_head.js";
|
|
21
|
+
/** A manifest entry for a head's current parameters. */
|
|
22
|
+
export declare function mlHeadEntry(task: string, engine: string, version: number, params: ArrayLike<number>, shape?: Record<string, number>, evalLoss?: number): EvermindMlHead;
|
|
23
|
+
/** The entry's flat parameters. */
|
|
24
|
+
export declare function mlHeadParams(entry: EvermindMlHead): Float32Array;
|
|
25
|
+
/** The head a package carries for `task`, if any. */
|
|
26
|
+
export declare function packageMlHead(pkg: EvermindModelPackage, task: string): EvermindMlHead | undefined;
|
|
27
|
+
/** `pkg` with `entry` as its head for `entry.task` (replacing the old one). */
|
|
28
|
+
export declare function withPackageMlHead(pkg: EvermindModelPackage, entry: EvermindMlHead): EvermindModelPackage;
|
|
29
|
+
/**
|
|
30
|
+
* The delta-wire payload for a locally trained head: its new parameters diffed
|
|
31
|
+
* against the version it started from. The caller owns the size guard, as for LM deltas.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildMlHeadDelta(base: EvermindMlHead, trained: ArrayLike<number>, weight?: number, label?: string): DeltaLearnPayload;
|
|
34
|
+
export interface MlHeadMergeOutcome {
|
|
35
|
+
/** The head after the round: version + 1 when accepted, the base unchanged when refused. */
|
|
36
|
+
head: EvermindMlHead;
|
|
37
|
+
merge: GatedMergeResult;
|
|
38
|
+
/** Contributions left out of the batch, by index, with why. */
|
|
39
|
+
rejected: {
|
|
40
|
+
index: number;
|
|
41
|
+
reason: string;
|
|
42
|
+
}[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* One federated round for a head: validate each contribution ON ITS OWN (wrong
|
|
46
|
+
* target, stale base or a malformed diff costs only itself), FedAvg the rest, and
|
|
47
|
+
* keep the result only if `score` (held-out loss of a parameter vector, lower is
|
|
48
|
+
* better) does not regress.
|
|
49
|
+
*
|
|
50
|
+
* Fails CLOSED: `requireEval` defaults to true here, so a round `score` cannot judge
|
|
51
|
+
* (null — e.g. `mlEvalLoss` for an anomaly/cluster head or an empty holdout — or a
|
|
52
|
+
* non-finite loss) is refused. A caller that federates an unscorable head on purpose
|
|
53
|
+
* passes `{ requireEval: false }` explicitly.
|
|
54
|
+
*/
|
|
55
|
+
export declare function mergeMlHeadDeltas(base: EvermindMlHead, payloads: readonly DeltaLearnPayload[], score: (params: Float32Array) => number | null, opts?: MergeGateOptions): MlHeadMergeOutcome;
|
|
56
|
+
//# sourceMappingURL=federate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federate.d.ts","sourceRoot":"","sources":["../../src/ml/federate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAML,KAAK,iBAAiB,EACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAA6B,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC/G,OAAO,EAA8B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,wDAAwD;AACxD,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,EACzB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAClC,QAAQ,CAAC,EAAE,MAAM,GAChB,cAAc,CAShB;AAED,mCAAmC;AACnC,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAEhE;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,GAAG,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEjG;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,oBAAoB,EAAE,KAAK,EAAE,cAAc,GAAG,oBAAoB,CAExG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAGrI;AAED,MAAM,WAAW,kBAAkB;IACjC,4FAA4F;IAC5F,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,gBAAgB,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EACtC,KAAK,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,MAAM,GAAG,IAAI,EAC9C,IAAI,GAAE,gBAAqB,GAC1B,kBAAkB,CA+BpB"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml/federate.ts — trained ML heads federate like the model's own weights.
|
|
3
|
+
*
|
|
4
|
+
* A head's trained state is ONE flat f32 vector (`MlPredictor.exportParams`),
|
|
5
|
+
* stored as a CRC-trailed checkpoint so it is the same shape the delta pipeline
|
|
6
|
+
* already handles: a learner diffs its trained copy against the version it
|
|
7
|
+
* started from (`diffCheckpoints`), ships it on the existing delta wire with
|
|
8
|
+
* `target: "ml:<task>"`, and the writer folds N of them with the existing FedAvg
|
|
9
|
+
* (`mergeCheckpointDiffsGated` → `mergeCheckpointDiffs`), refusing a merge whose
|
|
10
|
+
* held-out loss regresses. No second wire, no second merge.
|
|
11
|
+
*
|
|
12
|
+
* The head's manifest entry and checkpoint format live with the artifact
|
|
13
|
+
* (`evermind/ml_head.ts`); this module only imports evermind/, never the reverse.
|
|
14
|
+
*/
|
|
15
|
+
import { buildDeltaLearnPayload, decodeDeltaPayload, deltaTargetMismatch, deltaUnusableReason, mlHeadTarget, } from "../evermind/delta_wire.js";
|
|
16
|
+
import { mergeCheckpointDiffsGated } from "../evermind/merge.js";
|
|
17
|
+
import { headCheckpoint, headParams } from "../evermind/ml_head.js";
|
|
18
|
+
import { base64ToBytes, bytesToBase64 } from "../utils/base64.js";
|
|
19
|
+
import { diffCheckpoints } from "../utils/delta.js";
|
|
20
|
+
export { headCheckpoint, headParams, mlHeadUnusableReason } from "../evermind/ml_head.js";
|
|
21
|
+
/** A manifest entry for a head's current parameters. */
|
|
22
|
+
export function mlHeadEntry(task, engine, version, params, shape = {}, evalLoss) {
|
|
23
|
+
return {
|
|
24
|
+
task,
|
|
25
|
+
engine,
|
|
26
|
+
version,
|
|
27
|
+
shape,
|
|
28
|
+
params: bytesToBase64(headCheckpoint(params)),
|
|
29
|
+
...(evalLoss != null && Number.isFinite(evalLoss) ? { evalLoss } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** The entry's flat parameters. */
|
|
33
|
+
export function mlHeadParams(entry) {
|
|
34
|
+
return headParams(base64ToBytes(entry.params));
|
|
35
|
+
}
|
|
36
|
+
/** The head a package carries for `task`, if any. */
|
|
37
|
+
export function packageMlHead(pkg, task) {
|
|
38
|
+
return pkg.manifest.mlHeads?.find((h) => h.task === task);
|
|
39
|
+
}
|
|
40
|
+
/** `pkg` with `entry` as its head for `entry.task` (replacing the old one). */
|
|
41
|
+
export function withPackageMlHead(pkg, entry) {
|
|
42
|
+
return pkg.withMlHeads([...(pkg.manifest.mlHeads ?? []).filter((h) => h.task !== entry.task), entry]);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The delta-wire payload for a locally trained head: its new parameters diffed
|
|
46
|
+
* against the version it started from. The caller owns the size guard, as for LM deltas.
|
|
47
|
+
*/
|
|
48
|
+
export function buildMlHeadDelta(base, trained, weight, label) {
|
|
49
|
+
const diff = diffCheckpoints(base64ToBytes(base.params), headCheckpoint(trained));
|
|
50
|
+
return buildDeltaLearnPayload(diff, base.version, weight, label ?? `ml head ${base.task}`, mlHeadTarget(base.task));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* One federated round for a head: validate each contribution ON ITS OWN (wrong
|
|
54
|
+
* target, stale base or a malformed diff costs only itself), FedAvg the rest, and
|
|
55
|
+
* keep the result only if `score` (held-out loss of a parameter vector, lower is
|
|
56
|
+
* better) does not regress.
|
|
57
|
+
*
|
|
58
|
+
* Fails CLOSED: `requireEval` defaults to true here, so a round `score` cannot judge
|
|
59
|
+
* (null — e.g. `mlEvalLoss` for an anomaly/cluster head or an empty holdout — or a
|
|
60
|
+
* non-finite loss) is refused. A caller that federates an unscorable head on purpose
|
|
61
|
+
* passes `{ requireEval: false }` explicitly.
|
|
62
|
+
*/
|
|
63
|
+
export function mergeMlHeadDeltas(base, payloads, score, opts = {}) {
|
|
64
|
+
const baseCp = base64ToBytes(base.params);
|
|
65
|
+
const target = mlHeadTarget(base.task);
|
|
66
|
+
const diffs = [];
|
|
67
|
+
const weights = [];
|
|
68
|
+
const rejected = [];
|
|
69
|
+
payloads.forEach((p, index) => {
|
|
70
|
+
const wrongTarget = deltaTargetMismatch(p.target, target);
|
|
71
|
+
if (wrongTarget)
|
|
72
|
+
return void rejected.push({ index, reason: wrongTarget });
|
|
73
|
+
if (p.baseVersion !== base.version)
|
|
74
|
+
return void rejected.push({ index, reason: `stale base version ${p.baseVersion} (head is ${base.version})` });
|
|
75
|
+
let diff;
|
|
76
|
+
try {
|
|
77
|
+
diff = decodeDeltaPayload(p);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
return void rejected.push({ index, reason: `diff is not base64: ${error instanceof Error ? error.message : String(error)}` });
|
|
81
|
+
}
|
|
82
|
+
const why = deltaUnusableReason(diff, baseCp);
|
|
83
|
+
if (why)
|
|
84
|
+
return void rejected.push({ index, reason: why });
|
|
85
|
+
diffs.push(diff);
|
|
86
|
+
weights.push(p.weight ?? 1);
|
|
87
|
+
});
|
|
88
|
+
const merge = mergeCheckpointDiffsGated(baseCp, diffs, weights, (cp) => score(headParams(cp)), { ...opts, requireEval: opts.requireEval ?? true });
|
|
89
|
+
if (!merge.accepted)
|
|
90
|
+
return { head: base, merge, rejected };
|
|
91
|
+
const head = {
|
|
92
|
+
...base,
|
|
93
|
+
version: base.version + 1,
|
|
94
|
+
params: bytesToBase64(merge.checkpoint),
|
|
95
|
+
...(merge.newLoss != null ? { evalLoss: merge.newLoss } : {}),
|
|
96
|
+
};
|
|
97
|
+
return { head, merge, rejected };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=federate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federate.js","sourceRoot":"","sources":["../../src/ml/federate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml/head_trainer.ts — HeadTrainer: the ONE gradient trainer for a small head over
|
|
3
|
+
* an embedding (extracted from the limbic affect trainer, which is now a thin
|
|
4
|
+
* registration over it).
|
|
5
|
+
*
|
|
6
|
+
* Full-batch gradient descent with AdamW. When a GPUDevice is supplied the
|
|
7
|
+
* optimiser step runs on the GPU via the shared WEIGHT_UPDATE_WGSL kernel; with
|
|
8
|
+
* no device it runs the kernel's CPU mirror, `adamwUpdateInPlace` (`optim/adamw.ts`,
|
|
9
|
+
* NaN/Inf guard included), so training works everywhere (CI, Node without
|
|
10
|
+
* @webgpu/node, a laptop with no GPU). Neither path bounds the step (maxDelta 0).
|
|
11
|
+
*
|
|
12
|
+
* The head owns its forward/backward and its loss (MSE for regression, BCE /
|
|
13
|
+
* softmax cross-entropy for classification); this file owns only the loop:
|
|
14
|
+
* zero → accumulate per sample → average → clip → AdamW step.
|
|
15
|
+
*/
|
|
16
|
+
/** A named trainable tensor (flat row-major Float32Array). */
|
|
17
|
+
export interface HeadParam {
|
|
18
|
+
name: string;
|
|
19
|
+
data: Float32Array;
|
|
20
|
+
numel: number;
|
|
21
|
+
}
|
|
22
|
+
/** What a head must expose to be trained by {@link HeadTrainer}. */
|
|
23
|
+
export interface TrainableHead<S> {
|
|
24
|
+
/** Trainable parameters, in a stable order. */
|
|
25
|
+
parameters(): HeadParam[];
|
|
26
|
+
/** Gradient buffers, index-aligned with {@link parameters}. */
|
|
27
|
+
gradients(): HeadParam[];
|
|
28
|
+
zeroGrad(): void;
|
|
29
|
+
/** Accumulate gradients for one sample into {@link gradients}; returns its loss. */
|
|
30
|
+
accumulate(sample: S): number;
|
|
31
|
+
/** Forward-only loss of one sample. */
|
|
32
|
+
loss(sample: S): number;
|
|
33
|
+
}
|
|
34
|
+
export interface HeadTrainOptions {
|
|
35
|
+
learningRate?: number;
|
|
36
|
+
epochs?: number;
|
|
37
|
+
weightDecay?: number;
|
|
38
|
+
beta1?: number;
|
|
39
|
+
beta2?: number;
|
|
40
|
+
eps?: number;
|
|
41
|
+
/** Max global gradient L2 norm before the optimiser step. Default 1.0. */
|
|
42
|
+
maxGradNorm?: number;
|
|
43
|
+
/** Per-epoch hook. `gradNorm` is the pre-clip gradient L2 norm this epoch (the
|
|
44
|
+
* instability early-warning) — computed CPU-side so it's always available. */
|
|
45
|
+
onEpochEnd?: ((epoch: number, loss: number, gradNorm?: number) => void) | null;
|
|
46
|
+
}
|
|
47
|
+
export declare class HeadTrainer<S> {
|
|
48
|
+
/** Name used in error messages (the registration that owns this trainer). */
|
|
49
|
+
private readonly label;
|
|
50
|
+
readonly head: TrainableHead<S>;
|
|
51
|
+
readonly device: GPUDevice | null;
|
|
52
|
+
private _moments;
|
|
53
|
+
private _step;
|
|
54
|
+
private readonly _adamwPipeline;
|
|
55
|
+
constructor(head: TrainableHead<S>, device?: GPUDevice | null,
|
|
56
|
+
/** Name used in error messages (the registration that owns this trainer). */
|
|
57
|
+
label?: string);
|
|
58
|
+
/** Whether the optimiser step runs on the GPU. */
|
|
59
|
+
get gpuTraining(): boolean;
|
|
60
|
+
private _initMoments;
|
|
61
|
+
/**
|
|
62
|
+
* Train on `samples` for `epochs` passes; returns the per-epoch mean loss.
|
|
63
|
+
* Full-batch: grads accumulate over every sample, are averaged, clipped, then
|
|
64
|
+
* applied once per epoch.
|
|
65
|
+
*/
|
|
66
|
+
train(samples: S[], opts?: HeadTrainOptions): Promise<number[]>;
|
|
67
|
+
/** Mean loss over samples (no weight update). 0 for an empty set. */
|
|
68
|
+
evaluate(samples: S[]): number;
|
|
69
|
+
/** AdamW on the CPU via the kernel's shared mirror (`adamwUpdateInPlace`). */
|
|
70
|
+
private _adamwStepCpu;
|
|
71
|
+
/** AdamW on the GPU via the shared WEIGHT_UPDATE_WGSL kernel. Awaited per step. */
|
|
72
|
+
private _adamwStepGpu;
|
|
73
|
+
}
|
|
74
|
+
/** Concatenate a head's parameters into one flat vector (the federation unit). */
|
|
75
|
+
export declare function flattenParams(params: readonly HeadParam[]): Float32Array;
|
|
76
|
+
/** Write a flat vector back into a head's parameters (inverse of {@link flattenParams}). */
|
|
77
|
+
export declare function assignParams(params: readonly HeadParam[], flat: ArrayLike<number>): void;
|
|
78
|
+
//# sourceMappingURL=head_trainer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head_trainer.d.ts","sourceRoot":"","sources":["../../src/ml/head_trainer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oEAAoE;AACpE,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,+CAA+C;IAC/C,UAAU,IAAI,SAAS,EAAE,CAAC;IAC1B,+DAA+D;IAC/D,SAAS,IAAI,SAAS,EAAE,CAAC;IACzB,QAAQ,IAAI,IAAI,CAAC;IACjB,oFAAoF;IACpF,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;IAC9B,uCAAuC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;mFAC+E;IAC/E,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAChF;AAuBD,qBAAa,WAAW,CAAC,CAAC;IAUtB,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK;IAVxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;gBAGzD,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,EACtB,MAAM,GAAE,SAAS,GAAG,IAAW;IAC/B,6EAA6E;IAC5D,KAAK,GAAE,MAAsB;IAShD,kDAAkD;IAClD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,OAAO,CAAC,YAAY;IAQpB;;;;OAIG;IACG,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA8CzE,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,MAAM;IAO9B,8EAA8E;IAC9E,OAAO,CAAC,aAAa;IAQrB,mFAAmF;YACrE,aAAa;CA2B5B;AAcD,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,YAAY,CAQxE;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAQxF"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml/head_trainer.ts — HeadTrainer: the ONE gradient trainer for a small head over
|
|
3
|
+
* an embedding (extracted from the limbic affect trainer, which is now a thin
|
|
4
|
+
* registration over it).
|
|
5
|
+
*
|
|
6
|
+
* Full-batch gradient descent with AdamW. When a GPUDevice is supplied the
|
|
7
|
+
* optimiser step runs on the GPU via the shared WEIGHT_UPDATE_WGSL kernel; with
|
|
8
|
+
* no device it runs the kernel's CPU mirror, `adamwUpdateInPlace` (`optim/adamw.ts`,
|
|
9
|
+
* NaN/Inf guard included), so training works everywhere (CI, Node without
|
|
10
|
+
* @webgpu/node, a laptop with no GPU). Neither path bounds the step (maxDelta 0).
|
|
11
|
+
*
|
|
12
|
+
* The head owns its forward/backward and its loss (MSE for regression, BCE /
|
|
13
|
+
* softmax cross-entropy for classification); this file owns only the loop:
|
|
14
|
+
* zero → accumulate per sample → average → clip → AdamW step.
|
|
15
|
+
*/
|
|
16
|
+
import { createUniformBuffer, createStorageBuffer, createComputePipeline, createBindGroup, dispatchKernel, readBuffer, cdiv, } from "../utils/gpu_utils.js";
|
|
17
|
+
import { WEIGHT_UPDATE_WGSL } from "../kernels/weight_update.js";
|
|
18
|
+
import { adamwUpdateInPlace } from "../optim/adamw.js";
|
|
19
|
+
/** Byte size of WEIGHT_UPDATE_WGSL's `AdamParams` uniform: 1 u32 + 8 f32 + 3 f32 pad = 48. */
|
|
20
|
+
const ADAM_PARAMS_BYTES = 48;
|
|
21
|
+
/**
|
|
22
|
+
* Pack `AdamParams` exactly as WEIGHT_UPDATE_WGSL declares it:
|
|
23
|
+
* `num_elements: u32, lr, beta1, beta2, eps, weight_decay, beta1_t, beta2_t,
|
|
24
|
+
* max_delta, _pad0, _pad1, _pad2` (all f32 after the first) — 48 bytes.
|
|
25
|
+
*/
|
|
26
|
+
function packAdamParams(numElements, hp) {
|
|
27
|
+
const buf = new ArrayBuffer(ADAM_PARAMS_BYTES);
|
|
28
|
+
new Uint32Array(buf, 0, 1).set([numElements]);
|
|
29
|
+
// Pads stay 0 (fresh ArrayBuffer).
|
|
30
|
+
new Float32Array(buf, 4, 8).set([hp.lr, hp.beta1, hp.beta2, hp.eps, hp.weightDecay, hp.beta1_t, hp.beta2_t, hp.maxDelta]);
|
|
31
|
+
return buf;
|
|
32
|
+
}
|
|
33
|
+
export class HeadTrainer {
|
|
34
|
+
label;
|
|
35
|
+
head;
|
|
36
|
+
device;
|
|
37
|
+
_moments = null;
|
|
38
|
+
_step = 0;
|
|
39
|
+
_adamwPipeline;
|
|
40
|
+
constructor(head, device = null,
|
|
41
|
+
/** Name used in error messages (the registration that owns this trainer). */
|
|
42
|
+
label = "HeadTrainer") {
|
|
43
|
+
this.label = label;
|
|
44
|
+
this.head = head;
|
|
45
|
+
this.device = device;
|
|
46
|
+
this._adamwPipeline = device
|
|
47
|
+
? createComputePipeline(device, WEIGHT_UPDATE_WGSL, "adamw_update")
|
|
48
|
+
: null;
|
|
49
|
+
}
|
|
50
|
+
/** Whether the optimiser step runs on the GPU. */
|
|
51
|
+
get gpuTraining() {
|
|
52
|
+
return this.device != null && this._adamwPipeline != null;
|
|
53
|
+
}
|
|
54
|
+
_initMoments() {
|
|
55
|
+
if (this._moments)
|
|
56
|
+
return;
|
|
57
|
+
this._moments = this.head.parameters().map((p) => ({
|
|
58
|
+
m: new Float32Array(p.numel),
|
|
59
|
+
v: new Float32Array(p.numel),
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Train on `samples` for `epochs` passes; returns the per-epoch mean loss.
|
|
64
|
+
* Full-batch: grads accumulate over every sample, are averaged, clipped, then
|
|
65
|
+
* applied once per epoch.
|
|
66
|
+
*/
|
|
67
|
+
async train(samples, opts = {}) {
|
|
68
|
+
if (samples.length === 0)
|
|
69
|
+
throw new Error(`${this.label}.train: no samples`);
|
|
70
|
+
const { learningRate = 0.05, epochs = 50, weightDecay = 0.0, beta1 = 0.9, beta2 = 0.999, eps = 1e-8, maxGradNorm = 1.0, onEpochEnd = null, } = opts;
|
|
71
|
+
this._initMoments();
|
|
72
|
+
const losses = [];
|
|
73
|
+
for (let epoch = 0; epoch < epochs; epoch++) {
|
|
74
|
+
this.head.zeroGrad();
|
|
75
|
+
let epochLoss = 0;
|
|
76
|
+
for (const s of samples)
|
|
77
|
+
epochLoss += this.head.accumulate(s);
|
|
78
|
+
const grads = this.head.gradients();
|
|
79
|
+
const invN = 1 / samples.length;
|
|
80
|
+
for (const g of grads) {
|
|
81
|
+
for (let i = 0; i < g.data.length; i++)
|
|
82
|
+
g.data[i] *= invN;
|
|
83
|
+
}
|
|
84
|
+
const gradNorm = clipGradients(grads, maxGradNorm);
|
|
85
|
+
this._step++;
|
|
86
|
+
const beta1_t = Math.pow(beta1, this._step);
|
|
87
|
+
const beta2_t = Math.pow(beta2, this._step);
|
|
88
|
+
const hp = { lr: learningRate, weightDecay, beta1, beta2, eps, beta1_t, beta2_t, maxDelta: 0 };
|
|
89
|
+
if (this.gpuTraining) {
|
|
90
|
+
await this._adamwStepGpu(grads, hp);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
this._adamwStepCpu(grads, hp);
|
|
94
|
+
}
|
|
95
|
+
const avg = epochLoss / samples.length;
|
|
96
|
+
losses.push(avg);
|
|
97
|
+
if (onEpochEnd)
|
|
98
|
+
onEpochEnd(epoch + 1, avg, gradNorm);
|
|
99
|
+
}
|
|
100
|
+
return losses;
|
|
101
|
+
}
|
|
102
|
+
/** Mean loss over samples (no weight update). 0 for an empty set. */
|
|
103
|
+
evaluate(samples) {
|
|
104
|
+
if (samples.length === 0)
|
|
105
|
+
return 0;
|
|
106
|
+
let total = 0;
|
|
107
|
+
for (const s of samples)
|
|
108
|
+
total += this.head.loss(s);
|
|
109
|
+
return total / samples.length;
|
|
110
|
+
}
|
|
111
|
+
/** AdamW on the CPU via the kernel's shared mirror (`adamwUpdateInPlace`). */
|
|
112
|
+
_adamwStepCpu(grads, hp) {
|
|
113
|
+
const params = this.head.parameters();
|
|
114
|
+
for (let pi = 0; pi < params.length; pi++) {
|
|
115
|
+
const mom = this._moments[pi];
|
|
116
|
+
adamwUpdateInPlace(params[pi].data, grads[pi].data, mom.m, mom.v, hp);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** AdamW on the GPU via the shared WEIGHT_UPDATE_WGSL kernel. Awaited per step. */
|
|
120
|
+
async _adamwStepGpu(grads, hp) {
|
|
121
|
+
const device = this.device;
|
|
122
|
+
const pipeline = this._adamwPipeline;
|
|
123
|
+
const params = this.head.parameters();
|
|
124
|
+
for (let pi = 0; pi < params.length; pi++) {
|
|
125
|
+
const p = params[pi];
|
|
126
|
+
const mom = this._moments[pi];
|
|
127
|
+
const paramBuf = createStorageBuffer(device, p.data, true);
|
|
128
|
+
const gradBuf = createStorageBuffer(device, grads[pi].data, false);
|
|
129
|
+
const mBuf = createStorageBuffer(device, mom.m, true);
|
|
130
|
+
const vBuf = createStorageBuffer(device, mom.v, true);
|
|
131
|
+
const uni = createUniformBuffer(device, packAdamParams(p.numel, hp));
|
|
132
|
+
const bg = createBindGroup(device, pipeline, [uni, paramBuf, gradBuf, mBuf, vBuf]);
|
|
133
|
+
dispatchKernel(device, pipeline, bg, [cdiv(p.numel, 256), 1, 1]);
|
|
134
|
+
p.data.set((await readBuffer(device, paramBuf, p.numel * 4)).subarray(0, p.numel));
|
|
135
|
+
mom.m.set((await readBuffer(device, mBuf, p.numel * 4)).subarray(0, p.numel));
|
|
136
|
+
mom.v.set((await readBuffer(device, vBuf, p.numel * 4)).subarray(0, p.numel));
|
|
137
|
+
paramBuf.destroy();
|
|
138
|
+
gradBuf.destroy();
|
|
139
|
+
mBuf.destroy();
|
|
140
|
+
vBuf.destroy();
|
|
141
|
+
uni.destroy();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** Clip grads to `maxNorm` in place; returns the PRE-clip L2 norm (the signal). */
|
|
146
|
+
function clipGradients(grads, maxNorm) {
|
|
147
|
+
let normSq = 0;
|
|
148
|
+
for (const g of grads)
|
|
149
|
+
for (let i = 0; i < g.data.length; i++)
|
|
150
|
+
normSq += g.data[i] * g.data[i];
|
|
151
|
+
const norm = Math.sqrt(normSq);
|
|
152
|
+
if (norm > maxNorm && norm > 0) {
|
|
153
|
+
const scale = maxNorm / norm;
|
|
154
|
+
for (const g of grads)
|
|
155
|
+
for (let i = 0; i < g.data.length; i++)
|
|
156
|
+
g.data[i] *= scale;
|
|
157
|
+
}
|
|
158
|
+
return norm;
|
|
159
|
+
}
|
|
160
|
+
/** Concatenate a head's parameters into one flat vector (the federation unit). */
|
|
161
|
+
export function flattenParams(params) {
|
|
162
|
+
const out = new Float32Array(params.reduce((n, p) => n + p.numel, 0));
|
|
163
|
+
let o = 0;
|
|
164
|
+
for (const p of params) {
|
|
165
|
+
out.set(p.data, o);
|
|
166
|
+
o += p.numel;
|
|
167
|
+
}
|
|
168
|
+
return out;
|
|
169
|
+
}
|
|
170
|
+
/** Write a flat vector back into a head's parameters (inverse of {@link flattenParams}). */
|
|
171
|
+
export function assignParams(params, flat) {
|
|
172
|
+
const total = params.reduce((n, p) => n + p.numel, 0);
|
|
173
|
+
if (flat.length !== total)
|
|
174
|
+
throw new Error(`assignParams: expected ${total} values, got ${flat.length}`);
|
|
175
|
+
let o = 0;
|
|
176
|
+
for (const p of params) {
|
|
177
|
+
for (let i = 0; i < p.numel; i++)
|
|
178
|
+
p.data[i] = flat[o + i];
|
|
179
|
+
o += p.numel;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=head_trainer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head_trainer.js","sourceRoot":"","sources":["../../src/ml/head_trainer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml — the ML task catalog (docs/ml-task-catalog.md): small, purpose-built models
|
|
3
|
+
* for bounded questions, answered on the person's own machine without a GPU or an
|
|
4
|
+
* LLM call. ONE registry, ONE runner, ONE trainer seam; trained heads federate on
|
|
5
|
+
* the existing delta wire. Pure and portable: no vscode, no DOM, no network.
|
|
6
|
+
*/
|
|
7
|
+
export type { MlTask, MlTaskKind, MlEngineRef, ClassicalAlgorithm, InferenceMode, MlPrediction, MlPredictor, FeatureSpec, MlSample, TrainSpec, OutputSpec, } from "./types.js";
|
|
8
|
+
export { engineKey, ML_TASK_ID_RE } from "./types.js";
|
|
9
|
+
export { MlTaskRegistry } from "./registry.js";
|
|
10
|
+
export { runMlTask, candidateEngines, InMemoryMlModels, MlDecisionLog, MlEngineUnavailableError, } from "./run.js";
|
|
11
|
+
export type { MlRunContext, MlResult, MlModelStore, MlCloudPort, MlDecision, MlDecisionSink, MlSkipReason } from "./run.js";
|
|
12
|
+
export { trainMlTask, mlEvalLoss } from "./train.js";
|
|
13
|
+
export type { MlTrainExample, MlTrainOptions, MlTrainResult } from "./train.js";
|
|
14
|
+
export { HeadTrainer, flattenParams, assignParams } from "./head_trainer.js";
|
|
15
|
+
export type { HeadParam, TrainableHead, HeadTrainOptions } from "./head_trainer.js";
|
|
16
|
+
export { DenseHead } from "./dense_head.js";
|
|
17
|
+
export type { DenseHeadConfig } from "./dense_head.js";
|
|
18
|
+
export { extractFeatures, extractFeatureMatrix, logScale, clampRatio } from "./features.js";
|
|
19
|
+
export * from "./classical/index.js";
|
|
20
|
+
export { headCheckpoint, headParams, mlHeadEntry, mlHeadParams, mlHeadUnusableReason, packageMlHead, withPackageMlHead, buildMlHeadDelta, mergeMlHeadDeltas, } from "./federate.js";
|
|
21
|
+
export type { EvermindMlHead, MlHeadMergeOutcome } from "./federate.js";
|
|
22
|
+
export * from "./tasks/index.js";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ml/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,EACV,MAAM,EACN,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,WAAW,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE5H,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7E,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE5F,cAAc,sBAAsB,CAAC;AAErC,OAAO,EACL,cAAc,EACd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExE,cAAc,kBAAkB,CAAC"}
|
package/dist/ml/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { engineKey, ML_TASK_ID_RE } from "./types.js";
|
|
2
|
+
export { MlTaskRegistry } from "./registry.js";
|
|
3
|
+
export { runMlTask, candidateEngines, InMemoryMlModels, MlDecisionLog, MlEngineUnavailableError, } from "./run.js";
|
|
4
|
+
export { trainMlTask, mlEvalLoss } from "./train.js";
|
|
5
|
+
export { HeadTrainer, flattenParams, assignParams } from "./head_trainer.js";
|
|
6
|
+
export { DenseHead } from "./dense_head.js";
|
|
7
|
+
export { extractFeatures, extractFeatureMatrix, logScale, clampRatio } from "./features.js";
|
|
8
|
+
export * from "./classical/index.js";
|
|
9
|
+
export { headCheckpoint, headParams, mlHeadEntry, mlHeadParams, mlHeadUnusableReason, packageMlHead, withPackageMlHead, buildMlHeadDelta, mergeMlHeadDeltas, } from "./federate.js";
|
|
10
|
+
export * from "./tasks/index.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ml/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,wBAAwB,GACzB,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE5F,cAAc,sBAAsB,CAAC;AAErC,OAAO,EACL,cAAc,EACd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml/registry.ts — the ONE registry of ML tasks, keyed by task id.
|
|
3
|
+
*
|
|
4
|
+
* A new task is a new row, not a new module. The registry only stores and looks
|
|
5
|
+
* up rows; running lives in `run.ts`, training in `train.ts`.
|
|
6
|
+
*/
|
|
7
|
+
import { type MlTask } from "./types.js";
|
|
8
|
+
export declare class MlTaskRegistry {
|
|
9
|
+
private readonly _tasks;
|
|
10
|
+
/** Register a row. Throws on a malformed id, a duplicate id, or a row with no engine. */
|
|
11
|
+
register<I, O>(task: MlTask<I, O>): MlTask<I, O>;
|
|
12
|
+
/** The row for `id`, or undefined. */
|
|
13
|
+
get<I = unknown, O = unknown>(id: string): MlTask<I, O> | undefined;
|
|
14
|
+
/** The row for `id`; throws when it is not registered. */
|
|
15
|
+
require<I = unknown, O = unknown>(id: string): MlTask<I, O>;
|
|
16
|
+
has(id: string): boolean;
|
|
17
|
+
/** Every row, in registration order. */
|
|
18
|
+
list(): MlTask<any, any>[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/ml/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAExD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAE9D,yFAAyF;IACzF,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IAWhD,sCAAsC;IACtC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS;IAInE,0DAA0D;IAC1D,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IAM3D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,wCAAwC;IACxC,IAAI,IAAI,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;CAG3B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ml/registry.ts — the ONE registry of ML tasks, keyed by task id.
|
|
3
|
+
*
|
|
4
|
+
* A new task is a new row, not a new module. The registry only stores and looks
|
|
5
|
+
* up rows; running lives in `run.ts`, training in `train.ts`.
|
|
6
|
+
*/
|
|
7
|
+
import { ML_TASK_ID_RE } from "./types.js";
|
|
8
|
+
export class MlTaskRegistry {
|
|
9
|
+
_tasks = new Map();
|
|
10
|
+
/** Register a row. Throws on a malformed id, a duplicate id, or a row with no engine. */
|
|
11
|
+
register(task) {
|
|
12
|
+
if (!ML_TASK_ID_RE.test(task.id))
|
|
13
|
+
throw new Error(`MlTaskRegistry: malformed task id '${task.id}'`);
|
|
14
|
+
if (this._tasks.has(task.id))
|
|
15
|
+
throw new Error(`MlTaskRegistry: task '${task.id}' is already registered`);
|
|
16
|
+
if (task.engines.length === 0)
|
|
17
|
+
throw new Error(`MlTaskRegistry: task '${task.id}' lists no engine`);
|
|
18
|
+
if (task.kind === "classify" && !(task.output.labels && task.output.labels.length >= 2)) {
|
|
19
|
+
throw new Error(`MlTaskRegistry: classify task '${task.id}' needs at least two output labels`);
|
|
20
|
+
}
|
|
21
|
+
this._tasks.set(task.id, task);
|
|
22
|
+
return task;
|
|
23
|
+
}
|
|
24
|
+
/** The row for `id`, or undefined. */
|
|
25
|
+
get(id) {
|
|
26
|
+
return this._tasks.get(id);
|
|
27
|
+
}
|
|
28
|
+
/** The row for `id`; throws when it is not registered. */
|
|
29
|
+
require(id) {
|
|
30
|
+
const t = this.get(id);
|
|
31
|
+
if (!t)
|
|
32
|
+
throw new Error(`MlTaskRegistry: unknown task '${id}'`);
|
|
33
|
+
return t;
|
|
34
|
+
}
|
|
35
|
+
has(id) {
|
|
36
|
+
return this._tasks.has(id);
|
|
37
|
+
}
|
|
38
|
+
/** Every row, in registration order. */
|
|
39
|
+
list() {
|
|
40
|
+
return [...this._tasks.values()];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/ml/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAe,MAAM,YAAY,CAAC;AAExD,MAAM,OAAO,cAAc;IACR,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE9D,yFAAyF;IACzF,QAAQ,CAAO,IAAkB;QAC/B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACpG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,EAAE,yBAAyB,CAAC,CAAC;QACzG,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACpG,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC;YACxF,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,EAAE,oCAAoC,CAAC,CAAC;QACjG,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,GAAG,CAA2B,EAAU;QACtC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAA6B,CAAC;IACzD,CAAC;IAED,0DAA0D;IAC1D,OAAO,CAA2B,EAAU;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAO,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,wCAAwC;IACxC,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;CACF"}
|