@seanhogg/builderforce-memory-engine 2026.6.39 → 2026.7.12

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 (66) hide show
  1. package/dist/codec/evermind_video.d.ts +35 -0
  2. package/dist/codec/evermind_video.d.ts.map +1 -0
  3. package/dist/codec/evermind_video.js +37 -0
  4. package/dist/codec/evermind_video.js.map +1 -0
  5. package/dist/codec/image_rvq.d.ts +28 -0
  6. package/dist/codec/image_rvq.d.ts.map +1 -0
  7. package/dist/codec/image_rvq.js +39 -0
  8. package/dist/codec/image_rvq.js.map +1 -0
  9. package/dist/codec/index.d.ts +13 -0
  10. package/dist/codec/index.d.ts.map +1 -0
  11. package/dist/codec/index.js +11 -0
  12. package/dist/codec/index.js.map +1 -0
  13. package/dist/codec/multimodal_vocab.d.ts +79 -0
  14. package/dist/codec/multimodal_vocab.d.ts.map +1 -0
  15. package/dist/codec/multimodal_vocab.js +96 -0
  16. package/dist/codec/multimodal_vocab.js.map +1 -0
  17. package/dist/codec/video_rvq.d.ts +116 -0
  18. package/dist/codec/video_rvq.d.ts.map +1 -0
  19. package/dist/codec/video_rvq.js +450 -0
  20. package/dist/codec/video_rvq.js.map +1 -0
  21. package/dist/index.d.ts +3 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +2 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/kernels/selective_scan.d.ts.map +1 -1
  26. package/dist/kernels/selective_scan.js +9 -3
  27. package/dist/kernels/selective_scan.js.map +1 -1
  28. package/dist/kernels/ssd.d.ts.map +1 -1
  29. package/dist/kernels/ssd.js +8 -2
  30. package/dist/kernels/ssd.js.map +1 -1
  31. package/dist/kernels/weight_update.d.ts.map +1 -1
  32. package/dist/kernels/weight_update.js +22 -3
  33. package/dist/kernels/weight_update.js.map +1 -1
  34. package/dist/limbic/limbic_trainer.d.ts +5 -1
  35. package/dist/limbic/limbic_trainer.d.ts.map +1 -1
  36. package/dist/limbic/limbic_trainer.js +4 -2
  37. package/dist/limbic/limbic_trainer.js.map +1 -1
  38. package/dist/model/mamba_model.d.ts +17 -0
  39. package/dist/model/mamba_model.d.ts.map +1 -1
  40. package/dist/model/mamba_model.js +27 -0
  41. package/dist/model/mamba_model.js.map +1 -1
  42. package/dist/moe/index.d.ts +1 -1
  43. package/dist/moe/index.d.ts.map +1 -1
  44. package/dist/moe/moe_package.d.ts +40 -2
  45. package/dist/moe/moe_package.d.ts.map +1 -1
  46. package/dist/moe/moe_package.js +90 -7
  47. package/dist/moe/moe_package.js.map +1 -1
  48. package/dist/training/trainer.d.ts +34 -2
  49. package/dist/training/trainer.d.ts.map +1 -1
  50. package/dist/training/trainer.js +76 -26
  51. package/dist/training/trainer.js.map +1 -1
  52. package/package.json +1 -1
  53. package/src/codec/evermind_video.ts +55 -0
  54. package/src/codec/image_rvq.ts +50 -0
  55. package/src/codec/index.ts +16 -0
  56. package/src/codec/multimodal_vocab.ts +115 -0
  57. package/src/codec/video_rvq.ts +496 -0
  58. package/src/index.ts +22 -0
  59. package/src/kernels/selective_scan.ts +9 -3
  60. package/src/kernels/ssd.ts +8 -2
  61. package/src/kernels/weight_update.ts +22 -3
  62. package/src/limbic/limbic_trainer.ts +9 -4
  63. package/src/model/mamba_model.ts +27 -0
  64. package/src/moe/index.ts +1 -0
  65. package/src/moe/moe_package.ts +107 -6
  66. package/src/training/trainer.ts +92 -28
@@ -14,22 +14,54 @@ export interface TrainOptions {
14
14
  beta2?: number;
15
15
  eps?: number;
16
16
  wsla?: boolean;
17
- onEpochEnd?: ((epoch: number, loss: number) => void) | null;
17
+ /** Trust region: max |Δθ| per optimizer step. 0 disables. Defaults to
18
+ * {@link WSLA_MAX_DELTA} in WSLA (write-through) mode, else 0 (full training). */
19
+ maxDelta?: number;
20
+ /** Read back the pre-clip gradient L2 norm each step (the `grad_norm_reduce`
21
+ * kernel already computes it — this just maps it to the CPU). OFF by default: the
22
+ * readback is a GPU sync point that would slow a long finetune. `adapt()` turns it
23
+ * ON so the norm reaches {@link AdaptResult} as an instability signal. */
24
+ trackGradNorm?: boolean;
25
+ onEpochEnd?: ((epoch: number, loss: number, gradNorm?: number) => void) | null;
18
26
  }
27
+ /**
28
+ * Default per-step trust region for WSLA / write-through adaptation. Small
29
+ * enough that a single `adapt()` nudges the narrow params without lurching, so
30
+ * repeated adapts stay stable (and any that regress are cheaply rolled back by
31
+ * the session). Full-training callers pass `maxDelta: 0` (or omit it in
32
+ * non-WSLA mode) for unbounded steps.
33
+ */
34
+ export declare const WSLA_MAX_DELTA = 0.05;
19
35
  export declare class MambaTrainer {
20
36
  model: HybridMambaModel;
21
37
  tokenizer: BPETokenizer | null;
22
38
  device: GPUDevice;
39
+ /**
40
+ * Adam moments keyed by parameter NAME (not array index). Name-keying is what
41
+ * lets WSLA toggle safely: a narrow write-through step updates only the
42
+ * `layer{i}.wXProj/bXProj` subset, a full fine-tune updates everything, and
43
+ * both reuse the SAME `m`/`v` buffers per parameter. Index-keyed moments (the
44
+ * old scheme) silently misaligned the moment with the wrong parameter the
45
+ * moment the trainable set changed shape — corrupting the update.
46
+ */
23
47
  private _moments;
24
48
  private _step;
25
49
  private _adamwPipeline;
26
50
  private _clipReducePipeline;
27
51
  private _clipScalePipeline;
28
52
  constructor(model: HybridMambaModel | MambaModel, tokenizer?: BPETokenizer | null);
29
- private _initMoments;
53
+ /** Get-or-create the Adam first/second moments for a parameter, by name. */
54
+ private _momentFor;
30
55
  train(input: string | number[], opts?: TrainOptions): Promise<number[]>;
31
56
  private _trainStep;
32
57
  private _adamwStep;
58
+ /**
59
+ * Clip gradients to `maxNorm` in place. The reduce kernel writes Σg² into
60
+ * `normSqBuf`; the scale kernel then rescales the grads. When `trackNorm` is set
61
+ * we read Σg² back and return the true pre-clip L2 norm (√Σg²) — the kernel
62
+ * already computed it, so this is only a small buffer readback (a GPU sync,
63
+ * hence opt-in). Returns null when not tracking.
64
+ */
33
65
  private _clipGradients;
34
66
  evaluate(input: string | number[]): Promise<number>;
35
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"trainer.d.ts","sourceRoot":"","sources":["../../src/training/trainer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAC7D;AAiBD,qBAAa,YAAY;IACrB,KAAK,EAAE,gBAAgB,CAAC;IACxB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAAqB;gBAEnC,KAAK,EAAE,gBAAgB,GAAG,UAAU,EAAE,SAAS,GAAE,YAAY,GAAG,IAAW;IAavF,OAAO,CAAC,YAAY;IAQd,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAkEnE,UAAU;YAkDV,UAAU;YAgCV,cAAc;IAuBtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA4B5D"}
1
+ {"version":3,"file":"trainer.d.ts","sourceRoot":"","sources":["../../src/training/trainer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;uFACmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;+EAG2E;IAC3E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAChF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC;AAkBnC,qBAAa,YAAY;IACrB,KAAK,EAAE,gBAAgB,CAAC;IACxB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAAqB;gBAEnC,KAAK,EAAE,gBAAgB,GAAG,UAAU,EAAE,SAAS,GAAE,YAAY,GAAG,IAAW;IAavF,4EAA4E;IAC5E,OAAO,CAAC,UAAU;IAYZ,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YA2EnE,UAAU;YAqDV,UAAU;IAiCxB;;;;;;OAMG;YACW,cAAc;IAgCtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA4B5D"}
@@ -1,13 +1,29 @@
1
1
  /**
2
2
  * trainer.ts – MambaTrainer class
3
3
  */
4
- import { createUniformBuffer, createStorageBuffer, createEmptyStorageBuffer, createComputePipeline, createBindGroup, dispatchKernel, cdiv, } from '../utils/gpu_utils.js';
4
+ import { createUniformBuffer, createStorageBuffer, createEmptyStorageBuffer, createComputePipeline, createBindGroup, dispatchKernel, readBuffer, cdiv, } from '../utils/gpu_utils.js';
5
5
  import { crossEntropyLoss, crossEntropyGrad } from './autograd.js';
6
6
  import { WEIGHT_UPDATE_WGSL, GRAD_CLIP_WGSL } from '../kernels/weight_update.js';
7
+ /**
8
+ * Default per-step trust region for WSLA / write-through adaptation. Small
9
+ * enough that a single `adapt()` nudges the narrow params without lurching, so
10
+ * repeated adapts stay stable (and any that regress are cheaply rolled back by
11
+ * the session). Full-training callers pass `maxDelta: 0` (or omit it in
12
+ * non-WSLA mode) for unbounded steps.
13
+ */
14
+ export const WSLA_MAX_DELTA = 0.05;
7
15
  export class MambaTrainer {
8
16
  model;
9
17
  tokenizer;
10
18
  device;
19
+ /**
20
+ * Adam moments keyed by parameter NAME (not array index). Name-keying is what
21
+ * lets WSLA toggle safely: a narrow write-through step updates only the
22
+ * `layer{i}.wXProj/bXProj` subset, a full fine-tune updates everything, and
23
+ * both reuse the SAME `m`/`v` buffers per parameter. Index-keyed moments (the
24
+ * old scheme) silently misaligned the moment with the wrong parameter the
25
+ * moment the trainable set changed shape — corrupting the update.
26
+ */
11
27
  _moments;
12
28
  _step;
13
29
  _adamwPipeline;
@@ -17,22 +33,28 @@ export class MambaTrainer {
17
33
  this.model = model;
18
34
  this.tokenizer = tokenizer;
19
35
  this.device = model.device;
20
- this._moments = null;
36
+ this._moments = new Map();
21
37
  this._step = 0;
22
38
  this._adamwPipeline = createComputePipeline(this.device, WEIGHT_UPDATE_WGSL, 'adamw_update');
23
39
  this._clipReducePipeline = createComputePipeline(this.device, GRAD_CLIP_WGSL, 'grad_norm_reduce');
24
40
  this._clipScalePipeline = createComputePipeline(this.device, GRAD_CLIP_WGSL, 'grad_clip_scale');
25
41
  }
26
- _initMoments() {
27
- if (this._moments)
28
- return;
29
- this._moments = this.model.parameters().map(p => ({
30
- m: createEmptyStorageBuffer(this.device, p.numel * 4, false),
31
- v: createEmptyStorageBuffer(this.device, p.numel * 4, false),
32
- }));
42
+ /** Get-or-create the Adam first/second moments for a parameter, by name. */
43
+ _momentFor(p) {
44
+ let mom = this._moments.get(p.name);
45
+ if (!mom) {
46
+ mom = {
47
+ m: createEmptyStorageBuffer(this.device, p.numel * 4, false),
48
+ v: createEmptyStorageBuffer(this.device, p.numel * 4, false),
49
+ };
50
+ this._moments.set(p.name, mom);
51
+ }
52
+ return mom;
33
53
  }
34
54
  async train(input, opts = {}) {
35
- const { learningRate = 1e-4, epochs = 5, batchSize = 1, seqLen = 512, maxGradNorm = 1.0, weightDecay = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8, wsla = false, onEpochEnd = null, } = opts;
55
+ const { learningRate = 1e-4, epochs = 5, batchSize = 1, seqLen = 512, maxGradNorm = 1.0, weightDecay = 0.01, beta1 = 0.9, beta2 = 0.999, eps = 1e-8, wsla = false, trackGradNorm = false, onEpochEnd = null, } = opts;
56
+ // Trust region defaults ON for write-through (WSLA) adapts, OFF otherwise.
57
+ const maxDelta = opts.maxDelta ?? (wsla ? WSLA_MAX_DELTA : 0);
36
58
  if (wsla)
37
59
  this.model.setWSLAMode(true);
38
60
  let tokenIds;
@@ -53,27 +75,34 @@ export class MambaTrainer {
53
75
  if (chunks.length === 0) {
54
76
  throw new Error('Input is too short to form any training chunk.');
55
77
  }
56
- this._initMoments();
78
+ // Moments are created lazily per-parameter (name-keyed) on first touch —
79
+ // no upfront allocation needed, and it stays correct as WSLA narrows the
80
+ // trainable set.
57
81
  const epochLosses = [];
58
82
  for (let epoch = 0; epoch < epochs; epoch++) {
59
83
  let epochLoss = 0;
84
+ let epochGradNorm = 0;
60
85
  let numSteps = 0;
61
86
  for (const { inputs, targets } of chunks) {
62
- const loss = await this._trainStep(inputs, targets, batchSize, { learningRate, maxGradNorm, weightDecay, beta1, beta2, eps, wsla });
87
+ const { loss, gradNorm } = await this._trainStep(inputs, targets, batchSize, { learningRate, maxGradNorm, weightDecay, beta1, beta2, eps, wsla, maxDelta, trackGradNorm });
63
88
  epochLoss += loss;
89
+ if (gradNorm != null)
90
+ epochGradNorm += gradNorm;
64
91
  numSteps++;
65
92
  }
66
93
  const avgLoss = epochLoss / numSteps;
67
94
  epochLosses.push(avgLoss);
95
+ // Mean pre-clip grad norm this epoch (only measured when trackGradNorm is on).
96
+ const avgGradNorm = trackGradNorm ? epochGradNorm / numSteps : undefined;
68
97
  if (onEpochEnd)
69
- onEpochEnd(epoch + 1, avgLoss);
98
+ onEpochEnd(epoch + 1, avgLoss, avgGradNorm);
70
99
  }
71
100
  if (wsla)
72
101
  this.model.setWSLAMode(false);
73
102
  return epochLosses;
74
103
  }
75
104
  async _trainStep(inputs, targets, batch, hyperparams) {
76
- const { learningRate, maxGradNorm, weightDecay, beta1, beta2, eps } = hyperparams;
105
+ const { learningRate, maxGradNorm, weightDecay, beta1, beta2, eps, maxDelta, trackGradNorm } = hyperparams;
77
106
  this._step++;
78
107
  const seqLen = inputs.length;
79
108
  const vocabSize = this.model.config.vocabSize;
@@ -92,35 +121,46 @@ export class MambaTrainer {
92
121
  }
93
122
  const loss = totalLoss / seqLen;
94
123
  const dLogitsBuf = createStorageBuffer(this.device, dLogits, false);
95
- await this._clipGradients(dLogitsBuf, dLogits.length, maxGradNorm);
96
- const params = this.model.parameters();
124
+ const gradNorm = await this._clipGradients(dLogitsBuf, dLogits.length, maxGradNorm, !!trackGradNorm);
125
+ // Only the trainable set is updated. Under WSLA (write-through) that is
126
+ // the narrow per-layer subset and the backbone (incl. every A_log) stays
127
+ // frozen — the guarantee that repeated adapts can't destabilise the SSM.
128
+ const params = this.model.getTrainableParams();
97
129
  const beta1_t = Math.pow(beta1, this._step);
98
130
  const beta2_t = Math.pow(beta2, this._step);
99
- await this._adamwStep(params, [dLogitsBuf], { learningRate, weightDecay, beta1, beta2, eps, beta1_t, beta2_t });
131
+ await this._adamwStep(params, [dLogitsBuf], { learningRate, weightDecay, beta1, beta2, eps, beta1_t, beta2_t, maxDelta });
100
132
  dLogitsBuf.destroy();
101
133
  gpuLogits.destroy();
102
- return loss;
134
+ return { loss, gradNorm };
103
135
  }
104
136
  async _adamwStep(params, gradBufs, hp) {
105
- const { learningRate, weightDecay, beta1, beta2, eps, beta1_t, beta2_t } = hp;
137
+ const { learningRate, weightDecay, beta1, beta2, eps, beta1_t, beta2_t, maxDelta } = hp;
106
138
  for (let i = 0; i < params.length; i++) {
107
139
  const p = params[i];
108
140
  const gradBuf = gradBufs[Math.min(i, gradBufs.length - 1)];
109
141
  if (!gradBuf || gradBuf.size < p.numel * 4)
110
142
  continue;
111
- const paramsBuf = createUniformBuffer(this.device, packAdamParams(p.numel, learningRate, beta1, beta2, eps, weightDecay, beta1_t, beta2_t));
143
+ const mom = this._momentFor(p);
144
+ const paramsBuf = createUniformBuffer(this.device, packAdamParams(p.numel, learningRate, beta1, beta2, eps, weightDecay, beta1_t, beta2_t, maxDelta));
112
145
  const bg = createBindGroup(this.device, this._adamwPipeline, [
113
146
  paramsBuf,
114
147
  p.buf,
115
148
  gradBuf,
116
- this._moments[i].m,
117
- this._moments[i].v,
149
+ mom.m,
150
+ mom.v,
118
151
  ]);
119
152
  dispatchKernel(this.device, this._adamwPipeline, bg, [cdiv(p.numel, 256), 1, 1]);
120
153
  paramsBuf.destroy();
121
154
  }
122
155
  }
123
- async _clipGradients(gradBuf, numel, maxNorm) {
156
+ /**
157
+ * Clip gradients to `maxNorm` in place. The reduce kernel writes Σg² into
158
+ * `normSqBuf`; the scale kernel then rescales the grads. When `trackNorm` is set
159
+ * we read Σg² back and return the true pre-clip L2 norm (√Σg²) — the kernel
160
+ * already computed it, so this is only a small buffer readback (a GPU sync,
161
+ * hence opt-in). Returns null when not tracking.
162
+ */
163
+ async _clipGradients(gradBuf, numel, maxNorm, trackNorm = false) {
124
164
  const normSqBuf = createEmptyStorageBuffer(this.device, 4, true);
125
165
  this.device.queue.writeBuffer(normSqBuf, 0, new Float32Array([0.0]));
126
166
  const clipParams = new ArrayBuffer(8);
@@ -129,10 +169,18 @@ export class MambaTrainer {
129
169
  const pBuf = createUniformBuffer(this.device, clipParams);
130
170
  const bg1 = createBindGroup(this.device, this._clipReducePipeline, [pBuf, gradBuf, normSqBuf]);
131
171
  dispatchKernel(this.device, this._clipReducePipeline, bg1, [cdiv(numel, 256), 1, 1]);
172
+ // Read Σg² AFTER the reduce (the scale kernel only reads it, never overwrites),
173
+ // so the returned norm is the pre-clip magnitude — the instability signal.
174
+ let gradNorm = null;
175
+ if (trackNorm) {
176
+ const out = await readBuffer(this.device, normSqBuf, 4);
177
+ gradNorm = Math.sqrt(Math.max(0, out[0] ?? 0));
178
+ }
132
179
  const bg2 = createBindGroup(this.device, this._clipScalePipeline, [pBuf, gradBuf, normSqBuf]);
133
180
  dispatchKernel(this.device, this._clipScalePipeline, bg2, [cdiv(numel, 256), 1, 1]);
134
181
  pBuf.destroy();
135
182
  normSqBuf.destroy();
183
+ return gradNorm;
136
184
  }
137
185
  async evaluate(input) {
138
186
  let tokenIds;
@@ -174,10 +222,12 @@ function buildChunks(ids, seqLen) {
174
222
  }
175
223
  return chunks;
176
224
  }
177
- function packAdamParams(numElements, lr, beta1, beta2, eps, weightDecay, beta1_t, beta2_t) {
178
- const buf = new ArrayBuffer(32);
225
+ function packAdamParams(numElements, lr, beta1, beta2, eps, weightDecay, beta1_t, beta2_t, maxDelta) {
226
+ // 48 bytes: u32 + 8×f32 = 36, padded to a 16-byte multiple for the uniform
227
+ // layout (matches AdamParams' _pad0.._pad2 in WEIGHT_UPDATE_WGSL).
228
+ const buf = new ArrayBuffer(48);
179
229
  new Uint32Array(buf, 0, 1).set([numElements]);
180
- new Float32Array(buf, 4, 7).set([lr, beta1, beta2, eps, weightDecay, beta1_t, beta2_t]);
230
+ new Float32Array(buf, 4, 8).set([lr, beta1, beta2, eps, weightDecay, beta1_t, beta2_t, maxDelta]);
181
231
  return buf;
182
232
  }
183
233
  //# sourceMappingURL=trainer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trainer.js","sourceRoot":"","sources":["../../src/training/trainer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trainer.js","sourceRoot":"","sources":["../../src/training/trainer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanhogg/builderforce-memory-engine",
3
- "version": "2026.6.39",
3
+ "version": "2026.7.12",
4
4
  "description": "BuilderForce Agent Memory — engine layer. TypeScript/WGSL Mamba SSM kernels, model blocks, autograd, training, and BPE tokenizer (zero runtime deps, WebGPU-native).",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -0,0 +1,55 @@
1
+ /**
2
+ * evermind_video.ts — thin bridge that makes the EXISTING EvermindLM generate
3
+ * video. No new model, no new generator: the codec turns frames into tokens, the
4
+ * unqualified `EvermindLM.generate` autoregresses over them, and the codec turns
5
+ * the emitted tokens back into frames. Deliberately DRY — everything the text
6
+ * path already has (sampling, checkpoints, delta export, training) is reused.
7
+ */
8
+
9
+ import type { EvermindLM, LMGenerateOptions } from "../lm/evermind_lm.js";
10
+ import type { VideoRVQCodec, Video, Frame } from "./video_rvq.js";
11
+ import type { ImageRVQCodec } from "./image_rvq.js";
12
+
13
+ /**
14
+ * Build a unified training sequence `text… <vid> frames… </vid>` for
15
+ * `EvermindLMTrainer.fit`. `textTokens` are ids in the codec's text region (from
16
+ * a BPE tokenizer whose vocab size equals `codec.vocab.textVocabSize`). Training
17
+ * the LM on many such sequences is what teaches text→video.
18
+ */
19
+ export function buildVideoSequence(codec: VideoRVQCodec, textTokens: number[], video: Video): number[] {
20
+ return [...textTokens, ...codec.encode(video)];
21
+ }
22
+
23
+ /**
24
+ * Generate video from a prompt of already-tokenised context (text ids and/or a
25
+ * partial video stream). The prompt should normally end just before or at the
26
+ * `<vid>` marker; generation stops at `</vid>` or after `maxNewTokens`.
27
+ *
28
+ * Returns the decoded clip plus the raw produced token ids (useful for chaining
29
+ * or continued generation).
30
+ */
31
+ export function generateVideo(
32
+ lm: EvermindLM,
33
+ codec: VideoRVQCodec,
34
+ promptTokens: number[],
35
+ opts: LMGenerateOptions,
36
+ ): { video: Video; tokens: number[] } {
37
+ if (lm.config.vocabSize !== codec.vocabSize) {
38
+ throw new Error(
39
+ `generateVideo: EvermindLM vocabSize (${lm.config.vocabSize}) must equal codec.vocabSize (${codec.vocabSize})`,
40
+ );
41
+ }
42
+ const tokens = lm.generate(promptTokens, { ...opts, stopToken: opts.stopToken ?? codec.vocab.eosVideo });
43
+ return { video: codec.decode(tokens), tokens };
44
+ }
45
+
46
+ /** Generate a single image — the still-image case of {@link generateVideo}. */
47
+ export function generateImage(
48
+ lm: EvermindLM,
49
+ codec: ImageRVQCodec,
50
+ promptTokens: number[],
51
+ opts: LMGenerateOptions,
52
+ ): { image: Frame; tokens: number[] } {
53
+ const { video, tokens } = generateVideo(lm, codec.video, promptTokens, opts);
54
+ return { image: video[0] ?? new Float32Array(codec.frameSize), tokens };
55
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * image_rvq.ts — ImageRVQCodec: still-image generation as the single-frame case
3
+ * of {@link VideoRVQCodec}. An image has no temporal axis, so every frame is a
4
+ * keyframe (intra) — this wrapper just fixes `keyframeInterval = 1` and speaks in
5
+ * single frames instead of clips. Deliberately thin: it reuses the video codec's
6
+ * patchify + residual-VQ + learned codebooks + tolerant decode wholesale, so
7
+ * there is exactly one implementation to maintain.
8
+ */
9
+
10
+ import { VideoRVQCodec, type VideoRVQConfig, type Frame } from "./video_rvq.js";
11
+
12
+ export type { Frame } from "./video_rvq.js";
13
+
14
+ export class ImageRVQCodec {
15
+ /** The underlying video codec (pass to `generateVideo`/`generateImage`). */
16
+ readonly video: VideoRVQCodec;
17
+
18
+ constructor(config: Omit<VideoRVQConfig, "keyframeInterval">) {
19
+ this.video = new VideoRVQCodec({ ...config, keyframeInterval: 1 });
20
+ }
21
+
22
+ get vocab() {
23
+ return this.video.vocab;
24
+ }
25
+ get vocabSize(): number {
26
+ return this.video.vocabSize;
27
+ }
28
+ get frameSize(): number {
29
+ return this.video.height * this.video.width * this.video.channels;
30
+ }
31
+
32
+ /** Encode one image to a `<vid> <key> codes… </vid>` token stream. */
33
+ encode(image: Frame): number[] {
34
+ return this.video.encode([image]);
35
+ }
36
+
37
+ /** Decode a token stream to a single image (zeros if the stream yields no frame). */
38
+ decode(tokens: number[]): Frame {
39
+ const frames = this.video.decode(tokens);
40
+ return frames[0] ?? new Float32Array(this.frameSize);
41
+ }
42
+
43
+ /** Learn codebooks from a set of images (each is a one-frame clip). Returns recon MSE. */
44
+ fit(images: Frame[], opts?: { iterations?: number; seed?: number }): number {
45
+ return this.video.fit(
46
+ images.map((im) => [im]),
47
+ opts,
48
+ );
49
+ }
50
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * codec/ — modality codecs that turn non-text media into the discrete token
3
+ * streams Evermind's generator already speaks. Today: video (temporal residual
4
+ * VQ). Images are the single-frame case; audio/other modalities follow the same
5
+ * "media ⇄ tokens + unified vocab" shape.
6
+ */
7
+
8
+ export { MultimodalVocab, VIDEO_BANK_INTRA, VIDEO_BANK_INTER } from "./multimodal_vocab.js";
9
+ export type { MultimodalVocabConfig, TokenKind } from "./multimodal_vocab.js";
10
+
11
+ export { VideoRVQCodec } from "./video_rvq.js";
12
+ export type { VideoRVQConfig, Frame, Video } from "./video_rvq.js";
13
+
14
+ export { ImageRVQCodec } from "./image_rvq.js";
15
+
16
+ export { buildVideoSequence, generateVideo, generateImage } from "./evermind_video.js";
@@ -0,0 +1,115 @@
1
+ /**
2
+ * multimodal_vocab.ts — one flat token space shared by text and video.
3
+ *
4
+ * Evermind's generator ({@link ../lm/evermind_lm.EvermindLM}) is a pure
5
+ * next-token predictor: it neither knows nor cares whether a token id is a BPE
6
+ * text piece or a quantised video-patch code. So "make Evermind generate video"
7
+ * is a *vocabulary* problem, not a model problem — lay text tokens, a handful of
8
+ * modality control tokens, and the video codebook codes out on a single integer
9
+ * axis, and the same model handles `(caption … <vid> … frames … </vid>)`.
10
+ *
11
+ * Layout (low → high):
12
+ *
13
+ * [ 0 .. textVocabSize ) text (BPE) — passthrough
14
+ * textVocabSize + 0 <vid> (BOS_VIDEO)
15
+ * textVocabSize + 1 </vid> (EOS_VIDEO)
16
+ * textVocabSize + 2 <key> (start of an intra frame)
17
+ * textVocabSize + 3 <delta> (start of an inter frame)
18
+ * codeBase + bank·levels·K + level·K + code residual-VQ code tokens
19
+ *
20
+ * where `bank ∈ {INTRA, INTER}`, `level ∈ [0, levels)`, `code ∈ [0, K)` and
21
+ * `K = codebookSize`. A frame is therefore a marker followed by
22
+ * `patchesPerFrame · levels` code tokens — a deterministic, self-delimiting
23
+ * structure the codec can parse straight out of the generator's output.
24
+ */
25
+
26
+ export const VIDEO_BANK_INTRA = 0;
27
+ export const VIDEO_BANK_INTER = 1;
28
+
29
+ export interface MultimodalVocabConfig {
30
+ /** Size of the text (BPE) region; 0 for a pure-video model. */
31
+ textVocabSize: number;
32
+ /** Residual-VQ depth (codes emitted per patch). */
33
+ levels: number;
34
+ /** Entries per codebook per level per bank. */
35
+ codebookSize: number;
36
+ }
37
+
38
+ /** What a token id decodes to when parsing a mixed stream. */
39
+ export type TokenKind =
40
+ | { kind: "text"; id: number }
41
+ | { kind: "control"; control: "bosVideo" | "eosVideo" | "frameKey" | "frameDelta" }
42
+ | { kind: "code"; bank: number; level: number; code: number };
43
+
44
+ /**
45
+ * Bijective map between (text ids, control tokens, video codes) and a single
46
+ * flat token id space. Owns the offset arithmetic so nothing else has to.
47
+ */
48
+ export class MultimodalVocab {
49
+ readonly textVocabSize: number;
50
+ readonly levels: number;
51
+ readonly codebookSize: number;
52
+
53
+ readonly bosVideo: number;
54
+ readonly eosVideo: number;
55
+ readonly frameKey: number;
56
+ readonly frameDelta: number;
57
+ readonly codeBase: number;
58
+ /** Total vocabulary size — pass this as EvermindLM's `vocabSize`. */
59
+ readonly size: number;
60
+
61
+ private readonly perBank: number;
62
+
63
+ constructor(cfg: MultimodalVocabConfig) {
64
+ if (cfg.textVocabSize < 0) throw new Error("MultimodalVocab: textVocabSize must be ≥ 0");
65
+ if (cfg.levels <= 0 || cfg.codebookSize <= 0) throw new Error("MultimodalVocab: levels and codebookSize must be > 0");
66
+ this.textVocabSize = cfg.textVocabSize;
67
+ this.levels = cfg.levels;
68
+ this.codebookSize = cfg.codebookSize;
69
+
70
+ this.bosVideo = cfg.textVocabSize;
71
+ this.eosVideo = cfg.textVocabSize + 1;
72
+ this.frameKey = cfg.textVocabSize + 2;
73
+ this.frameDelta = cfg.textVocabSize + 3;
74
+ this.codeBase = cfg.textVocabSize + 4;
75
+ this.perBank = cfg.levels * cfg.codebookSize;
76
+ this.size = this.codeBase + 2 * this.perBank;
77
+ }
78
+
79
+ /** Global token id for a residual-VQ code. */
80
+ codeToken(bank: number, level: number, code: number): number {
81
+ return this.codeBase + bank * this.perBank + level * this.codebookSize + code;
82
+ }
83
+
84
+ isText(tok: number): boolean {
85
+ return tok >= 0 && tok < this.textVocabSize;
86
+ }
87
+
88
+ isCode(tok: number): boolean {
89
+ return tok >= this.codeBase && tok < this.size;
90
+ }
91
+
92
+ isVideoMarker(tok: number): boolean {
93
+ return tok === this.frameKey || tok === this.frameDelta;
94
+ }
95
+
96
+ /** Decompose a code token into (bank, level, code). Level/code are meaningful even if the bank differs. */
97
+ decodeCode(tok: number): { bank: number; level: number; code: number } {
98
+ const idx = tok - this.codeBase;
99
+ const bank = Math.floor(idx / this.perBank);
100
+ const rem = idx - bank * this.perBank;
101
+ const level = Math.floor(rem / this.codebookSize);
102
+ const code = rem - level * this.codebookSize;
103
+ return { bank, level, code };
104
+ }
105
+
106
+ /** Classify any token id in the flat space. */
107
+ classify(tok: number): TokenKind {
108
+ if (this.isText(tok)) return { kind: "text", id: tok };
109
+ if (tok === this.bosVideo) return { kind: "control", control: "bosVideo" };
110
+ if (tok === this.eosVideo) return { kind: "control", control: "eosVideo" };
111
+ if (tok === this.frameKey) return { kind: "control", control: "frameKey" };
112
+ if (tok === this.frameDelta) return { kind: "control", control: "frameDelta" };
113
+ return { kind: "code", ...this.decodeCode(tok) };
114
+ }
115
+ }