Experiment — WebGPU

decision.js

An experiment: how fast can a browser run System One models? These are small models that make quick decisions (yes / no, pick an option, give a score) instead of writing text. decision.js is a small WebGPU inference engine written from scratch for them.

View playground →View code
Statea ticket, a form, any JSON
Questionsyes / no · choice · score
Model · WebGPUd1, d3-lite or EmbeddingGemma 2, no text generated
Answersdelivery96%billing3%bug1%

So far

const model = await Decision.load(url);
const { answers } = await model.systemOne(ticket, {
  topic: { type: "choice", instructions: "What is the topic?",
           criteria: { billing: null, delivery: null } },
  churn: { type: "noul",   instructions: "Is the customer about to leave?" },
});
// answers.churn → { noul: 0.83 }

How it works

1 · Every question in one pass, no padding

Each question becomes its own prompt. decision.js packs them end to end on one token axis and runs the whole batch as a single GPU command buffer; per-token metadata tells the attention which tokens belong together. Engines with static shapes pad every prompt to a fixed length instead.

decision.js
q1q2q3
static shapes
Same questions, same width per token. On d1-omni, padding was about a quarter of LiteRT.js's work.

2 · Weights converted once, then straight to the matrix units

The weights ship as 8-bit (half the download). At load time a GPU kernel turns them into f16 laid out in 8×8 blocks, the shape the GPU's matrix units read, so the matrix multiplication loads them directly with no dequantization in the hot loop (the design of Google's ML Drift).

weights.binq8 · 803 MB
Hugging Face, cached
Once, at loadq8 → f16
8×8 blocks
Matmulsubgroup matrices
≈ 93% of the chip's peak

3 · Where the time goes

Once the matrix multiplications run near the hardware's limit, everything else is small, so it is fused: each d3-lite DeltaNet layer (convolution, norms, gates, the recurrence and the gated norm) is a single kernel, and the MLP's activation runs inside its matmul.

matrix multiplicationsDeltaNet kernel · 8%attention · 4%the rest · 2%
GPU time of one d3-lite ticket (3 questions), kernel by kernel.

4 · Only the options are scored

A chat model would compute a score for every word of its vocabulary at every step. A decision needs one step and a few candidates: decision.js reads the hidden state at the answer position and scores only the options' codes.

Last tokenhidden state
1,024 values
3 dot productsA · B · C
not 248,320 words
SoftmaxA96%B3%C1%