Expérimenter l’IA dans le navigateur : créer un chatbot local avec WebGPU et WebLLM

Publié le 22/09/2025 20:08
Image de l'article Expérimenter l’IA dans le navigateur : créer un chatbot local avec WebGPU et WebLLM

[Cet article a été généré par IA à des fins de tests du système de blog, vu qu'il reste interessant et concerne une experimentation disponible sur le lab, je le laisse à titre informatif]

Depuis plusieurs années, l’intelligence artificielle générative s’est démocratisée via des plateformes en ligne comme ChatGPT, Claude ou Gemini. Mais derrière la facilité d’usage se cache un inconvénient majeur : tout passe par le cloud, vos prompts comme vos données.

Avec l’arrivée de WebGPU et de bibliothèques comme WebLLM, il devient possible d’exécuter des modèles directement dans le navigateur, sans dépendre d’un serveur externe. L’approche est encore expérimentale, mais elle ouvre des perspectives intéressantes : confidentialité renforcée, indépendance vis-à-vis des fournisseurs de cloud, et possibilité de démos interactives 100 % locales.

Dans cet article, je partage un retour d’expérience : comment j’ai mis en place un chatbot en navigateur, les défis rencontrés, et une explication pas à pas du code utilisé.


Pourquoi un chatbot IA dans le navigateur ?

L’idée de départ était simple : recréer une interface inspirée de ChatGPT, mais qui fonctionne sans backend.
Le navigateur télécharge un modèle quantisé, l’exécute via WebGPU et renvoie les réponses en temps réel.

Les avantages sont multiples :

  • Confidentialité : rien ne transite par un serveur tiers, vos conversations restent locales.
  • Accessibilité : pas besoin d’installer Python, Node ou autre environnement complexe.
  • Pédagogie : parfait pour expérimenter et comprendre comment tourne un modèle d’IA sous le capot.

Évidemment, il y a des limites : les modèles supportés sont petits (quelques centaines de Mo), la compatibilité dépend de WebGPU, et la performance varie selon votre carte graphique. Mais en termes de démonstration et de recherche, c’est déjà bluffant.


L’interface utilisateur

La première étape a été de construire une interface claire et fonctionnelle.
J’ai opté pour du HTML5 + CSS, avec un peu de Bootstrap Icons pour ajouter des pictogrammes familiers.

L’interface est découpée en trois zones :

  1. L’en-tête : titre + menu déroulant pour choisir le modèle.
  2. La zone de messages : affichage des conversations, bulles façon messagerie.
  3. Le pied de page : champ de saisie, bouton d’envoi et statut technique (GPU, modèle, mémoire).

Exemple simplifié :

 

<div class="chatbot-container">  <div class="chatbot-header">    <i class="bi bi-robot"></i> Chatbot IA navigateur    <select id="chatbotModelSelect" class="chatbot-model-select">      <option value="Phi-3.5-mini-instruct-q4f16_1-MLC">Phi-3.5-mini-instruct</option>      <option value="TinyLlama-1.1B-Chat-v1.0-q4f16_1-MLC">TinyLlama-1.1B-Chat</option>    </select>  </div>  <div class="chatbot-messages" id="chatbotMessages"></div>  <div class="chatbot-input-area">    <input type="text" id="chatbotInput" class="chatbot-input" placeholder="Votre message..." />    <button id="chatbotSendBtn" class="chatbot-send-btn"><i class="bi bi-arrow-up"></i></button>  </div>  <div class="chatbot-status">    <span id="gpuStatus">GPU: vérification...</span>    <span id="modelStatus">Modèle: en attente</span>    <span id="memStatus">Mémoire: --</span>  </div> </div>

Côté CSS, j’ai opté pour un thème sombre proche de l’expérience ChatGPT, avec avatars pour différencier l’utilisateur et l’assistant.


Vérification de WebGPU

Avant même de charger un modèle, il faut vérifier si WebGPU est disponible.
Cette API est récente et encore incomplètement supportée.

Le code suivant s’occupe de la détection :

 

if (!navigator.gpu) {  updateStatus(elements.gpuStatus, "WebGPU non disponible", "status-error");  let errorMsg = "WebGPU requis.";  if (window.location.protocol === 'http:' && window.location.hostname !== 'localhost') {    errorMsg += " HTTPS nécessaire pour WebGPU (sauf localhost).";  } else if (navigator.userAgent.includes('Firefox')) {    errorMsg += " Firefox ne supporte pas encore WebGPU officiellement.";  } else {    errorMsg += " Activez WebGPU dans chrome://flags/#enable-unsafe-webgpu";  }    throw new Error(errorMsg); }

Concrètement :

  • Chrome/Edge : nécessite d’activer chrome://flags/#enable-unsafe-webgpu.
  • Firefox : non supporté officiellement.
  • Mobile : incompatible dans la plupart des cas.
  • HTTP : bloqué (sauf en localhost).

Si WebGPU n’est pas dispo, je propose automatiquement un mode fallback (réponses simulées), afin que l’utilisateur puisse au moins tester l’interface.


Chargement de WebLLM et du modèle

Une fois WebGPU validé, j’importe WebLLM de manière dynamique pour éviter les erreurs de compatibilité :

 

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

Puis, j’initialise le moteur :

 

engine = await CreateMLCEngine(CONFIG.model, {  initProgressCallback: (progress) => {    const percent = Math.round(progress.progress * 100);    updateStatus(elements.modelStatus, `Modèle: ${percent}%`, "status-loading");  },  logLevel: "error" });

Le callback initProgressCallback permet d’afficher en direct le pourcentage de téléchargement du modèle – très utile car un modèle peut faire 300 à 500 Mo.

Une fois chargé, le moteur est prêt à recevoir des messages.


Générer une réponse

L’appel à l’IA s’effectue via la méthode engine.chat.completions.create().
On lui passe une liste de messages (style API OpenAI) :

 

const messages = [  {    role: "system",    content: "Tu es un assistant IA concis et utile. Réponds en français."  },  {    role: "user",    content: message  } ]; const response = await engine.chat.completions.create({  messages: messages,  temperature: 0.7,  max_tokens: 512 });

Le résultat est ensuite affiché dans la bulle de l’assistant, après une petite animation « réflexion en cours… » qui rend l’interface plus naturelle.


Gestion du fallback

Quand WebGPU est absent, impossible de charger un modèle. Plutôt que de laisser l’utilisateur face à une erreur technique, j’ai prévu des réponses simulées :

 

function generateFallbackResponse(message) {  if (message.toLowerCase().includes('webgpu')) {    return "🔧 Pour activer WebGPU: ouvrez chrome://flags/#enable-unsafe-webgpu";  }  return `Mode démo actif. Message reçu: "${message}"`; }
Cela permet de tester l’interface dans tous les cas, même si la partie IA n’est pas fonctionnelle.

Résultats et limites

Après quelques ajustements, le chatbot fonctionne :

  • L’interface est réactive et agréable.
  • Les modèles légers (Phi-3.5-mini, TinyLlama) tournent correctement sur GPU intégré.
  • Les modèles plus gros (RedPajama 3B) demandent beaucoup de mémoire et peuvent planter.
  • Le temps de chargement initial reste le point faible : plusieurs minutes la première fois.

Conclusion

Cette expérimentation démontre qu’il est désormais possible d’exécuter un chatbot IA complet dans un simple navigateur, sans backend ni cloud.
L’expérience reste perfectible : compatibilité WebGPU limitée, modèles lourds à charger, performances variables. Mais la direction est claire : à terme, nous pourrons imaginer des applications IA entièrement locales, sécurisées et privées, distribuées comme de simples pages web.

Pour des projets de démonstration, d’apprentissage ou de prototypage, cette approche est déjà exploitable et ouvre de belles perspectives.

← Retour au blog