AILLMWebLLMWebGPUJavaScript

Exécuter des LLM dans le navigateur — Guide complet de WebLLM

Sloth255
Sloth255
·4 min read·789 words

WebLLM en bref

WebLLM est une bibliothèque qui permet d'exécuter des LLM (Large Language Models) directement dans le navigateur, sans avoir besoin d'un serveur backend.

GitHub: https://github.com/mlc-ai/web-llm

Elle offre une API compatible avec l'API Chat d'OpenAI, il est donc possible de migrer depuis une application utilisant l'API OpenAI avec un minimum de modifications.

Architecture de WebLLM

WebLLM tire parti de trois technologies Web modernes :

graph TD
    A[Application Web] --> B[WebLLM Engine]
    B --> C[WebGPU]
    B --> D[WebAssembly]
    B --> E[Web Workers]
    C --> F[GPU Hardware]
    D --> G[CPU Fallback]
    E --> H[Background Thread]

WebGPU

  • Nouvelle API d'accès direct au GPU (Chrome 113+)
  • Peut exécuter des calculs parallèles dont les opérations matricielles pour l'inférence LLM
  • Significativement plus rapide que WebGL

WebAssembly (Wasm)

  • Exécuter du code haute performance dans le navigateur
  • Utilisé pour le traitement du tokenizer et les calculs CPU
  • Utilisé comme fallback lorsque WebGPU n'est pas disponible

Web Workers

  • Exécuter le traitement lourd sur des threads en arrière-plan non bloquants
  • Maintenir la réactivité de l'UI pendant l'inférence du modèle
  • Isoler les opérations mémoire intensive

Performances et limites

Résultats benchmarks

WebLLM peut atteindre environ 80% des performances d'inférence native dans un environnement WebGPU. Par exemple :

Modèle Environnement Vitesse (tokens/sec)
Phi-3.5-mini WebGPU ~30-40
Phi-3.5-mini CPU (ONNX) ~5-10
Llama-3.2-1B WebGPU ~50-70
Gemma-2-2B WebGPU ~20-30

*Les résultats varient selon le matériel et le navigateur.

Support navigateur

Navigateur WebGPU Statut
Chrome 113+ Pleinement supporté
Edge 113+ Pleinement supporté
Firefox ⚠️ Experimental (derrière un flag)
Safari ⚠️ Support partiel (macOS 15+)
Chrome Android Supporté (GPU performant requis)

Limites pratiques

  • Taille du modèle : Limité à ~4-8GB en raison des restrictions de mémoire du navigateur
  • Délai de chargement : Le premier chargement prend 1-5 minutes (mis en cache après)
  • Compatibilité matérielle : Les GPU dédiés sont fortement préférés aux GPU intégrés
  • Surcharge navigateur : L'inférence entre en concurrence avec les autres onglets et processus

Modèles supportés

WebLLM supporte de nombreux modèles populaires. Voici une sélection :

Famille Nom du modèle Taille aprox.
Llama Llama-3.2-1B-Instruct ~0.7GB
Llama Llama-3.1-8B-Instruct ~4.3GB
Phi Phi-3.5-mini-instruct ~2.2GB
Phi Phi-3-medium-128k-instruct ~7.8GB
Gemma gemma-2-2b-it ~1.5GB
Mistral Mistral-7B-Instruct-v0.3 ~4.1GB
Qwen Qwen2.5-1.5B-Instruct ~1.0GB

La liste complète des modèles : https://github.com/mlc-ai/web-llm/blob/main/src/config.ts

Implémentation basique

Installation

npm install @mlc-ai/web-llm

Exemple d'utilisation — Implémentation basique

import * as webllm from "@mlc-ai/web-llm";

async function main() {
  const engine = await webllm.CreateMLCEngine(
    "Llama-3.2-1B-Instruct-q4f32_1-MLC",
    {
      initProgressCallback: (progress) => {
        console.log("Loading:", progress.text);
      }
    }
  );

  const response = await engine.chat.completions.create({
    messages: [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: "What is WebGPU?" }
    ],
    temperature: 0.7,
    max_tokens: 512
  });

  console.log(response.choices[0].message.content);
}

Implémentation avec Web Worker

Pour un fonctionnement non bloquant, il est recommandé d'utiliser des Web Workers :

// main.js
import * as webllm from "@mlc-ai/web-llm";

const engine = new webllm.WebWorkerMLCEngine(
  new Worker(
    new URL("./worker.js", import.meta.url),
    { type: "module" }
  )
);

await engine.reload("Llama-3.2-1B-Instruct-q4f32_1-MLC");
// worker.js
import { WebWorkerMLCEngineHandler } from "@mlc-ai/web-llm";
const handler = new WebWorkerMLCEngineHandler();
self.onmessage = (msg) => handler.onmessage(msg);

Implémentation de réponse en streaming

const chunks = await engine.chat.completions.create({
  messages: [{ role: "user", content: "Tell me a story." }],
  stream: true,
  stream_options: { include_usage: true }
});

let outputText = "";
for await (const chunk of chunks) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) {
    outputText += delta;
    console.log(outputText); // Mise à jour en temps réel
  }
  if (chunk.usage) {
    console.log("Usage:", chunk.usage);
  }
}

Points à considérer dans les applications concrètes

Détection de la disponibilité de WebGPU

async function checkWebGPUSupport() {
  if (!navigator.gpu) {
    return { supported: false, reason: "WebGPU not available" };
  }
  
  try {
    const adapter = await navigator.gpu.requestAdapter();
    if (!adapter) {
      return { supported: false, reason: "No GPU adapter found" };
    }
    return { supported: true, adapter };
  } catch (error) {
    return { supported: false, reason: error.message };
  }
}

Expérience de mise en cache

Les fichiers de modèle sont mis en cache dans le stockage du navigateur après le premier téléchargement. En tirant parti du Cache API :

const engine = await webllm.CreateMLCEngine(modelId, {
  initProgressCallback: ({ progress, text }) => {
    // progress: 0.0~1.0
    updateLoadingUI(progress, text);
  }
});
// Les accès suivants utiliseront le cache et seront rapides

Cas d'utilisation

WebLLM est particulièrement adapté aux :

  1. Applications à confidentialité stricte — Les données n'quittent jamais l'appareil de l'utilisateur
  2. Fonctionnalités hors ligne — Fonctionnement sans connexion internet
  3. Protections de PWA — Intégration de fonctionnalités AI comme application hors ligne
  4. Prototypage et démos — Aucun serveur backend requis
  5. Distribution de coût — Zéro coût de calcul côté serveur

Défis et perspectives d'avenir

Principaux défis :

  • La fragmentation du support WebGPU entre navigateurs crée des incohérences d'expérience
  • Les contraintes de mémoire du navigateur rendent difficile l'utilisation de grands modèles
  • Les GPU modestes peuvent rencontrer des problèmes de performance

Développements futurs à surveiller :

  • Amélioration du support WebGPU dans Firefox et Safari
  • Optimisation des modèles spécifiquement pour l'environnement web
  • Support WebNN (Web Neural Network API)
  • Optimisations de compression de modèles

Conclusion

WebLLM permet véritablement d'exécuter des LLM dans le navigateur, ce qui était inimaginable il y a quelques années encore. En particulier pour les applications à confidentialité stricte et les applications hors ligne, il offre une valeur pratique réelle.

Actuellement, il y a encore des limitations en termes de performance et de compatibilité, mais avec l'évolution du support WebGPU et les avancées de WebLLM, l'expérience des LLM côté navigateur devrait se généraliser dans les deux prochaines années.

C'est une technologie qui mérite réellement d'être expérimentée.