Byg privat ML i browseren med WebGPU og lokal vektorsøgning

Forestil dig, at du kan spørge din virksomheds interne vidensbase - eller din helt private journal - om alverdens ting … uden at én eneste byte forlader din computer

Ingen API-nøgler, ingen skygge-logning, ingen utryg ventetid på, at compliance-afdelingen nikker ja. Lyder det som science fiction? Det er det ikke længere.

Med WebGPU på de nyeste browsere, kompakte sprog- og embeddings­modeller i WASM og lynhurtige, lokale vektor­indekser kan du bygge en RAG-pipeline (Retrieval-Augmented Generation) der kører 100 % på klienten. Resultatet er en oplevelse, hvor maskinlæringen føles lige så flydende som en klassisk web­app - men hvor dine data forbliver dér, hvor de hører til: hos dig selv.

I denne artikel går vi fra de strategiske forretnings­argumenter til det helt lav­praktiske kode­grundlag og viser, hvordan du:

  • accelererer inferens med WebGPU,
  • embedder og søger i dokumenter med lokale vektor­indekser,
  • og til sidst binder det hele sammen i en elegant, offline-klar PWA.

Uanset om du sidder med GDPR-følsomme sundheds­data, vil bygge en personaliseret lige-i-browseren co-pilot, eller blot er nysgerrig på, hvad fremtidens edge-ML kan, så er der god grund til at læse med. Vi dykker ned i arkitektur­principperne, viser trin-for-trin hvordan du kommer i gang - og afslutter med tips til performans-tuning, sikkerhed og udrulning.

Klar til at opleve, hvordan privat ML i browseren kan revolutionere din næste løsning? Lad os springe direkte ud i det.

Byg privat ML i browseren med WebGPU og lokal vektorsøgning

Hvorfor privat ML i browseren med WebGPU og lokal vektorsøgning?

Privat maskinlæring direkte i browseren forener hastighed, sikkerhed og enkel udrulning. Når både embedding-beregninger, vektorsøgning og eventuel generering sker lokalt, slipper organisationer for datatransit til eksterne servere - og det åbner for helt nye anvendelser.

Forretningsværdi & centrale use cases

  • Personlige vidensbaser: Brugere kan indeksere egne noter, mails eller kode-snippets og få svar på sekunder - også på flyrejser.
  • Intern dokument-QA: Juridiske eller R&D-teams kan søge i konfidente PDF’er uden at materialet forlader pc’en.
  • Kunde- og sundhedsdata: Call-centre eller klinikker kan køre FAQ-assistenter på følsomme journaler uden risiko for datalæk.

Gdpr & compliance - Et arkitekturprincip

Hele pipeline-ideen bygger på “data stays on device”. Ingen serverlogs, ingen tredjepartstransit og intet behov for DPA’er. Resultatet er:

  • Kortere risikovurderinger og hurtigere godkendelser fra DPO’er.
  • Eliminering af Schrems II-problematikker ved cloud-overførsler til tredjelande.
  • Mindre angrebsoverflade og færre indsigtsanmodninger.

Teknologipakken i browseren

  • WebGPU - giver næsten native GPU-throughput til matmul og softmax på moderne kort.
  • WebAssembly (WASM) - kører C/C++/Rust-biblioteker sikkert i sandbox.
  • ONNX Runtime Web & Transformers.js - loader quantiserede BERT- eller MiniLM-embeddings på få hundrede MB/s.
  • WebLLM / MLC - bringer ~1-3 B parametre store LLM’er som phi-2 ind i fanebladet.
  • Web Workers - holder UI-tråden flydende under batch-inferens og baggrundsindeksering.
  • IndexedDB / OPFS - persisterer tokenizers, tjekpunkter og vektorindekser mellem besøg.
  • USearch-/HNSWlib-wasm eller SQLite WASM + vektor-extension - giver sub-100 ms ANN-slag selv på laptops.

Ydelse vs. Begrænsninger

  • GPU/VRAM-budget: 2-4 GB er nok til INT8-embeddings; større LLM’er kræver 6-8 GB.
  • Modelstørrelser & kvantisering: FP16 til præcision, INT8 til mobil; dynamic range kan påvirke semantisk afstand.
  • Første download/caching: 50-300 MB bliver typisk gemt i HTTP-cache + IndexedDB; “install as PWA” giver offline-mode.
  • Numerisk stabilitet: Browser-GPU’er varierer; brug ONNX-operatorer testet til WebGPU og fallback til CPU/WASM ved overflow.

Kompatibilitet og sikkerhedsmodel

Chrome / Edge kører WebGPU stabilt; Safari og Firefox er på “Origin Trial”/Nightly pr. Q2 2024. Alt afvikles alligevel i browser-sandboxen, så No Filesystem, No exec. Tilladelser kræves kun til PWA-features (notifikationer, filadgang).

Ux-overvejelser

  • PWA-indpakning: “Tilføj til startskærm” gør ML-assistenten til en offline desktop-app.
  • Progressiv enhancement: Ældre browsere falder tilbage til WebGL/CPU med langsommere, men fungerende søgning.
  • Streaming UI: Vis “GPU warm-up” og loader-progress for at undgå white-screen-effekt.

Kort sagt: Med WebGPU og lokal vektorsøgning kan organisationer høste AI-fordele uden at svække datasikkerheden - og uden at opsætte en eneste server.


Blueprint: Byg en privat RAG‑pipeline i browseren trin for trin

Første skridt er at sikre, at browseren kan køre din pipeline på GPU’en - og at den falder elegant tilbage, når WebGPU ikke er tilgængelig.

// Feature-detektionexport async function getDevice() { if ("gpu" in navigator) { try { const adapter = await navigator.gpu.requestAdapter(); if (adapter) return await adapter.requestDevice(); } catch (_) { /* ignore */ } } // Fallbacks: WebGL → CPU return "webgl2" in document.createElement("canvas") ? initWebGL() : initCPU();}
  • Start tunge beregninger i en Web Worker (eller DedicatedWorker) for at holde UI’et responsivt.
  • Brug streaming loading af modeller (HTTP Range + ReadableStream), så brugeren kan begynde interaktion, mens resten hentes.
  • Strukturér projektet med én worker til ML-kernal, én til I/O og evt. en tredje til UI-side kanal (Comlink gør det nemt).

Trin 2 - Modelvalg

Model Størrelse (fp16) Licens Typisk VRAM
e5-small-v2 40 MB Apache-2.0 ≈200 MB
MiniLM-L6-v2 60 MB MIT ≈250 MB
Optional reranker: cross-encoder/ms-marco-MiniLM-L-6-v2 120 MB MIT ≈450 MB
Lille LLaMA-variant via WebLLM (llama-2-7b-q4f16) ≈1,3 GB Meta (com-only) ≈4 GB

Kravet om at blive på klienten betyder, at INT8- eller 4-bit-kvantisering ofte er afgørende. ONNX Runtime Web understøtter pt. INT8 på WebGPU, mens Transformers.js gør det i JS/wasm-ringen.

Trin 3 - Indtagelse (ingestion)

  1. Chunk dokumenterne (f.eks. 512 tokens med 20 % overlap).
  2. Kør sprogdetektion (cld3 eller fastText wasm) → rute til korrekt tokenizer.
  3. Normaliser: fjern markup, fold Unicode, lowercase (behold case hvis du har case-sensitive modeller), fjern irrelevante boilerplates.

Trin 4 - Embeddings på enheden

import { env, pipeline } from "@xenova/transformers";env.useBrowserCache = true; // cache til IndexedDBenv.backends.webgpu = { // aktiver WebGPU-backend device: await getDevice(), dtype: "f16"};const embed = await pipeline("feature-extraction", "intfloat/e5-small-v2");const vectors = await embed("Dit chunkede input", { pooling: "mean" });
  • Batch så GPU’en fyldes (fx 32 × 512 tokens).
  • Reducer præcision til float16 eller INT8 for VRAM-budget < 2 GB.

Trin 5 - Lokal vektorsøgning

To populære muligheder:

  1. USearch / HNSWlib-wasm - ren wasm, hurtig buildtid, kræver manuelt persisterings-lag.
  2. SQLite wasm + vss-extension - forener ANN-indeks og metadata i ét ACID-sikkert DB-lag.
// Eksempel med USearchimport { Index } from "usearch";// dimension = 384 (MiniLM) eller 768 (e5-large)const index = new Index({ dimensions: 384, metric: "cos" });vectors.forEach((v,i) => index.add(i, v));await index.save("/ml/index.usearch"); // gem til OPFS

Læg filerne i navigator.storage.getDirectory() (OPFS) for at få næsten-native I/O. Husk schema-versionering - et simpelt schema.json med hash af model + paramètres lader dig invalidere cache og reindeksere.

Trin 6 - Forespørgsler

  1. Embed brugerens query (embed(query)).
  2. ANN-søg med k (typisk 5-20) og sæt ef højt nok til recall ≈0,9.
  3. Valgfrit: rerank top 50 med cross-encoder for bedre præcision.
  4. Samle top-k chunks til context window; kør prompt til lokal LLM eller send svaret direkte (FAQ-style).

Trin 7 - Optimering

  • Cache ONNX/WASM artefakter i CacheStorage + IndexedDB.
  • Warm-up: kørs få dummy-inferenser efter load for at kompilere shadere.
  • Shader-limits: på iOS begrænser WebGPU til 65535 threads - split batch hvis du rammer loftet.
  • Lazy loading: hent reranker/LLM først når brugeren slår “detaljeret svar” til.
  • Incremental ingestion: kør MutationObserver når nye dokumenter tilføjes, embed kun deltaen.

Trin 8 - Kvalitetsmåling

Du måler lokalt uden at opsamle rådata:

  • recall@k og MRR mod et lille held-out datasæt i localStorage.
  • Latency: log p50/p95 i Performance API og vis resultatet i Dev-overlay.
  • Kør A/B in-browser: tilfældig tildeling til model A/B, gem kun anonymiserede metrics (ingen prompts).

Trin 9 - Privatliv & sikkerhed

  • Krypteret lagring: brug SubtleCrypto + password/biometric gating til at kryptere OPFS-filer.
  • Ingen telemetri som default - brugeren slår det til eksplicit.
  • Trusselsmodel: sandboxet browser-miljø, men vær opmærksom på side-channel-angreb (Spectre) - undlad at køre samtidig utrustet tredjeparts-wasm.

Trin 10 - Udrulning

  1. Bundl WASM/ONNX som split chunks (vite/webpack dynamic import()).
  2. Host på et CDN med immutable + max-age=31536000; brug service worker cache-strategier (Cache First for modeller).
  3. Tilføj PWA manifest + serviceworker.js → offline-mode.
  4. Vis browser-supportmatrix (Chrome 113+, Edge 113+, Safari TP, Firefox Nightly flag).
  5. Observabilitet uden rådata: rapportér kun performance-events (navigator.sendBeacon) med hash’et feature-flags.

Resultat: Du har nu en fuldt klient-kørende RAG-pipeline, hvor alle brugerdata forbliver på enheden, og hvor du kun sender anonyme performance-tal. Det giver maksimal GDPR-ro i maven - og en UX, der føles næsten lige så hurtig som native apps.