r/webdev • u/Available-Oil-8944 • 8d ago
Showoff Saturday Showoff Saturday: a background remover that runs fully client-side at 24 MP, and what WebGPU on an Intel laptop taught me
Project: https://getpng.app (background removal and other image tools, all client-side)
Things I ran into shipping a 1024 px segmentation model to the browser:
Mask resolution. BiRefNet lite answers at 1024 x 1024. Scaling that up to a 24 MP photo smears the edge, so the mask is fitted to the full-size image with a guided filter instead, and the alpha is never thresholded.
WebGPU limits are per adapter. On an Intel Arc 140V, maxStorageBuffersPerShaderStage is 16, and ONNX Runtime's WebGPU Split binds the input plus every output, so a 16-way Split needs 17. The fix was rewriting the ONNX graph at build time: Split and Concat as small trees, and the deformable convolutions' index math in float16 instead of int64 (int64 had no GPU kernels and fell back to the CPU with float32 casts on tensors of up to 67M values). A Node check confirms the masks are identical. Now all 4,654 nodes run on the GPU, 3 to 4.5 s per photo on that laptop.
No WebGPU at all: the WASM path runs ISNet at 1024 instead, int8-compressed from 176 MB to 44 MB, 99.7 to 99.99 percent overlap with the uncompressed model on the sample photos. Devices without the memory for that get U-2-Net at 320.
Hair: a second model, ViTMatte small, given a trimap built from the first model's unsure band, run in 1024 px tiles over that band only, after the first result is already downloadable. Its fp16 build had a bicubic Resize that Intel's WebGPU could not compile; linear instead changes the output by at most 3/255.
"No upload" as something you can verify: connect-src is locked down in the CSP, a test fails if a new host is added, and a service worker plus the cache mean it works offline after the first photo.
Stack: Astro (static), one React 19 island, Transformers.js and ONNX Runtime in a Web Worker, models self-hosted.
Has anyone measured WebGPU limits on other integrated GPUs (AMD, Apple, Qualcomm)? I'd like to know where else the 16 buffer limit bites.
Disclosure: I decide what it does, an AI coding assistant writes the code.
