← Back

Brimkern · Changelog

WebGPU-accelerated LLM inference, 100% in your browser.

August 14, 2026

Answers arrive about 40 % faster: the normalization step of every layer was running on a single GPU thread. Reasoning models no longer get stuck on “Thinking…”, the storage panel stops hoarding ranges that will never be read again, and a measured comparison with WebLLM is now online.

Faster answers

  • Every layer normalizes its values twice per token, and that step was written one row per thread — fine when reading your prompt (hundreds of rows at once), wasteful when writing the answer (one row, so 63 threads out of 64 idle). Rewritten to split the row across the whole workgroup: decoding goes from 36.0 to 49.5 tok/s (×1.38) on a Qwen3 0.6B, prompt reading unchanged.
  • The measurement that found it: a per-pass GPU profiler (?gpuprofile=1) added the same day, which showed normalization eating 51.9 % of decode time — twice the cost of the matrix multiplies it feeds.
  • On a 7B the same fix is worth ×1.27 (8.1 → 10.2 tok/s): the bigger the model, the more the matrix multiplies dominate, so normalization weighs less. That 7B is now in the catalogue — it is the model our published figures are measured on, and you can run it yourself.

Reasoning models: no more dead end

  • When a model stopped in the middle of its reasoning, the bubble stayed on “Thinking…” forever — no answer, no explanation, no way out. That state is now shown as a collapsible “Reasoning (interrupted)” block, the reply is marked as cut off, and a Continue button picks it back up.
  • Past reasoning is no longer sent back to the model on the next turn (the official Qwen3/R1 templates drop it too): the second-turn prompt shrank from ~240 to 68 tokens, leaving more room for the conversation itself.

Storage that stops growing for nothing

  • A model could occupy 239 MB of cache for a 149 MB file: pieces left behind by an older download plan, never read again but still counted against the browser quota that decides whether a model can be kept at all. They are now cleaned up automatically — only pieces fully contained in a larger one, so nothing you already have is lost.
  • Models whose download link carries a query string (a common Hugging Face form) were invisible to the storage panel, to “delete this model”, and to automatic cleanup. They are recognized again.

Llama, Mistral and SmolLM3 load differently

  • These three families order two of their attention matrices differently from the rest. Until now we rewrote those matrices at load time to match our kernel; the kernel now handles their convention directly. Llama 3.2, Ministral 3 and SmolLM3 were all re-checked and answer correctly either way (?ropenorm=0 restores the old path).
  • Consequence: these models can now be packaged as .brik. That rewrite was impossible on a quantized layout, which is why converting a Llama GGUF to .brik was refused.

The site

  • A measured comparison with WebLLM at /vs-webllm: same GPU, same 7B int4 model, prefill and decode side by side — including where WebLLM is ahead.
  • Accessibility: the four secondary pages carried contrast violations in dark mode that no audit had ever covered (the red used for solid buttons was also being used for small text). Eight pages × two themes now pass with zero violations.
  • On the French home page, the terminal panel stayed permanently faded because longer French sentences pushed it below the fold, where its scroll-driven appearance never completed. It now fades in with the rest of the hero.
  • The layer diagram now draws itself piece by piece as you scroll, and the measured figures count up when they come into view.
  • The SDK demo asked for “a short story” under a 100-token budget and stopped mid-sentence. It now asks for three sentences, and has the budget for them.
August 13, 2026

Any single-file GGUF from Hugging Face now runs here — paste an author/model and go. Decoding is 4× faster on large models, the first reply no longer costs ten seconds, the Llama family answers correctly again, and the site finally has a front door separate from the app.

A front door — and the app on its own address

  • The home page is now a real landing page explaining what the engine does; the chat lives at /chat. Links published earlier (?model=…) still land in the app.
  • A documentation hub at /docs gathers everything: loading a model, instant test links, the .brik format and its converter, the SDK, storage, diagnostics.
  • English is now the canonical version of the site (French at /fr), each language on its own indexable URL.

Any model from the Hub, in one paste

  • Paste author/model, a Hugging Face URL, or a direct .gguf / .brik link: the best quantization is picked for you and the tokenizer is read from the file itself — nothing to configure.
  • Large GGUFs stream by HTTP range instead of downloading whole: a 4.7 GB model reloads from cache in 15.8 s.

Speed

  • Decoding was reusing a kernel built for many tokens at once, leaving seven threads out of eight idle. A dedicated one: ×4.2 on 7B shapes (3.4 → 14.4 tok/s), ×2.4 on a 0.5B.
  • The first message of a session paid for moving the weights into VRAM (10.9 s on a 7B). A throwaway warm-up pass moves that cost off your first prompt: 1.1 s.
  • Prefill GEMMs are tiled and register-blocked in all three precisions: ×2–2.7 at kernel level, and ~1 TFLOP/s sustained on 7B shapes.

The Llama family answers correctly again

  • Llama 3.2 produced fluent nonsense. Cause: a load-time optimization (one HTTP range per layer) filled the weight cache directly, bypassing the row fix these models need on their Q/K matrices — so the chat path read mis-ordered weights. Fixed; Llama now answers correctly, and a CPU reference validates the engine layer by layer.

Everyday things

  • Models unused for 30 days are cleaned up automatically (adjustable, or off). The Storage panel now groups by model instead of listing hundreds of HTTP ranges.
  • Web search no longer fires on small talk, a truncated reply says so and offers Continue, and reasoning blocks are hidden by default.
  • Accessibility: 7 violations → 0 (contrast, form labels, landmarks, heading order), light and dark.
July 22, 2026

Brimkern goes open source (MIT) — and becomes embeddable: one <script> tag puts a local AI on your own site. The ultra-light chat no longer freezes, and video generation gets a resident engine plus a real WebM export.

Open source — the code is public

  • The entire engine is now on GitHub under the MIT license: WGSL kernels, the .brik format, the loaders, the app. New home: brimkern.romainkhanoyan.fr.
  • A product README with screenshots, and proper SEO plumbing (robots, sitemap, canonical domain).

Embeddable SDK (v0) — your site, your visitors’ GPU

  • One <script src="/sdk.js"> + Brimkern.embed({ system: … }) mounts a chat widget that runs a .brik model entirely on the visitor’s GPU: zero server, zero per-token cost, private, offline after the first load. Live example on /sdk-demo.html.
  • Configurable with a plain object: model (a hosted .brik URL), system prompt, title, greeting, accent color, token budget. The model only downloads when the visitor engages the widget — your PageSpeed is untouched.
  • It reuses the app’s fast path (resident GPU decode) and never interprets model output as HTML — plain text only, styles scoped to the widget.

LFM2.5 chat unfrozen — and 2.3× faster

  • Switching to LFM2.5 mid-conversation could freeze the tab: every token triggered ~100 GPU round-trips, and replaying the whole history multiplied them by thousands. The forward pass is now fully GPU-resident — one submission per token, one for the whole prefill.
  • Verified token-identical to the previous path before shipping, with an automatic fallback and a ?lfm2resident=0 switch. Measured: 13.5 → 31 tok/s on the same machine.

Video (lab) — resident engine, prompt enrichment, WebM export

  • The temporal (motion) modules now run entirely on the GPU in a single submission — 5× faster per module, with a CPU-verified fallback and ?videoresident=0.
  • Your short prompt is enriched by the local LFM2.5 model into a proper cinematic description before generation — better motion, still 100% on-device.
  • The result exports as a looping WebM clip of bounded duration (~10 s) instead of raw frames.

RWKV-7 joins the catalog — linear attention, constant memory

  • RWKV-7 G1 0.1B is loadable from the model browser: a 100% recurrent architecture where a fixed ~1 MB state replaces the KV cache — memory does not grow with the conversation. 128 MB, Apache-2.0, embedded World tokenizer, naive-but-honest replies (it is a 0.1B).

Mobile & housekeeping

  • The full model browser is now reachable on mobile with a “Change model” action — Qwen 3 0.6B and friends are one tap away, no longer desktop-only.
  • The storage gauge now shows the browser’s real quota (it depends on your free disk space) instead of an optimistic estimate, the misleading first-visit splash is gone, and the “GPU engine” card is more compact.
July 21, 2026

A second engine is born: linear-attention and hybrid models run in your browser. A 149 MB model that chats in French, a live demo on /local-ai — and the first video ever generated by Brimkern, entirely on your GPU.

LFM2.5 230M — the ultra-light that actually chats (mobile too)

  • New engine path for hybrid architectures (short-convolution + attention): LFM2.5-230M runs end-to-end on our WGSL kernels — 149 MB, replies in clean French, ~24 tok/s.
  • Available in the main chat as a preset — and on mobile, where you now pick between LFM2.5 (149 MB, recommended) and Qwen 0.5B (378 MB).
  • Every kernel validated against a CPU oracle, token-for-token vs llama.cpp before shipping.

Live demo on /local-ai — classify, extract & chat

  • Sentiment (12/12 on our benches), email extraction with an anti-hallucination guard (an email absent from your text is never invented), and a small French-speaking chat — all in your browser, cached after the first 149 MB download.
  • Constrained classification under the hood: the model can only answer within the allowed label set — the technique that makes tiny models reliable.

First video generated in the browser (lab)

  • 16 temporally-coherent frames (a fox walking through snow) in ~3.5 minutes, 100% local: AnimateDiff-Lightning motion modules grafted onto our existing image pipeline — zero new GPU kernels needed.
  • Still lab-only (dev bench) — the product UI, thermal pacing and WebM export are next.

Fixes & housekeeping

  • Reopening a conversation that contains images no longer auto-downloads the image model: only text models auto-load, your saved images display as-is.
  • “Cached” badge renamed “Downloaded” with a distinct solid style — no more confusion with the “Runs well” GPU verdict.
July 18, 2026

Brimkern learns to see: show it a photo and ask questions — entirely on your GPU. Refining an image now starts from its real pixels, and the last deferred kernel lands.

Vision (beta, desktop) — image + text → text

  • Qwen2-VL 2B runs fully in the browser: a 675M-parameter vision encoder (32 transformer layers, 2D rotary positions) reads your image as patches, a merger projects them into the language model, and the LLM answers your questions about it. Both weight files stream from Hugging Face and stay cached (~2.3 GB, desktop GPUs only).
  • Under the hood: two new position kernels (2D RoPE for the vision tower, M-RoPE for the language model) — the second one touches the chat hot path, so it only ever dispatches for this architecture and self-tests at load with a fallback that disables vision, never text.
  • In the model browser, the Qwen2-VL card is now loadable (desktop). Attach an image with the 📎 button and ask away — multi-turn works, everything stays local.

Two new brains in the catalog — Qwen 3, and Llama is back

  • Qwen 3 (4B and 0.6B): the next generation, clearly stronger than Qwen 2.5 at equal size, with native step-by-step reasoning — the thinking budget selector applies to it. Its QK-Norm architecture is self-tested at load like every kernel change.
  • Llama 3.2 is repaired and back in the catalog: llama.cpp permutes attention weights at GGUF conversion in a way our kernels didn’t expect — they are now un-permuted at load (all quantizations), and the llama3 long-context frequency scaling is applied. Measured: 178 t/s prefill, 19.5 t/s generation.

Real img2img — refine from the pixels

  • “Refine this image” used to replay the same starting noise; it now encodes the displayed image back into latent space (tiny 5 MB VAE encoder, fetched on first use), re-noises it partially and regenerates: composition is preserved from the actual pixels. Tune with ?strength= (default 0.55).
  • A refined image depends on its source pixels, so it can’t be regenerated from prompt+seed like the others — it is saved whole with the conversation.

Under the hood

  • The last deferred kernel is in: full (non-causal) attention now gives each (token, head) a 64-lane workgroup with online softmax — one pass over keys instead of two. Self-tested at real UNet shapes at load, silent fallback, ?attnfullwg=0 to force the old kernel.
  • Clearing the conversation history now really clears the screen (fresh chat), and the app no longer auto-reopens a conversation whose model isn’t cached — you land on a fresh home instead of a dead chat.
July 16, 2026

Long conversations get their speed back (up to ×26 on attention), the GPU can disconnect without killing the app, the model loads itself, and the interface adopts its print identity for good.

Attention rebuilt for decoding — the end of 1 t/s on long context

  • The attention kernel used a single GPU thread per head: 14 threads total while decoding — on hardware built for thousands. Past ~1,000 tokens of context it became the wall (~680 ms per token). New kernels give each head a full 64-lane workgroup with online softmax: ×14 to ×26 measured, identical results to 1e-7.
  • Belt and braces: at load time the engine self-tests the new kernels at real-world shapes; a GPU driver that miscompiles them falls back silently to the classic kernels (slower on long context, correct everywhere). ?attndecode=0 forces the fallback for diagnosis.
  • On mobile, answers are now deliberately concise (the phone shouldn’t heat up for a minute per reply), and the screen stays awake while the model works.

A GPU crash is no longer the end

  • When the system reclaims the GPU (long conversation, backgrounded tab, thermal pressure), the app used to keep running on a dead device — “ready” status, sends allowed, every compute failing. It now detects the loss, keeps your conversation, and offers real exits: reload the model, inspect/clear storage.
  • WebGPU detection retries before giving up, and “Unsupported” now explains the #1 cause: hardware acceleration disabled in the browser — with the exact setting to flip.

The model loads itself

  • Reopening the app resumes your last conversation AND its model when it’s fully cached (streamed BRIKs included — desktop and mobile alike, zero network). Partially downloaded? The background prefetch finishes the job — with real progress shown on the first-visit splash — then loads the model on its own.
  • Fixed along the way: the background prefetch could silently die before ever starting, and an auto-load at startup mistook the phone for a desktop (loading f16 instead of the mixed format).

Image generation slims down — and lands on mobile

  • The image pipeline downloaded 2.4 GB of fp16 weights, then quantized them to int8 on your GPU at every load. The weights now ship pre-quantized and range-streamed (resumable, cached): 1.28 GB on desktop, identical output — verified numerically AND visually against the old path.
  • New on mobile (beta): “Try image generation” loads SDXS-512, a distilled 1-step UNet, in an int4 “light” build with a lightened text encoder — ~445 MB all-in for a native 512px image. Judged side-by-side against the heavy build: near-identical.

“Le Kern”, fully inked

  • The display face becomes Fraunces (a printer’s serif — the kern-B mark, titles and splash carry it), a red printer’s rule crowns the app, the caret and text selection turn Kern red, and the welcome screen reads like a type specimen. The last purple remnants and gradients are gone.
  • Mobile decluttered: the BRIK-conversion banner is gone (the mixed model is served automatically), and a single starter suggestion leaves room for the model’s welcome message.
July 15, 2026

The mobile model gets int8 quality at nearly the int4 size (new “mixed” format), downloads itself in the background while you read the home screen, and greets first-time visitors properly.

Mixed quantization — int8 quality, (almost) int4 size

  • A tensor-by-tensor A/B study showed WHERE int4 breaks a small model: full-int4 produces nonsense, but keeping just the attention matrices in int8 restores int8-grade quality. The new “mixed” format stores exactly that: int4 body + int8 attention.
  • The mobile model is served in mixed format: 377 MB instead of 508 (full int8) — for +18 MB over the old int4 file that degraded it. The diagnostics strip shows “mixed int8+int4” honestly.
  • The “Mixed” profile is also available in both BRIK converters (recommended for small models — int4 stays for the big ones).

The download disappears into the background

  • On mobile, if the model isn’t (fully) cached yet, its download now starts by itself shortly after you arrive — by the time you tap “Load the model”, most of it is already local. Resumable: a closed tab only re-downloads what’s missing.
  • Visible and polite: a progress line with a Cancel link, nothing starts if your phone’s Data Saver is on, and any real load takes over instantly.
  • First visit on mobile: a short welcome screen (“Preparing your AI space…”) covers the kickoff — tap to skip, never shown again.

Under the hood

  • Prompts are no longer re-tokenized from scratch on every message: only the new turn is tokenized (~×90 faster on long histories).
  • Generated images no longer freeze the page for ~100 ms after rendering (async PNG encoding).
July 6, 2026

Mobile finally smooth and reliable: ~4× faster conversations (KV cache reused across turns, GPU-side sampling), int8 by default, and a Settings panel.

Faster conversations — especially on mobile

  • The attention (KV) cache is now reused from one message to the next: only your new message is processed, never the full history again. Previously every turn re-read the entire conversation — response time doubled from the 2nd message on; it is now constant.
  • Next-token sampling now runs on the GPU (softcap, repetition penalty and top-K fused into the same pass as the forward computation): ~600 KB read back per token → 512 bytes. Self-tested at load time, with automatic fallback to the CPU path if the device’s GPU fails the test.
  • Leaner generation loop: end-of-text detection on the last few tokens only, and the display refreshes ~8×/s (instead of a full re-detokenization and re-render on EVERY token, which choked phones). Only the bubble being typed re-renders.
  • Measured on a phone (Qwen 0.5B): full response in ~10 s instead of 20–38 s, generation at ~5 t/s instead of 2.7.

Mobile quality — int8 by default

  • Small models (≤ ~1.2B parameters) now load in int8 on mobile instead of int4: int4 severely degraded a 0.5B (nonsensical answers, repetition loops) while it easily fits in int8. int4 stays reserved for large models that would not fit otherwise.
  • And the attention cache stays in f32 by default (faster): its int8 variant — which adds work on every token — is only enabled where its VRAM savings really matter (large models, int4).
  • New diagnostics strip under every response: actual precision, KV cache format, sampling path and context reuse — so you can see what actually ran, even without a console. And it tells the truth: when the model file is more quantized than the requested precision, it shows e.g. “int8 (source int4)”.
  • Persistent storage is now requested from the browser: the cached streamed model should no longer be evicted between sessions on mobile.

Image pipeline — even leaner

  • The text encoder (CLIP) joins the UNet: int8-quantized, GPU-resident, executed in a single submission — no more ~280 round trips and ~500 MB of weights re-uploaded to the GPU for every image.
  • The image model now loads without freezing: fp16 weight conversion happens on the GPU (the tab used to lock up for ~10 s on every load).
  • GPU memory is released after each image (the scratch buffer used to hold on to hundreds of MB), and the image pipeline is fully freed (~1 GB) when a text model is loaded.
  • Faster 512px decode: the dominant 3×3 convolutions now run as a tiled kernel with shared memory (each pixel read once instead of 9×, each weight once instead of 256×), and group normalization uses 4× more threads. Both self-tested at load with automatic fallback.

Web & tools (MCP) — first steps, fully transparent

  • Optional web search (OFF by default): the model draws on Wikipedia excerpts and cites its sources. Only your question is sent — never the conversation. Flagged under every affected response and in the input bar.
  • Local calculator (ON by default, no network): arithmetic in your messages is evaluated exactly on-device and the result handed to the model — small models systematically get arithmetic wrong. The model also knows today’s date.
  • Pasted-link reading (OFF by default): paste a URL and the model reads the page (via the r.jina.ai reader — noted on the option).

Settings & fixes

  • New “Settings” panel in the sidebar: GPU power (Eco / Balanced / Max — keeps heat in check during image generation) and the Web & tools options above.
  • Fully bilingual interface: the FR/EN toggle now covers the entire application (panels, errors, loading steps, tooltips…) — including this changelog.
  • Snappier streamed model loading: a layer’s weights are fetched in a single request instead of 9–12 (~25 requests instead of ~220 for a whole model).
  • The loading screen is now a real log: opaque background and a list of the actual steps (download, quantization, validation) with their progress.
  • Auto-scroll respects your reading: if you scroll up while the AI is writing, you are never yanked back to the bottom — it resumes once you scroll back down.
  • Fixed: loading a text model on top of image mode did not switch over — messages were still sent to image generation (and the image pipeline stayed in memory).
  • Diagnostic switches in the URL (?gputopk=0, ?kvreuse=0) to isolate device-specific issues.
July 2, 2026

100% in-browser image generation (SD-Turbo on hand-written WGSL), int8-quantized GPU-resident UNet, thermal throttling — and a new visual identity.

Image generation — Stable Diffusion Turbo, 100% local

  • New image mode in the chat: describe an image and it is generated entirely in the browser — CLIP (prompt encoding), UNet (denoising) and the TAESD decoder all run on our own WGSL kernels, with no server involved.
  • Prompt fidelity fixed against the diffusers reference: tokenizer padding (“!”, not <|endoftext|> — with no attention mask, all 77 positions count) and CLIP’s final LayerNorm now applied. Result: images that actually match the request.
  • Per-generation quality selector above the input area: 128px (fast), 256px (recommended) or 512px (SD-Turbo’s native resolution).
  • Lightweight conversations: only a blurred thumbnail + the prompt + the seed are persisted; “click to reveal” regenerates the exact same image (deterministic generation) without ever storing the pixels.
  • Weights (UNet + CLIP fp16, TAESD) are cached by the browser on first load → no download on subsequent runs.

Performance & thermals — resident int8 + throttling

  • UNet quantized to int8 (BRIK8) directly on the GPU at load time: ~0.9 GB of VRAM instead of ~3.4 GB in f32, and no more weight re-uploads per image (previously: ~3.4 GB re-transferred per generation). New int8 conv2d kernel with fused dequantization, covered by the self-test.
  • End-to-end GPU-resident execution: activations stay on the GPU across all blocks (UNet and decoder), with a single CPU readback per denoising step → far fewer round trips, more efficient generation.
  • Built-in thermal throttling: the pipeline measures the GPU time actually consumed and inserts proportional pauses (~60% target load) — generation smooths out its power draw instead of heating up the machine in one continuous burst.
  • Detailed progress during generation (current denoising step + UNet block).

New identity — “Le Kern”

  • Goodbye purple and gradient logo: enter a paper / ink / printer’s-red identity, a nod to the typographic kerning in brimKERN. Matching “ink” dark mode.
  • Logo redrawn as flat SVG (a massive B notched by a diagonal kern): crisp at every size, follows the light/dark theme, and replaces 700 KB of PNG.
  • Favicon and share card (OpenGraph) updated to the new identity.

Cleanup

  • Removed the “preview” placeholder image generator, the Llama 2/3 prompt templates unreachable since Llama was pulled, and unused assets — lighter bundle.
June 25, 2026

Gemma 2 fully working, automatic tokenizer matching, conversation resume, prefill performance (tiled matmul), Skills, a richer storage panel and a bilingual FR/EN interface.

Gemma 2 — fully working

  • Coherent generation on Gemma 2 (2B): fixed a numeric overflow in the GELU activation (which produced NaNs) and the double application of the (1+w) RMSNorm — the cause of the garbled text.
  • Automatic tokenizer + architecture matching from the GGUF file: loading a model can no longer mistakenly use another model’s tokenizer (a vocabulary mismatch produced gibberish even though the math was correct).
  • Reusable foundation for adding more local model families (next target: Microsoft Phi-3.5-mini).

Model selection & storage

  • Full resume on open: the last conversation is reloaded and, if the model it used is already cached, it is reloaded automatically (no network) → you land straight back in a ready-to-chat session.
  • New wide-format “Browse models” picker with search (name, use case, tag) and a grid — far more readable than the cramped list as the catalog grows.
  • Badges on every model: “● cached” (already downloaded locally), “BRIK recommended” (≥ ~1.5B: 2–4× less VRAM + instant reopens), and an indicator on the currently loaded model.
  • Storage panel: the active model is highlighted, a “loaded” badge marks the matching BRIK, and a “Delete all” button clears everything (caches + BRIK + history).
  • Roadmap: preview of the next architecture to be ported to our kernels (Microsoft Phi-3.5-mini).

Interface — unified model picker

  • All model selection now goes through a single fixed-size “Choose a model” window (internal scroll): a Models tab (grid + search + creator/modality per tile) and an Import tab (local file, GGUF URL, .brik stream), with the “Convert to BRIK” checkbox.
  • Leaner chat header: shortened model name (tooltip on hover), language/theme toggle moved next to the logo, and dev options (precision/VRAM, KV cache, benchmark) folded into an accordion closed by default.
  • Multimodal roadmap preview (Microsoft Phi-3.5, Mistral, Stable Diffusion, Qwen2-VL) as “coming soon” cards.

Performance & conversion

  • Tiled q8/q4 matmul for prefill: each invocation computes 4 tokens at once, dequantizing each weight only once → ~4× less weight memory traffic during prompt processing.
  • Streaming GGUF → BRIK conversion (shard by shard): peak memory ≈ one layer instead of the whole model → large models convert in the browser without exhausting RAM.
  • Llama temporarily removed from the offered architectures (RoPE incompatibility with weights permuted by llama.cpp → incoherent output); it will return with a suitable RoPE mode. Active architectures: Qwen 2/2.5, Gemma 2, DeepSeek-R1 (Qwen distill).

Skills — reusable instructions

  • A library of “skills” (personas / system instructions): built-ins + your own skills, persisted locally.
  • Multi-select (skills combine), import from a GitHub URL, and a popup reachable via a button to the left of the chat bar.

Storage management

  • “Storage” panel: see the space taken by streamed models, downloaded GGUFs, converted BRIKs and chat history — with per-item deletion.

Mobile & bilingual

  • Simplified mobile: a single ready-to-use model (streamed Qwen 0.5B BRIK), a download progress bar, and the chat area shows while loading.
  • Bilingual interface: French (default) / English, toggle in the header, remembered.
June 24, 2026

Self-contained BRIK: hosted models, embedded tokenizer, lighter files — and optimized mobile loading.

Self-contained BRIK, hosted & mobile-optimized

  • Tokenizer embedded in the .brik → 100% offline loading, no external fetch and no manual tokenizer selection.
  • Tied embeddings deduplicated (output = token_embd) → file ~⅓ smaller, with no quality loss.
  • Pre-converted Qwen 2.5 0.5B model, hosted and streamed via HTTP Range (low VRAM) → optimized direct loading, on mobile and desktop alike.
  • More reliable GGUF → BRIK conversion: very large tensors are processed in slices so they no longer exceed the GPU buffer limit (which silently corrupted weights).
  • Adjustable thinking level (off / low / medium / high) for reasoning models; catalog narrowed to fully supported architectures (Qwen, Gemma, DeepSeek).

BRIK v2 format — lighter & streamable

  • Web-native BRIK8 (int8) and BRIK4 (int4) quants: dequantization fused into the GPU matmul (weights kept quantized in VRAM), small download AND fast inference.
  • Single self-contained .brik file (header + manifest + 16-byte-aligned data) replacing .brik.zip — one file to host/load.
  • HTTP Range streaming: only the header (manifest) is fetched first, then each tensor on demand, cached (Cache API) → instant, offline reloads.
  • Embeddings stored in int8 (often the largest tensor) → markedly smaller download and VRAM, with near-identical quality.

Longer context — q8 KV cache

  • Optional int8 attention (K/V) cache: ~4× less cache VRAM → up to ~4× more context at equal VRAM, near-f16 quality.
  • “KV f32 / KV q8” toggle in the precision setting (dequantization fused into attention, with no f32 expansion).

New architectures

  • Gemma 2 supported by the optimized kernels: attention + logit softcapping, GELU activation, dual “sandwich” norms, (1+w) RMSNorm, embedding scaling, head_dim ≠ d/heads.
  • Kernels made parameterizable (attention scale, activation, norms) — a reusable foundation for other model families.

Loading & caching

  • Automatic GGUF → BRIK conversion at load time (optional): done once, then the converted .brik is cached (IndexedDB) for instant opens.
  • Dedicated conversion page with converted-model cache management (list / delete).
  • Weight precision clarified: GGUF in f16/f32, BRIK8/BRIK4 tiers reserved for BRIK models.

Robustness & fixes

  • Fixed a GPU dispatch overflow on long prompts (> ~860 tokens) that produced incoherent output — now spread across a 2D grid.
  • Token counter + context warning in the composer.
  • Large pastes collapse to a “snippet” in the input field (the full text is still sent to the model).
  • UI fixes: no more lingering focus ring on click, message bubbles no longer break short words.
June 23, 2026

First release — an LLM inference engine written from scratch, 100% in the browser.

Custom WebGPU engine

  • Hand-written WGSL compute kernels: vectorized matmul (128-bit vec4), RMSNorm, RoPE, causal GQA attention with KV cache, SwiGLU.
  • GGUF parsing directly in JavaScript and weight dequantization on the GPU.
  • GPU-resident decode path: a token’s entire forward pass chained into a single GPU submission.
  • Kernel self-validation at load time (selfValidate): the model only loads if the math checks out.

Performance

  • Logit projection cached on the GPU instead of being recomputed for every token.
  • Next-token argmax computed on the GPU (a single integer read back per token instead of ~152k logits).
  • Buffer pool reused across tokens. Overall result: ~2.5× faster decoding.

Weight precision (switchable)

  • f32 — full precision (quality reference).
  • f16 — half precision: ~1.25× faster, half the VRAM (GPU-dependent).
  • int4 (BRIK “q4web” format) — on-the-fly dequantization, ¼ of the VRAM → lets you load larger models in the browser.

Models & quantizations

  • Models: Qwen 2.5 (0.5B, Coder 1.5B), Llama 3.2 1B, DeepSeek-R1 Distill Qwen 1.5B (<think> reasoning).
  • GGUF quantizations supported: Q4_0, Q4_K, Q5_0, Q5_K, Q6_K, Q8_0, F16, F32.
  • Import any compatible GGUF (local file or Hugging Face URL).

Interface

  • Chat with Markdown rendering (bold, italics, lists, headings) plus syntax highlighting and copy on code blocks.
  • Persistent conversation history (IndexedDB), independent of the loaded model.
  • Built-in benchmark comparing f32 / f16 / int4, plus a precision selector.
  • Collapsible sidebar, mobile-friendly interface.

Privacy

  • No data ever sent to a server: the model and all computation run entirely on your GPU, offline once the model is downloaded.

Brimkern — open WebGPU engine, built by Romain Khanoyan. Local AI, WebGPU, on-device engines.