volvoxai 0.2.0 → 0.3.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.
- package/README.md +254 -380
- package/bin/volvox.js +18 -9
- package/dist/{0.2.0 → 0.3.0}/volvoxai.full.js +26148 -21619
- package/dist/0.3.0/volvoxai.full.min.js +9806 -0
- package/dist/{0.2.0 → 0.3.0}/volvoxai.full.wasm +0 -0
- package/dist/{0.2.0 → 0.3.0}/volvoxai.js +9656 -4626
- package/dist/0.3.0/volvoxai.min.js +6848 -0
- package/dist/{0.2.0 → 0.3.0}/volvoxai.wasm +0 -0
- package/dist/{0.2.0 → 0.3.0}/volvoxai.wasm.js +9814 -6920
- package/dist/0.3.0/volvoxai.wasm.min.js +2 -0
- package/package.json +13 -13
- package/dist/0.2.0/volvoxai.full.min.js +0 -8975
- package/dist/0.2.0/volvoxai.min.js +0 -6061
- package/dist/0.2.0/volvoxai.wasm.min.js +0 -2
package/README.md
CHANGED
|
@@ -1,447 +1,321 @@
|
|
|
1
1
|
# VolvoxAI
|
|
2
2
|
|
|
3
|
-
**A zero-dependency
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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.
|
|
3
|
+
**A zero-dependency deep-learning runtime for browsers, Node.js, and native
|
|
4
|
+
Windows, Linux, macOS, and Android targets.**
|
|
5
|
+
|
|
6
|
+
VolvoxAI runs compact graph packages without embedding a general-purpose ML
|
|
7
|
+
framework. It supports WebNN, WebGPU, WASM SIMD, JavaScript CPU, native CPU,
|
|
8
|
+
Vulkan, OpenGL, optional CUDA, Metal, and NNAPI integrations.
|
|
9
|
+
|
|
10
|
+
The repository is also a from-scratch textbook:
|
|
11
|
+
|
|
12
|
+
- [Idea, Build, and Deep tracks](docs/textbook/README.md)
|
|
13
|
+
- [Architecture](ARCHITECTURE.md)
|
|
14
|
+
- [Runtime design](REFACTORING.md)
|
|
30
15
|
|
|
31
16
|
## Highlights
|
|
32
17
|
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
textbook.
|
|
18
|
+
- One explicit inference lifecycle: Runtime → Model → CompiledModel →
|
|
19
|
+
ExecutionContext → ExecutionResult.
|
|
20
|
+
- Stable named outputs on every backend. Host reads return caller-owned arrays;
|
|
21
|
+
WebGPU results may also expose result-owned device buffers.
|
|
22
|
+
- Independent execution and decode contexts with immutable compiled model and
|
|
23
|
+
weight revisions.
|
|
24
|
+
- Required or preferred backend policy with independent operator-fallback
|
|
25
|
+
control and machine-readable reports.
|
|
26
|
+
- A single context-aware provider contract for built-in and external devices.
|
|
27
|
+
- A full profile with a retained Trainer for CPU, WebGPU, or strict WASM
|
|
28
|
+
training.
|
|
29
|
+
- Inspectable model packages using graph.json and safetensors.
|
|
30
|
+
- Strict inference/training composition boundaries in JavaScript, WASM, and
|
|
31
|
+
native builds.
|
|
48
32
|
|
|
49
33
|
## Install
|
|
50
34
|
|
|
51
|
-
|
|
35
|
+
~~~bash
|
|
52
36
|
npm install volvoxai
|
|
53
|
-
|
|
37
|
+
~~~
|
|
54
38
|
|
|
55
|
-
For
|
|
39
|
+
For repository development:
|
|
56
40
|
|
|
57
|
-
|
|
41
|
+
~~~bash
|
|
58
42
|
npm install
|
|
59
43
|
npm run typecheck
|
|
60
44
|
npm run build:all
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
dist/0.
|
|
69
|
-
dist/0.
|
|
70
|
-
dist/0.
|
|
71
|
-
dist/0.
|
|
72
|
-
dist/0.
|
|
73
|
-
dist/0.
|
|
74
|
-
dist/0.
|
|
75
|
-
dist/0.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
45
|
+
~~~
|
|
46
|
+
|
|
47
|
+
## Release artifacts
|
|
48
|
+
|
|
49
|
+
The fixed browser release files for package version 0.3.0 are:
|
|
50
|
+
|
|
51
|
+
~~~text
|
|
52
|
+
dist/0.3.0/volvoxai.js
|
|
53
|
+
dist/0.3.0/volvoxai.min.js
|
|
54
|
+
dist/0.3.0/volvoxai.full.js
|
|
55
|
+
dist/0.3.0/volvoxai.full.min.js
|
|
56
|
+
dist/0.3.0/volvoxai.wasm.js
|
|
57
|
+
dist/0.3.0/volvoxai.wasm.min.js
|
|
58
|
+
dist/0.3.0/volvoxai.wasm
|
|
59
|
+
dist/0.3.0/volvoxai.full.wasm
|
|
60
|
+
~~~
|
|
61
|
+
|
|
62
|
+
The standard JavaScript entry is inference-only and resolves the forward-only
|
|
63
|
+
WASM sidecar. The full entry adds training and resolves volvoxai.full.wasm.
|
|
64
|
+
The WASM-only JavaScript entry contains strict WASM inference and training but
|
|
65
|
+
no CPU, WebNN, WebGPU, WGSL, or Node filesystem implementation.
|
|
66
|
+
|
|
67
|
+
Build all browser artifacts reproducibly with:
|
|
68
|
+
|
|
69
|
+
~~~bash
|
|
86
70
|
make build_web
|
|
87
|
-
|
|
71
|
+
~~~
|
|
72
|
+
|
|
73
|
+
## Model packages
|
|
74
|
+
|
|
75
|
+
An inference package contains:
|
|
76
|
+
|
|
77
|
+
~~~text
|
|
78
|
+
graph.json
|
|
79
|
+
model.safetensors
|
|
80
|
+
~~~
|
|
88
81
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
checkout; use `make build_web` before `npm pack` or `npm publish`.
|
|
82
|
+
Every graph root, including named subgraphs, must carry the exact
|
|
83
|
+
case-sensitive discriminator:
|
|
92
84
|
|
|
93
|
-
|
|
85
|
+
~~~json
|
|
86
|
+
{
|
|
87
|
+
"format": "volvox-graph/v1"
|
|
88
|
+
}
|
|
89
|
+
~~~
|
|
94
90
|
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
The loader rejects a missing or different discriminator before allocating
|
|
92
|
+
weights or backend resources. Every node input must resolve to a declared graph
|
|
93
|
+
input, a named weight, or an earlier node output.
|
|
97
94
|
|
|
98
|
-
|
|
99
|
-
const graph = await engine.loadGraph('./models/my-model/model.safetensors');
|
|
100
|
-
const executor = await engine.compile(graph);
|
|
95
|
+
## Inference
|
|
101
96
|
|
|
102
|
-
|
|
97
|
+
~~~javascript
|
|
98
|
+
import { VolvoxAI } from 'volvoxai';
|
|
99
|
+
|
|
100
|
+
const runtime = await VolvoxAI.createRuntime({
|
|
101
|
+
backends: ['webnn', 'webgpu', 'wasm', 'cpu'],
|
|
102
|
+
onDiagnostic(event) {
|
|
103
|
+
console.debug(event.kind, event.report ?? event);
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const model = await runtime.loadModel(
|
|
108
|
+
'./models/my-model/model.safetensors',
|
|
109
|
+
);
|
|
110
|
+
const compiled = await model.compile({
|
|
111
|
+
backend: {
|
|
112
|
+
mode: 'prefer',
|
|
113
|
+
order: ['webgpu', 'wasm', 'cpu'],
|
|
114
|
+
operatorFallback: 'allow',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
const context = await compiled.createContext();
|
|
118
|
+
|
|
119
|
+
const result = await context.execute({
|
|
103
120
|
images: new Float32Array(1 * 224 * 224 * 3),
|
|
104
|
-
};
|
|
121
|
+
});
|
|
122
|
+
const scores = await result.output('scores').read();
|
|
123
|
+
|
|
124
|
+
await result.close();
|
|
125
|
+
await context.close();
|
|
126
|
+
await compiled.close();
|
|
127
|
+
await model.close();
|
|
128
|
+
await runtime.close();
|
|
129
|
+
~~~
|
|
130
|
+
|
|
131
|
+
Runtime loading resolves graph.json beside the first safetensors URL. Pass
|
|
132
|
+
graphUrl in the loader options when the graph is stored elsewhere; its basename
|
|
133
|
+
must be `graph.json` or a named `*.graph.json` document.
|
|
134
|
+
|
|
135
|
+
Compilation pins an immutable topology and weight revision. Create multiple
|
|
136
|
+
contexts from one compiled model for independent request or decode state. Each
|
|
137
|
+
context serializes its own accepted operations, while different contexts may
|
|
138
|
+
progress concurrently.
|
|
139
|
+
|
|
140
|
+
ExecutionResult owns a stable snapshot of every declared graph output. A result
|
|
141
|
+
remains usable after later executions and after its context closes. Each read()
|
|
142
|
+
returns a fresh typed array. A device result may expose deviceBuffer; that
|
|
143
|
+
buffer remains owned by the result and must not be destroyed by the caller.
|
|
144
|
+
|
|
145
|
+
Use a strict policy when execution must stay on one provider:
|
|
146
|
+
|
|
147
|
+
~~~javascript
|
|
148
|
+
const compiled = await model.compile({
|
|
149
|
+
backend: {
|
|
150
|
+
mode: 'require',
|
|
151
|
+
backend: 'webgpu',
|
|
152
|
+
operatorFallback: 'forbid',
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
~~~
|
|
156
|
+
|
|
157
|
+
Backend selection finishes during compilation. Execution failure is reported
|
|
158
|
+
and is never retried on another provider.
|
|
105
159
|
|
|
106
|
-
|
|
107
|
-
```
|
|
160
|
+
## Training
|
|
108
161
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
162
|
+
Training is available only from the full and WASM-only profiles. Trainer owns
|
|
163
|
+
gradients, optimizer slots, accumulation, and a private working
|
|
164
|
+
revision. `trainStep()` mutates only that private revision. `commit()` atomically
|
|
165
|
+
publishes it as a new Model weight revision; already compiled models and
|
|
166
|
+
contexts remain pinned to their original revision.
|
|
112
167
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
in [Browser and Node runtime](docs/browser-runtime.md#javascript-backend-contract).
|
|
168
|
+
~~~javascript
|
|
169
|
+
import {
|
|
170
|
+
ModelBuilder,
|
|
171
|
+
VolvoxAI,
|
|
172
|
+
} from 'volvoxai/full';
|
|
119
173
|
|
|
120
|
-
|
|
174
|
+
const builder = new ModelBuilder();
|
|
175
|
+
const x = builder.input('x', [1, 4]);
|
|
176
|
+
const weight = builder.weight('projection', [4, 8], 'float32', {
|
|
177
|
+
initializer: { type: 'xavierUniform', seed: 17 },
|
|
178
|
+
});
|
|
179
|
+
const logits = builder.addOp(
|
|
180
|
+
'MatMul',
|
|
181
|
+
{ input: x, weight },
|
|
182
|
+
{ out: { name: 'logits', shape: [1, 8] } },
|
|
183
|
+
{},
|
|
184
|
+
{ id: 'projection', wLayout: 'din' },
|
|
185
|
+
).out;
|
|
186
|
+
builder.outputs(logits);
|
|
187
|
+
const graph = builder.build();
|
|
188
|
+
|
|
189
|
+
const runtime = await VolvoxAI.createRuntime({ backends: ['cpu'] });
|
|
190
|
+
const model = runtime.createModel(graph);
|
|
191
|
+
const trainer = await VolvoxAI.createTrainer(model, {
|
|
192
|
+
backend: 'cpu',
|
|
193
|
+
});
|
|
121
194
|
|
|
122
|
-
|
|
123
|
-
|
|
195
|
+
const step = await trainer.trainStep({
|
|
196
|
+
inputs: { x: new Float32Array([1, 2, 3, 4]) },
|
|
197
|
+
logitsTensor: 'logits',
|
|
198
|
+
targets: new Int32Array([3]),
|
|
199
|
+
trainableTensors: ['projection'],
|
|
200
|
+
updateMode: 'adamw',
|
|
201
|
+
optimizer: { learningRate: 1e-3, maxGradNorm: 1 },
|
|
202
|
+
});
|
|
203
|
+
await trainer.commit();
|
|
124
204
|
|
|
125
|
-
|
|
205
|
+
await trainer.close();
|
|
206
|
+
await model.close();
|
|
207
|
+
await runtime.close();
|
|
208
|
+
~~~
|
|
209
|
+
|
|
210
|
+
The same Trainer contract accepts backend: 'webgpu' or backend: 'wasm'. WASM
|
|
211
|
+
training is strict and rejects an unsupported graph before mutating weights.
|
|
212
|
+
There is no implicit publication: call `commit()` before compiling inference
|
|
213
|
+
against the update, or `rollback()` to restore the last committed baseline.
|
|
214
|
+
The full profile also exports training builders, checkpoints, gradient
|
|
215
|
+
accumulation controls, LoRA helpers, and PTQ authoring tools. See
|
|
216
|
+
[model construction and training](docs/model_builder_training.md) and the
|
|
217
|
+
[operation matrix](docs/operation_list.md).
|
|
218
|
+
|
|
219
|
+
## WASM-only browser extensions
|
|
220
|
+
|
|
221
|
+
For a Manifest V3 extension, package one WASM-only JavaScript variant, the full
|
|
222
|
+
sidecar, and the model:
|
|
223
|
+
|
|
224
|
+
~~~text
|
|
126
225
|
vendor/volvoxai.wasm.min.js
|
|
127
226
|
vendor/volvoxai.full.wasm
|
|
128
|
-
model/
|
|
227
|
+
model/graph.json
|
|
129
228
|
model/model.safetensors
|
|
130
|
-
|
|
229
|
+
~~~
|
|
131
230
|
|
|
132
|
-
|
|
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
|
|
231
|
+
~~~javascript
|
|
141
232
|
import { VolvoxAI } from './vendor/volvoxai.wasm.min.js';
|
|
142
233
|
|
|
143
|
-
const runtime = await VolvoxAI.
|
|
144
|
-
'wasm',
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const graph = await runtime.loadGraph(
|
|
234
|
+
const runtime = await VolvoxAI.createRuntime({
|
|
235
|
+
wasmUrl: chrome.runtime.getURL('vendor/volvoxai.full.wasm'),
|
|
236
|
+
});
|
|
237
|
+
const model = await runtime.loadModel(
|
|
148
238
|
chrome.runtime.getURL('model/model.safetensors'),
|
|
239
|
+
{ graphUrl: chrome.runtime.getURL('model/graph.json') },
|
|
149
240
|
);
|
|
150
|
-
|
|
241
|
+
~~~
|
|
151
242
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
targets: correctedTokenIds,
|
|
156
|
-
trainableTensors: ['decoder.lora_a', 'decoder.lora_b'],
|
|
157
|
-
updateMode: 'adamw',
|
|
158
|
-
optimizer: { learningRate: 1e-4 },
|
|
159
|
-
});
|
|
243
|
+
Extension pages need wasm-unsafe-eval in their content security policy. The
|
|
244
|
+
WASM-only release has no dynamic import and contains no alternate backend.
|
|
245
|
+
See [Browser and Node runtime](docs/browser-runtime.md).
|
|
160
246
|
|
|
161
|
-
|
|
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
|
-
);
|
|
247
|
+
## Native use
|
|
218
248
|
|
|
219
|
-
|
|
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.
|
|
318
|
-
|
|
319
|
-
## Native Usage
|
|
320
|
-
|
|
321
|
-
```bash
|
|
249
|
+
~~~bash
|
|
322
250
|
make build_native
|
|
323
251
|
|
|
324
|
-
# inference-only executable
|
|
325
252
|
./native/volvoxai --help
|
|
326
|
-
|
|
327
|
-
# inference + training executable
|
|
328
253
|
./native/volvoxai-full --help
|
|
329
|
-
|
|
254
|
+
~~~
|
|
330
255
|
|
|
331
|
-
The
|
|
332
|
-
|
|
333
|
-
files, decode images, or implement generation and task postprocessing.
|
|
256
|
+
The inference executable provides model-agnostic tensor execution. The full
|
|
257
|
+
executable additionally provides training:
|
|
334
258
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
```bash
|
|
259
|
+
~~~bash
|
|
338
260
|
./native/volvoxai run models/tinystories_1m \
|
|
339
261
|
--input tokens=models/tinystories_1m/tokens.i32 \
|
|
340
262
|
--input positions=models/tinystories_1m/positions.i32 \
|
|
341
|
-
--output logits=out.f32
|
|
342
|
-
|
|
343
|
-
```
|
|
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:
|
|
263
|
+
--output logits=out.f32
|
|
264
|
+
~~~
|
|
367
265
|
|
|
368
|
-
|
|
369
|
-
|
|
266
|
+
Raw files use a storage suffix matching their declared dtype: .f32, .i32,
|
|
267
|
+
.i8, or .u8. Outputs contain the complete declared tensor; applications
|
|
268
|
+
select task-specific rows or slices. Model-specific tokenization, image
|
|
269
|
+
decoding, generation, and postprocessing live under examples/.
|
|
370
270
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
```
|
|
271
|
+
Native releases use embedded shaders. For shader development,
|
|
272
|
+
VOLVOXAI_SHADER_DIR may point to generated spv/, glsl/, gles/, and metal/
|
|
273
|
+
directories; VolvoxAI logs once when that external override is actually used.
|
|
375
274
|
|
|
376
|
-
|
|
377
|
-
and the `generate`, `classify`, `detect`, `ctc`, `seq2seq`, and `chat` commands.
|
|
275
|
+
## Example models
|
|
378
276
|
|
|
379
|
-
|
|
380
|
-
point `VOLVOXAI_SHADER_DIR` at a generated directory containing `spv/`,
|
|
381
|
-
`glsl/`, `gles/`, and `metal/`; VolvoxAI logs once when that override is used.
|
|
277
|
+
Weights are not committed. Recreate the example packages from public sources:
|
|
382
278
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
Model weights are not committed. Regenerate the example packages from public
|
|
386
|
-
sources:
|
|
387
|
-
|
|
388
|
-
```bash
|
|
279
|
+
~~~bash
|
|
389
280
|
make models_deps
|
|
390
281
|
make models_efficientdet
|
|
391
282
|
make models_tinystories
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
ts/
|
|
401
|
-
ts/
|
|
402
|
-
ts/
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
shaders/
|
|
406
|
-
native/include/
|
|
407
|
-
native/src/
|
|
408
|
-
native/src/
|
|
409
|
-
native/src/
|
|
410
|
-
native/src/
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
native/tests/ Native tests
|
|
414
|
-
runtime/ Rust service wrapper around the C engine
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
See [ARCHITECTURE.md](ARCHITECTURE.md) for dependency and build-composition
|
|
418
|
-
rules.
|
|
283
|
+
make validate_model_packages
|
|
284
|
+
~~~
|
|
285
|
+
|
|
286
|
+
See [Models and exporters](docs/models.md).
|
|
287
|
+
|
|
288
|
+
## Repository layout
|
|
289
|
+
|
|
290
|
+
~~~text
|
|
291
|
+
ts/core/ graph/data objects and runtime ownership
|
|
292
|
+
ts/ops/ operators, validation, and normalization
|
|
293
|
+
ts/backends/ backend providers and device resources
|
|
294
|
+
ts/training/ Trainer, autograd, optimizers, checkpoints, and PTQ
|
|
295
|
+
examples/ model-specific applications and integrations
|
|
296
|
+
shaders/ authoritative WGSL source
|
|
297
|
+
native/include/ public opaque inference/provider and full Trainer/PTQ C APIs
|
|
298
|
+
native/src/runtime/ runtime/model/context/result implementation
|
|
299
|
+
native/src/kernels/ portable and optimized CPU/WASM kernels
|
|
300
|
+
native/src/backends/ native device integrations
|
|
301
|
+
native/src/training/ full-profile training implementation
|
|
302
|
+
runtime/ optional in-process Synurang FFI plugin
|
|
303
|
+
~~~
|
|
419
304
|
|
|
420
305
|
## Documentation
|
|
421
306
|
|
|
422
307
|
- [Quickstart](docs/quickstart.md)
|
|
423
308
|
- [Browser and Node runtime](docs/browser-runtime.md)
|
|
424
309
|
- [Native runtime](docs/native-runtime.md)
|
|
425
|
-
- [
|
|
310
|
+
- [Backend SDK](docs/backend-sdk.md)
|
|
426
311
|
- [Model format](docs/model-format.md)
|
|
427
|
-
- [
|
|
428
|
-
- [
|
|
429
|
-
- [Model construction
|
|
430
|
-
- [Models and exporters](docs/models.md)
|
|
312
|
+
- [Graph exporter and optimizer design](docs/graph-optimizer-design.md)
|
|
313
|
+
- [Typed PTQ](docs/typed-ptq.md)
|
|
314
|
+
- [Model construction and training](docs/model_builder_training.md)
|
|
431
315
|
- [Operation support matrix](docs/operation_list.md)
|
|
432
316
|
- [Testing and validation](docs/testing.md)
|
|
433
|
-
- [
|
|
434
|
-
- [Textbook
|
|
435
|
-
- [EfficientDet benchmark notes](docs/efficientdet_tflite_vs_volvoxai.md)
|
|
436
|
-
|
|
437
|
-
## Current Status
|
|
438
|
-
|
|
439
|
-
VolvoxAI can run real browser and native inference paths, but it is still early.
|
|
440
|
-
Known gaps include WebGPU multi-output readback, broader WebNN coverage, additional
|
|
441
|
-
native/WebGPU shaders for a few fallback ops, browser-side generation helpers,
|
|
442
|
-
and formal CI wiring for the existing smoke tests.
|
|
443
|
-
|
|
444
|
-
See [docs/roadmap.md](docs/roadmap.md) for the detailed list.
|
|
317
|
+
- [Models and exporters](docs/models.md)
|
|
318
|
+
- [Textbook](docs/textbook/README.md)
|
|
445
319
|
|
|
446
320
|
## License
|
|
447
321
|
|