summaryrefslogtreecommitdiff
path: root/cnn_v3/tools/tester.js
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-03-25 06:25:53 +0100
committerskal <pascal.massimino@gmail.com>2026-03-25 06:25:53 +0100
commita71c95c8caf7e570c3f484ce1a53b7acb5ef2006 (patch)
tree9ff08f15ef79c7752a3389e7fb2c54ce3ba7eb72 /cnn_v3/tools/tester.js
parentfc74d8e36449e0040564debd381e666df40d671b (diff)
feat(cnn_v3/tools): embed default weights in HTML tool; add --html export flag
- cnn_v3/tools/weights.js: new file — base64-encoded cnn_v3_weights.bin + cnn_v3_film_mlp.bin; loaded at startup so the tool works without dropping files - tester.js: preload() falls back to embedded weights.js constants when fetch fails; logs "Loaded embedded" vs "Preloaded" to distinguish the two paths - index.html: load weights.js before tester.js - export_cnn_v3_weights.py: add --html / --html-output flags that call update_weights_js() to regenerate weights.js after a training run - HOW_TO_CNN.md: update pipeline diagram, §3 export commands, §7 HTML tool section (file table, workflow, weights.js description), Appendix A handoff(Gemini): weights.js now the canonical source for HTML tool defaults; regenerate with `uv run export_cnn_v3_weights.py <ckpt> --output ... --html`
Diffstat (limited to 'cnn_v3/tools/tester.js')
-rw-r--r--cnn_v3/tools/tester.js45
1 files changed, 25 insertions, 20 deletions
diff --git a/cnn_v3/tools/tester.js b/cnn_v3/tools/tester.js
index 0412cae..81c869d 100644
--- a/cnn_v3/tools/tester.js
+++ b/cnn_v3/tools/tester.js
@@ -52,29 +52,34 @@ class CNNv3Tester {
async preload() {
const base = '../../workspaces/main/weights/';
const files = [
- {url: base+'cnn_v3_weights.bin', isFilm: false},
- {url: base+'cnn_v3_film_mlp.bin', isFilm: true},
+ {url: base+'cnn_v3_weights.bin', isFilm: false, b64: CNN_V3_WEIGHTS_B64},
+ {url: base+'cnn_v3_film_mlp.bin', isFilm: true, b64: CNN_V3_FILM_MLP_B64},
];
- for (const {url, isFilm} of files) {
+ for (const {url, isFilm, b64} of files) {
+ let buf = null;
+ const name = url.split('/').pop();
try {
const r = await fetch(url);
- if (!r.ok) { this.log(`preload skip: ${url.split('/').pop()} (${r.status})`); continue; }
- const buf = await r.arrayBuffer();
- const name = url.split('/').pop();
- if (isFilm) {
- this.filmMlp = this.parseFilm(buf);
- const el = document.getElementById('fDrop');
- el.textContent = `✓ ${name}`; el.classList.add('ok');
- document.getElementById('fSt').textContent = 'FiLM MLP loaded';
- document.getElementById('fSt').style.color = '#28a745';
- } else {
- this.weightsU32 = this.parseWeights(buf); this.weightsBuffer = buf;
- if (this.weightsGPU) { this.weightsGPU.destroy(); this.weightsGPU = null; }
- const el = document.getElementById('wDrop');
- el.textContent = `✓ ${name}`; el.classList.add('ok');
- }
- this.log(`Preloaded: ${name}`);
- } catch(e) { this.log(`preload error (${url.split('/').pop()}): ${e.message}`, 'err'); }
+ if (r.ok) { buf = await r.arrayBuffer(); this.log(`Preloaded: ${name}`); }
+ } catch(_) {}
+ if (!buf) {
+ const s = atob(b64); const u = new Uint8Array(s.length);
+ for (let i = 0; i < s.length; i++) u[i] = s.charCodeAt(i);
+ buf = u.buffer;
+ this.log(`Loaded embedded: ${name}`);
+ }
+ if (isFilm) {
+ this.filmMlp = this.parseFilm(buf);
+ const el = document.getElementById('fDrop');
+ el.textContent = `✓ ${name}`; el.classList.add('ok');
+ document.getElementById('fSt').textContent = 'FiLM MLP loaded';
+ document.getElementById('fSt').style.color = '#28a745';
+ } else {
+ this.weightsU32 = this.parseWeights(buf); this.weightsBuffer = buf;
+ if (this.weightsGPU) { this.weightsGPU.destroy(); this.weightsGPU = null; }
+ const el = document.getElementById('wDrop');
+ el.textContent = `✓ ${name}`; el.classList.add('ok');
+ }
}
if (this.weightsU32) {
if (this.image || this.isVideo) this.run();