working wasm version and candle
it runs in the browser now!! like, actually. wasm target, Slint rendering to a canvas, the whole thing. I’ve been dreading the wasm build this whole project and it just… went. mostly.
the big win here is model caching, because downloading a ~130MB embedding model every single page load is obviously insane. so there’s a model_cache module now that’s the same two functions (get/put) with two backends behind cfg: native writes the bytes to a temp dir, wasm shoves them into the browser’s Cache API. first launch downloads and stashes, every launch after just pulls from cache. same idea as before but now it works on both sides.
to make that clean I split CandleEmbedder::load() into two pieces: from_bytes() that takes raw model/config/tokenizer bytes and builds the thing, and load() (native only) that downloads then calls from_bytes. so the wasm path can grab bytes from cache (or fetch them itself) and hand them straight to from_bytes without the reqwest download dance. Candle running on CPU in wasm, no GPU, producing the same 384-dim vectors. genuinely did not expect that to just work.
the wasm caching code is… a lot of JsFuture and dyn_into and web_sys ceremony. open the cache, build a Request, match it, pull the arraybuffer, convert to a Uint8Array, to_vec. and the put side builds a fake 200 Response with the bytes as the body and stuffs it in. it’s verbose but it’s the standard, nothing clever.
the UI crate is a cdylib now (plus rlib) so it can compile to wasm, tokio features got split per-target (no rt-multi-thread in the browser, obviously), and there’s a tiny index.html that just imports the generated js and calls init(). Slint paints onto a <canvas id="canvas">
also wrote an inference benchmark test… all you need to know
so yeah. desktop AND browser, same codebase, real ML embeddings on both.
the “true cross-platformity” thing from the very first devlog is… actually real now?
that rule I set on day one about no #[cfg] in the interfaces paid off HARD here, the only cfgs are tucked inside the cache and download internals where they belong.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.