volvoxai 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +346 -43
  2. package/bin/volvox.js +9 -3
  3. package/dist/0.2.0/volvoxai.full.js +28607 -0
  4. package/dist/0.2.0/volvoxai.full.min.js +8975 -0
  5. package/dist/0.2.0/volvoxai.full.wasm +0 -0
  6. package/dist/0.2.0/volvoxai.js +18380 -0
  7. package/dist/0.2.0/volvoxai.min.js +6061 -0
  8. package/dist/0.2.0/volvoxai.wasm +0 -0
  9. package/dist/0.2.0/volvoxai.wasm.js +10337 -0
  10. package/dist/0.2.0/volvoxai.wasm.min.js +2 -0
  11. package/package.json +26 -12
  12. package/dist/v0.1.0/volvoxai.js +0 -4664
  13. package/dist/v0.1.0/volvoxai.min.js +0 -1848
  14. package/dist/v0.1.0/volvoxai.wasm +0 -0
  15. package/dist/volvoxai.js +0 -4664
  16. package/dist/volvoxai.min.js +0 -1848
  17. package/dist/volvoxai.wasm +0 -0
  18. package/docs/README.md +0 -22
  19. package/docs/browser-runtime.md +0 -87
  20. package/docs/efficientdet_tflite_vs_volvoxai.md +0 -445
  21. package/docs/microkernel_optimization_guide.md +0 -153
  22. package/docs/model-format.md +0 -108
  23. package/docs/models.md +0 -103
  24. package/docs/native-runtime.md +0 -189
  25. package/docs/operation_list.md +0 -232
  26. package/docs/operator_fusion_patterns.md +0 -58
  27. package/docs/quickstart.md +0 -115
  28. package/docs/roadmap.md +0 -19
  29. package/docs/testing.md +0 -97
  30. package/docs/textbook/01-foundations.md +0 -233
  31. package/docs/textbook/02-tinystories-language-model.md +0 -300
  32. package/docs/textbook/03-efficientdet-vision-model.md +0 -281
  33. package/docs/textbook/04-precision-and-quantization.md +0 -208
  34. package/docs/textbook/05-inside-the-engine.md +0 -155
  35. package/docs/textbook/06-native-engine-architecture.md +0 -338
  36. package/docs/textbook/07-glossary-and-next-steps.md +0 -258
  37. package/docs/textbook/README.md +0 -85
  38. package/docs/textbook/ko/01-foundations.md +0 -231
  39. package/docs/textbook/ko/02-tinystories-language-model.md +0 -300
  40. package/docs/textbook/ko/03-efficientdet-vision-model.md +0 -277
  41. package/docs/textbook/ko/04-precision-and-quantization.md +0 -206
  42. package/docs/textbook/ko/05-inside-the-engine.md +0 -154
  43. package/docs/textbook/ko/06-native-engine-architecture.md +0 -333
  44. package/docs/textbook/ko/07-glossary-and-next-steps.md +0 -253
  45. package/docs/textbook/ko/README.md +0 -83
  46. package/docs/xnnpack_optimization_guide.md +0 -197
  47. package/js/CPUEngine.js +0 -241
  48. package/js/Graph.js +0 -49
  49. package/js/GraphExecutor.js +0 -1020
  50. package/js/GraphLoader.js +0 -282
  51. package/js/ShaderLibrary.js +0 -236
  52. package/js/Tensor.js +0 -25
  53. package/js/Tokenizer.js +0 -266
  54. package/js/VolvoxAI.js +0 -130
  55. package/js/WasmEngine.js +0 -378
  56. package/js/WebNNEngine.js +0 -169
  57. package/js/index.js +0 -11
  58. package/js/ops/add.js +0 -31
  59. package/js/ops/argMax.js +0 -33
  60. package/js/ops/averagePool2D.js +0 -38
  61. package/js/ops/batchNorm2D.js +0 -28
  62. package/js/ops/cast.js +0 -19
  63. package/js/ops/clip.js +0 -15
  64. package/js/ops/concat2.js +0 -18
  65. package/js/ops/conv1D.js +0 -35
  66. package/js/ops/conv2D.js +0 -70
  67. package/js/ops/convTranspose2D.js +0 -45
  68. package/js/ops/crossAttention.js +0 -69
  69. package/js/ops/crossSDPA.js +0 -41
  70. package/js/ops/dequantizeLinear.js +0 -9
  71. package/js/ops/div.js +0 -15
  72. package/js/ops/embedding.js +0 -14
  73. package/js/ops/expand.js +0 -24
  74. package/js/ops/gELU.js +0 -9
  75. package/js/ops/gather.js +0 -51
  76. package/js/ops/gatherElements.js +0 -33
  77. package/js/ops/globalAveragePool.js +0 -21
  78. package/js/ops/hardSigmoid.js +0 -12
  79. package/js/ops/hardSwish.js +0 -12
  80. package/js/ops/interp1D.js +0 -25
  81. package/js/ops/layerNorm.js +0 -25
  82. package/js/ops/leakyReLU.js +0 -10
  83. package/js/ops/logSoftmax.js +0 -15
  84. package/js/ops/matMul.js +0 -35
  85. package/js/ops/maxPool2D.js +0 -36
  86. package/js/ops/meanHeight.js +0 -17
  87. package/js/ops/mul.js +0 -31
  88. package/js/ops/nonMaxSuppression.js +0 -72
  89. package/js/ops/pReLU.js +0 -11
  90. package/js/ops/pad.js +0 -35
  91. package/js/ops/profileX.js +0 -22
  92. package/js/ops/profileY.js +0 -22
  93. package/js/ops/rMSNorm.js +0 -14
  94. package/js/ops/reLU.js +0 -8
  95. package/js/ops/reduceMean.js +0 -17
  96. package/js/ops/reduceSum.js +0 -19
  97. package/js/ops/reshape.js +0 -6
  98. package/js/ops/resize.js +0 -44
  99. package/js/ops/sDPA.js +0 -44
  100. package/js/ops/siLU.js +0 -8
  101. package/js/ops/sigmoid.js +0 -6
  102. package/js/ops/slice.js +0 -36
  103. package/js/ops/softmax.js +0 -18
  104. package/js/ops/spatialSoftargmaxY.js +0 -28
  105. package/js/ops/split.js +0 -24
  106. package/js/ops/sub.js +0 -11
  107. package/js/ops/tanh.js +0 -7
  108. package/js/ops/transpose.js +0 -34
  109. package/js/ops/upsample2x.js +0 -23
  110. package/js/ops/where.js +0 -15
  111. package/shaders/add.wgsl +0 -13
  112. package/shaders/add3Relu.wgsl +0 -23
  113. package/shaders/addRelu.wgsl +0 -22
  114. package/shaders/averagePool2D.wgsl +0 -24
  115. package/shaders/batchNorm2D.wgsl +0 -21
  116. package/shaders/binaryBroadcast.wgsl +0 -34
  117. package/shaders/broadcastBinary.wgsl +0 -26
  118. package/shaders/clip.wgsl +0 -10
  119. package/shaders/concat2.wgsl +0 -16
  120. package/shaders/concatCopy.wgsl +0 -10
  121. package/shaders/concatSigmoidCopy.wgsl +0 -16
  122. package/shaders/conv1D.wgsl +0 -37
  123. package/shaders/conv2D.wgsl +0 -80
  124. package/shaders/conv2DDepthwise4.wgsl +0 -74
  125. package/shaders/conv2DDepthwise8.wgsl +0 -66
  126. package/shaders/conv2DPointwise16.wgsl +0 -67
  127. package/shaders/conv2DPointwise16Tile.wgsl +0 -86
  128. package/shaders/conv2DPointwise8.wgsl +0 -85
  129. package/shaders/conv2DPointwise8Vec2.wgsl +0 -70
  130. package/shaders/conv2DPointwise8Vec4.wgsl +0 -65
  131. package/shaders/conv2DRegularC3Out16.wgsl +0 -75
  132. package/shaders/convTranspose2D.wgsl +0 -33
  133. package/shaders/copy.wgsl +0 -13
  134. package/shaders/crossAttention.wgsl +0 -140
  135. package/shaders/crossAttentionF32.wgsl +0 -98
  136. package/shaders/crossSDPA.wgsl +0 -74
  137. package/shaders/dequantizeLinear.wgsl +0 -14
  138. package/shaders/div.wgsl +0 -34
  139. package/shaders/elementwise.wgsl +0 -13
  140. package/shaders/embedding.wgsl +0 -22
  141. package/shaders/expand.wgsl +0 -18
  142. package/shaders/gELU.wgsl +0 -13
  143. package/shaders/gather.wgsl +0 -17
  144. package/shaders/generalTranspose.wgsl +0 -19
  145. package/shaders/globalAveragePool.wgsl +0 -19
  146. package/shaders/hardSigmoid.wgsl +0 -13
  147. package/shaders/hardSwish.wgsl +0 -13
  148. package/shaders/interp1D.wgsl +0 -28
  149. package/shaders/layerNorm.wgsl +0 -33
  150. package/shaders/leakyReLU.wgsl +0 -11
  151. package/shaders/linearF32.wgsl +0 -33
  152. package/shaders/linearF32RowMajor.wgsl +0 -24
  153. package/shaders/linearInt8.wgsl +0 -42
  154. package/shaders/logSoftmax.wgsl +0 -22
  155. package/shaders/maxPool2D.wgsl +0 -37
  156. package/shaders/meanHeight.wgsl +0 -18
  157. package/shaders/mul.wgsl +0 -32
  158. package/shaders/nonMaxSuppression.wgsl +0 -92
  159. package/shaders/pReLU.wgsl +0 -14
  160. package/shaders/pad.wgsl +0 -19
  161. package/shaders/profileX.wgsl +0 -28
  162. package/shaders/profileY.wgsl +0 -28
  163. package/shaders/quantizeLinear.wgsl +0 -69
  164. package/shaders/rMSNorm.wgsl +0 -21
  165. package/shaders/reLU.wgsl +0 -13
  166. package/shaders/reduce.wgsl +0 -17
  167. package/shaders/resize.wgsl +0 -52
  168. package/shaders/sDPA.wgsl +0 -71
  169. package/shaders/siLU.wgsl +0 -13
  170. package/shaders/sigmoid.wgsl +0 -13
  171. package/shaders/slice.wgsl +0 -26
  172. package/shaders/softmax.wgsl +0 -23
  173. package/shaders/spatialSoftargmaxY.wgsl +0 -32
  174. package/shaders/split.wgsl +0 -15
  175. package/shaders/sub.wgsl +0 -34
  176. package/shaders/tanh.wgsl +0 -13
  177. package/shaders/upsample2x.wgsl +0 -24
  178. package/shaders/where.wgsl +0 -12
  179. package/volvoxai.wasm +0 -0
package/README.md CHANGED
@@ -1,31 +1,50 @@
1
1
  # VolvoxAI
2
2
 
3
- **A zero-dependency, bare-metal deep learning inference engine for the browser,
4
- Node.js, and native Windows/Linux/macOS/Android targets.**
5
-
6
- VolvoxAI runs exported neural-network graphs without shipping a full ML runtime.
7
- Train in PyTorch or another framework, export to a small Volvox blueprint plus
8
- safetensors weights, and run inference through WebNN, WebGPU, WASM SIMD, pure JS,
9
- or a freestanding native C binary.
10
-
11
- The project is inference-only. It is built for small, inspectable model packages,
12
- constrained web apps, extensions, local tools, and edge devices where heavyweight
13
- runtimes such as ONNX Runtime Web or TensorFlow.js are too large or too opaque.
3
+ **A zero-dependency, bare-metal deep learning engine for the
4
+ browser, Node.js, and native Windows/Linux/macOS/Android targets.**
5
+
6
+ > 🧭 **New here want to *understand* how AI actually works, not just use a library?**
7
+ > This repo doubles as a from-scratch **textbook** built on its own real code. Pick your path:
8
+ >
9
+ > - 🌱 **Just curious what AI really is?** → [Start the **Idea track**](docs/textbook/README.md) — plain words, analogies, **no code or math required**. A motivated 11-year-old can follow it.
10
+ > - 🔧 **Can code a little and want to see it run?** → [The **Build track**](docs/textbook/README.md) — the same ideas in graphs, JavaScript, and operators.
11
+ > - 🔬 **A developer who wants the engine?** → [The **Deep track**](docs/textbook/README.md) + [ARCHITECTURE.md](ARCHITECTURE.md) quantization, native, optimization, and training internals.
12
+ >
13
+ > One book, three depths. Everything below this line is the **product / release reference** for people who just want to install and ship.
14
+
15
+ ---
16
+
17
+ VolvoxAI runs and trains neural-network graphs without shipping a full ML
18
+ runtime. Load a small Volvox blueprint plus safetensors weights, or use the full
19
+ entry to create an empty model, initialize its parameters, and build it entirely
20
+ through the API.
21
+ The resulting graph can run through WebNN, WebGPU, WASM SIMD, pure JS, or a
22
+ freestanding native C binary.
23
+
24
+ The project is built for small, inspectable model packages, constrained web
25
+ apps, extensions, local tools, and edge devices where heavyweight runtimes such
26
+ as ONNX Runtime Web or TensorFlow.js are too large or too opaque. Training is an
27
+ explicit path: inference does not allocate gradients, optimizer state, or
28
+ backward pipelines. The inference bundle has no training dependency; the full
29
+ bundle adds training as a separate public entry.
14
30
 
15
31
  ## Highlights
16
32
 
17
- - Browser tiers: WebNN, WebGPU, WASM SIMD, and pure-JS CPU fallback.
18
- - Zero runtime dependency path: vanilla JS plus WGSL with optional freestanding WASM.
19
- - Small runtime artifacts: about 167 KiB minified JS, 55 KiB WASM, and a
20
- roughly 695 KiB native Linux executable in current builds.
21
- - Native runtime: freestanding C with dynamic Vulkan, OpenGL, Metal, and Android
22
- NNAPI loading.
23
- - Optimization-focused internals: operator fusion, weight packing, quantized CPU
24
- islands, vectorized WGSL/C kernels, and backend-specific dispatch.
25
- - Model format: `config.json` graph blueprint plus `model.safetensors` weights.
26
- - Shader source: WGSL for browser WebGPU and native shader generation.
27
- - Examples: EfficientDet Lite0 object detection and TinyStories-1M text generation.
28
- - License: MIT.
33
+ - Runs in browsers, Node.js, and native applications through WebNN, WebGPU,
34
+ WASM, JavaScript CPU, native CPU, Vulkan, OpenGL, and Metal.
35
+ - Compact current Linux x86-64 artifacts: 360 KiB WASM-only JS, 683 KiB
36
+ multi-backend inference JS, 174 KiB inference WASM, and 936 KiB native
37
+ inference; full training builds remain about 1–1.4 MiB.
38
+ - No external ML runtime: models use inspectable `config.json` graphs and
39
+ safetensors weights.
40
+ - Clean inference/training separation: inference builds contain no autograd,
41
+ optimizer state, backward shaders, or public training symbols.
42
+ - Built-in model construction, training, LoRA, checkpointing, PTQ, and portable
43
+ W8A8 execution.
44
+ - Extensible browser and native backend APIs with embedded native shaders and
45
+ portable CPU fallback.
46
+ - Includes EfficientDet, TinyStories, multimodal examples, and a three-level
47
+ textbook.
29
48
 
30
49
  ## Install
31
50
 
@@ -37,27 +56,44 @@ For local development from this repository:
37
56
 
38
57
  ```bash
39
58
  npm install
59
+ npm run typecheck
40
60
  npm run build:all
41
61
  ```
42
62
 
43
- The browser bundle is emitted to:
63
+ The TypeScript sources are checked before esbuild emits the six fixed-name
64
+ JavaScript bundles; the build preserves an existing WASM sidecar. For version
65
+ 0.2.0, the complete browser release consists of:
44
66
 
45
67
  ```text
46
- dist/volvoxai.js
47
- dist/volvoxai.min.js
68
+ dist/0.2.0/volvoxai.js # readable inference
69
+ dist/0.2.0/volvoxai.min.js # minified inference
70
+ dist/0.2.0/volvoxai.full.js # readable inference + training
71
+ dist/0.2.0/volvoxai.full.min.js # minified inference + training
72
+ dist/0.2.0/volvoxai.wasm.js # readable WASM-only inference + training/PTQ
73
+ dist/0.2.0/volvoxai.wasm.min.js # minified WASM-only inference + training/PTQ
74
+ dist/0.2.0/volvoxai.wasm # forward kernels used by the WASM backend
75
+ dist/0.2.0/volvoxai.full.wasm # forward kernels plus C training/PTQ ABIs
48
76
  ```
49
77
 
50
- The WASM tier also needs `volvoxai.wasm`. The reproducible Docker build copies it
51
- into `dist/`:
78
+ `volvoxai.wasm` deliberately exports no training symbol. `volvoxai.full.wasm`
79
+ keeps every forward export and adds C loss, backward, gradient utility, SGD, and
80
+ AdamW operators plus generic PTQ observation, affine quantization, weight
81
+ packing, and bias packing. Quantized LoRA synchronization is one higher-level
82
+ use of those reusable kernels. From a clean checkout, the reproducible Docker
83
+ build creates all eight files:
52
84
 
53
85
  ```bash
54
86
  make build_web
55
87
  ```
56
88
 
89
+ The npm `prepack` check rejects a missing sidecar or stale extra artifact.
90
+ `npm run build:all` bundles JavaScript but cannot compile C/WASM from a clean
91
+ checkout; use `make build_web` before `npm pack` or `npm publish`.
92
+
57
93
  ## Browser Usage
58
94
 
59
95
  ```javascript
60
- import { VolvoxAI } from './volvoxai.js';
96
+ import { VolvoxAI } from './dist/0.2.0/volvoxai.js';
61
97
 
62
98
  const engine = await VolvoxAI.init(); // auto: WebNN, WebGPU, WASM, CPU
63
99
  const graph = await engine.loadGraph('./models/my-model/model.safetensors');
@@ -70,19 +106,232 @@ const inputs = {
70
106
  const output = await executor.execute(inputs);
71
107
  ```
72
108
 
109
+ Every input referenced by a blueprint node must be declared in `config.inputs`,
110
+ loaded as a named weight, or produced by an earlier node. The loader does not
111
+ invent a default image input or shape for an undeclared name.
112
+
73
113
  On WebGPU, `execute()` currently returns a `GPUBuffer` for the final node's first
74
- output. WASM and CPU return a map keyed by `graph.outputNames`.
114
+ output. The executor owns GPU buffers; core `Tensor` objects contain portable
115
+ descriptors and optional CPU storage, not device handles. WASM and CPU return a
116
+ map keyed by `graph.outputNames`. All four browser engines share the versioned
117
+ backend lifecycle, named registration hook, and decode-session facade described
118
+ in [Browser and Node runtime](docs/browser-runtime.md#javascript-backend-contract).
119
+
120
+ ### WASM-only Chrome extensions, training, and PTQ
121
+
122
+ For a Manifest V3 extension that needs no CPU, WebNN, WebGPU, or shader code,
123
+ ship exactly one JavaScript variant, the full WASM sidecar, and the model:
124
+
125
+ ```text
126
+ vendor/volvoxai.wasm.min.js
127
+ vendor/volvoxai.full.wasm
128
+ model/config.json
129
+ model/model.safetensors
130
+ ```
131
+
132
+ `volvoxai.wasm.min.js` names the only selectable backend, not a forward-only
133
+ capability set. It uses `volvoxai.full.wasm` because updating LoRA A/B still
134
+ requires backward propagation through the surrounding graph. The ordinary
135
+ `volvoxai.wasm` sidecar remains forward-only for the standard inference entry.
136
+ The `./wasm` and `./wasm/min` package subpaths are browser-only and deliberately
137
+ omit Node's filesystem loader; Node applications should use `.` or `./full`
138
+ and select the WASM backend.
139
+
140
+ ```javascript
141
+ import { VolvoxAI } from './vendor/volvoxai.wasm.min.js';
142
+
143
+ const runtime = await VolvoxAI.init(
144
+ 'wasm',
145
+ chrome.runtime.getURL('vendor/volvoxai.full.wasm'),
146
+ );
147
+ const graph = await runtime.loadGraph(
148
+ chrome.runtime.getURL('model/model.safetensors'),
149
+ );
150
+ const executor = await runtime.compile(graph);
151
+
152
+ const step = await runtime.trainLoRAStep(graph, {
153
+ inputs: teacherForcedInputs,
154
+ logitsTensor: 'logits',
155
+ targets: correctedTokenIds,
156
+ trainableTensors: ['decoder.lora_a', 'decoder.lora_b'],
157
+ updateMode: 'adamw',
158
+ optimizer: { learningRate: 1e-4 },
159
+ });
160
+
161
+ // Applied updates refresh packed WASM weights, so this executor observes A/B.
162
+ const corrected = await executor.execute(nextInputs);
163
+ ```
164
+
165
+ The same runtime exposes the existing stateless C PTQ implementation as a
166
+ generic typed toolkit, independent of LoRA:
167
+
168
+ ```javascript
169
+ const ptq = await runtime.createPTQ();
170
+ try {
171
+ const observer = ptq.createObserver();
172
+ observer.observe(calibrationValues); // Float32Array; repeat for more samples
173
+
174
+ const parameters = observer.parameters({
175
+ dtype: 'int8',
176
+ scheme: 'symmetric',
177
+ });
178
+ const activation = ptq.quantize(values, parameters);
179
+ const weight = ptq.packWeight(weightValues, [outputSize, inputSize], { axis: 0 });
180
+ const bias = ptq.packBias(biasValues, parameters.scale, weight.scales);
181
+ } finally {
182
+ ptq.dispose();
183
+ }
184
+ ```
185
+
186
+ These calls run in a private scratch WASM instance and return caller-owned
187
+ typed arrays. They do not rewrite a graph or choose how an application stores
188
+ or deploys the result. Reuse one toolkit across related operations and call
189
+ `dispose()` when finished so its isolated WASM memory can be garbage-collected.
190
+ Developers may use it for calibration, conversion, custom model builders, or
191
+ their own update workflow. Browser safetensors and graph/package authoring
192
+ remain JavaScript orchestration rather than C file I/O.
193
+
194
+ The model must represent LoRA A/B as explicit initialized F32 graph weights and
195
+ wire them through its low-rank MatMul/Add branch. Listing only those names in
196
+ `trainableTensors` freezes the base model. A corrected answer string is
197
+ application policy: tokenize it and construct teacher-forced model inputs,
198
+ target token IDs, and any loss mask before calling `trainLoRAStep()`.
199
+ Immutable staged adapter snapshots are deployment/routing objects, not
200
+ autograd parameters; checkpoint or export the updated explicit graph factors
201
+ after training.
202
+
203
+ To retain an existing W8A8 inference topology, use a separate supported F32
204
+ training graph as the persistent master and bind its A/B factors to the I8
205
+ factor weights already present in the inference graph:
206
+
207
+ ```javascript
208
+ const trainer = await runtime.createQuantizedLoRATrainer(
209
+ f32TrainingGraph,
210
+ w8InferenceGraph,
211
+ {
212
+ bindings: [
213
+ { master: 'decoder.lora_a', target: 'decoder.lora_a.i8', transpose: true },
214
+ { master: 'decoder.lora_b', target: 'decoder.lora_b.i8', transpose: true },
215
+ ],
216
+ },
217
+ );
218
+
219
+ try {
220
+ // Use this once only when starting from a W8 snapshot without an F32
221
+ // checkpoint. Do not dequantize again after training begins.
222
+ await trainer.initializeMastersFromQuantized();
223
+
224
+ await trainer.trainStep({
225
+ inputs: teacherForcedInputs,
226
+ logitsTensor: 'logits',
227
+ targets: correctedTokenIds,
228
+ trainableTensors: ['decoder.lora_a', 'decoder.lora_b'],
229
+ updateMode: 'adamw',
230
+ optimizer: { learningRate: 1e-4 },
231
+ });
232
+
233
+ const corrected = await trainer.engine.execute(nextQuantizedInputs);
234
+ } finally {
235
+ await trainer.dispose();
236
+ }
237
+ ```
238
+
239
+ The C conversion helper transposes the builder's IN_OUT factors into canonical
240
+ OUT_IN I8 weights and recomputes symmetric axis-0 scales. The JavaScript trainer
241
+ stages every converted factor before atomically updating the graph, then
242
+ refreshes the WASM raw bytes, scale metadata, and packed Q8 caches without
243
+ changing nodes or activation descriptors. Version 0.2.0 requires I8 targets
244
+ with zero points of zero and all-zero I32 LoRA biases. Persist the F32
245
+ checkpoint and optimizer state as the resumable authority; the W8 graph is an
246
+ inference snapshot. After restoring an F32 checkpoint, call `trainer.sync()`
247
+ instead of `initializeMastersFromQuantized()`.
248
+
249
+ This is F32-master LoRA requantization, not QAT or backward support for a deep
250
+ W8A8 graph. `QLinear`/`QGemm` are still rejected by strict WASM training, so
251
+ the separate training graph must provide the supported F32 backward path. The
252
+ inference graph must already contain its quantized LoRA branch; this API does
253
+ not rewrite graph topology.
254
+
255
+ The extension must package all executable code locally and enable WebAssembly
256
+ for extension pages. Use an ES-module service worker and this CSP:
257
+
258
+ ```json
259
+ {
260
+ "manifest_version": 3,
261
+ "background": { "service_worker": "service-worker.js", "type": "module" },
262
+ "content_security_policy": {
263
+ "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
264
+ }
265
+ }
266
+ ```
267
+
268
+ The WASM-only release bundle contains no dynamic `import()`, which Chrome
269
+ extension service workers do not support. `web_accessible_resources` is not
270
+ needed when only extension-owned pages/workers fetch the packaged model and
271
+ sidecar; declare the narrow resources explicitly if a normal web page must
272
+ fetch them. See [Browser and Node runtime](docs/browser-runtime.md#wasm-only-manifest-v3-extensions)
273
+ for complete packaging notes.
274
+
275
+ ## Training from APIs
276
+
277
+ Use the full entry when calling training, checkpoint, or gradient-accumulation
278
+ APIs:
279
+
280
+ ```javascript
281
+ import { VolvoxAI } from './dist/0.2.0/volvoxai.full.js';
282
+ ```
283
+
284
+ In this module, the familiar `VolvoxAI`, `Graph`, and `ModelBuilder` exports are
285
+ the training-capable variants; the explicit `TrainingVolvoxAI`,
286
+ `TrainingGraph`, and `TrainingModelBuilder` names are also available.
287
+ Initializers, optimizer state, and training-only builder helpers are deliberately
288
+ absent from the inference entry.
289
+
290
+ Models can start from an empty graph and initialized weights; no PyTorch export
291
+ or seed safetensors file is required. The JavaScript builder provides generic
292
+ GroupNorm, MoE and routed bottleneck adapters, deterministic Dropout, and
293
+ explicit trainable-tensor selection. The repository's
294
+ `examples/seq2seq_training/Seq2SeqBuilder.js` composes those primitives into an
295
+ encoder-decoder with multimodal source features and teacher forcing; that
296
+ model-family policy is not exported by either package entry.
297
+
298
+ `trainStep()` accepts either the legacy single cross-entropy target or a
299
+ `losses` list with independent logits, targets, weights, masks, and normalizers.
300
+ Repeated logits tensors are allowed and their gradients add. Accumulation has
301
+ reset/flush controls, and `maxGradNorm` clips one global norm over all trainable
302
+ tensors. JavaScript CPU and WebGPU regenerate the same SDPA/CrossSDPA
303
+ attention-dropout mask in forward and backward; inference never applies it.
304
+
305
+ For an explicit C-backed browser training path, initialize the full entry with
306
+ the full sidecar and set `backend: "wasm"`. It is strict: its current portable
307
+ contracts are listed in [the operation status reference](docs/operation_list.md).
308
+ Unsupported or non-canonical layouts are rejected before any model state
309
+ changes, including ambiguous square linear layouts.
310
+
311
+ Native CPU, Vulkan, OpenGL compute, and Metal support deterministic standalone
312
+ Dropout training while keeping inference as an identity. Their SDPA/CrossSDPA
313
+ training paths also implement after-softmax attention-probability dropout and
314
+ regenerate the mask during backward; unsupported GPU layouts fall back to the
315
+ matching complete native CPU path. See
316
+ [model construction, routing, and training](docs/model_builder_training.md) and
317
+ the [operation matrix](docs/operation_list.md) for exact backend limits.
75
318
 
76
319
  ## Native Usage
77
320
 
78
321
  ```bash
79
322
  make build_native
80
323
 
81
- ./native/volvoxai generate models/tinystories_1m \
82
- --prompt "Once upon a time, Lily" \
83
- --max-new 50
324
+ # inference-only executable
325
+ ./native/volvoxai --help
326
+
327
+ # inference + training executable
328
+ ./native/volvoxai-full --help
84
329
  ```
85
330
 
331
+ The fixed release executables stay model-agnostic: both expose `run`, and only
332
+ `volvoxai-full` additionally exposes `train`. They do not choose vocabulary
333
+ files, decode images, or implement generation and task postprocessing.
334
+
86
335
  Generic tensor execution:
87
336
 
88
337
  ```bash
@@ -90,9 +339,47 @@ Generic tensor execution:
90
339
  --input tokens=models/tinystories_1m/tokens.i32 \
91
340
  --input positions=models/tinystories_1m/positions.i32 \
92
341
  --output logits=out.f32 \
93
- --last-token 4
342
+ --row 4
94
343
  ```
95
344
 
345
+ Raw input and output filenames must end in the declared storage dtype suffix:
346
+ `.f32`, `.f16`, `.i32`, `.i8`, or `.u8`. Row output is currently F32-only.
347
+
348
+ Generic cross-entropy training is available only in the full executable:
349
+
350
+ ```bash
351
+ ./native/volvoxai-full train models/my_model \
352
+ --input input=batch.f32 \
353
+ --targets targets.i32 \
354
+ --logits logits \
355
+ --trainable classifier.weight \
356
+ --trainable classifier.bias \
357
+ --steps 10 \
358
+ --learning-rate 0.001 \
359
+ --output-weights trained.safetensors \
360
+ --output-optimizer optimizer.safetensors
361
+ ```
362
+
363
+ Use `--input-optimizer` to resume saved optimizer state. Run
364
+ `./native/volvoxai-full train --help` for all optimizer and backend options.
365
+
366
+ Model-facing native task wrappers are an opt-in example:
367
+
368
+ ```bash
369
+ make -C examples native_task_cli
370
+
371
+ examples/target/bin/volvoxai-tasks generate models/tinystories_1m \
372
+ --prompt "Once upon a time, Lily" \
373
+ --max-new 50
374
+ ```
375
+
376
+ That example owns image decoding, vocabulary-file selection, generation loops,
377
+ and the `generate`, `classify`, `detect`, `ctc`, `seq2seq`, and `chat` commands.
378
+
379
+ Native executables do not need a shader directory. For shader development,
380
+ point `VOLVOXAI_SHADER_DIR` at a generated directory containing `spv/`,
381
+ `glsl/`, `gles/`, and `metal/`; VolvoxAI logs once when that override is used.
382
+
96
383
  ## Example Models
97
384
 
98
385
  Model weights are not committed. Regenerate the example packages from public
@@ -109,21 +396,37 @@ See [docs/models.md](docs/models.md) for export details.
109
396
  ## Repository Layout
110
397
 
111
398
  ```text
112
- js/ Browser and Node engine implementation
113
- shaders/ WGSL compute shaders
114
- native/ Freestanding C engine and native backends
115
- runtime/ Rust service wrapper around the C engine
116
- examples/ Browser examples
117
- tools/ Export, shader, and test utilities
118
- docs/ Detailed documentation
399
+ ts/core/ TypeScript inference graph/data objects and model-agnostic orchestration
400
+ ts/ops/ TypeScript operators plus graph validation and normalization
401
+ ts/backends/ TypeScript CPU, WASM, WebGPU, and WebNN execution/device resources
402
+ ts/training/ TypeScript training graphs/builders, autograd, optimizers, checkpoints
403
+ examples/ Model-specific applications and reference integrations
404
+ shaders/inference/ Forward WGSL sources
405
+ shaders/training/ Backward and training WGSL sources
406
+ native/include/ Public C APIs
407
+ native/src/shader_store.* Lazy embedded-shader asset loader
408
+ native/src/runtime/ Model state, graph, memory, and execution
409
+ native/src/kernels/ Portable and optimized CPU/WASM kernels
410
+ native/src/backends/ Vulkan, OpenGL, Metal, and NNAPI integrations
411
+ native/src/training/ Training-specific orchestration
412
+ native/cli/ Fixed model-agnostic command-line applications
413
+ native/tests/ Native tests
414
+ runtime/ Rust service wrapper around the C engine
119
415
  ```
120
416
 
417
+ See [ARCHITECTURE.md](ARCHITECTURE.md) for dependency and build-composition
418
+ rules.
419
+
121
420
  ## Documentation
122
421
 
123
422
  - [Quickstart](docs/quickstart.md)
124
423
  - [Browser and Node runtime](docs/browser-runtime.md)
125
424
  - [Native runtime](docs/native-runtime.md)
425
+ - [Custom backend SDK](docs/backend-sdk.md)
126
426
  - [Model format](docs/model-format.md)
427
+ - [W8A8 safetensors companion scales](docs/w8a8-safetensors.md)
428
+ - [Post-training quantization](docs/quantization.md)
429
+ - [Model construction, routing, and training](docs/model_builder_training.md)
127
430
  - [Models and exporters](docs/models.md)
128
431
  - [Operation support matrix](docs/operation_list.md)
129
432
  - [Testing and validation](docs/testing.md)
@@ -135,8 +438,8 @@ docs/ Detailed documentation
135
438
 
136
439
  VolvoxAI can run real browser and native inference paths, but it is still early.
137
440
  Known gaps include WebGPU multi-output readback, broader WebNN coverage, additional
138
- native/WebGPU shaders for a few fallback ops, browser-side generation helpers, and
139
- formal CI wiring for the existing smoke tests.
441
+ native/WebGPU shaders for a few fallback ops, browser-side generation helpers,
442
+ and formal CI wiring for the existing smoke tests.
140
443
 
141
444
  See [docs/roadmap.md](docs/roadmap.md) for the detailed list.
142
445
 
package/bin/volvox.js CHANGED
@@ -1,17 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { Command } from 'commander';
4
- import { VolvoxAI } from '../js/index.js';
5
4
  import fs from 'fs';
6
5
  import path from 'path';
7
6
  import { fileURLToPath } from 'url';
8
7
 
8
+ const packageVersion = JSON.parse(
9
+ fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'),
10
+ ).version;
11
+ const { VolvoxAI } = await import(
12
+ new URL(`../dist/${packageVersion}/volvoxai.js`, import.meta.url)
13
+ );
14
+
9
15
  const program = new Command();
10
16
 
11
17
  program
12
18
  .name('volvox')
13
19
  .description('Volvox AI CLI for running local inference')
14
- .version('0.1.0');
20
+ .version(packageVersion);
15
21
 
16
22
  program
17
23
  .command('run')
@@ -23,7 +29,7 @@ program
23
29
  installFileFetchShim();
24
30
  console.log(`[Volvox CLI] Initializing Engine (Backend: ${options.backend})...`);
25
31
  const cliDir = path.dirname(fileURLToPath(import.meta.url));
26
- const wasmPath = path.resolve(cliDir, '..', 'volvoxai.wasm');
32
+ const wasmPath = path.resolve(cliDir, '..', 'dist', packageVersion, 'volvoxai.wasm');
27
33
  const engine = await VolvoxAI.init(options.backend, wasmPath);
28
34
 
29
35
  console.log(`[Volvox CLI] Loading Model: ${options.model}`);