WebLLM: Hoogwaardige In-Browser LLM Inference Engine

WebLLM is volledig compatibel met de OpenAI API. Dit betekent dat u dezelfde OpenAI API kunt gebruiken op diverse open-source modellen lokaal, met functionaliteiten zoals streaming, JSON-modus, function-calling (in ontwikkeling), enzovoort.

Dit opent talrijke mogelijkheden voor het bouwen van AI-assistenten voor iedereen, waarbij privacy gewaarborgd blijft terwijl er toch gebruik wordt gemaakt van GPU-versnelling. WebLLM kan worden gebruikt als een basis npm-pakket waarop u uw eigen webapplicatie kunt bouwen. Dit project is een begeleidend project van MLC LLM, wat universele implementatie van LLM's over verschillende hardwareomgevingen mogelijk maakt.

Belangrijkste Kenmerken

  • In-Browser Inference: Een hoogwaardige engine die WebGPU gebruikt voor hardwareversnelling, waardoor krachtige LLM-operaties direct in de browser kunnen plaatsvinden zonder server-side verwerking.
  • Volledige OpenAI API Compatibiliteit: Integreer uw applicatie naadloos met WebLLM via de OpenAI API, inclusief functionaliteiten zoals streaming, JSON-modus, controle op logit-niveau, seeding en meer.
  • Gestructureerde JSON-generatie: Ondersteuning voor state-of-the-art JSON-modus gestructureerde generatie, geïmplementeerd in het WebAssembly-gedeelte van de modellib voor optimale prestaties.
  • Uitgebreide Modelondersteuning: Native ondersteuning voor een breed scala aan modellen, waaronder Llama 3, Phi 3, Gemma, Mistral, Qwen (通义千问) en vele anderen.
  • Integratie van Custom Modellen: Eenvoudige integratie en implementatie van aangepaste modellen in MLC-formaat, waardoor WebLLM kan worden aangepast aan specifieke behoeften en scenario's.
  • Plug-and-Play Integratie: Eenvoudige integratie in projecten via pakketbeheerders zoals NPM en Yarn, of direct via CDN, inclusief uitgebreide voorbeelden en een modulair ontwerp voor koppeling met UI-componenten.
  • Streaming & Real-time Interacties: Ondersteunt streaming chat completions, wat real-time outputgeneratie mogelijk maakt en interactieve applicaties zoals chatbots en virtuele assistenten verbetert.
  • Web Worker & Service Worker Ondersteuning: Optimaliseer UI-prestaties en beheer de levenscyclus van modellen efficiënt door berekeningen uit te besteden aan aparte worker-threads of service workers.
  • Chrome Extension Ondersteuning: Breid de functionaliteit van browsers uit via aangepaste Chrome-extensies met WebLLM.

Ingebouwde Modellen

WebLLM ondersteunt een subset van de beschikbare modellen op MLC Models (te vinden via prebuiltAppConfig.model_list). De belangrijkste ondersteunde modelfamilies zijn:

  • Llama: Llama 3, Llama 2, Hermes-2-Pro-Llama-3
  • Phi: Phi 3, Phi 2, Phi 1.5
  • Gemma: Gemma-2B
  • Mistral: Mistral-7B-v0.3, Hermes-2-Pro-Mistral-7B, NeuralHermes-2.5-Mistral-7B, OpenHermes-2.5-Mistral-7B
  • Qwen (通义千问): Qwen2 0.5B, 1.5B, 7B

Voor meer modellen kunt u een verzoek indienen via een issue of de sectie Custom Models raadplegen om uw eigen modellen te compileren.

Snelstart met Voorbeelden

Leert u hoe u WebLLM kunt integreren in uw applicatie via het eenvoudige Chatbot-voorbeeld. Voor een geavanceerder voorbeeld van een groter project kunt u kijken naar WebLLM Chat. Meer voorbeelden voor verschillende use cases zijn beschikbaar in de examples map.

Aan de Slag

WebLLM biedt een minimalistische en modulaire interface om de chatbot in de browser te benaderen. Het pakket is modulair ontworpen om aan elke UI-component te worden gekoppeld.

Installatie

Via Pakketbeheerder

# npm
npm install @mlc-ai/web-llm
# yarn
yarn add @mlc-ai/web-llm
# of pnpm
pnpm install @mlc-ai/web-llm

Importeer vervolgens de module in uw code:

// Importeer alles
import * as webllm from "@mlc-ai/web-llm";
// Of importeer alleen wat nodig is
import { CreateMLCEngine } from "@mlc-ai/web-llm";

Via CDN-levering

Dankzij jsdelivr.com kan WebLLM direct via een URL worden geïmporteerd, wat direct werkt op cloud-ontwikkelingsplatforms zoals jsfiddle.net, Codepen.io en Scribbler:

import * as webllm from "https://esm.run/@mlc-ai/web-llm";

Het kan ook dynamisch worden geïmporteerd:

const webllm = await import("https://esm.run/@mlc-ai/web-llm");

Create MLCEngine

De meeste operaties in WebLLM worden aangeroepen via de MLCEngine interface. U kunt een instantie van MLCEngine maken en het model laden door de factory-functie CreateMLCEngine() aan te roepen.

(Let op: het laden van modellen vereist downloaden en kan bij de eerste keer zonder caching aanzienlijke tijd in beslag nemen. Behandel deze asynchrone aanroep correct.)

import { CreateMLCEngine } from "@mlc-ai/web-llm";

// Callback-functie om de voortgang van het laden van het model bij te werken
const initProgressCallback = (initProgress) => {
  console.log(initProgress);
};

const selectedModel = "Llama-3.1-8B-Instruct-q4f32_1-MLC";
const engine = await CreateMLCEngine(
  selectedModel,
  { initProgressCallback: initProgressCallback }, // engineConfig
);

Onder de motorkap voert deze factory-functie de volgende stappen uit: eerst het maken van een engine-instantie (synchroon) en vervolgens het laden van het model (asynchroon). U kunt deze stappen ook apart uitvoeren in uw applicatie:

import { MLCEngine } from "@mlc-ai/web-llm";

// Dit is een synchrone aanroep die onmiddellijk terugkeert
const engine = new MLCEngine({
  initProgressCallback: initProgressCallback,
});

// Dit is een asynchrone aanroep en kan lang duren
await engine.reload(selectedModel);

Cache Backend Beleid

WebLLM ondersteunt vier cache-backends via AppConfig.cacheBackend:

  • "cache": Browser Cache API (standaard).
  • "indexeddb": Browser IndexedDB.
  • "opfs": Browser Origin Private File System (OPFS).
  • "cross-origin": Experimentele Chrome Cross-Origin Storage API extensie backend. Installeer de Cross-Origin Storage extensie om dit te gebruiken (valt anders automatisch terug op de standaard cache).

Voorbeeld:

import { CreateMLCEngine, prebuiltAppConfig } from "@mlc-ai/web-llm";
const appConfig = { ...prebuiltAppConfig, cacheBackend: "cross-origin" };
const engine = await CreateMLCEngine("Llama-3.1-8B-Instruct-q4f32_1-MLC", {
  appConfig,
});

Opmerkingen:

  • Als "opfs" is geselecteerd in een omgeving zonder OPFS-ondersteuning, mislukken cache-operaties met een OPFS-beschikbaarheidsfout.
  • Bij gebruik van "opfs" kan appConfig.opfsAccessMode worden ingesteld op "auto" (gebruik sync access handles waar ondersteund) of "sync" (vereis sync access handles). Standaard is dit "async".
  • De "cross-origin" backend vereist een compatibele browser-extensie.
  • De cross-origin backend ondersteunt momenteel geen programmatische verwijdering van tensor-caches; opschonen wordt beheerd door de extensie.

Chat Completion

Na succesvolle initialisatie van de engine kunt u chat completions aanroepen met OpenAI-stijl chat API's via de engine.chat.completions interface.

(Opmerking: de model parameter wordt hier niet ondersteund en genegeerd. Gebruik in plaats daarvan CreateMLCEngine(model) of engine.reload(model).)

const messages = [
  { role: "system", content: "You are a helpful AI assistant." },
  { role: "user", content: "Hello!" },
];
const reply = await engine.chat.completions.create({
  messages,
});
console.log(reply.choices[0].message);
console.log(reply.usage);

Streaming

WebLLM ondersteunt ook streaming chat completion. Geef hiervoor stream: true mee bij de aanroep.

const messages = [
  { role: "system", content: "You are a helpful AI assistant." },
  { role: "user", content: "Hello!" },
];

// Chunks is een AsyncGenerator object
const chunks = await engine.chat.completions.create({
  messages,
  temperature: 1,
  stream: true, // <-- Streaming inschakelen
  stream_options: { include_usage: true },
});

let reply = "";
for await (const chunk of chunks) {
  reply += chunk.choices[0]?.delta.content || "";
  console.log(reply);
  if (chunk.usage) {
    console.log(chunk.usage); // Alleen de laatste chunk bevat usage
  }
}
const fullReply = await engine.getMessage();
console.log(fullReply);

Geavanceerd Gebruik

Gebruik van Workers

Om de prestaties van uw applicatie te optimaliseren, kunt u zware berekeningen in een worker-script plaatsen. Hiervoor moet u:

  1. Een handler in de worker-thread maken die communiceert met de frontend.
  2. Een Worker Engine in uw hoofdapplicatie maken, die berichten naar de handler in de worker-thread stuurt.

Dedicated Web Worker

WebLLM biedt API-ondersteuning voor WebWorkers, zodat het generatieproces in een aparte worker-thread kan plaatsvinden zonder de UI te verstoren.

Worker-thread (worker.ts):

import { WebWorkerMLCEngineHandler } from "@mlc-ai/web-llm";
// Een handler die in de worker-thread verblijft
const handler = new WebWorkerMLCEngineHandler();
self.onmessage = (msg: MessageEvent) => {
  handler.onmessage(msg);
};

Hoofdlogica (main.ts):

import { CreateWebWorkerMLCEngine } from "@mlc-ai/web-llm";
async function main() {
  // Gebruik een WebWorkerMLCEngine in plaats van MLCEngine
  const engine = await CreateWebWorkerMLCEngine(
    new Worker(new URL("./worker.ts", import.meta.url), {
      type: "module",
    }),
    selectedModel,
    { initProgressCallback }, // engineConfig
  );
  // De rest van de logica blijft hetzelfde
}

Service Worker Gebruik

Met ServiceWorker-ondersteuning kunt u het generatieproces koppelen aan een service worker om te voorkomen dat het model bij elk pagina-bezoek opnieuw geladen moet worden, wat de offline-ervaring optimaliseert.

(Let op: de levenscyclus van een Service Worker wordt beheerd door de browser en kan op elk moment worden beëindigd. ServiceWorkerMLCEngine probeert de thread actief te houden via heartbeat-events, maar uw applicatie moet correcte foutafhandeling bevatten. Zie keepAliveMs en missedHeatbeat voor details.)

Worker-thread (sw.ts):

import { ServiceWorkerMLCEngineHandler } from "@mlc-ai/web-llm";
new ServiceWorkerMLCEngineHandler();
console.log("Service Worker is ready");

Hoofdlogica (main.ts):

import {
  MLCEngineInterface,
  CreateServiceWorkerMLCEngine,
} from "@mlc-ai/web-llm";

if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register(
    new URL("sw.ts", import.meta.url), // worker script
    { type: "module" },
  );
}

const engine: MLCEngineInterface = await CreateServiceWorkerMLCEngine(
  selectedModel,
  { initProgressCallback }, // engineConfig
);

Chrome Extension

Er zijn voorbeelden beschikbaar voor het bouwen van Chrome-extensies met WebLLM in examples/chrome-extension en examples/chrome-extension-webgpu-service-worker. De laatste maakt gebruik van een service worker, waardoor de extensie persistent op de achtergrond draait. Ook is er het project "WebLLM Assistant" te bekijken.

Volledige OpenAI Compatibiliteit

WebLLM is ontworpen om volledig compatibel te zijn met de OpenAI API. Naast eenvoudige chatbots kunt u gebruikmaken van:

  • Streaming: Output in real-time als chunks via een AsyncGenerator.
  • JSON-mode: Efficiënt waarborgen dat de output in JSON-formaat is.
  • Seed-to-reproduce: Gebruik van seeding voor reproduceerbare output via het veld seed.
  • Function-calling (WIP): Voorlopige ondersteuning via tools en tool_choice, of handmatige function calling voor maximale flexibiliteit.

Integriteitsverificatie

WebLLM ondersteunt optionele integriteitsverificatie voor model-artifacts via SRI (Subresource Integrity) hashes. Wanneer het integrity veld is ingesteld op een ModelRecord, verifieert WebLLM de gedownloade config, WASM en tokenizer bestanden voordat ze worden geladen.

import { CreateMLCEngine } from "@mlc-ai/web-llm";
const appConfig = {
  model_list: [
    {
      model: "https://huggingface.co/mlc-ai/Llama-3.2-1B-Instruct-q4f16_1-MLC",
      model_id: "Llama-3.2-1B-Instruct-q4f16_1-MLC",
      model_lib: "https://raw.githubusercontent.com/user/model-libs/main/model.wasm",
      integrity: {
        config: "sha256-<base64-hash-of-mlc-chat-config.json>",
        model_lib: "sha256-<base64-hash-of-wasm-file>",
        tokenizer: {
          "tokenizer.json": "sha256-<base64-hash-of-tokenizer.json>",
        },
        onFailure: "error", // "error" (standaard) gooit IntegrityError, "warn" logt en gaat door
      },
    },
  ],
};
const engine = await CreateMLCEngine("Llama-3.2-1B-Instruct-q4f16_1-MLC", {
  appConfig,
});

U kunt SRI-hashes genereren met de volgende OpenSSL commando's (vereist Unix-like shell):

  • SHA-256: openssl dgst -sha256 -binary <file> | openssl base64 -A | sed 's/^/sha256-/'
  • SHA-384: openssl dgst -sha384 -binary <file> | openssl base64 -A | sed 's/^/sha384-/'
  • SHA-512: openssl dgst -sha512 -binary <file> | openssl base64 -A | sed 's/^/sha512-/'

Custom Modellen

WebLLM werkt als een begeleidend project van MLC LLM en ondersteunt custom modellen in MLC-formaat. Voor details over het compileren en implementeren van nieuwe modelgewichten en libraries, raadpleeg de MLC LLM documentatie.

Hooguit zijn er twee elementen van het WebLLM-pakket die nieuwe modellen mogelijk maken:

  1. model: Een URL naar model-artifacts (gewichten en metadata).
  2. model_lib: Een URL naar de WebAssembly-library (.wasm bestand) die de berekeningen versnelt.

Voorbeeld van custom configuratie:

import { CreateMLCEngine } from "@mlc-ai/web-llm";
async main() {
  const appConfig = {
    "model_list": [
      {
        "model": "/url/to/my/llama",
        "model_id": "MyLlama-3b-v1-q4f32_0",
        "model_lib": "/url/to/myllama3b.wasm",
      }
    ],
  };
  const chatOpts = {
    "repetition_penalty": 1.01
  };
  const engine = await CreateMLCEngine(
    "MyLlama-3b-v1-q4f32_0",
    { appConfig },
    chatOpts,
  );
}

In veel gevallen kan een nieuwe modelvariant een bestaande model-library hergebruiken (bijv. NeuralHermes-Mistral kan de Mistral-library gebruiken).

WebLLM Package Bouwen vanuit Source

Opmerking: u hoeft alleen uit source te bouwen als u het WebLLM-pakket zelf wilt wijzigen. Gebruik anders de npm-versie.

Om te bouwen uit source:

npm install
npm run build

Om wijzigingen te testen in een voorbeeld (bijv. examples/get-started), wijzigt u in package.json de referentie van "@mlc-ai/web-llm": "^0.2.84" naar "@mlc-ai/web-llm": ../.... Voer daarna uit:

cd examples/get-started
npm install
npm start

TVMjs Bouwen vanuit Source

De runtime van WebLLM is grotendeels afhankelijk van TVMjs. Indien nodig kunt u dit als volgt bouwen:

  1. Installeer Emscripten (emsdk).
  2. Voer source path/to/emsdk_env.sh uit zodat emcc beschikbaar is.
  3. Gebruik ./emsdk install 3.1.56 (recente versies kunnen runtime-problemen veroorzaken).
  4. Pas in package.json de referentie naar @mlc-ai/web-runtime aan naar file:./tvm_home/web.
  5. Bereid dependencies voor: ./scripts/prep_deps.sh.
  6. Bouw het pakket: npm run build.

Links & Referenties

Erkenningen

Dit project is geïnitieerd door leden van CMU Catalyst, UW SAMPL, SJTU, OctoML en de MLC community. We danken de Apache TVM community, de ontwikkelaars van TVM Unity, en de open-source ML community die modellen publiek beschikbaar hebben gemaakt. Speciale dank gaat uit naar de teams achter Vicuna, SentencePiece, LLaMA en Alpaca, evenals de WebAssembly, Emscripten en WebGPU communities, en de ontwikkelaars van Dawn.

Citatie

Indien u dit project gebruikt, citeer dan als volgt:

@misc{ruan2026webllmhighperformanceinbrowserllm,
title={WebLLM: A High-Performance In-Browser LLM Inference Engine},
author={Charlie F. Ruan and Yucheng Qin and Akaash R. Parthasarathy and Xun Zhou and Ruihang Lai and Hongyi Jin and Yixin Dong and Bohan Hou and Meng-Shiun Yu and Yiyan Zhai and Sudeep Agarwal and Hangrui Cao and Siyuan Feng and Tianqi Chen},
year={2026},
eprint={2412.15803},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2412.15803},
}