Lokalen und offlinefähigen Chatbot mit WebLLM erstellen

Veröffentlicht: 13. Januar 2024

Dies ist der zweite Teil einer dreiteiligen Reihe zu LLMs und Chatbots. Im vorherigen Artikel wurden die Vor- und Nachteile von On-Device- und In-Browser-LLMs besprochen.

Nachdem Sie nun mehr über clientseitige KI wissen, können Sie WebLLM einer Webanwendung für eine To-do-Liste hinzufügen. Den Code finden Sie im web-llm-Branch des GitHub-Repositorys.

WebLLM ist eine webbasierte Laufzeit für LLMs, die von Machine Learning Compilation bereitgestellt wird. Sie können WebLLM als eigenständige Anwendung ausprobieren. Die Anwendung wurde von cloudbasierten Chat-Anwendungen wie Gemini inspiriert. Die LLM-Inferenz wird jedoch auf Ihrem Gerät und nicht in der Cloud ausgeführt. Ihre Prompts und Daten verlassen Ihr Gerät nie und werden nicht zum Trainieren von Modellen verwendet.

Für die Modellinferenz auf dem Gerät kombiniert WebLLM WebAssembly und WebGPU. Während WebAssembly effiziente Berechnungen auf der Zentraleinheit (CPU) ermöglicht, bietet WebGPU Entwicklern Low-Level-Zugriff auf die Grafikprozessoreinheit (GPU) des Geräts.

Browser Support

  • Chrome: 113.
  • Edge: 113.
  • Firefox Technology Preview: supported.
  • Safari Technology Preview: supported.

Source

WebLLM installieren

WebLLM ist als npm-Paket verfügbar. Sie können dieses Paket Ihrer To-do-Listen-Anwendung hinzufügen, indem Sie npm install @mlc-ai/web-llm ausführen.

Modell auswählen

Als Nächstes müssen Sie sich für eine LLM entscheiden, die lokal ausgeführt werden soll. Es sind verschiedene Modelle verfügbar.

Um eine Entscheidung treffen zu können, sollten Sie die folgenden wichtigen Begriffe und Zahlen kennen:

  • Token: Die kleinste Texteinheit, die ein LLM verarbeiten kann.
  • Kontextfenster:Die maximale Anzahl von Tokens, die das Modell verarbeiten kann.
  • Parameter oder Gewichte: Die internen Variablen, die während des Trainings gelernt werden, werden in Milliarden gezählt.
  • Quantisierung: Die Anzahl der Bits, die die Gewichte darstellen. Mehr Bits bedeuten zwar eine höhere Genauigkeit, aber auch eine höhere Arbeitsspeichernutzung.
  • Gleitkommaformate: 32‑Bit-Gleitkommazahlen (Vollgenauigkeit, F32) bieten eine bessere Genauigkeit, während 16‑Bit-Gleitkommazahlen (Halbgenauigkeit, F16) eine höhere Geschwindigkeit und eine geringere Speichernutzung haben, aber kompatible Hardware erfordern.

Diese Begriffe sind in der Regel Teil des Modellnamens. Llama-3.2-3B-Instruct-q4f32_1-MLC enthält beispielsweise die folgenden Informationen:

  • Das Modell ist LLaMa 3.2.
  • Das Modell hat 3 Milliarden Parameter.
  • Sie ist für Assistenten mit Anleitungs- und Prompt-Funktionen (Instruct) optimiert.
  • Es wird eine einheitliche (_1) Quantisierung mit 4 Bit (q4) verwendet.
  • Es unterstützt 32-Bit-Gleitkommazahlen mit voller Genauigkeit.
  • Es handelt sich um eine spezielle Version, die mithilfe von Machine Learning Compilation erstellt wurde.

Möglicherweise müssen Sie verschiedene Modelle testen, um herauszufinden, welches für Ihren Anwendungsfall am besten geeignet ist.

Ein Modell mit 3 Milliarden Parametern und 4 Bit pro Parameter kann zu diesem Zeitpunkt bereits eine Dateigröße von 1,4 GB haben, die die Anwendung vor der ersten Verwendung auf das Gerät des Nutzers herunterladen muss. Sie können auch mit 3B-Modellen arbeiten, aber bei Übersetzungsfunktionen oder Allgemeinwissen liefern 7B-Modelle bessere Ergebnisse. Ab 3,3 GB sind sie jedoch deutlich größer.

Fügen Sie Ihrer Anwendung den folgenden Code hinzu, um die WebLLM-Engine zu erstellen und den Modelldownload für Ihren To-do-Liste-Chatbot zu starten:

import {CreateMLCEngine} from '@mlc-ai/web-llm';
const engine = await CreateMLCEngine('Llama-3.2-3B-Instruct-q4f32_1-MLC', {
  initProgressCallback: ({progress}) =>  console.log(progress);
});

Die Methode CreateMLCEngine nimmt den Modellstring und ein optionales Konfigurationsobjekt entgegen. Mit der Methode initProgressCallback können Sie den Downloadfortschritt des Modells abfragen und den Nutzern während des Wartens anzeigen.

Cache API: LLM offline ausführen

Das Modell wird in den Cachespeicher Ihrer Website heruntergeladen. Die Cache API wurde zusammen mit Service Workers eingeführt, damit Ihre Website oder Webanwendung auch offline ausgeführt werden kann. Es ist der beste Speichermechanismus zum Caching von KI-Modellen. Im Gegensatz zum HTTP-Caching ist die Cache API ein programmierbarer Cache, der vollständig vom Entwickler gesteuert wird.

Nach dem Download liest WebLLM die Modelldateien aus der Cache API, anstatt sie über das Netzwerk anzufordern. Dadurch ist WebLLM vollständig offlinefähig.

Wie bei allen Website-Speichern ist der Cache pro Ursprung isoliert. Das bedeutet, dass zwei Ursprünge, beispiel.de und beispiel.net, nicht denselben Speicherplatz nutzen können. Wenn diese beiden Websites dasselbe Modell verwenden möchten, müssen sie es separat herunterladen.

Sie können den Cache mithilfe der DevTools prüfen, indem Sie Anwendung > Speicher aufrufen und den Cachespeicher öffnen.

Unterhaltung einrichten

Das Modell kann mit einer Reihe von anfänglichen Prompts initialisiert werden. Normalerweise gibt es drei Nachrichtenrollen:

  • System-Prompt: Dieser Prompt definiert das Verhalten, die Rolle und den Charakter des Modells. Sie kann auch für die Datengrundlage verwendet werden, d. h. für die Eingabe benutzerdefinierter Daten in das Modell, die nicht Teil des Trainings-Datasets sind (z. B. Ihre domänenspezifischen Daten). Sie können nur einen Systemprompt angeben.
  • Nutzer-Prompt: Prompts, die vom Nutzer eingegeben werden.
  • Assistant-Prompt: Antworten von Assistant, optional.

Nutzer- und Assistant-Prompts können für N-Shot-Prompts verwendet werden, indem dem LLM Beispiele in natürlicher Sprache zur Verfügung gestellt werden, wie es sich verhalten oder reagieren soll.

Hier ist ein einfaches Beispiel für die Einrichtung der Unterhaltung für die To-do-Liste-App:

const messages = [
  { role: "system",
    content: `You are a helpful assistant. You will answer questions related to
    the user's to-do list. Decline all other requests not related to the user's
    todos. This is the to-do list in JSON: ${JSON.stringify(todos)}`
  },
  {role: "user", content: "How many open todos do I have?"}
];

Erste Frage beantworten

Die Funktion zur Chat-Vervollständigung wird als Property in der zuvor erstellten WebLLM-Engine (engine.chat.completions) bereitgestellt. Nachdem das Modell heruntergeladen wurde, können Sie die Modellinferenz ausführen, indem Sie die Methode create() für diese Property aufrufen. Für Ihren Anwendungsfall möchten Sie Antworten streamen, damit der Nutzer sie schon lesen kann, während sie generiert werden. So wird die wahrgenommene Wartezeit verkürzt:

const chunks = await engine.chat.completions.create({  messages,  stream: true, });

Diese Methode gibt eine AsyncGenerator zurück, eine Unterklasse der ausgeblendeten Klasse AsyncIterator. Verwende eine for await...of-Schleife, um auf die Chunks zu warten, sobald sie eingehen. Die Antwort enthält jedoch nur die neuen Tokens (delta). Sie müssen die vollständige Antwort also selbst zusammenstellen.

let reply = '';

for await (const chunk of chunks) {
  reply += chunk.choices[0]?.delta.content ?? '';
  console.log(reply);
}

Es stellte sich heraus, dass das Web schon immer mit Streamingantworten zu tun hatte. Sie können APIs wie DOMImplementation verwenden, um mit diesen Streamingantworten zu arbeiten und Ihre HTML-Datei effizient zu aktualisieren.

Die Ergebnisse sind rein stringbasiert. Sie müssen sie zuerst parsen, wenn Sie sie als JSON oder in anderen Dateiformaten interpretieren möchten.

WebLLM hat jedoch einige Einschränkungen: Die Anwendung muss vor der ersten Verwendung ein riesiges Modell herunterladen, das nicht zwischen Ursprüngen geteilt werden kann. Daher muss möglicherweise eine andere Webanwendung dasselbe Modell noch einmal herunterladen. WebGPU erreicht zwar eine nahezu native Inferenzleistung, aber nicht die volle native Geschwindigkeit.

Demo

Diese Nachteile werden durch die Prompt API behoben, eine explorative API, die von Google vorgeschlagen wurde und ebenfalls clientseitig ausgeführt wird, aber ein zentrales Modell verwendet, das in Chrome heruntergeladen wird. So können mehrere Anwendungen dasselbe Modell mit voller Ausführungsgeschwindigkeit nutzen.

Im nächsten Artikel erfahren Sie mehr darüber, wie Sie Chatbot-Funktionen mit der Prompt API hinzufügen.