@seanhogg/builderforce-memory-engine 2026.7.12 → 2026.9.27

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.
Files changed (196) hide show
  1. package/README.md +14 -0
  2. package/dist/bench/adaptation.d.ts +57 -0
  3. package/dist/bench/adaptation.d.ts.map +1 -0
  4. package/dist/bench/adaptation.js +167 -0
  5. package/dist/bench/adaptation.js.map +1 -0
  6. package/dist/bench/harness.d.ts +2 -0
  7. package/dist/bench/harness.d.ts.map +1 -1
  8. package/dist/bench/harness.js +1 -1
  9. package/dist/bench/harness.js.map +1 -1
  10. package/dist/bench/index.d.ts +5 -3
  11. package/dist/bench/index.d.ts.map +1 -1
  12. package/dist/bench/index.js +4 -2
  13. package/dist/bench/index.js.map +1 -1
  14. package/dist/bench/types.d.ts +88 -0
  15. package/dist/bench/types.d.ts.map +1 -1
  16. package/dist/evermind/adapt.d.ts +40 -0
  17. package/dist/evermind/adapt.d.ts.map +1 -0
  18. package/dist/evermind/adapt.js +25 -0
  19. package/dist/evermind/adapt.js.map +1 -0
  20. package/dist/evermind/delta_wire.d.ts +43 -0
  21. package/dist/evermind/delta_wire.d.ts.map +1 -0
  22. package/dist/evermind/delta_wire.js +94 -0
  23. package/dist/evermind/delta_wire.js.map +1 -0
  24. package/dist/evermind/eval.d.ts +31 -0
  25. package/dist/evermind/eval.d.ts.map +1 -0
  26. package/dist/evermind/eval.js +36 -0
  27. package/dist/evermind/eval.js.map +1 -0
  28. package/dist/evermind/index.d.ts +16 -0
  29. package/dist/evermind/index.d.ts.map +1 -0
  30. package/dist/evermind/index.js +11 -0
  31. package/dist/evermind/index.js.map +1 -0
  32. package/dist/evermind/merge.d.ts +21 -0
  33. package/dist/evermind/merge.d.ts.map +1 -0
  34. package/dist/evermind/merge.js +79 -0
  35. package/dist/evermind/merge.js.map +1 -0
  36. package/dist/{moe/moe_package.d.ts → evermind/package.d.ts} +55 -5
  37. package/dist/evermind/package.d.ts.map +1 -0
  38. package/dist/{moe/moe_package.js → evermind/package.js} +118 -19
  39. package/dist/evermind/package.js.map +1 -0
  40. package/dist/import/foreign/adapter.d.ts +59 -0
  41. package/dist/import/foreign/adapter.d.ts.map +1 -0
  42. package/dist/import/foreign/adapter.js +76 -0
  43. package/dist/import/foreign/adapter.js.map +1 -0
  44. package/dist/import/foreign/apply.d.ts +23 -0
  45. package/dist/import/foreign/apply.d.ts.map +1 -0
  46. package/dist/import/foreign/apply.js +43 -0
  47. package/dist/import/foreign/apply.js.map +1 -0
  48. package/dist/import/foreign/codestral_mamba.d.ts +57 -0
  49. package/dist/import/foreign/codestral_mamba.d.ts.map +1 -0
  50. package/dist/import/foreign/codestral_mamba.js +174 -0
  51. package/dist/import/foreign/codestral_mamba.js.map +1 -0
  52. package/dist/import/foreign/falcon_mamba.d.ts +51 -0
  53. package/dist/import/foreign/falcon_mamba.d.ts.map +1 -0
  54. package/dist/import/foreign/falcon_mamba.js +131 -0
  55. package/dist/import/foreign/falcon_mamba.js.map +1 -0
  56. package/dist/import/foreign/index.d.ts +21 -0
  57. package/dist/import/foreign/index.d.ts.map +1 -0
  58. package/dist/import/foreign/index.js +18 -0
  59. package/dist/import/foreign/index.js.map +1 -0
  60. package/dist/import/foreign/plan.d.ts +122 -0
  61. package/dist/import/foreign/plan.d.ts.map +1 -0
  62. package/dist/import/foreign/plan.js +171 -0
  63. package/dist/import/foreign/plan.js.map +1 -0
  64. package/dist/import/foreign/registry.d.ts +35 -0
  65. package/dist/import/foreign/registry.d.ts.map +1 -0
  66. package/dist/import/foreign/registry.js +89 -0
  67. package/dist/import/foreign/registry.js.map +1 -0
  68. package/dist/import/index.d.ts +7 -0
  69. package/dist/import/index.d.ts.map +1 -1
  70. package/dist/import/index.js +7 -0
  71. package/dist/import/index.js.map +1 -1
  72. package/dist/index.d.ts +29 -12
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +24 -9
  75. package/dist/index.js.map +1 -1
  76. package/dist/kernels/selective_scan.d.ts.map +1 -1
  77. package/dist/kernels/selective_scan.js +15 -9
  78. package/dist/kernels/selective_scan.js.map +1 -1
  79. package/dist/kernels/slice.d.ts +26 -0
  80. package/dist/kernels/slice.d.ts.map +1 -0
  81. package/dist/kernels/slice.js +52 -0
  82. package/dist/kernels/slice.js.map +1 -0
  83. package/dist/kernels/weight_update.d.ts.map +1 -1
  84. package/dist/kernels/weight_update.js +30 -4
  85. package/dist/kernels/weight_update.js.map +1 -1
  86. package/dist/lm/evermind_lm.d.ts +180 -4
  87. package/dist/lm/evermind_lm.d.ts.map +1 -1
  88. package/dist/lm/evermind_lm.js +433 -116
  89. package/dist/lm/evermind_lm.js.map +1 -1
  90. package/dist/lm/index.d.ts +8 -2
  91. package/dist/lm/index.d.ts.map +1 -1
  92. package/dist/lm/index.js +6 -1
  93. package/dist/lm/index.js.map +1 -1
  94. package/dist/lm/text_embedder.d.ts +55 -0
  95. package/dist/lm/text_embedder.d.ts.map +1 -0
  96. package/dist/lm/text_embedder.js +62 -0
  97. package/dist/lm/text_embedder.js.map +1 -0
  98. package/dist/model/attention_block.d.ts.map +1 -1
  99. package/dist/model/attention_block.js +9 -5
  100. package/dist/model/attention_block.js.map +1 -1
  101. package/dist/model/mamba1_block.d.ts.map +1 -1
  102. package/dist/model/mamba1_block.js +28 -12
  103. package/dist/model/mamba1_block.js.map +1 -1
  104. package/dist/model/mamba2_block.d.ts.map +1 -1
  105. package/dist/model/mamba2_block.js +14 -9
  106. package/dist/model/mamba2_block.js.map +1 -1
  107. package/dist/model/mamba3_block.d.ts.map +1 -1
  108. package/dist/model/mamba3_block.js +14 -9
  109. package/dist/model/mamba3_block.js.map +1 -1
  110. package/dist/moe/index.d.ts +0 -2
  111. package/dist/moe/index.d.ts.map +1 -1
  112. package/dist/moe/index.js +0 -1
  113. package/dist/moe/index.js.map +1 -1
  114. package/dist/optim/adamw.d.ts +58 -1
  115. package/dist/optim/adamw.d.ts.map +1 -1
  116. package/dist/optim/adamw.js +69 -4
  117. package/dist/optim/adamw.js.map +1 -1
  118. package/dist/tokenizer/bpe.d.ts +28 -0
  119. package/dist/tokenizer/bpe.d.ts.map +1 -1
  120. package/dist/tokenizer/bpe.js +47 -0
  121. package/dist/tokenizer/bpe.js.map +1 -1
  122. package/dist/training/cpu_ops.d.ts +44 -0
  123. package/dist/training/cpu_ops.d.ts.map +1 -0
  124. package/dist/training/cpu_ops.js +111 -0
  125. package/dist/training/cpu_ops.js.map +1 -0
  126. package/dist/training/lora.d.ts +153 -0
  127. package/dist/training/lora.d.ts.map +1 -0
  128. package/dist/training/lora.js +324 -0
  129. package/dist/training/lora.js.map +1 -0
  130. package/dist/training/mamba1_cpu.d.ts +109 -0
  131. package/dist/training/mamba1_cpu.d.ts.map +1 -0
  132. package/dist/training/mamba1_cpu.js +316 -0
  133. package/dist/training/mamba1_cpu.js.map +1 -0
  134. package/dist/training/mixed_precision.d.ts +67 -0
  135. package/dist/training/mixed_precision.d.ts.map +1 -0
  136. package/dist/training/mixed_precision.js +101 -0
  137. package/dist/training/mixed_precision.js.map +1 -0
  138. package/dist/training/model_cpu.d.ts +100 -0
  139. package/dist/training/model_cpu.d.ts.map +1 -0
  140. package/dist/training/model_cpu.js +252 -0
  141. package/dist/training/model_cpu.js.map +1 -0
  142. package/dist/training/trainer.d.ts +156 -16
  143. package/dist/training/trainer.d.ts.map +1 -1
  144. package/dist/training/trainer.js +327 -101
  145. package/dist/training/trainer.js.map +1 -1
  146. package/dist/utils/base64.d.ts +12 -0
  147. package/dist/utils/base64.d.ts.map +1 -0
  148. package/dist/utils/base64.js +27 -0
  149. package/dist/utils/base64.js.map +1 -0
  150. package/package.json +3 -1
  151. package/src/bench/adaptation.ts +180 -0
  152. package/src/bench/harness.ts +1 -1
  153. package/src/bench/index.ts +13 -2
  154. package/src/bench/types.ts +93 -0
  155. package/src/evermind/adapt.ts +61 -0
  156. package/src/evermind/delta_wire.ts +114 -0
  157. package/src/evermind/eval.ts +62 -0
  158. package/src/evermind/index.ts +33 -0
  159. package/src/evermind/merge.ts +106 -0
  160. package/src/{moe/moe_package.ts → evermind/package.ts} +148 -17
  161. package/src/import/foreign/adapter.ts +106 -0
  162. package/src/import/foreign/apply.ts +54 -0
  163. package/src/import/foreign/codestral_mamba.ts +224 -0
  164. package/src/import/foreign/falcon_mamba.ts +173 -0
  165. package/src/import/foreign/index.ts +37 -0
  166. package/src/import/foreign/plan.ts +294 -0
  167. package/src/import/foreign/registry.ts +126 -0
  168. package/src/import/index.ts +30 -0
  169. package/src/index.ts +104 -13
  170. package/src/kernels/selective_scan.ts +15 -9
  171. package/src/kernels/slice.ts +64 -0
  172. package/src/kernels/weight_update.ts +30 -4
  173. package/src/lm/evermind_lm.ts +470 -116
  174. package/src/lm/index.ts +12 -2
  175. package/src/lm/text_embedder.ts +84 -0
  176. package/src/model/attention_block.ts +9 -5
  177. package/src/model/mamba1_block.ts +28 -12
  178. package/src/model/mamba2_block.ts +14 -9
  179. package/src/model/mamba3_block.ts +14 -9
  180. package/src/moe/index.ts +0 -9
  181. package/src/optim/adamw.ts +115 -7
  182. package/src/tokenizer/bpe.ts +55 -0
  183. package/src/training/cpu_ops.ts +127 -0
  184. package/src/training/lora.ts +365 -0
  185. package/src/training/mamba1_cpu.ts +421 -0
  186. package/src/training/mixed_precision.ts +119 -0
  187. package/src/training/model_cpu.ts +360 -0
  188. package/src/training/trainer.ts +397 -154
  189. package/src/utils/base64.ts +28 -0
  190. package/dist/model/mamba_block.d.ts +0 -64
  191. package/dist/model/mamba_block.d.ts.map +0 -1
  192. package/dist/model/mamba_block.js +0 -303
  193. package/dist/model/mamba_block.js.map +0 -1
  194. package/dist/moe/moe_package.d.ts.map +0 -1
  195. package/dist/moe/moe_package.js.map +0 -1
  196. package/src/model/mamba_block.ts +0 -401
@@ -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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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * mamba1_cpu.ts — exact CPU forward + backward for a Mamba-1 (S6) block.
3
+ *
4
+ * This is the REFERENCE implementation of the same maths the WGSL kernels run
5
+ * (`rmsnorm_forward`, `linear_forward`, `conv1d_forward`, `silu_forward`,
6
+ * `forward_scan` + `forward_reduce`). It exists so real per-parameter gradients
7
+ * can be computed — and, crucially, PROVEN correct by finite differences —
8
+ * without a WebGPU device. {@link MambaTrainer} consumes it as its gradient
9
+ * engine: the optimizer (AdamW + trust region + NaN guard) stays on the GPU,
10
+ * the gradients are exact.
11
+ *
12
+ * Every formula below is a line-for-line mirror of the corresponding kernel; if
13
+ * a kernel changes, this file changes with it and `tests/backprop.test.ts`
14
+ * catches the drift (the gradient check fails the moment forward and backward
15
+ * disagree).
16
+ *
17
+ * Layout conventions (identical to the GPU buffers):
18
+ * x (M, dModel) M = batch * seqLen, row r = b * seqLen + t
19
+ * wInProj (2*dInner, dModel) row-major, Y = X @ W^T + b
20
+ * wConv (dInner, dConv) depthwise, causal
21
+ * wXProj (dtRank + 2*dState, dInner)
22
+ * wDtProj (dInner, dtRank)
23
+ * A_log (dInner, dState)
24
+ * wOutProj (dModel, dInner)
25
+ * hCache (B, L, dInner, dState)
26
+ */
27
+ /** The 13 learnable tensors of a Mamba-1 block, keyed by the SAME names
28
+ * {@link Mamba1Block.parameters} publishes. */
29
+ export interface Mamba1CpuWeights {
30
+ wInProj: Float32Array;
31
+ bInProj: Float32Array;
32
+ wConv: Float32Array;
33
+ bConv: Float32Array;
34
+ wXProj: Float32Array;
35
+ bXProj: Float32Array;
36
+ wDtProj: Float32Array;
37
+ bDtProj: Float32Array;
38
+ A_log: Float32Array;
39
+ D_vec: Float32Array;
40
+ wOutProj: Float32Array;
41
+ bOutProj: Float32Array;
42
+ normWeight: Float32Array;
43
+ }
44
+ /** Parameter names of a Mamba-1 block, in `parameters()` order. */
45
+ export declare const MAMBA1_PARAM_NAMES: readonly ["wInProj", "bInProj", "wConv", "bConv", "wXProj", "bXProj", "wDtProj", "bDtProj", "A_log", "D_vec", "wOutProj", "bOutProj", "normWeight"];
46
+ export interface Mamba1CpuDims {
47
+ dModel: number;
48
+ dState: number;
49
+ dConv: number;
50
+ dInner: number;
51
+ dtRank: number;
52
+ batch: number;
53
+ seqLen: number;
54
+ }
55
+ /** Everything the backward pass needs from the forward pass. */
56
+ export interface Mamba1CpuCache {
57
+ x: Float32Array;
58
+ normInv: Float32Array;
59
+ normOut: Float32Array;
60
+ xConvIn: Float32Array;
61
+ z: Float32Array;
62
+ convOut: Float32Array;
63
+ u: Float32Array;
64
+ dtRaw: Float32Array;
65
+ bRaw: Float32Array;
66
+ cRaw: Float32Array;
67
+ deltaFull: Float32Array;
68
+ dv: Float32Array;
69
+ aCont: Float32Array;
70
+ aBar: Float32Array;
71
+ bBar: Float32Array;
72
+ h: Float32Array;
73
+ scanY: Float32Array;
74
+ siluZ: Float32Array;
75
+ gated: Float32Array;
76
+ }
77
+ export interface Mamba1CpuForwardResult {
78
+ output: Float32Array;
79
+ cache: Mamba1CpuCache;
80
+ }
81
+ /** Gradients for every Mamba-1 parameter, same keys as {@link Mamba1CpuWeights}. */
82
+ export type Mamba1CpuGrads = Record<keyof Mamba1CpuWeights, Float32Array>;
83
+ /**
84
+ * Clamp bounds on `A_log` applied by `discretise_A`/`discretise_B` in
85
+ * `SELECTIVE_SCAN_FORWARD_WGSL`. Outside this range the kernel's output is
86
+ * constant in `A_log`, so the gradient is exactly zero — mirrored here so the
87
+ * analytic gradient matches the function the model actually computes.
88
+ */
89
+ export declare const A_LOG_CLAMP_LO = -10;
90
+ export declare const A_LOG_CLAMP_HI = 5;
91
+ /** Allocate a zeroed gradient set matching `dims`. */
92
+ export declare function zeroMamba1Grads(dims: Mamba1CpuDims): Mamba1CpuGrads;
93
+ /**
94
+ * Exact CPU forward for one Mamba-1 block.
95
+ *
96
+ * Mirrors `Mamba1Block.forward` step for step:
97
+ * RMSNorm → in_proj → split(x, z) → causal conv1d → SiLU → x_proj(Δ, B, C)
98
+ * → dt_proj → selective scan → gate by SiLU(z) → out_proj → residual add.
99
+ */
100
+ export declare function mamba1CpuForward(x: Float32Array, w: Mamba1CpuWeights, dims: Mamba1CpuDims): Mamba1CpuForwardResult;
101
+ /**
102
+ * Exact CPU backward for one Mamba-1 block.
103
+ *
104
+ * @param dOut dL/d(block output), (M, dModel)
105
+ * @param grads accumulator — parameter gradients are ADDED into it
106
+ * @returns dL/d(block input), (M, dModel)
107
+ */
108
+ export declare function mamba1CpuBackward(dOut: Float32Array, w: Mamba1CpuWeights, cache: Mamba1CpuCache, dims: Mamba1CpuDims, grads: Mamba1CpuGrads): Float32Array;
109
+ //# sourceMappingURL=mamba1_cpu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mamba1_cpu.d.ts","sourceRoot":"","sources":["../../src/training/mamba1_cpu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAcH;gDACgD;AAChD,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAK,YAAY,CAAC;IACzB,OAAO,EAAK,YAAY,CAAC;IACzB,KAAK,EAAO,YAAY,CAAC;IACzB,KAAK,EAAO,YAAY,CAAC;IACzB,MAAM,EAAM,YAAY,CAAC;IACzB,MAAM,EAAM,YAAY,CAAC;IACzB,OAAO,EAAK,YAAY,CAAC;IACzB,OAAO,EAAK,YAAY,CAAC;IACzB,KAAK,EAAO,YAAY,CAAC;IACzB,KAAK,EAAO,YAAY,CAAC;IACzB,QAAQ,EAAI,YAAY,CAAC;IACzB,QAAQ,EAAI,YAAY,CAAC;IACzB,UAAU,EAAE,YAAY,CAAC;CAC5B;AAED,mEAAmE;AACnE,eAAO,MAAM,kBAAkB,qJAG2B,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB,KAAK,EAAI,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;IAChB,KAAK,EAAI,MAAM,CAAC;IAChB,MAAM,EAAG,MAAM,CAAC;CACnB;AAED,gEAAgE;AAChE,MAAM,WAAW,cAAc;IAC3B,CAAC,EAAU,YAAY,CAAC;IACxB,OAAO,EAAI,YAAY,CAAC;IACxB,OAAO,EAAI,YAAY,CAAC;IACxB,OAAO,EAAI,YAAY,CAAC;IACxB,CAAC,EAAU,YAAY,CAAC;IACxB,OAAO,EAAI,YAAY,CAAC;IACxB,CAAC,EAAU,YAAY,CAAC;IACxB,KAAK,EAAM,YAAY,CAAC;IACxB,IAAI,EAAO,YAAY,CAAC;IACxB,IAAI,EAAO,YAAY,CAAC;IACxB,SAAS,EAAE,YAAY,CAAC;IACxB,EAAE,EAAS,YAAY,CAAC;IACxB,KAAK,EAAM,YAAY,CAAC;IACxB,IAAI,EAAO,YAAY,CAAC;IACxB,IAAI,EAAO,YAAY,CAAC;IACxB,CAAC,EAAU,YAAY,CAAC;IACxB,KAAK,EAAM,YAAY,CAAC;IACxB,KAAK,EAAM,YAAY,CAAC;IACxB,KAAK,EAAM,YAAY,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAG,cAAc,CAAC;CAC1B;AAED,oFAAoF;AACpF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,gBAAgB,EAAE,YAAY,CAAC,CAAC;AAE1E;;;;;GAKG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CAiBnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC5B,CAAC,EAAE,YAAY,EACf,CAAC,EAAE,gBAAgB,EACnB,IAAI,EAAE,aAAa,GACpB,sBAAsB,CAoHxB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,YAAY,EAClB,CAAC,EAAE,gBAAgB,EACnB,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,cAAc,GACtB,YAAY,CAiJd"}