Moteur d'inférence LLM in-browser haute performance.
Documentation | Blogpost | Papier | Exemples
WebLLM est un moteur d'inférence LLM In-Browser haute performance qui apporte l'inférence du modèle de langage directement sur les navigateurs Web avec une accélération matérielle. Tout s'exécute à l'intérieur du navigateur sans support de serveur et est accéléré avec WebGPU.
Webllm est entièrement compatible avec l'API OpenAI. Autrement dit, vous pouvez utiliser la même API OpenAI sur tous les modèles open source localement, avec des fonctionnalités, y compris le streaming, le mode JSON, l'appel de fonction (WIP), etc.
Nous pouvons apporter de nombreuses opportunités amusantes pour construire des assistants d'IA pour tout le monde et permettre la vie privée tout en profitant de l'accélération du GPU.
Vous pouvez utiliser WebLLM comme package NPM de base et créer votre propre application Web en haut de celle-ci en suivant les exemples ci-dessous. Ce projet est un projet compagnon de MLC LLM, qui permet le déploiement universel de LLM dans les environnements matériels.
Découvrez le chat Webllm pour l'essayer!
Inférence dans le navigateur : WebLLM est un moteur d'inférence du modèle de langage in-courbé à haute performance qui exploite WebGPU pour l'accélération matérielle, permettant des opérations LLM puissantes directement dans les navigateurs Web sans traitement côté serveur.
Compatibilité complète de l'API OpenAI : intégrez de manière transparente votre application avec WebLLM en utilisant l'API OpenAI avec des fonctionnalités telles que le streaming, le mode JSON, le contrôle au niveau logit, l'ensemencement, etc.
Génération JSON structurée : WebLLM prend en charge la génération structurée en mode JSON de pointe, implémentée dans la partie Webassembly de la bibliothèque de modèles pour des performances optimales. Vérifiez le terrain de jeu JSON Webllm sur HuggingFace pour essayer de générer une sortie JSON avec un schéma JSON personnalisé.
Support complet du modèle : Webllm soutient nativement une gamme de modèles, notamment LLAMA 3, PHI 3, Gemma, Mistral, Qwen (通义千问) et bien d'autres, ce qui le rend polyvalent pour diverses tâches d'IA. Pour la liste complète des modèles pris en charge, vérifiez les modèles MLC.
Intégration des modèles personnalisés : intégrer et déployer facilement les modèles personnalisés au format MLC, vous permettant d'adapter WebLLM à des besoins et des scénarios spécifiques, en améliorant la flexibilité dans le déploiement du modèle.
Intégration de plug-and-play : intégrer facilement WebLLM dans vos projets à l'aide de gestionnaires de packages comme NPM et YARN, ou directement via CDN, avec des exemples complets et une conception modulaire pour se connecter avec des composants d'interface utilisateur.
Streaming et interactions en temps réel : prend en charge les compléments de chat en streaming, permettant la génération de sortie en temps réel qui améliore les applications interactives comme les chatbots et les assistants virtuels.
Soutien du travailleur Web et des employés des services : optimiser les performances de l'interface utilisateur et gérer efficacement le cycle de vie des modèles en déchargeant les calculs pour séparer les threads ou les travailleurs de service.
Prise en charge de l'extension Chrome : étendez la fonctionnalité des navigateurs Web à travers des extensions de chrome personnalisées à l'aide de WebLLM, avec des exemples disponibles pour la création d'extensions de base et avancées.
Consultez la liste complète des modèles disponibles sur les modèles MLC. WebLLM prend en charge un sous-ensemble de ces modèles disponibles et la liste est accessible sur prebuiltAppConfig.model_list .
Voici les principales familles de modèles actuellement soutenues:
Si vous avez besoin de plus de modèles, demandez un nouveau modèle en ouvrant un problème ou vérifiez des modèles personnalisés pour compiler et utiliser vos propres modèles avec WebLLM.
Apprenez à utiliser WebLLM pour intégrer de grands modèles de langage dans votre application et générer des compléments de chat via ce simple exemple de chatbot:
Pour un exemple avancé d'un projet plus grand et plus compliqué, vérifiez le chat Webllm.
Plus d'exemples pour différents cas d'utilisation sont disponibles dans le dossier Exemples.
WebLLM propose une interface minimaliste et modulaire pour accéder au chatbot dans le navigateur. Le package est conçu de manière modulaire pour s'accrocher à l'un des composants de l'interface utilisateur.
# npm
npm install @mlc-ai/web-llm
# yarn
yarn add @mlc-ai/web-llm
# or pnpm
pnpm install @mlc-ai/web-llmImportez ensuite le module dans votre code.
// Import everything
import * as webllm from "@mlc-ai/web-llm" ;
// Or only import what you need
import { CreateMLCEngine } from "@mlc-ai/web-llm" ; Grâce à jsdelivr.com, webllm peut être importé directement via URL et travailler hors de la boîte sur les plates-formes de développement cloud comme jsfiddle.net, codepen.io et scribbler:
import * as webllm from "https://esm.run/@mlc-ai/web-llm" ;Il peut également être importé dynamiquement comme:
const webllm = await import ( "https://esm.run/@mlc-ai/web-llm" ) ; La plupart des opérations dans WebLLM sont invoquées via l'interface MLCEngine . Vous pouvez créer une instance MLCEngine et charger le modèle en appelant la fonction d'usine CreateMLCEngine() .
(Notez que les modèles de chargement nécessitent le téléchargement et cela peut prendre beaucoup de temps pour la toute première exécution sans mise en cache précédemment. Vous devez correctement gérer cet appel asynchrone.)
import { CreateMLCEngine } from "@mlc-ai/web-llm" ;
// Callback function to update model loading progress
const initProgressCallback = ( initProgress ) => {
console . log ( initProgress ) ;
}
const selectedModel = "Llama-3.1-8B-Instruct-q4f32_1-MLC" ;
const engine = await CreateMLCEngine (
selectedModel ,
{ initProgressCallback : initProgressCallback } , // engineConfig
) ;Sous le capot, cette fonction d'usine effectue les étapes suivantes pour créer d'abord une instance de moteur (synchrone), puis charger le modèle (asynchrone). Vous pouvez également les faire séparément dans votre application.
import { MLCEngine } from "@mlc-ai/web-llm" ;
// This is a synchronous call that returns immediately
const engine = new MLCEngine ( {
initProgressCallback : initProgressCallback
} ) ;
// This is an asynchronous call and can take a long time to finish
await engine . reload ( selectedModel ) ; Après avoir réussi à initialiser le moteur, vous pouvez désormais invoquer les compléments de chat à l'aide d'API de chat de style Openai via l'interface engine.chat.completions . Pour la liste complète des paramètres et de leurs descriptions, vérifiez la section ci-dessous et la référence API OpenAI.
(Remarque: le paramètre model n'est pas pris en charge et sera ignoré ici. Au lieu de cela, appelez CreateMLCEngine(model) ou engine.reload(model) à la place comme indiqué dans la création mlCengine ci-dessus.)
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 ) ; WebLLM prend également en charge la génération d'achèvement du chat en streaming. Pour l'utiliser, passez simplement stream: true au engine.chat.completions.create Call.
const messages = [
{ role : "system" , content : "You are a helpful AI assistant." } ,
{ role : "user" , content : "Hello!" } ,
]
// Chunks is an AsyncGenerator object
const chunks = await engine . chat . completions . create ( {
messages ,
temperature : 1 ,
stream : true , // <-- Enable streaming
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 ) ; // only last chunk has usage
}
}
const fullReply = await engine . getMessage ( ) ;
console . log ( fullReply ) ; Vous pouvez mettre le calcul lourd dans un script de travail pour optimiser les performances de votre application. Pour ce faire, vous devez:
Pour des implémentations détaillées de différents types de travailleurs, consultez les sections suivantes.
WebLLM est livré avec la prise en charge de l'API pour le webworker afin que vous puissiez accrocher le processus de génération dans un thread de travailleur séparé afin que l'informatique dans le fil du travailleur ne perturbe pas l'interface utilisateur.
Nous créons un gestionnaire dans le fil de travail qui communique avec le frontend lors de la gestion des demandes.
// worker.ts
import { WebWorkerMLCEngineHandler } from "@mlc-ai/web-llm" ;
// A handler that resides in the worker thread
const handler = new WebWorkerMLCEngineHandler ( ) ;
self . onmessage = ( msg : MessageEvent ) => {
handler . onmessage ( msg ) ;
} ; Dans la logique principale, nous créons un WebWorkerMLCEngine qui implémente le même MLCEngineInterface . Le reste de la logique reste le même.
// main.ts
import { CreateWebWorkerMLCEngine } from "@mlc-ai/web-llm" ;
async function main ( ) {
// Use a WebWorkerMLCEngine instead of MLCEngine here
const engine = await CreateWebWorkerMLCEngine (
new Worker (
new URL ( "./worker.ts" , import . meta . url ) ,
{
type : "module" ,
}
) ,
selectedModel ,
{ initProgressCallback } , // engineConfig
) ;
// everything else remains the same
}WebLLM est livré avec la prise en charge de l'API pour travailleur de service afin que vous puissiez accrocher le processus de génération à un travailleur de service pour éviter de recharger le modèle à chaque page de visite et d'optimiser l'expérience hors ligne de votre application.
(Remarque, le cycle de vie du travailleur des services est géré par le navigateur et peut être tué à tout moment sans notifier le keepAliveMs . ServiceWorkerMLCEngine essaiera de garder le fil de service en vie en envoyant périodiquement des événements de battements de cœur, mais votre ServiceWorkerMLCEngine devrait également inclure une bonne gestion missedHeatbeat erreurs.
Nous créons un gestionnaire dans le fil de travail qui communique avec le frontend lors de la gestion des demandes.
// sw.ts
import { ServiceWorkerMLCEngineHandler } from "@mlc-ai/web-llm" ;
let handler : ServiceWorkerMLCEngineHandler ;
self . addEventListener ( "activate" , function ( event ) {
handler = new ServiceWorkerMLCEngineHandler ( ) ;
console . log ( "Service Worker is ready" ) ;
} ) ; Ensuite, dans la logique principale, nous enregistrons le travailleur des services et créons le moteur à l'aide de la fonction CreateServiceWorkerMLCEngine . Le reste de la logique reste le même.
// 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
) ;Vous pouvez trouver un exemple complet sur la façon d'exécuter WebLLM dans le travailleur des services dans des exemples / travailleur de service.
Vous pouvez également trouver des exemples de construction d'extension chromée avec WebLLM dans des exemples / chrome-extension et des exemples / chrome-extension-webgpu-service-travailleur. Ce dernier tire parti du travailleur des services, donc l'extension est persistante en arrière-plan. De plus, vous pouvez explorer un autre projet complet d'une extension Chrome, WebllM Assistant, qui exploite Webllm ici.
Webllm est conçu pour être entièrement compatible avec l'API OpenAI. Ainsi, en plus de construire un chatbot simple, vous pouvez également avoir les fonctionnalités suivantes avec Webllm:
seed .tools et tool_choice (avec support préliminaire); ou l'appel de fonction manuelle sans tools ou tool_choice (maintient le plus de flexibilité). WebLLM fonctionne comme un projet compagnon de MLC LLM et il prend en charge les modèles personnalisés au format MLC. Il réutilise l'artefact modèle et construit le flux de MLC LLM. Pour compiler et utiliser vos propres modèles avec WebLLM, veuillez consulter le document MLC LLM sur la façon de compiler et de déployer de nouveaux poids et bibliothèques de modèles sur WebLLM.
Ici, nous passons en revue l'idée de haut niveau. Il y a deux éléments du package WebLLM qui permettent de nouveaux modèles et variantes de poids.
model : contient une URL pour modéliser des artefacts, tels que les poids et les méta-données.model_lib : une URL à la bibliothèque d'assembly Web (fichier WASM) qui contient les exécutables pour accélérer les calculs du modèle.Les deux sont personnalisables dans le Webllm.
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" ,
}
] ,
} ;
// override default
const chatOpts = {
"repetition_penalty" : 1.01
} ;
// load a prebuilt model
// with a chat option override and app config
// under the hood, it will load the model from myLlamaUrl
// and cache it in the browser cache
// The chat will also load the model library from "/url/to/myllama3b.wasm",
// assuming that it is compatible to the model in myLlamaUrl.
const engine = await CreateMLCEngine (
"MyLlama-3b-v1-q4f32_0" ,
{ appConfig } , // engineConfig
chatOpts ,
) ;
} Dans de nombreux cas, nous voulons seulement fournir la variante du poids du modèle, mais pas nécessairement un nouveau modèle (par exemple, NeuralHermes-Mistral peut réutiliser la bibliothèque de modèles de Mistral ). Pour des exemples de la façon dont une bibliothèque de modèles peut être partagée par différentes variantes de modèle, voir webllm.prebuiltAppConfig .
Remarque: vous n'avez pas besoin de construire à partir de la source, sauf si vous souhaitez modifier le package WebLLM. Pour utiliser le NPM, suivez simplement démarrer ou l'un des exemples à la place.
Pour construire à partir de la source, exécutez simplement:
npm install
npm run build Ensuite, pour tester les effets de votre code, changez par exemple, à l'intérieur examples/get-started/package.json , passez de "@mlc-ai/web-llm": "^0.2.77" à "@mlc-ai/web-llm": ../..
Puis courez:
cd examples/get-started
npm install
npm start Notez que parfois vous deviez basculer entre file:../.. et ../.. pour déclencher le NPM pour reconnaître les nouveaux changements. Dans le pire des cas, vous pouvez courir:
cd examples/get-started
rm -rf node_modules dist package-lock.json .parcel-cache
npm install
npm startLe runtime de Webllm dépend en grande partie de TVMJS: https://github.com/apache/tvm/tree/main/web
Bien qu'il soit également disponible en tant que package NPM: https://www.npmjs.com/package/@mlc-ai/web-runtime, vous pouvez le construire à partir de la source si nécessaire en suivant les étapes ci-dessous.
Installez Emscripten. Il s'agit d'un compilateur basé sur LLVM qui compile le code source C / C ++ sur WebAssembly.
emsdk_env.sh par source path/to/emsdk_env.sh , de sorte que emcc est accessible à partir de Path et que la commande emcc fonctionne. Nous pouvons vérifier l'installation réussie en essayant le terminal emcc .
Remarque: Nous avons récemment constaté que l'utilisation de la dernière version emcc pourrait rencontrer des problèmes pendant l'exécution. Utilisez ./emsdk install 3.1.56 au lieu de ./emsdk install latest pour l'instant comme solution de contournement. L'erreur peut ressembler
Init error, LinkError: WebAssembly.instantiate(): Import #6 module="wasi_snapshot_preview1"
function="proc_exit": function import requires a callable
Dans ./package.json , passer à partir de "@mlc-ai/web-runtime": "0.18.0-dev2", à "@mlc-ai/web-runtime": "file:./tvm_home/web", .
Configuration de l'environnement nécessaire
Préparez toutes les dépendances nécessaires à la construction Web:
./scripts/prep_deps.sh Dans cette étape, si $TVM_SOURCE_DIR n'est pas défini dans l'environnement, nous exécuterons la ligne suivante pour créer la dépendance tvmjs :
git clone https://github.com/mlc-ai/relax 3rdparty/tvm-unity --recursive Cela clones la tête actuelle de mlc-ai/relax . Cependant, ce n'est peut-être pas toujours la branche correcte ou s'engager à clone. Pour construire une version NPM spécifique à partir de Source, reportez-vous à la version Bump Pr, qui indique quelle branche (c'est-à-dire mlc-ai/relax ou apache/tvm ) et qui commet la version WebLLM actuelle dépend. Par exemple, la version 0.2.52, selon sa version Bump PR # 521, est construite en consultant le commit suivant https://github.com/apache/tvm/commit/e6476847753c80e054719ac47bc2091c888418b6 dans apache/tvm , plutôt que le chef de la tête de mlc-ai/relax .
En outre, --recursive est nécessaire et important. Sinon, vous pouvez rencontrer des erreurs comme fatal error: 'dlpack/dlpack.h' file not found .
Construire le package Webllm
npm run buildValider certains des sous-packages
Vous pouvez ensuite accéder aux sous-dossiers par exemple pour valider certains des sous-packages. Nous utilisons Parcelv2 pour le regroupement. Bien que le colis ne soit pas très bon pour suivre parfois les changements du répertoire parent. Lorsque vous apportez un changement dans le package Webllm, essayez de modifier le package.json du sous-dossier et l'enregistrera, ce qui déclenchera la parcelle pour reconstruire.
Ce projet est lancé par des membres de CMU Catalyst, UW Sampl, SJTU, Octoml et la communauté MLC. Nous serions ravis de continuer à développer et à soutenir la communauté ML open source.
Ce projet n'est possible que grâce aux écosystèmes open source des épaules sur lesquels nous nous tenons. Nous tenons à remercier la communauté Apache TVM et les développeurs de l'effort TVM Unity. Les membres de la communauté ML open-source ont rendu ces modèles accessibles au public. Les communautés de pytorch et d'étreinte rendent ces modèles accessibles. Nous tenons à remercier les équipes derrière Vicuna, la phrase, le lama et l'alpaga. Nous tenons également à remercier les communautés WebAssembly, Emscripten et WebGPU. Enfin, grâce aux développeurs de Dawn et WebGPU.
Si vous trouvez ce projet utile, veuillez citer:
@misc{ruan2024webllmhighperformanceinbrowserllm,
title={WebLLM: A High-Performance In-Browser LLM Inference Engine},
author={Charlie F. Ruan and Yucheng Qin 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={2024},
eprint={2412.15803},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2412.15803},
}
⬆ Retour vers le haut ⬆