Stefatorus Claude Opus 5.5 commited on
Commit
8d1a72e
·
1 Parent(s): 146ba97

Why Agate: scope (glyph/symbol and vector-native font generation), released to share our architectural efforts

Browse files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018EtDckYfNgMbkwqVmTsdha

Files changed (2) hide show
  1. README.md +113 -105
  2. index.html +147 -146
README.md CHANGED
@@ -1,105 +1,113 @@
1
- ---
2
- title: Agate WebGPU
3
- colorFrom: red
4
- colorTo: gray
5
- sdk: static
6
- app_file: index.html
7
- pinned: false
8
- license: mit
9
- short_description: Agate text-to-image, 100% in your browser on WebGPU
10
- custom_headers:
11
- cross-origin-embedder-policy: require-corp
12
- cross-origin-opener-policy: same-origin
13
- cross-origin-resource-policy: cross-origin
14
- models:
15
- - Logolabs/agate-preview-003
16
- - Logolabs/agate-preview-002
17
- - Logolabs/agate-preview-001
18
- ---
19
-
20
- # Agate WebGPU
21
-
22
- LogoLabs' Agate text-to-image models (a ~0.19B flow generator with a 68M text encoder) running as a static page.
23
- The tokenizer, text encoder, 50-step flow sampler with classifier-free guidance and the TAESD decoder all run
24
- on your own GPU through WebGPU (onnxruntime-web).
25
-
26
- **Runs entirely in your browser — prompts never leave your machine.** There is no server and no API call.
27
-
28
- ## Models
29
-
30
- Pick a model at the top of the page. A first visit gets Preview 003; the page remembers your last choice in
31
- this browser.
32
-
33
- | model | resolution | notes | download |
34
- |---|---|---|---|
35
- | [Preview 003](https://huggingface.co/Logolabs/agate-preview-003) | 512 px (or 256) | multi-resolution model; prompt pipeline: normaliser, quoted text spelled out, object counts coded, "no X" moved to the negative prompt; SD3 timestep shift 2 at 512 | 531 MB (both resolutions share one weights file) |
36
- | [Preview 002](https://huggingface.co/Logolabs/agate-preview-002) | 256 px | same network as 001, trained longer | 530 MB |
37
- | [Preview 001](https://huggingface.co/Logolabs/agate-preview-001) | 256 px | the first preview | 530 MB |
38
-
39
- Each model is downloaded once and kept in the browser's Cache Storage. The files live in each release's model repo
40
- under `webgpu/v2/` (e.g. [Logolabs/agate-preview-003/webgpu/v2](https://huggingface.co/Logolabs/agate-preview-003/tree/main/webgpu/v2)),
41
- with a `manifest.json` holding sizes and sha256s (the cache keys). `models/` in this Space is the original 001 build
42
- (without the plan output), kept for `?models=./models/`.
43
-
44
- ## Show thinker
45
-
46
- Agate's thinker lays the picture out on a 16 × 16 grid (the plan) that steers the renderer. With **Show thinker**
47
- (on by default; it does not slow sampling: previews are read back asynchronously and coloured in a Web Worker) the page shows, at every step, the plan of the conditional branch as
48
- colours and the image the model currently expects (x₁ = z + (1 − t)·v, with the SD latent→RGB approximation) —
49
- the same live preview as the [ComfyUI nodes](https://github.com/logolabs/agate-comfyui): the plan's cells are
50
- projected on its top three principal components, fitted at the first step with the 2% / 98% quantiles fixed then,
51
- so a colour keeps its meaning while the plan evolves.
52
-
53
- ## Requirements
54
-
55
- A browser with WebGPU: a recent Chrome or Edge (113+). Safari and Firefox may lack WebGPU or need it enabled in
56
- their settings; without it the page offers a WebAssembly (CPU) path that works but takes minutes per image.
57
-
58
- ## Speed and accuracy (RTX 4060 laptop, Edge, WebGPU, warm, 50 steps)
59
-
60
- | model | per step (CFG batch of 2) | image | before (2026-09-29 morning) |
61
- |---|---|---|---|
62
- | 003 at 512 px | ~161 ms | **~8.1 s** (Fast, 25 steps: ~4.1 s) | 275 ms, 14 s |
63
- | 003 at 256 px | ~70 ms | ~3.5 s | 120 ms, 6.1 s |
64
- | 002 / 001 | ~65 ms | ~3.3 s | 105 ms, 5.3 s |
65
-
66
- How: each step is one graph run that also does the CFG mix and the Euler update, so the latent never leaves the
67
- GPU between steps (the only readback is the final latent); the network computes in **fp16** (WebGPU `shader-f16`;
68
- WGSL has no bf16), with fp32 kept for the graph I/O, the CFG/Euler arithmetic, the timestep / resolution / count
69
- embeddings (sin(1000·t·f) needs fp32) and `Range`; the transposed-conv upsamplers run as 1x1 conv + depth-to-space.
70
- The thinker preview never blocks sampling: its tensors are downloaded asynchronously, coloured in a Web Worker,
71
- and frames are dropped while one is pending (measured cost: none).
72
-
73
- fp16 compute moves the result slightly: against the fp32 PyTorch reference with the same initial noise, 001 is
74
- within 16/255 (PSNR 48 dB), 002 36 dB, 003 at 256 px 42 dB and 003 at 512 px 31 dB (mean 0.6-1.8/255). For scale,
75
- the Python package's own CUDA path (bf16) is 14 dB from that fp32 reference for the same noise. Run `?parity=1`.
76
- Seeds use a JavaScript PRNG, so a seed gives the same image in every browser, but not the same image as the
77
- PyTorch pipeline with that seed. The Python packages decode with the full SD-VAE by default; this page uses TAESD.
78
-
79
- ## AI-generated content marking
80
-
81
- Every image the page makes is marked as AI-generated (EU AI Act Art. 50(2)), with the same marks as the Python
82
- packages:
83
-
84
- - an invisible watermark in the pixels: [invisible-watermark](https://github.com/ShieldMnt/invisible-watermark)'s
85
- `dwtDctSvd` method, ported to JavaScript bit for bit, with the 64-bit payload `AGATE` + release
86
- (`AGATE003`, ...). `agate.detect_watermark(img)` from the model packages reads it;
87
- - in the saved PNG: text fields `ai_generated`, `generator`, `model` and `watermark`. The prompt is not written;
88
- - a visible "AI-generated" note next to each result.
89
-
90
- Neither mark is tamper-proof: screenshots and re-encodes drop the metadata, and heavy edits can remove the
91
- watermark. If you publish images made here, label them as AI-generated.
92
-
93
- Query parameters: `?v=001|002|003` picks a model, `?res=256` picks 003's resolution, `?autoload=1` loads the
94
- model immediately, `?ep=wasm` forces the CPU backend, `?parity=1` runs the parity self-test, `?golden=1` checks
95
- 003's prompt pipeline against the Python package's output (38 prompts).
96
-
97
- ## Links
98
-
99
- - [logolabs.org](https://logolabs.org)
100
- - [huggingface.co/Logolabs](https://huggingface.co/Logolabs)
101
-
102
- Licence: MIT.
103
-
104
- We acknowledge EuroHPC JU for awarding the project ID EHPC-AIF-2026PG01-907 access to resources on
105
- Arrhenius GPU at NAISS, Sweden.
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Agate WebGPU
3
+ colorFrom: red
4
+ colorTo: gray
5
+ sdk: static
6
+ app_file: index.html
7
+ pinned: false
8
+ license: mit
9
+ short_description: Agate text-to-image, 100% in your browser on WebGPU
10
+ custom_headers:
11
+ cross-origin-embedder-policy: require-corp
12
+ cross-origin-opener-policy: same-origin
13
+ cross-origin-resource-policy: cross-origin
14
+ models:
15
+ - Logolabs/agate-preview-003
16
+ - Logolabs/agate-preview-002
17
+ - Logolabs/agate-preview-001
18
+ ---
19
+
20
+ # Agate WebGPU
21
+
22
+ LogoLabs' Agate text-to-image models (a ~0.19B flow generator with a 68M text encoder) running as a static page.
23
+ The tokenizer, text encoder, 50-step flow sampler with classifier-free guidance and the TAESD decoder all run
24
+ on your own GPU through WebGPU (onnxruntime-web).
25
+
26
+ **Runs entirely in your browser — prompts never leave your machine.** There is no server and no API call.
27
+
28
+ **Why we built Agate.** Agate is LogoLabs' search for the best architecture for small-scale image generation. It is
29
+ not meant as a general image model: it is the groundwork for glyph and symbol generation, so that we can generate
30
+ vector-native fonts to go with the wordmarks we make at LogoLabs. Font and SVG generation have almost no established
31
+ benchmarks, so we tested the architecture on natural images, where GenEval, Qwen-Image-Bench and FID exist, as a proxy
32
+ for architectural performance. Next, we plan to build on it to generate SVGs with our vectoriser, Inkvec, and to
33
+ improve Inkvec's prior with flow matching to help trace the fonts. We decided to release Agate to share
34
+ these architectural efforts.
35
+
36
+ ## Models
37
+
38
+ Pick a model at the top of the page. A first visit gets Preview 003; the page remembers your last choice in
39
+ this browser.
40
+
41
+ | model | resolution | notes | download |
42
+ |---|---|---|---|
43
+ | [Preview 003](https://huggingface.co/Logolabs/agate-preview-003) | 512 px (or 256) | multi-resolution model; prompt pipeline: normaliser, quoted text spelled out, object counts coded, "no X" moved to the negative prompt; SD3 timestep shift 2 at 512 | 531 MB (both resolutions share one weights file) |
44
+ | [Preview 002](https://huggingface.co/Logolabs/agate-preview-002) | 256 px | same network as 001, trained longer | 530 MB |
45
+ | [Preview 001](https://huggingface.co/Logolabs/agate-preview-001) | 256 px | the first preview | 530 MB |
46
+
47
+ Each model is downloaded once and kept in the browser's Cache Storage. The files live in each release's model repo
48
+ under `webgpu/v2/` (e.g. [Logolabs/agate-preview-003/webgpu/v2](https://huggingface.co/Logolabs/agate-preview-003/tree/main/webgpu/v2)),
49
+ with a `manifest.json` holding sizes and sha256s (the cache keys). `models/` in this Space is the original 001 build
50
+ (without the plan output), kept for `?models=./models/`.
51
+
52
+ ## Show thinker
53
+
54
+ Agate's thinker lays the picture out on a 16 × 16 grid (the plan) that steers the renderer. With **Show thinker**
55
+ (on by default; it does not slow sampling: previews are read back asynchronously and coloured in a Web Worker) the page shows, at every step, the plan of the conditional branch as
56
+ colours and the image the model currently expects (x₁ = z + (1 − t)·v, with the SD latent→RGB approximation) —
57
+ the same live preview as the [ComfyUI nodes](https://github.com/logolabs/agate-comfyui): the plan's cells are
58
+ projected on its top three principal components, fitted at the first step with the 2% / 98% quantiles fixed then,
59
+ so a colour keeps its meaning while the plan evolves.
60
+
61
+ ## Requirements
62
+
63
+ A browser with WebGPU: a recent Chrome or Edge (113+). Safari and Firefox may lack WebGPU or need it enabled in
64
+ their settings; without it the page offers a WebAssembly (CPU) path that works but takes minutes per image.
65
+
66
+ ## Speed and accuracy (RTX 4060 laptop, Edge, WebGPU, warm, 50 steps)
67
+
68
+ | model | per step (CFG batch of 2) | image | before (2026-09-29 morning) |
69
+ |---|---|---|---|
70
+ | 003 at 512 px | ~161 ms | **~8.1 s** (Fast, 25 steps: ~4.1 s) | 275 ms, 14 s |
71
+ | 003 at 256 px | ~70 ms | ~3.5 s | 120 ms, 6.1 s |
72
+ | 002 / 001 | ~65 ms | ~3.3 s | 105 ms, 5.3 s |
73
+
74
+ How: each step is one graph run that also does the CFG mix and the Euler update, so the latent never leaves the
75
+ GPU between steps (the only readback is the final latent); the network computes in **fp16** (WebGPU `shader-f16`;
76
+ WGSL has no bf16), with fp32 kept for the graph I/O, the CFG/Euler arithmetic, the timestep / resolution / count
77
+ embeddings (sin(1000·t·f) needs fp32) and `Range`; the transposed-conv upsamplers run as 1x1 conv + depth-to-space.
78
+ The thinker preview never blocks sampling: its tensors are downloaded asynchronously, coloured in a Web Worker,
79
+ and frames are dropped while one is pending (measured cost: none).
80
+
81
+ fp16 compute moves the result slightly: against the fp32 PyTorch reference with the same initial noise, 001 is
82
+ within 16/255 (PSNR 48 dB), 002 36 dB, 003 at 256 px 42 dB and 003 at 512 px 31 dB (mean 0.6-1.8/255). For scale,
83
+ the Python package's own CUDA path (bf16) is 14 dB from that fp32 reference for the same noise. Run `?parity=1`.
84
+ Seeds use a JavaScript PRNG, so a seed gives the same image in every browser, but not the same image as the
85
+ PyTorch pipeline with that seed. The Python packages decode with the full SD-VAE by default; this page uses TAESD.
86
+
87
+ ## AI-generated content marking
88
+
89
+ Every image the page makes is marked as AI-generated (EU AI Act Art. 50(2)), with the same marks as the Python
90
+ packages:
91
+
92
+ - an invisible watermark in the pixels: [invisible-watermark](https://github.com/ShieldMnt/invisible-watermark)'s
93
+ `dwtDctSvd` method, ported to JavaScript bit for bit, with the 64-bit payload `AGATE` + release
94
+ (`AGATE003`, ...). `agate.detect_watermark(img)` from the model packages reads it;
95
+ - in the saved PNG: text fields `ai_generated`, `generator`, `model` and `watermark`. The prompt is not written;
96
+ - a visible "AI-generated" note next to each result.
97
+
98
+ Neither mark is tamper-proof: screenshots and re-encodes drop the metadata, and heavy edits can remove the
99
+ watermark. If you publish images made here, label them as AI-generated.
100
+
101
+ Query parameters: `?v=001|002|003` picks a model, `?res=256` picks 003's resolution, `?autoload=1` loads the
102
+ model immediately, `?ep=wasm` forces the CPU backend, `?parity=1` runs the parity self-test, `?golden=1` checks
103
+ 003's prompt pipeline against the Python package's output (38 prompts).
104
+
105
+ ## Links
106
+
107
+ - [logolabs.org](https://logolabs.org)
108
+ - [huggingface.co/Logolabs](https://huggingface.co/Logolabs)
109
+
110
+ Licence: MIT.
111
+
112
+ We acknowledge EuroHPC JU for awarding the project ID EHPC-AIF-2026PG01-907 access to resources on
113
+ Arrhenius GPU at NAISS, Sweden.
index.html CHANGED
@@ -1,146 +1,147 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>Agate — in your browser</title>
7
- <meta name="description" content="Agate Preview 001, 002 and 003, LogoLabs' 0.26B text-to-image models, running entirely in your browser on WebGPU.">
8
- <link rel="icon" href="assets/agate-a.svg" type="image/svg+xml">
9
- <link rel="preconnect" href="https://fonts.googleapis.com">
10
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link crossorigin="anonymous" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&family=Inter+Tight:wght@700;800&display=swap" rel="stylesheet">
12
- <link rel="stylesheet" href="css/style.css">
13
- </head>
14
- <body>
15
- <div class="page">
16
- <header class="mast">
17
- <div class="mast-left">
18
- <img class="lockup" src="assets/agate-lockup.svg" alt="Agate">
19
- <div class="mast-meta">
20
- <span class="label"><i class="sq"></i><span id="mast-version">Preview 003</span></span>
21
- <span class="label dim" id="mast-spec">0.26B · text-to-image · 512 px</span>
22
- </div>
23
- </div>
24
- <a class="imprint" href="https://logolabs.org" target="_blank" rel="noopener">
25
- <img src="assets/logolabs-mark.svg" alt="" width="22" height="30">
26
- <span class="label">LogoLabs</span>
27
- </a>
28
- </header>
29
- <hr class="rule">
30
-
31
- <section class="intro">
32
- <h1>Agate, in your browser.</h1>
33
- <p>A 0.19B-parameter flow model with a 68M text encoder, running on your own GPU through WebGPU.
34
- The first visit downloads the chosen model once (<span id="dl-size">about 530 MB</span>); after that it loads from the browser cache.</p>
35
- </section>
36
-
37
- <section class="versions" aria-labelledby="ver-label">
38
- <span class="label" id="ver-label">Model</span>
39
- <div class="seg" role="radiogroup" aria-labelledby="ver-label" id="versions"></div>
40
- <p class="ver-note" id="ver-note"></p>
41
- </section>
42
-
43
- <div id="nogpu" class="notice" hidden>
44
- <span class="label"><i class="sq red"></i>WebGPU unavailable</span>
45
- <p id="nogpu-why"></p>
46
- <p>Agate needs WebGPU for usable speed: use a recent Chrome or Edge (113+) on Windows, macOS or ChromeOS,
47
- or Chrome on Android 121+; on Linux and in Firefox/Safari WebGPU may have to be enabled in the browser's flags.
48
- You can still run it on the CPU (WebAssembly) — correct, but several minutes per image (far longer at 512 px).</p>
49
- <button id="use-wasm" class="btn ghost">Run on CPU instead</button>
50
- </div>
51
-
52
- <main class="grid">
53
- <section class="panel controls">
54
- <label class="label" for="prompt">Prompt</label>
55
- <textarea id="prompt" rows="3" spellcheck="false">a green teapot and a red cup on a table</textarea>
56
- <div class="examples" id="examples">
57
- <span class="label dim">Try</span>
58
- </div>
59
- <label class="label" for="negative">Avoid <span class="dim" id="neg-hint">(optional negative prompt)</span></label>
60
- <input id="negative" type="text" spellcheck="false" placeholder="e.g. text, blur">
61
-
62
- <div class="row">
63
- <div class="field">
64
- <label class="label" for="seed">Seed</label>
65
- <div class="seed-row">
66
- <input id="seed" type="number" min="0" max="4294967295" step="1" value="0">
67
- <button id="dice" class="btn icon" title="Random seed" aria-label="Random seed">⟳</button>
68
- </div>
69
- </div>
70
- <div class="field">
71
- <label class="label" for="steps">Steps <b id="steps-v">50</b>
72
- <span class="toggle fast" title="25 steps: about twice as fast; detail holds, the layout can change"><input type="checkbox" id="fast"> Fast</span></label>
73
- <input id="steps" type="range" min="4" max="50" step="1" value="50">
74
- </div>
75
- <div class="field">
76
- <label class="label" for="cfg">CFG <b id="cfg-v">3.0</b></label>
77
- <input id="cfg" type="range" min="1" max="8" step="0.5" value="3">
78
- </div>
79
- </div>
80
- <div class="row res-row" id="res-row" hidden>
81
- <div class="field">
82
- <span class="label">Resolution</span>
83
- <div class="seg small" role="radiogroup" id="res"></div>
84
- </div>
85
- </div>
86
-
87
- <button id="go" class="btn primary" disabled>Load model</button>
88
-
89
- <div class="progress" aria-live="polite">
90
- <div class="bar"><div id="bar-fill"></div></div>
91
- <div class="progress-text"><span id="status" class="label">Idle</span><span id="status-r" class="label dim"></span></div>
92
- </div>
93
- <p class="prepared" id="prepared" hidden></p>
94
- </section>
95
-
96
- <section class="panel output">
97
- <div class="out-head">
98
- <span class="label"><i class="sq"></i><span id="out-label">Output · 512 × 512</span></span>
99
- <span class="toggles">
100
- <label class="label toggle" title="Show the thinker's 16 x 16 plan and the expected final image at every step"><input type="checkbox" id="show-thinker" checked> Show thinker</label>
101
- <label class="label toggle"><input type="checkbox" id="crisp"> Crisp pixels</label>
102
- </span>
103
- </div>
104
- <div class="frame" id="frame">
105
- <canvas id="canvas" width="512" height="512"></canvas>
106
- <div class="placeholder" id="placeholder">
107
- <img src="assets/agate-a.svg" alt="">
108
- </div>
109
- </div>
110
- <div class="thinker" id="thinker" hidden>
111
- <figure><canvas id="plan-canvas" width="16" height="16"></canvas>
112
- <figcaption class="label dim">Thinker plan · 16 × 16</figcaption></figure>
113
- <figure><canvas id="pred-canvas" width="32" height="32"></canvas>
114
- <figcaption class="label dim">Expected · <span id="thinker-step">0 / 0</span></figcaption></figure>
115
- <p class="thinker-note">The thinker lays the picture out on a 16 × 16 grid before the renderer paints it.
116
- Colours are the plan's three main directions (fixed at the first step, as in the ComfyUI nodes); the
117
- expected image is x₁ = z + (1 − t)·v, shown with the SD latent→RGB approximation.</p>
118
- </div>
119
- <p class="ai-note" id="ai-note" hidden><i class="sq red"></i><span><b>AI-generated image.</b>
120
- Made by <span id="ai-model">Agate Preview 003</span>; it carries an invisible watermark and, when saved, PNG provenance metadata (no prompt).</span></p>
121
- <div class="out-foot">
122
- <dl class="timings" id="timings"></dl>
123
- <a id="save" class="btn ghost small" download="agate.png" hidden>Save PNG</a>
124
- </div>
125
- </section>
126
- </main>
127
-
128
- <div id="parity" class="notice" hidden></div>
129
-
130
- <hr class="rule">
131
- <footer class="foot">
132
- <p class="strong">Runs entirely in your browser on WebGPU — nothing leaves your machine.</p>
133
- <p class="small-print">Every image made here is marked as AI-generated (EU AI Act Art. 50): an invisible watermark in the
134
- pixels (invisible-watermark “dwtDctSvd”, payload AGATE + release) and, in the saved PNG, text fields
135
- <code>ai_generated</code>, <code>generator</code>, <code>model</code>. Neither survives every edit; please label AI images you publish.</p>
136
- <p class="label dim">
137
- <a href="https://logolabs.org" target="_blank" rel="noopener">logolabs.org</a> ·
138
- <a href="https://huggingface.co/Logolabs" target="_blank" rel="noopener">huggingface.co/Logolabs</a> ·
139
- MIT licence · <span id="backend">backend: —</span>
140
- </p>
141
- </footer>
142
- </div>
143
- <script src="js/config.js"></script>
144
- <script type="module" src="js/app.js"></script>
145
- </body>
146
- </html>
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Agate — in your browser</title>
7
+ <meta name="description" content="Agate Preview 001, 002 and 003, LogoLabs' 0.26B text-to-image models, running entirely in your browser on WebGPU.">
8
+ <link rel="icon" href="assets/agate-a.svg" type="image/svg+xml">
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link crossorigin="anonymous" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600&family=Inter+Tight:wght@700;800&display=swap" rel="stylesheet">
12
+ <link rel="stylesheet" href="css/style.css">
13
+ </head>
14
+ <body>
15
+ <div class="page">
16
+ <header class="mast">
17
+ <div class="mast-left">
18
+ <img class="lockup" src="assets/agate-lockup.svg" alt="Agate">
19
+ <div class="mast-meta">
20
+ <span class="label"><i class="sq"></i><span id="mast-version">Preview 003</span></span>
21
+ <span class="label dim" id="mast-spec">0.26B · text-to-image · 512 px</span>
22
+ </div>
23
+ </div>
24
+ <a class="imprint" href="https://logolabs.org" target="_blank" rel="noopener">
25
+ <img src="assets/logolabs-mark.svg" alt="" width="22" height="30">
26
+ <span class="label">LogoLabs</span>
27
+ </a>
28
+ </header>
29
+ <hr class="rule">
30
+
31
+ <section class="intro">
32
+ <h1>Agate, in your browser.</h1>
33
+ <p>A 0.19B-parameter flow model with a 68M text encoder, running on your own GPU through WebGPU.
34
+ The first visit downloads the chosen model once (<span id="dl-size">about 530 MB</span>); after that it loads from the browser cache.</p>
35
+ </section>
36
+
37
+ <section class="versions" aria-labelledby="ver-label">
38
+ <span class="label" id="ver-label">Model</span>
39
+ <div class="seg" role="radiogroup" aria-labelledby="ver-label" id="versions"></div>
40
+ <p class="ver-note" id="ver-note"></p>
41
+ </section>
42
+
43
+ <div id="nogpu" class="notice" hidden>
44
+ <span class="label"><i class="sq red"></i>WebGPU unavailable</span>
45
+ <p id="nogpu-why"></p>
46
+ <p>Agate needs WebGPU for usable speed: use a recent Chrome or Edge (113+) on Windows, macOS or ChromeOS,
47
+ or Chrome on Android 121+; on Linux and in Firefox/Safari WebGPU may have to be enabled in the browser's flags.
48
+ You can still run it on the CPU (WebAssembly) — correct, but several minutes per image (far longer at 512 px).</p>
49
+ <button id="use-wasm" class="btn ghost">Run on CPU instead</button>
50
+ </div>
51
+
52
+ <main class="grid">
53
+ <section class="panel controls">
54
+ <label class="label" for="prompt">Prompt</label>
55
+ <textarea id="prompt" rows="3" spellcheck="false">a green teapot and a red cup on a table</textarea>
56
+ <div class="examples" id="examples">
57
+ <span class="label dim">Try</span>
58
+ </div>
59
+ <label class="label" for="negative">Avoid <span class="dim" id="neg-hint">(optional negative prompt)</span></label>
60
+ <input id="negative" type="text" spellcheck="false" placeholder="e.g. text, blur">
61
+
62
+ <div class="row">
63
+ <div class="field">
64
+ <label class="label" for="seed">Seed</label>
65
+ <div class="seed-row">
66
+ <input id="seed" type="number" min="0" max="4294967295" step="1" value="0">
67
+ <button id="dice" class="btn icon" title="Random seed" aria-label="Random seed">⟳</button>
68
+ </div>
69
+ </div>
70
+ <div class="field">
71
+ <label class="label" for="steps">Steps <b id="steps-v">50</b>
72
+ <span class="toggle fast" title="25 steps: about twice as fast; detail holds, the layout can change"><input type="checkbox" id="fast"> Fast</span></label>
73
+ <input id="steps" type="range" min="4" max="50" step="1" value="50">
74
+ </div>
75
+ <div class="field">
76
+ <label class="label" for="cfg">CFG <b id="cfg-v">3.0</b></label>
77
+ <input id="cfg" type="range" min="1" max="8" step="0.5" value="3">
78
+ </div>
79
+ </div>
80
+ <div class="row res-row" id="res-row" hidden>
81
+ <div class="field">
82
+ <span class="label">Resolution</span>
83
+ <div class="seg small" role="radiogroup" id="res"></div>
84
+ </div>
85
+ </div>
86
+
87
+ <button id="go" class="btn primary" disabled>Load model</button>
88
+
89
+ <div class="progress" aria-live="polite">
90
+ <div class="bar"><div id="bar-fill"></div></div>
91
+ <div class="progress-text"><span id="status" class="label">Idle</span><span id="status-r" class="label dim"></span></div>
92
+ </div>
93
+ <p class="prepared" id="prepared" hidden></p>
94
+ </section>
95
+
96
+ <section class="panel output">
97
+ <div class="out-head">
98
+ <span class="label"><i class="sq"></i><span id="out-label">Output · 512 × 512</span></span>
99
+ <span class="toggles">
100
+ <label class="label toggle" title="Show the thinker's 16 x 16 plan and the expected final image at every step"><input type="checkbox" id="show-thinker" checked> Show thinker</label>
101
+ <label class="label toggle"><input type="checkbox" id="crisp"> Crisp pixels</label>
102
+ </span>
103
+ </div>
104
+ <div class="frame" id="frame">
105
+ <canvas id="canvas" width="512" height="512"></canvas>
106
+ <div class="placeholder" id="placeholder">
107
+ <img src="assets/agate-a.svg" alt="">
108
+ </div>
109
+ </div>
110
+ <div class="thinker" id="thinker" hidden>
111
+ <figure><canvas id="plan-canvas" width="16" height="16"></canvas>
112
+ <figcaption class="label dim">Thinker plan · 16 × 16</figcaption></figure>
113
+ <figure><canvas id="pred-canvas" width="32" height="32"></canvas>
114
+ <figcaption class="label dim">Expected · <span id="thinker-step">0 / 0</span></figcaption></figure>
115
+ <p class="thinker-note">The thinker lays the picture out on a 16 × 16 grid before the renderer paints it.
116
+ Colours are the plan's three main directions (fixed at the first step, as in the ComfyUI nodes); the
117
+ expected image is x₁ = z + (1 − t)·v, shown with the SD latent→RGB approximation.</p>
118
+ </div>
119
+ <p class="ai-note" id="ai-note" hidden><i class="sq red"></i><span><b>AI-generated image.</b>
120
+ Made by <span id="ai-model">Agate Preview 003</span>; it carries an invisible watermark and, when saved, PNG provenance metadata (no prompt).</span></p>
121
+ <div class="out-foot">
122
+ <dl class="timings" id="timings"></dl>
123
+ <a id="save" class="btn ghost small" download="agate.png" hidden>Save PNG</a>
124
+ </div>
125
+ </section>
126
+ </main>
127
+
128
+ <div id="parity" class="notice" hidden></div>
129
+
130
+ <hr class="rule">
131
+ <footer class="foot">
132
+ <p class="strong">Runs entirely in your browser on WebGPU — nothing leaves your machine.</p>
133
+ <p class="small-print">Every image made here is marked as AI-generated (EU AI Act Art. 50): an invisible watermark in the
134
+ pixels (invisible-watermark “dwtDctSvd”, payload AGATE + release) and, in the saved PNG, text fields
135
+ <code>ai_generated</code>, <code>generator</code>, <code>model</code>. Neither survives every edit; please label AI images you publish.</p>
136
+ <p class="small-print">Why Agate: LogoLabs' search for the best small-scale image architecture, the groundwork for glyph and symbol generation and vector-native fonts to go with our wordmarks. Natural images served as a benchmarkable proxy; next it feeds SVG generation with Inkvec. Released to share these architectural efforts.</p>
137
+ <p class="label dim">
138
+ <a href="https://logolabs.org" target="_blank" rel="noopener">logolabs.org</a> ·
139
+ <a href="https://huggingface.co/Logolabs" target="_blank" rel="noopener">huggingface.co/Logolabs</a> ·
140
+ MIT licence · <span id="backend">backend: —</span>
141
+ </p>
142
+ </footer>
143
+ </div>
144
+ <script src="js/config.js"></script>
145
+ <script type="module" src="js/app.js"></script>
146
+ </body>
147
+ </html>