@seanhogg/builderforce-memory-engine 2026.7.11 → 2026.7.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"adamw.d.ts","sourceRoot":"","sources":["../../src/optim/adamw.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,IAAI,UAAU,EAAE,CAAC;IAC3B,SAAS,IAAI,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,KAAK;IAOd,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAsB;IACxC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAsB;IACxC,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;gBAG1B,MAAM,EAAE,WAAW,EACpC,OAAO,GAAE,YAAiB;IAe5B,mEAAmE;IACnE,IAAI,IAAI,IAAI;CAsBb"}
1
+ {"version":3,"file":"adamw.d.ts","sourceRoot":"","sources":["../../src/optim/adamw.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,IAAI,UAAU,EAAE,CAAC;IAC3B,SAAS,IAAI,UAAU,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,SAAS;IACxB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,qBAAa,KAAK;IASd,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAA+B;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAC,CAA+B;IACjD,OAAO,CAAC,CAAC,CAAK;IACd,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwC;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;gBAGtB,MAAM,EAAE,WAAW,EACpC,OAAO,GAAE,YAAiB;IA0B5B,kEAAkE;IAClE,OAAO,CAAC,KAAK;IAIb,wFAAwF;IACxF,IAAI,IAAI,IAAI;IAwBZ,qFAAqF;IACrF,UAAU,IAAI,MAAM;CAMrB"}
@@ -7,10 +7,12 @@
7
7
  */
8
8
  export class AdamW {
9
9
  target;
10
+ // Per-parameter moments, or null for tensors this shard does not own (no memory).
10
11
  m = [];
11
12
  v = [];
12
13
  t = 0;
13
14
  opt;
15
+ shard;
14
16
  constructor(target, options = {}) {
15
17
  this.target = target;
16
18
  this.opt = {
@@ -20,12 +22,28 @@ export class AdamW {
20
22
  eps: options.eps ?? 1e-8,
21
23
  weightDecay: options.weightDecay ?? 0,
22
24
  };
23
- for (const p of target.parameters()) {
24
- this.m.push(new Float32Array(p.data.length));
25
- this.v.push(new Float32Array(p.data.length));
25
+ const shard = options.shard ?? null;
26
+ if (shard && (shard.count <= 0 || shard.index < 0 || shard.index >= shard.count)) {
27
+ throw new Error(`AdamW: invalid shard ${shard.index}/${shard.count}`);
26
28
  }
29
+ this.shard = shard;
30
+ const params = target.parameters();
31
+ for (let p = 0; p < params.length; p++) {
32
+ if (this._owns(p)) {
33
+ this.m.push(new Float32Array(params[p].data.length));
34
+ this.v.push(new Float32Array(params[p].data.length));
35
+ }
36
+ else {
37
+ this.m.push(null);
38
+ this.v.push(null);
39
+ }
40
+ }
41
+ }
42
+ /** Whether this shard owns (and updates) parameter tensor `p`. */
43
+ _owns(p) {
44
+ return this.shard === null || p % this.shard.count === this.shard.index;
27
45
  }
28
- /** One optimiser step from the currently-accumulated gradients. */
46
+ /** One optimiser step from the currently-accumulated gradients (owned tensors only). */
29
47
  step() {
30
48
  this.t++;
31
49
  const { lr, beta1, beta2, eps, weightDecay } = this.opt;
@@ -34,6 +52,8 @@ export class AdamW {
34
52
  const bc1 = 1 - Math.pow(beta1, this.t);
35
53
  const bc2 = 1 - Math.pow(beta2, this.t);
36
54
  for (let p = 0; p < params.length; p++) {
55
+ if (!this._owns(p))
56
+ continue;
37
57
  const w = params[p].data;
38
58
  const g = grads[p].data;
39
59
  const m = this.m[p];
@@ -48,5 +68,16 @@ export class AdamW {
48
68
  }
49
69
  }
50
70
  }
71
+ /** Bytes of optimizer state this shard holds (m + v) — 1/count of the full state. */
72
+ stateBytes() {
73
+ let n = 0;
74
+ for (const arr of this.m)
75
+ if (arr)
76
+ n += arr.byteLength;
77
+ for (const arr of this.v)
78
+ if (arr)
79
+ n += arr.byteLength;
80
+ return n;
81
+ }
51
82
  }
52
83
  //# sourceMappingURL=adamw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adamw.js","sourceRoot":"","sources":["../../src/optim/adamw.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adamw.js","sourceRoot":"","sources":["../../src/optim/adamw.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * lora.ts — Low-Rank Adaptation (LoRA) + QLoRA for the EvermindLM CPU reference.
3
+ *
4
+ * The Meta llama-cookbook's central PEFT idea: freeze the base weights and train
5
+ * a tiny low-rank delta ΔW = (α/r)·B·A on top. Three payoffs, all realised here:
6
+ *
7
+ * • Cheap — you train r·(rows+cols) params instead of rows·cols. For the tied
8
+ * embedding (vocab×dModel) at rank 8 that is orders of magnitude smaller.
9
+ * • Composable — the adapter serialises to a few KB (see {@link LoRAAdapter.serialize}),
10
+ * so a persona / tenant / project is an MB-scale artifact you swap at load
11
+ * time, not a full checkpoint.
12
+ * • Forgetting-safe — the base never moves, so an adapter cannot catastrophically
13
+ * overwrite the pretrained model (the exact property WSLA approximates with a
14
+ * trust region; LoRA gets it structurally).
15
+ *
16
+ * QLoRA adds one more: the frozen base is held QUANTIZED (fp16 or int8) and
17
+ * dequantized on the fly for the merged forward, while the small adapter trains
18
+ * in fp32. On a single constrained device (our WebGPU target) the frozen base is
19
+ * where most bytes live, so quantizing it is the biggest memory unlock.
20
+ *
21
+ * Pure CPU, exact gradients (finite-difference checked in tests). The WGSL path
22
+ * is a future acceleration with the same shapes — same contract as EvermindLM.
23
+ */
24
+ import { type AdamWOptions } from "../optim/adamw.js";
25
+ /** How the frozen base matrix is stored. `none` = fp32 (plain LoRA); the others = QLoRA. */
26
+ export type BaseQuant = "none" | "fp16" | "int8";
27
+ export interface LoRAConfig {
28
+ /** Low-rank bottleneck. Higher = more capacity, larger adapter. Default 8. */
29
+ rank?: number;
30
+ /** LoRA scaling; the delta is scaled by alpha/rank. Default = rank (unit scale). */
31
+ alpha?: number;
32
+ /** Deterministic init seed for the A matrix. */
33
+ seed?: number;
34
+ }
35
+ /**
36
+ * A low-rank adapter over one base matrix of shape [rows × cols] (row-major).
37
+ *
38
+ * ΔW[i,j] = (α/r) · Σ_k B[i,k]·A[k,j] B: [rows×r] A: [r×cols]
39
+ *
40
+ * Standard LoRA init: A ~ N(0, σ²), B = 0, so ΔW starts at exactly zero and the
41
+ * adapted model equals the base until training moves it. Only A and B are
42
+ * trainable ({@link parameters}/{@link gradients} expose them to {@link AdamW});
43
+ * the base is supplied by the caller and never mutated here.
44
+ */
45
+ export declare class LoRAAdapter {
46
+ readonly rows: number;
47
+ readonly cols: number;
48
+ readonly rank: number;
49
+ readonly alpha: number;
50
+ readonly scale: number;
51
+ /** [rows × rank], zero-initialised. */
52
+ readonly B: Float32Array;
53
+ /** [rank × cols], gaussian-initialised. */
54
+ readonly A: Float32Array;
55
+ private readonly gB;
56
+ private readonly gA;
57
+ constructor(rows: number, cols: number, config?: LoRAConfig);
58
+ /** Trainable count — the LoRA saving vs a full rows·cols matrix. */
59
+ numParams(): number;
60
+ /** Materialise ΔW = scale·B·A as a flat [rows·cols] row-major array. */
61
+ delta(): Float32Array;
62
+ /** Base + ΔW (new array; `base` is not mutated). */
63
+ applyTo(base: Float32Array): Float32Array;
64
+ /**
65
+ * Project dL/dW (flat [rows·cols], the gradient the base matrix WOULD receive)
66
+ * onto the adapter, accumulating dL/dA and dL/dB. Exact chain rule for
67
+ * ΔW = scale·B·A: gA = scale·Bᵀ·G, gB = scale·G·Aᵀ.
68
+ */
69
+ accumulateGradient(gW: Float32Array): void;
70
+ parameters(): {
71
+ data: Float32Array;
72
+ }[];
73
+ gradients(): {
74
+ data: Float32Array;
75
+ }[];
76
+ zeroGrad(): void;
77
+ /** Compact self-describing adapter blob (magic, rows, cols, rank, alpha, B, A). */
78
+ serialize(): ArrayBuffer;
79
+ static deserialize(buffer: ArrayBuffer): LoRAAdapter;
80
+ }
81
+ /** Quantize a base matrix for QLoRA storage; returns a dequantized view + byte cost. */
82
+ export declare function quantizeBase(base: Float32Array, mode: BaseQuant): {
83
+ view: Float32Array;
84
+ bytes: number;
85
+ };
86
+ import { EvermindLM } from "../lm/evermind_lm.js";
87
+ export interface LoRAFitOptions extends AdamWOptions {
88
+ epochs?: number;
89
+ /**
90
+ * Gradient accumulation: average the adapter gradient over this many sequences
91
+ * (micro-batches) before each optimiser step. Lets a memory-constrained device
92
+ * train at a larger *effective* batch. Default 1 (step per sequence).
93
+ */
94
+ accumSteps?: number;
95
+ }
96
+ /**
97
+ * LoRA / QLoRA fine-tuning of an {@link EvermindLM} through its tied token
98
+ * embedding — the dominant parameter (vocab×dModel) and the natural adapter
99
+ * target (input lookup and output head share it). The base model is frozen; only
100
+ * the {@link LoRAAdapter} trains.
101
+ *
102
+ * QLoRA: pass `baseQuant: "fp16" | "int8"` and the frozen base is stored
103
+ * quantized and dequantized on the fly for the merged forward, so the resident
104
+ * base costs half (fp16) or a quarter (int8) of the bytes while the adapter
105
+ * trains full-precision.
106
+ *
107
+ * The adapter is the shippable artifact: {@link serializeAdapter} emits a few KB
108
+ * you swap per persona/tenant/project, versus rewriting the whole checkpoint.
109
+ */
110
+ export declare class EvermindLMLoRA {
111
+ private readonly model;
112
+ readonly adapter: LoRAAdapter;
113
+ readonly baseQuant: BaseQuant;
114
+ /** Frozen base embedding as used in the merged forward (dequantized under QLoRA). */
115
+ private readonly frozenBase;
116
+ private readonly baseBytesStored;
117
+ private readonly rows;
118
+ private readonly cols;
119
+ constructor(model: EvermindLM, config?: LoRAConfig & {
120
+ baseQuant?: BaseQuant;
121
+ });
122
+ /** The frozen base model this adapter rides on. */
123
+ get baseModel(): EvermindLM;
124
+ /** Effective embedding used for training/generation: frozenBase + adapter delta. */
125
+ mergedEmb(): Float32Array;
126
+ /**
127
+ * One forward+backward on the merged weights, projecting the base-embedding
128
+ * gradient onto the adapter. The underlying model's own weights are left
129
+ * exactly as they were (base frozen); adapter gradients ACCUMULATE (caller
130
+ * zeroes between optimiser windows).
131
+ */
132
+ private _accumulate;
133
+ /** Train the adapter (only) with AdamW + optional gradient accumulation. */
134
+ fit(sequences: number[][], opts?: LoRAFitOptions): number[];
135
+ generate(prompt: number[], opts: import("../lm/evermind_lm.js").LMGenerateOptions): number[];
136
+ generateText(prompt: string, codec: import("../lm/evermind_lm.js").TextCodec, opts: import("../lm/evermind_lm.js").LMGenerateOptions): string;
137
+ /** The shippable adapter artifact (a few KB). */
138
+ serializeAdapter(): ArrayBuffer;
139
+ /** Reconstruct a fine-tuned model from a base model + a serialized adapter. */
140
+ static loadAdapter(model: EvermindLM, adapterBuffer: ArrayBuffer, baseQuant?: BaseQuant): EvermindLMLoRA;
141
+ /** Bake the adapter into the base and return a standalone EVL0 checkpoint. */
142
+ merge(opts?: {
143
+ fp16?: boolean;
144
+ }): ArrayBuffer;
145
+ /** Byte cost of the trainable adapter vs the frozen base — the LoRA/QLoRA saving. */
146
+ footprint(): {
147
+ adapterBytes: number;
148
+ baseBytes: number;
149
+ trainableParams: number;
150
+ baseParams: number;
151
+ };
152
+ }
153
+ //# sourceMappingURL=lora.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lora.d.ts","sourceRoot":"","sources":["../../src/training/lora.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAS7D,4FAA4F;AAC5F,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID;;;;;;;;;GASG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,CAAC,EAAE,YAAY,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAe;IAClC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAe;gBAEtB,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,UAAe;IA0B/D,oEAAoE;IACpE,SAAS,IAAI,MAAM;IAInB,wEAAwE;IACxE,KAAK,IAAI,YAAY;IAgBrB,oDAAoD;IACpD,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY;IAUzC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;IAqB1C,UAAU,IAAI;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE,EAAE;IAGtC,SAAS,IAAI;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE,EAAE;IAGrC,QAAQ,IAAI,IAAI;IAKhB,mFAAmF;IACnF,SAAS,IAAI,WAAW;IAgBxB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW;CAarD;AAED,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAavG;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IATxB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,qFAAqF;IACrF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAGX,KAAK,EAAE,UAAU,EAClC,MAAM,GAAE,UAAU,GAAG;QAAE,SAAS,CAAC,EAAE,SAAS,CAAA;KAAO;IAWrD,mDAAmD;IACnD,IAAI,SAAS,IAAI,UAAU,CAE1B;IAED,oFAAoF;IACpF,SAAS,IAAI,YAAY;IAIzB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAYnB,4EAA4E;IAC5E,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,EAAE;IA8B/D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,sBAAsB,EAAE,iBAAiB,GAAG,MAAM,EAAE;IAU5F,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,sBAAsB,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,sBAAsB,EAAE,iBAAiB,GAAG,MAAM;IAI7I,iDAAiD;IACjD,gBAAgB,IAAI,WAAW;IAI/B,+EAA+E;IAC/E,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,GAAE,SAAkB,GAAG,cAAc;IAQhH,8EAA8E;IAC9E,KAAK,CAAC,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,WAAW;IAKjD,qFAAqF;IACrF,SAAS,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;CAQtG"}
@@ -0,0 +1,324 @@
1
+ /**
2
+ * lora.ts — Low-Rank Adaptation (LoRA) + QLoRA for the EvermindLM CPU reference.
3
+ *
4
+ * The Meta llama-cookbook's central PEFT idea: freeze the base weights and train
5
+ * a tiny low-rank delta ΔW = (α/r)·B·A on top. Three payoffs, all realised here:
6
+ *
7
+ * • Cheap — you train r·(rows+cols) params instead of rows·cols. For the tied
8
+ * embedding (vocab×dModel) at rank 8 that is orders of magnitude smaller.
9
+ * • Composable — the adapter serialises to a few KB (see {@link LoRAAdapter.serialize}),
10
+ * so a persona / tenant / project is an MB-scale artifact you swap at load
11
+ * time, not a full checkpoint.
12
+ * • Forgetting-safe — the base never moves, so an adapter cannot catastrophically
13
+ * overwrite the pretrained model (the exact property WSLA approximates with a
14
+ * trust region; LoRA gets it structurally).
15
+ *
16
+ * QLoRA adds one more: the frozen base is held QUANTIZED (fp16 or int8) and
17
+ * dequantized on the fly for the merged forward, while the small adapter trains
18
+ * in fp32. On a single constrained device (our WebGPU target) the frozen base is
19
+ * where most bytes live, so quantizing it is the biggest memory unlock.
20
+ *
21
+ * Pure CPU, exact gradients (finite-difference checked in tests). The WGSL path
22
+ * is a future acceleration with the same shapes — same contract as EvermindLM.
23
+ */
24
+ import { AdamW } from "../optim/adamw.js";
25
+ import { SeededRng } from "../utils/rng.js";
26
+ import { quantizeFp16, dequantizeFp16, quantizeInt8, dequantizeInt8, } from "../utils/quantization.js";
27
+ const ADAPTER_MAGIC = 0x4c4f5241; // "LORA"
28
+ /**
29
+ * A low-rank adapter over one base matrix of shape [rows × cols] (row-major).
30
+ *
31
+ * ΔW[i,j] = (α/r) · Σ_k B[i,k]·A[k,j] B: [rows×r] A: [r×cols]
32
+ *
33
+ * Standard LoRA init: A ~ N(0, σ²), B = 0, so ΔW starts at exactly zero and the
34
+ * adapted model equals the base until training moves it. Only A and B are
35
+ * trainable ({@link parameters}/{@link gradients} expose them to {@link AdamW});
36
+ * the base is supplied by the caller and never mutated here.
37
+ */
38
+ export class LoRAAdapter {
39
+ rows;
40
+ cols;
41
+ rank;
42
+ alpha;
43
+ scale;
44
+ /** [rows × rank], zero-initialised. */
45
+ B;
46
+ /** [rank × cols], gaussian-initialised. */
47
+ A;
48
+ gB;
49
+ gA;
50
+ constructor(rows, cols, config = {}) {
51
+ if (rows <= 0 || cols <= 0)
52
+ throw new Error("LoRAAdapter: rows and cols must be > 0");
53
+ const rank = config.rank ?? 8;
54
+ if (rank <= 0 || rank > Math.min(rows, cols)) {
55
+ throw new Error(`LoRAAdapter: rank must be in [1, min(rows,cols)=${Math.min(rows, cols)}]`);
56
+ }
57
+ this.rows = rows;
58
+ this.cols = cols;
59
+ this.rank = rank;
60
+ this.alpha = config.alpha ?? rank;
61
+ this.scale = this.alpha / rank;
62
+ this.B = new Float32Array(rows * rank); // zero-init ⇒ ΔW starts at 0
63
+ this.A = new Float32Array(rank * cols);
64
+ const rng = new SeededRng((config.seed ?? 0x4c6f5241) >>> 0 || 1);
65
+ // Kaiming-ish small init for A (std ~ 1/sqrt(cols)).
66
+ const std = 1 / Math.sqrt(cols);
67
+ for (let i = 0; i < this.A.length; i++) {
68
+ const u1 = Math.max(rng.next(), 1e-12);
69
+ const u2 = rng.next();
70
+ this.A[i] = std * Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
71
+ }
72
+ this.gB = new Float32Array(this.B.length);
73
+ this.gA = new Float32Array(this.A.length);
74
+ }
75
+ /** Trainable count — the LoRA saving vs a full rows·cols matrix. */
76
+ numParams() {
77
+ return this.B.length + this.A.length;
78
+ }
79
+ /** Materialise ΔW = scale·B·A as a flat [rows·cols] row-major array. */
80
+ delta() {
81
+ const { rows, cols, rank, scale } = this;
82
+ const out = new Float32Array(rows * cols);
83
+ for (let i = 0; i < rows; i++) {
84
+ const bOff = i * rank;
85
+ const oOff = i * cols;
86
+ for (let k = 0; k < rank; k++) {
87
+ const b = this.B[bOff + k] * scale;
88
+ if (b === 0)
89
+ continue;
90
+ const aOff = k * cols;
91
+ for (let j = 0; j < cols; j++)
92
+ out[oOff + j] = out[oOff + j] + b * this.A[aOff + j];
93
+ }
94
+ }
95
+ return out;
96
+ }
97
+ /** Base + ΔW (new array; `base` is not mutated). */
98
+ applyTo(base) {
99
+ if (base.length !== this.rows * this.cols) {
100
+ throw new Error("LoRAAdapter.applyTo: base length mismatch");
101
+ }
102
+ const d = this.delta();
103
+ const out = new Float32Array(base.length);
104
+ for (let i = 0; i < out.length; i++)
105
+ out[i] = base[i] + d[i];
106
+ return out;
107
+ }
108
+ /**
109
+ * Project dL/dW (flat [rows·cols], the gradient the base matrix WOULD receive)
110
+ * onto the adapter, accumulating dL/dA and dL/dB. Exact chain rule for
111
+ * ΔW = scale·B·A: gA = scale·Bᵀ·G, gB = scale·G·Aᵀ.
112
+ */
113
+ accumulateGradient(gW) {
114
+ const { rows, cols, rank, scale } = this;
115
+ if (gW.length !== rows * cols)
116
+ throw new Error("LoRAAdapter.accumulateGradient: gW length mismatch");
117
+ for (let i = 0; i < rows; i++) {
118
+ const gOff = i * cols;
119
+ const bOff = i * rank;
120
+ for (let k = 0; k < rank; k++) {
121
+ const aOff = k * cols;
122
+ let gb = 0;
123
+ const bScaled = this.B[bOff + k] * scale;
124
+ for (let j = 0; j < cols; j++) {
125
+ const g = gW[gOff + j];
126
+ gb += g * this.A[aOff + j]; // gB[i,k] = scale·Σ_j G[i,j]·A[k,j]
127
+ this.gA[aOff + j] = this.gA[aOff + j] + bScaled * g; // gA[k,j] += scale·B[i,k]·G[i,j]
128
+ }
129
+ this.gB[bOff + k] = this.gB[bOff + k] + scale * gb;
130
+ }
131
+ }
132
+ }
133
+ // AdamW OptimTarget surface — trains ONLY the adapter.
134
+ parameters() {
135
+ return [{ data: this.B }, { data: this.A }];
136
+ }
137
+ gradients() {
138
+ return [{ data: this.gB }, { data: this.gA }];
139
+ }
140
+ zeroGrad() {
141
+ this.gB.fill(0);
142
+ this.gA.fill(0);
143
+ }
144
+ /** Compact self-describing adapter blob (magic, rows, cols, rank, alpha, B, A). */
145
+ serialize() {
146
+ const headerEls = 5;
147
+ const headerBytes = headerEls * 4;
148
+ const buf = new ArrayBuffer(headerBytes + (this.B.length + this.A.length) * 4);
149
+ const head = new Uint32Array(buf, 0, headerEls);
150
+ head[0] = ADAPTER_MAGIC;
151
+ head[1] = this.rows;
152
+ head[2] = this.cols;
153
+ head[3] = this.rank;
154
+ new Float32Array(buf, 16, 1)[0] = this.alpha;
155
+ const body = new Float32Array(buf, headerBytes);
156
+ body.set(this.B, 0);
157
+ body.set(this.A, this.B.length);
158
+ return buf;
159
+ }
160
+ static deserialize(buffer) {
161
+ const head = new Uint32Array(buffer, 0, 5);
162
+ if (head[0] !== ADAPTER_MAGIC)
163
+ throw new Error("LoRAAdapter.deserialize: bad magic");
164
+ const rows = head[1];
165
+ const cols = head[2];
166
+ const rank = head[3];
167
+ const alpha = new Float32Array(buffer, 16, 1)[0];
168
+ const adapter = new LoRAAdapter(rows, cols, { rank, alpha });
169
+ const body = new Float32Array(buffer, 20);
170
+ adapter.B.set(body.subarray(0, adapter.B.length));
171
+ adapter.A.set(body.subarray(adapter.B.length, adapter.B.length + adapter.A.length));
172
+ return adapter;
173
+ }
174
+ }
175
+ /** Quantize a base matrix for QLoRA storage; returns a dequantized view + byte cost. */
176
+ export function quantizeBase(base, mode) {
177
+ switch (mode) {
178
+ case "none":
179
+ return { view: base, bytes: base.length * 4 };
180
+ case "fp16": {
181
+ const q = quantizeFp16(base);
182
+ return { view: dequantizeFp16(q), bytes: q.length * 2 };
183
+ }
184
+ case "int8": {
185
+ const q = quantizeInt8(base);
186
+ return { view: dequantizeInt8(q.data, q.scale), bytes: q.data.length + 4 };
187
+ }
188
+ }
189
+ }
190
+ /**
191
+ * LoRA / QLoRA fine-tuning of an {@link EvermindLM} through its tied token
192
+ * embedding — the dominant parameter (vocab×dModel) and the natural adapter
193
+ * target (input lookup and output head share it). The base model is frozen; only
194
+ * the {@link LoRAAdapter} trains.
195
+ *
196
+ * QLoRA: pass `baseQuant: "fp16" | "int8"` and the frozen base is stored
197
+ * quantized and dequantized on the fly for the merged forward, so the resident
198
+ * base costs half (fp16) or a quarter (int8) of the bytes while the adapter
199
+ * trains full-precision.
200
+ *
201
+ * The adapter is the shippable artifact: {@link serializeAdapter} emits a few KB
202
+ * you swap per persona/tenant/project, versus rewriting the whole checkpoint.
203
+ */
204
+ export class EvermindLMLoRA {
205
+ model;
206
+ adapter;
207
+ baseQuant;
208
+ /** Frozen base embedding as used in the merged forward (dequantized under QLoRA). */
209
+ frozenBase;
210
+ baseBytesStored;
211
+ rows;
212
+ cols;
213
+ constructor(model, config = {}) {
214
+ this.model = model;
215
+ this.rows = model.config.vocabSize;
216
+ this.cols = model.config.dModel;
217
+ this.baseQuant = config.baseQuant ?? "none";
218
+ const { view, bytes } = quantizeBase(Float32Array.from(model.emb), this.baseQuant);
219
+ this.frozenBase = view;
220
+ this.baseBytesStored = bytes;
221
+ this.adapter = new LoRAAdapter(this.rows, this.cols, config);
222
+ }
223
+ /** The frozen base model this adapter rides on. */
224
+ get baseModel() {
225
+ return this.model;
226
+ }
227
+ /** Effective embedding used for training/generation: frozenBase + adapter delta. */
228
+ mergedEmb() {
229
+ return this.adapter.applyTo(this.frozenBase);
230
+ }
231
+ /**
232
+ * One forward+backward on the merged weights, projecting the base-embedding
233
+ * gradient onto the adapter. The underlying model's own weights are left
234
+ * exactly as they were (base frozen); adapter gradients ACCUMULATE (caller
235
+ * zeroes between optimiser windows).
236
+ */
237
+ _accumulate(seq) {
238
+ const merged = this.mergedEmb();
239
+ const saved = this.model.emb;
240
+ this.model.emb = merged; // swap in effective weights (tied lookup + head)
241
+ this.model.zeroGrad();
242
+ const loss = this.model.lossAndBackward(seq);
243
+ const gW = this.model.gradients()[0].data; // dL/dW_eff == dL/dΔW, shape [rows×cols]
244
+ this.adapter.accumulateGradient(gW);
245
+ this.model.emb = saved; // restore the frozen base
246
+ return loss;
247
+ }
248
+ /** Train the adapter (only) with AdamW + optional gradient accumulation. */
249
+ fit(sequences, opts = {}) {
250
+ const epochs = opts.epochs ?? 1;
251
+ const accum = Math.max(1, opts.accumSteps ?? 1);
252
+ const adam = new AdamW(this.adapter, opts);
253
+ const grads = this.adapter.gradients();
254
+ const history = [];
255
+ for (let e = 0; e < epochs; e++) {
256
+ let total = 0;
257
+ let n = 0;
258
+ let pending = 0;
259
+ this.adapter.zeroGrad();
260
+ const flush = () => {
261
+ if (pending === 0)
262
+ return;
263
+ if (pending !== 1)
264
+ for (const g of grads)
265
+ for (let i = 0; i < g.data.length; i++)
266
+ g.data[i] = g.data[i] / pending;
267
+ adam.step();
268
+ this.adapter.zeroGrad();
269
+ pending = 0;
270
+ };
271
+ for (const seq of sequences) {
272
+ if (seq.length < 2)
273
+ continue;
274
+ total += this._accumulate(seq);
275
+ n++;
276
+ if (++pending >= accum)
277
+ flush();
278
+ }
279
+ flush();
280
+ history.push(n > 0 ? total / n : 0);
281
+ }
282
+ return history;
283
+ }
284
+ generate(prompt, opts) {
285
+ const saved = this.model.emb;
286
+ this.model.emb = this.mergedEmb();
287
+ try {
288
+ return this.model.generate(prompt, opts);
289
+ }
290
+ finally {
291
+ this.model.emb = saved;
292
+ }
293
+ }
294
+ generateText(prompt, codec, opts) {
295
+ return codec.decode(this.generate(codec.encode(prompt), opts));
296
+ }
297
+ /** The shippable adapter artifact (a few KB). */
298
+ serializeAdapter() {
299
+ return this.adapter.serialize();
300
+ }
301
+ /** Reconstruct a fine-tuned model from a base model + a serialized adapter. */
302
+ static loadAdapter(model, adapterBuffer, baseQuant = "none") {
303
+ const loaded = LoRAAdapter.deserialize(adapterBuffer);
304
+ const wrap = new EvermindLMLoRA(model, { rank: loaded.rank, alpha: loaded.alpha, baseQuant });
305
+ wrap.adapter.B.set(loaded.B);
306
+ wrap.adapter.A.set(loaded.A);
307
+ return wrap;
308
+ }
309
+ /** Bake the adapter into the base and return a standalone EVL0 checkpoint. */
310
+ merge(opts = {}) {
311
+ this.model.emb.set(this.mergedEmb());
312
+ return this.model.exportWeights(opts);
313
+ }
314
+ /** Byte cost of the trainable adapter vs the frozen base — the LoRA/QLoRA saving. */
315
+ footprint() {
316
+ return {
317
+ adapterBytes: this.adapter.serialize().byteLength,
318
+ baseBytes: this.baseBytesStored,
319
+ trainableParams: this.adapter.numParams(),
320
+ baseParams: this.rows * this.cols,
321
+ };
322
+ }
323
+ }
324
+ //# sourceMappingURL=lora.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lora.js","sourceRoot":"","sources":["../../src/training/lora.ts"],"names":[],"mappings":"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"}