Publié le 13 janvier 2024
Il s'agit de la deuxième partie d'une série en trois parties sur les LLM et les chatbots. L'article précédent a décrit les avantages et les inconvénients des LLM sur l'appareil et dans le navigateur.
Maintenant que vous comprenez mieux l'IA côté client, vous êtes prêt à ajouter WebLLM à une application Web de liste de tâches. Vous trouverez le code dans la branche web-llm
du dépôt GitHub.
WebLLM est un environnement d'exécution Web pour les LLM fournis par la compilation du machine learning. Vous pouvez essayer WebLLM en tant qu'application autonome. L'application est inspirée des applications de chat cloud, telles que Gemini, mais l'inférence LLM est exécutée sur votre appareil plutôt que dans le cloud. Vos requêtes et vos données ne quittent jamais votre appareil, et vous pouvez être sûr qu'elles ne sont pas utilisées pour entraîner des modèles.
Pour effectuer l'inférence de modèle sur l'appareil, WebLLM combine WebAssembly et WebGPU. Alors que WebAssembly permet des calculs efficaces sur le processeur (CPU), WebGPU offre aux développeurs un accès de bas niveau à l'unité de traitement graphique (GPU) de l'appareil.
Installer WebLLM
WebLLM est disponible en tant que package npm.
Vous pouvez ajouter ce package à votre application de liste de tâches en exécutant npm install @mlc-ai/web-llm
.
Sélectionnez un modèle
Ensuite, vous devez choisir un LLM à exécuter localement. Plusieurs modèles sont disponibles.
Pour prendre cette décision, vous devez connaître les termes et chiffres clés suivants:
- Jeton:plus petite unité de texte qu'un LLM peut traiter.
- Fenêtre de contexte:nombre maximal de jetons que le modèle peut traiter.
- Paramètres ou pondérations:variables internes apprises lors de l'entraînement, qui se comptent en milliards.
- Quantisation:nombre de bits représentant les poids. Plus de bits signifie une précision plus élevée, mais aussi une utilisation de la mémoire plus importante.
- Formats de nombres à virgule flottante:les nombres à virgule flottante 32 bits (précision complète, F32) offrent une meilleure précision, tandis que les nombres à virgule flottante 16 bits (demi-précision, F16) offrent des vitesses plus élevées et une utilisation de la mémoire réduite, mais nécessitent du matériel compatible.
Ces termes clés font généralement partie du nom du modèle. Par exemple, Llama-3.2-3B-Instruct-q4f32_1-MLC
contient les informations suivantes:
- Le modèle est LLaMa 3.2.
- Le modèle compte trois milliards de paramètres.
- Il est optimisé pour les assistants de type instruction et invite (Instruct).
- Il utilise une quantification uniforme (_1) sur 4 bits (q4).
- Il utilise des nombres à virgule flottante de 32 bits à précision complète.
- Il s'agit d'une version spéciale créée par la compilation du machine learning.
Vous devrez peut-être tester différents modèles pour déterminer celui qui convient le mieux à votre cas d'utilisation.
Un modèle avec trois milliards de paramètres et quatre bits par paramètre peut déjà avoir une taille de fichier pouvant atteindre 1,4 Go au moment de la rédaction de cet article, que l'application doit télécharger sur l'appareil de l'utilisateur avant la première utilisation. Il est possible de travailler avec des modèles 3 milliards, mais en ce qui concerne les fonctionnalités de traduction ou les connaissances en culture générale, les modèles 7 milliards offrent de meilleurs résultats. À partir de 3, 3 Go, ils sont toutefois nettement plus volumineux.
Pour créer le moteur WebLLM et lancer le téléchargement du modèle pour votre chatbot de liste de tâches, ajoutez le code suivant à votre application:
import {CreateMLCEngine} from '@mlc-ai/web-llm';
const engine = await CreateMLCEngine('Llama-3.2-3B-Instruct-q4f32_1-MLC', {
initProgressCallback: ({progress}) => console.log(progress);
});
La méthode CreateMLCEngine
utilise la chaîne de modèle et un objet de configuration facultatif. À l'aide de la méthode initProgressCallback
, vous pouvez interroger la progression du téléchargement du modèle pour le présenter aux utilisateurs pendant qu'ils attendent.
API Cache: exécuter votre LLM hors connexion
Le modèle est téléchargé dans l'espace de stockage de cache de votre site Web. L'API Cache a été introduite avec les services workers pour permettre à votre site Web ou application Web de s'exécuter hors connexion. Il s'agit du meilleur mécanisme de stockage pour mettre en cache des modèles d'IA. Contrairement au cache HTTP, l'API Cache est un cache programmable entièrement contrôlé par le développeur.
Une fois téléchargés, WebLLM lit les fichiers de modèle à partir de l'API Cache au lieu de les demander sur le réseau, ce qui rend WebLLM entièrement compatible avec le mode hors connexion.
Comme pour tout stockage de site Web, le cache est isolé par origine. Cela signifie que deux origines, example.com et example.net, ne peuvent pas partager le même espace de stockage. Si ces deux sites Web souhaitaient utiliser le même modèle, ils devraient le télécharger séparément.
Vous pouvez inspecter le cache à l'aide des outils de développement en accédant à Application > Storage (Application > Stockage) et en ouvrant le stockage du cache.
Configurer la conversation
Le modèle peut être initialisé avec un ensemble d'invites initiales. Il existe généralement trois rôles de message:
- Invite système: cette invite définit le comportement, le rôle et le caractère du modèle. Il peut également être utilisé pour l'ancrage, c'est-à-dire pour fournir au modèle des données personnalisées qui ne font pas partie de son ensemble d'entraînement (telles que vos données spécifiques au domaine). Vous ne pouvez spécifier qu'une seule invite système.
- Requête de l'utilisateur: requêtes saisies par l'utilisateur.
- Invite de l'Assistant: réponses de l'Assistant, facultatives.
Les requêtes utilisateur et d'assistant peuvent être utilisées pour les requêtes N-shot en fournissant au LLM des exemples de langage naturel sur la façon dont il doit se comporter ou répondre.
Voici un exemple minimal de configuration de la conversation pour l'application de liste de tâches:
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?"}
];
Répondre à votre première question
La fonctionnalité de finalisation de chat est exposée en tant que propriété sur le moteur WebLLM créé précédemment (engine.chat.completions
). Une fois le modèle téléchargé, vous pouvez exécuter l'inférence du modèle en appelant la méthode create()
sur cette propriété. Pour votre cas d'utilisation, vous souhaitez diffuser les réponses afin que l'utilisateur puisse commencer à lire pendant qu'elles sont générées, ce qui réduit le temps d'attente perçu:
const chunks = await engine.chat.completions.create({ messages, stream: true, });
Cette méthode renvoie un AsyncGenerator
, une sous-classe de la classe AsyncIterator
masquée. Utilisez une boucle for await...of
pour attendre les blocs à mesure qu'ils arrivent. Toutefois, la réponse ne contient que les nouveaux jetons (delta
). Vous devez donc assembler vous-même la réponse complète.
let reply = '';
for await (const chunk of chunks) {
reply += chunk.choices[0]?.delta.content ?? '';
console.log(reply);
}
Il s'avère que le Web a toujours dû gérer les réponses en streaming. Vous pouvez utiliser des API telles que DOMImplementation pour utiliser ces réponses en streaming et mettre à jour efficacement votre code HTML.
Les résultats sont purement basés sur des chaînes. Vous devez d'abord les analyser si vous souhaitez les interpréter au format JSON ou dans d'autres formats de fichiers.
WebLLM présente toutefois certaines restrictions: l'application doit télécharger un modèle énorme avant la première utilisation, qui ne peut pas être partagé entre les origines. Il est donc possible qu'une autre application Web doive télécharger à nouveau le même modèle. Bien que WebGPU atteigne des performances d'inférence quasi natives, il n'atteint pas la vitesse native complète.
Démo
Ces inconvénients sont résolus par l'API Prompt, une API exploratoire proposée par Google qui s'exécute également côté client, mais qui utilise un modèle central téléchargé dans Chrome. Cela signifie que plusieurs applications peuvent utiliser le même modèle à pleine vitesse d'exécution.
Découvrez comment ajouter des fonctionnalités de chatbot à l'aide de l'API Prompt dans l'article suivant.