NanoDiffuser

NanoDiffuser logo

One-step text-to-image diffusion, running locally in your browser.

NanoDiffuser uses a custom-modified version of Stable Diffusion, adapted and quantized to fit a tight sub-400 MiB model budget. Compact ONNX graphs, a JavaScript inference pipeline, and a minimal interface generate 512 ร— 512 images using the visitor's GPU through WebGPU. Hosting serves static files; image generation requires no inference server, API key, or server-side GPU.

The modifications cover model conversion, mixed-precision quantization, browser compatibility, local inference, and static deployment. No additional training or fine-tuning was performed for this package. The approximately 382 MiB budget covers the inference graphs, weights, tokenizer, and configuration; JavaScript and WebAssembly assets are additional. In decimal units, the model assets are approximately 400.5 MB.

At a glance

Property Configuration
Base Custom-modified Stable Diffusion adapted for a sub-400 MiB model budget
Output One 512 ร— 512 RGB image, downloadable as PNG
Sampling One denoising step, classifier-free guidance disabled
Scheduler Exported one-step DEIS coefficients
Text encoder CLIP, asymmetric Q4 MatMul/Gather weights
Denoiser U-Net, Q4 matrix weights + per-channel INT8 convolution storage, with FP16 retained where needed
Decoder TAESD / AutoencoderTiny, FP16
Model assets Approximately 382 MiB, excluding JavaScript and WebAssembly runtime assets
Execution ONNX Runtime Web with WebGPU; tokenization and orchestration in JavaScript
Hosting Static HTML, CSS, JavaScript, WebAssembly, and model files

Getting started

Open the NanoDiffuser demo, use the ready-to-go prompt or enter your own, and select Generate image. Use a browser with WebGPU enabled.

How generation works

Prompt โ†’ CLIP tokenizer โ†’ Q4 CLIP encoder โ†’ FP16 text embeddings
Seed โ†’ Gaussian noise โ†’ one-step U-Net โ†’ scheduler update
                         โ†“
                   FP16 TAESD โ†’ pixels โ†’ canvas โ†’ PNG

The tokenizer runs locally through Transformers.js, pads or truncates the prompt to 77 tokens, and supplies an INT32 [1, 77] tensor. CLIP produces [1, 77, 768] text embeddings, which the browser converts to FP16 for the U-Net.

A seeded JavaScript random generator and Boxโ€“Muller transform create Gaussian noise with shape [1, 4, 64, 64]. The U-Net receives the scaled noise, text embeddings, and timestep 999. Its prediction is combined with the initial latent using coefficients saved from the one-step DEIS scheduler:

initial_latent = noise ร— initNoiseSigma
model_input   = initial_latent ร— modelInputScale
denoised      = sampleCoefficient ร— initial_latent
              + outputCoefficient ร— noise_prediction

The current manifest contains:

{
  "timestep": 999.0,
  "initNoiseSigma": 1.0,
  "modelInputScale": 1.0,
  "sampleCoefficient": 14.642590522766113,
  "outputCoefficient": -14.579278945922852
}

These values are part of this export's sampling contract. The browser uses the recorded values directly. It does not reconstruct Diffusers' scheduler internals or apply an extra classifier-free guidance pass.

The denoised latent is converted to FP16 and passed to TAESD. The decoder wrapper maps its output into [0, 1]; JavaScript converts the channel-first output into 8-bit RGBA pixels for the canvas and PNG export.

Fixed seeds make the JavaScript noise sequence repeatable. They do not imply pixel-identical results to PyTorch, which uses a different random generator, or across different browser/GPU implementations.

Conversion and quantization

The supplied sdxs512_webgpu_colab.ipynb exports three separate graphs using PyTorch's ONNX exporter, evaluation mode, constant folding, and fixed dimensions. Export starts with ONNX opset 17; the U-Net is subsequently set to opset 21 for its FP16 dequantization operations.

Component Conversion Graph + external weights
CLIP FP32 export; asymmetric Q4 weight-only quantization of eligible MatMul and Gather operations 63.36 MiB
U-Net FP16 export; mixed Q4 matrix weights and per-output-channel INT8 convolution storage 312.71 MiB
TAESD FP16 decoder export 2.36 MiB

Q4 quantization uses ONNX Runtime's weight-only quantizer with block size 128, asymmetric zero-points, QOperator format, and accuracy_level=2. Quantized matrix multiplication uses packed MatMulNBits weights. The graph checks require packed UINT8 zero-points.

U-Net convolution weights are quantized per output channel to signed INT8, with FP16 scales and a DequantizeLinear node before convolution. INT8 reduces weight storage; the convolution still executes in floating point. Input/output convolutions and timestep-projection MatMuls are excluded from their respective quantization passes and retain FP16 weights.

The U-Net uses Diffusers' explicit AttnProcessor during export. TAESD is loaded from the source checkpoint's vae subfolder; the export includes its decoder path.

Compatibility handling includes:

  • Keeping CLIP export and LayerNormalization parameters in FP32, then converting final embeddings to FP16 at the U-Net boundary.
  • A repair utility for older exports with mixed FP32/FP16 LayerNormalization parameters: test-site/scripts/repair_text_encoder_layernorm.py.
  • Normalizing reduction axes into attributes or inputs according to the graph's opset.
  • Using U-Net opset 21 so FP16 dequantization scales produce weights compatible with FP16 convolution inputs.
  • Removing unreferenced initializers and consolidating external weights into one .data file per graph.
  • Saving the tokenizer, fixed tensor shapes, filenames, and measured scheduler coefficients alongside the weights.

The Colab notebook is configured for a CUDA GPU, such as a T4. Its installation cell requests a session restart before export. Conversion can use several gigabytes of temporary disk space; the final release is much smaller. This conversion introduces no new training dataset.

Execution, memory, and caching

The browser pipeline uses onnxruntime-web/webgpu, NCHW layout, and ONNX Runtime graph optimization set to all. The current JavaScript dependency versions are ONNX Runtime Web 1.29.0 and Transformers.js 4.2.0. The source checkout's lockfile records the complete dependency versions.

Both the capability check and inference initialization request powerPreference: "high-performance". This asks the browser to prefer a discrete GPU, such as an NVIDIA RTX, on systems with integrated and discrete graphics. It is a preference; the browser and operating system retain the final selection. See the WebGPU adapter selection reference.

CLIP, U-Net, and TAESD sessions are created, run, and released sequentially to reduce peak GPU memory. Intermediate tensors are disposed when no longer needed. Model files can remain in browser memory, while GPU sessions are recreated on subsequent generations. This trades repeated initialization work for lower simultaneous GPU residency; the download size is not a VRAM requirement.

WebAssembly threading is set to one. The application does not require cross-origin isolation headers for WASM threads. Serve it over HTTPS or localhost so the browser can expose WebGPU; opening index.html directly as a local file is not the supported launch method. See ONNX Runtime's environment options.

The loader streams model downloads, checks file lengths, and stores assets in the browser's Cache API when available. A build-generated SHA-256 revision identifies the asset set and versions cache requests. Concurrent requests share the same pending model load; failed downloads can be retried, and truncated cached files are removed so retries can recover. Storage denial or quota errors do not prevent an uncached download.

Cache availability depends on browser policy, private browsing, available disk space, and eviction. Cached model files can avoid repeated network transfers, but they do not remove session initialization costs. No service worker is registered, and a fully offline page reload is not guaranteed.

Example prompts

Alpine lake (default)

vivid impressionist mountain landscape, crystalline turquoise lake surrounded by alpine meadows covered in blue purple yellow and red wildflowers, distant snow mountains softened by blue atmospheric haze, dramatic fluffy clouds catching warm sunlight, loose painterly brushwork, bright broken color, impasto texture, simplified forms, expansive peaceful composition

Sunlit garden

sunlit garden full of blooming flowers, stone path, small pond reflecting the sky, warm afternoon light, impressionist painting, oil on canvas, visible brushstrokes, soft broken color, luminous atmosphere, delicate painterly texture, elegant composition

Rainy Paris

rainy Paris street, pedestrians with umbrellas, reflections on wet pavement, glowing shop windows, soft evening light, impressionist painting, loose brushwork, atmospheric perspective, oil on canvas, muted colors, romantic mood, painterly texture

Wildflower meadow

woman walking through a meadow of wildflowers, flowing dress, summer breeze, bright sunlight, impressionist painting, oil on canvas, visible brushstrokes, luminous color, soft edges, natural light, poetic atmosphere

Flower bouquet

bouquet of wildflowers in a ceramic vase, scattered petals on a wooden table, warm window light, impressionist still life painting, oil on canvas, visible brushstrokes, rich painterly texture, beautiful color harmony

Hillside village

old European village on a hillside, stone cottages, narrow road, flowering trees, distant mountains, golden evening light, impressionist painting, oil on canvas, textured brushwork, warm colors, atmospheric perspective, timeless pastoral mood

Coastal sunset

quiet Mediterranean harbor at sunset, colorful fishing boats reflected in shimmering water, pastel houses along the shore, warm peach and golden sky, impressionist painting, oil on canvas, loose brushstrokes, bright broken color, rich painterly texture, peaceful composition

Autumn river

winding river through an autumn forest, golden birch trees and crimson leaves reflected in clear water, soft morning mist, sunlight filtering through branches, impressionist painting, oil on canvas, visible brushstrokes, luminous color, impasto texture, tranquil atmosphere

Performance and validation

NanoDiffuser generates an image in a single denoising step. The performance target is under 3 seconds on mid-tier consumer GPUs and capable mobile devices after model loading; this target has not been verified across devices.

The exporter includes ONNX structural checks, quantization checks, finite-output checks, and reference comparisons with minimum cosine similarity gates of 0.96 for CLIP embeddings and 0.90 for U-Net predictions. These are export acceptance thresholds, not measured benchmark scores or a general visual-quality rating.

Disclaimer

You're responsible for the content you generate. Do not use NanoDiffuser to create harmful or illegal content.

License

The converted weights retain their inherited OpenRAIL++ licensing requirements. Preserve applicable license and attribution notices when redistributing the files. Software dependencies retain their respective licenses.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support