diff options
| author | skal <pascal.massimino@gmail.com> | 2026-03-25 06:25:53 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-03-25 06:25:53 +0100 |
| commit | a71c95c8caf7e570c3f484ce1a53b7acb5ef2006 (patch) | |
| tree | 9ff08f15ef79c7752a3389e7fb2c54ce3ba7eb72 /cnn_v3/tools/tester.js | |
| parent | fc74d8e36449e0040564debd381e666df40d671b (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.js | 45 |
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(); |
