DEV Community

GINIGEN AI
GINIGEN AI

Posted on Originally published at huggingface.co

Zero-Token Decisions in the Browser: On-Device Multimodal Classification with EmbeddingGemma 2 and WebGPU

TL;DR

Decide Live is a static web page that turns a camera frame, a microphone window, an image or a line of text into a typed decision, entirely in the browser. It runs a fine-tuned EmbeddingGemma 2 (Apache-2.0) through transformers.js on WebGPU, generates zero tokens, and never uploads anything. No server, no per-decision API call, weights cached once.

Why a decision should not be a generation

If a model needs to answer "is this egg fertile", "is this scene safe to proceed", or "which of these four states are we in", asking a chat model to write a sentence is the wrong tool. Generation is slow, non-deterministic, and every token is a chance to drift. A decision has a type: a class, a yes or no, a score. You want that type directly.

Decide Live produces it with an embedding model and a calibrated similarity, so the number of generated tokens is zero. This is the on-device form of what we call ZTC (Zero-Token Confidence).

How a decision is computed

Everything below is in the page and the model card, so you can reproduce it.

  1. Query embedding. The media placeholders come first, then task: classification | query: {question}, and \nContext: {context} when a context is given. The model embeds the media and the text together in one pass.
  2. Option embeddings. Each option is written as title: none | text: {description}, embedded once and cached.
  3. Pooling. Mean pooling over the attention mask, then L2 normalization, giving a 768-dimensional unit vector.
  4. Scoring. P(option) = softmax(scale * cosine(query, option)). The scale is learned, 19.96 (a temperature near 0.05), shipped in decision.json.
P(option_i) = softmax_i( 19.96 * cos(e_query, e_option_i) )
Enter fullscreen mode Exit fullscreen mode

No decoding loop appears anywhere in that path. One forward pass of the encoder per card, then a dot product.

The on-device stack

  • transformers.js 4.3.1 loads the model in a Web Worker and returns embeddings.
  • WebGPU runs the ONNX graphs, with a WASM (CPU) fallback when WebGPU is absent.
  • The ONNX files are shipped in q4f16 and in a portable q4 build (4-bit weights with plain 8-bit gathers, so the same files also run on the WASM runtime, which lacks GatherBlockQuantized), plus a 4-bit audio encoder. fp16 and fp32 are omitted to fit the 1 GB Space limit.
  • Weights download once and are cached by the browser. After that, decisions are local.

What you can actually do with it

  • Live: embed camera frames and score up to four decision cards, each with its own question, in the trained one-pass-per-card format. Each card shows probability bars, the current decision, and a confidence gate.
  • Microphone or sound file: the same cards over 2 second windows at 16 kHz mono; windows quieter than -55 dBFS are skipped.
  • Single input: one image, text, audio clip or short video, plus a question and 2 to 8 options written as key: description, or a yes/no question.
  • Sample tests: 18 image tests with gold answers, run in the browser with an accuracy report and a comparison of prompt formats.

Why this matters for edge AI

A decision that runs on the device is private by construction (camera frames and audio never leave the machine), free per call, and available offline after the first load. Pair that with the zero-token form and you can score every frame or every audio window without a cloud bill or a latency round trip. That is the shape of practical edge intelligence.

FAQ

Does anything get uploaded?
No. Camera frames, audio, images and text are processed on the device. Only the model weights are downloaded, once.

What model is behind it?
A decision fine-tune of google/embeddinggemma-2 (Apache-2.0), served as ONNX and run with transformers.js on WebGPU or WASM.

Why zero tokens?
The decision is a softmax over cosine similarity between a query embedding and option embeddings. There is no text generation, so it is deterministic and cheap.

Do I need a GPU?
No. WebGPU is used when available for speed; otherwise it falls back to CPU (WASM), slower but working.


Built by VIDRAFT / FINAL-Bench. Apache-2.0. Try it, then read the page source to see the whole decision path.

Top comments (0)