Motor de inferencia LLM de alto rendimiento LLM.
Documentación | Blog Post | Papel | Ejemplos
WEBLLM es un motor de inferencia LLM en el navegador de alto rendimiento que lleva la inferencia del modelo de idioma directamente a los navegadores web con aceleración de hardware. Todo se ejecuta dentro del navegador sin soporte del servidor y se acelera con WebGPU.
WEBLLM es totalmente compatible con la API de OpenAI. Es decir, puede usar la misma API de OpenAI en cualquier modelo de código abierto localmente, con funcionalidades que incluyen transmisión, modo JSON, llamado de funciones (WIP), etc.
Podemos brindar muchas oportunidades divertidas para construir asistentes de IA para todos y permitir la privacidad mientras disfrutamos de la aceleración de GPU.
Puede usar WEBLLM como un paquete NPM base y crear su propia aplicación web además de él siguiendo los ejemplos a continuación. Este proyecto es un proyecto complementario de MLC LLM, que permite la implementación universal de LLM en entornos de hardware.
¡Mira el chat de Webllm para probarlo!
Inferencia en el navegador : WEBLLM es un motor de inferencia de modelos de lenguaje de alto rendimiento y en el navegador que aprovecha WebGPU para la aceleración de hardware, lo que permite las potentes operaciones de LLM directamente dentro de los navegadores web sin procesamiento del lado del servidor.
Compatibilidad completa de la API de OpenAI : integre perfectamente su aplicación con WEBLLM utilizando la API de OpenAI con funcionalidades como la transmisión, el modo JSON, el control de nivel logit, la siembra y más.
Generación JSON estructurada : WEBLLM admite la generación estructurada del modo JSON de última generación, implementada en la parte de WebAssembly de la biblioteca de modelos para un rendimiento óptimo. Verifique el patio de juegos WEBLLM JSON en Huggingface para intentar generar la salida JSON con el esquema JSON personalizado.
Soporte de modelo extenso : WebllM admite de forma nativa una gama de modelos que incluyen Llama 3, Phi 3, Gemma, Mistral, Qwen (通义千问) y muchos otros, lo que lo hace versátil para varias tareas de IA. Para la lista completa de modelos compatibles, verifique los modelos MLC.
Integración de modelos personalizados : integrar e implementar fácilmente modelos personalizados en formato MLC, lo que le permite adaptar WEBLLM a necesidades y escenarios específicos, mejorando la flexibilidad en la implementación del modelo.
Integración de plug-and-play : integre fácilmente WEBLLM en sus proyectos utilizando administradores de paquetes como NPM e hilo, o directamente a través de CDN, completo con ejemplos completos y un diseño modular para conectarse con componentes de UI.
Transmisión e interacciones en tiempo real : admite la transmisión de completaciones de chat, lo que permite la generación de salida en tiempo real que mejora aplicaciones interactivas como chatbots y asistentes virtuales.
Soporte de trabajadores web y trabajadores de servicio : optimice el rendimiento de la interfaz de usuario y administre el ciclo de vida de los modelos de manera eficiente mediante la descarga de cálculos para separar hilos de trabajadores o trabajadores de servicios.
Soporte de extensión de Chrome : Extienda la funcionalidad de los navegadores web a través de extensiones de cromo personalizadas utilizando WEBLLM, con ejemplos disponibles para construir extensiones básicas y avanzadas.
Consulte la lista completa de modelos disponibles en los modelos MLC. WEBLLM admite un subconjunto de estos modelos disponibles y se puede acceder a la lista en prebuiltAppConfig.model_list .
Aquí están las principales familias de modelos que actualmente están compatibles:
Si necesita más modelos, solicite un nuevo modelo abriendo un problema o verifique los modelos personalizados sobre cómo compilar y usar sus propios modelos con WEBLLM.
Aprenda a usar WEBLLM para integrar modelos de idiomas grandes en su aplicación y generar completaciones de chat a través de este simple ejemplo de chatbot:
Para un ejemplo avanzado de un proyecto más grande y complicado, consulte el chat de WEBLLM.
Hay más ejemplos para diferentes casos de uso disponibles en la carpeta de ejemplos.
WEBLLM ofrece una interfaz minimalista y modular para acceder al chatbot en el navegador. El paquete está diseñado de manera modular para engancharse a cualquiera de los componentes de la interfaz de usuario.
# npm
npm install @mlc-ai/web-llm
# yarn
yarn add @mlc-ai/web-llm
# or pnpm
pnpm install @mlc-ai/web-llmLuego importe el módulo en su código.
// Import everything
import * as webllm from "@mlc-ai/web-llm" ;
// Or only import what you need
import { CreateMLCEngine } from "@mlc-ai/web-llm" ; Gracias a JSDelivr.com, WEBLLM se puede importar directamente a través de URL y trabajar fuera de la caja en plataformas de desarrollo en la nube como JSFIDDLE.NET, CodePen.io y Scribbler:
import * as webllm from "https://esm.run/@mlc-ai/web-llm" ;También se puede importar dinámicamente como:
const webllm = await import ( "https://esm.run/@mlc-ai/web-llm" ) ; La mayoría de las operaciones en WEBLLM se invocan a través de la interfaz MLCEngine . Puede crear una instancia MLCEngine y cargar el modelo llamando a la función de fábrica CreateMLCEngine() .
(Tenga en cuenta que la carga de los modelos requiere la descarga y puede tomar una cantidad significativa de tiempo para la primera ejecución sin almacenamiento en caché anteriormente. Debe manejar correctamente esta llamada asíncrona).
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
) ;Debajo del capó, esta función de fábrica realiza los siguientes pasos para crear primero una instancia del motor (sincrónica) y luego cargar el modelo (asíncrono). También puede hacerlos por separado en su aplicación.
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 ) ; Después de inicializar con éxito el motor, ahora puede invocar completaciones de chat utilizando las API de chat de estilo Operai a través de la interfaz engine.chat.completions . Para obtener la lista completa de parámetros y sus descripciones, verifique la sección a continuación y la referencia de la API de OpenAI.
(Nota: El parámetro model no es compatible y se ignorará aquí. En su lugar, llame CreateMLCEngine(model) o engine.reload(model)
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 también es compatible con la generación de finalización de chat. Para usarlo, simplemente pase stream: true al 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 ) ; Puede poner el cálculo pesado en un script de trabajadores para optimizar el rendimiento de su aplicación. Para hacerlo, necesitas:
Para obtener implementaciones detalladas de diferentes tipos de trabajadores, consulte las siguientes secciones.
WEBLLM viene con soporte API para WebWorker para que pueda conectar el proceso de generación en un hilo de trabajador separado para que la informática en el hilo del trabajador no interrumpa la interfaz de usuario.
Creamos un manejador en el hilo del trabajador que se comunica con el interfaz mientras maneja las solicitudes.
// 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 ) ;
} ; En la lógica principal, creamos un WebWorkerMLCEngine que implementa la misma MLCEngineInterface . El resto de la lógica sigue siendo el mismo.
// 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 viene con soporte API para ServiceWorker para que pueda conectar el proceso de generación en un trabajador de servicios para evitar recargar el modelo en cada visita de página y optimizar la experiencia fuera de línea de su aplicación.
(Tenga en cuenta que el ciclo de vida del trabajador del servicio es administrado por el navegador y puede ser asesinado en cualquier momento sin notificar a la webpp. ServiceWorkerMLCEngine intentará mantener vivo el hilo del trabajador del servicio enviando periódicamente eventos del corazón, pero su aplicación también debe incluir el manejo de errores adecuado. Compruebe keepAliveMs y missedHeatbeat en ServiceWorkerMLCEngine para obtener más detalles.
Creamos un manejador en el hilo del trabajador que se comunica con el interfaz mientras maneja las solicitudes.
// 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" ) ;
} ) ; Luego, en la lógica principal, registramos el trabajador de servicio y creamos el motor utilizando la función CreateServiceWorkerMLCEngine . El resto de la lógica sigue siendo el mismo.
// 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
) ;Puede encontrar un ejemplo completo sobre cómo ejecutar WEBLLM en Service Worker en ejemplos/trabajador de servicio.
También puede encontrar ejemplos de extensión de cromo de construcción con WEBLLM en ejemplos/extensión de cromo y ejemplos/crome-extension-webgpu-service-service-worker. Este último aprovecha el trabajador del servicio, por lo que la extensión es persistente en el fondo. Además, puede explorar otro proyecto completo de una extensión de Chrome, asistente de WEBLLM, que aprovecha WEBLLM aquí.
WEBLLM está diseñado para ser totalmente compatible con la API de OpenAI. Por lo tanto, además de construir un chatbot simple, también puede tener las siguientes funcionalidades con WEBLLM:
seed de campos.tools de campos y tool_choice (con soporte preliminar); o la función manual llamando sin tools o tool_choice (mantiene la mayor flexibilidad). WEBLLM funciona como un proyecto complementario de MLC LLM y admite modelos personalizados en formato MLC. Reutiliza el artefacto modelo y construye el flujo de MLC LLM. Para compilar y usar sus propios modelos con WEBLLM, consulte el documento MLC LLM sobre cómo compilar e implementar nuevas pesas y bibliotecas de modelos a WEBLLM.
Aquí, repasamos la idea de alto nivel. Hay dos elementos del paquete WEBLLM que habilitan nuevos modelos y variantes de peso.
model : contiene una URL para modelar artefactos, como pesos y metadatos.model_lib : una URL a la biblioteca de ensamblaje web (es decir, el archivo WASM) que contiene los ejecutables para acelerar los cálculos del modelo.Ambos son personalizables en el 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 ,
) ;
} En muchos casos, solo queremos suministrar la variante de peso del modelo, pero no necesariamente un nuevo modelo (por ejemplo, NeuralHermes-Mistral puede reutilizar la biblioteca de modelos de Mistral ). Para ver ejemplos de cómo una biblioteca de modelos puede ser compartida por diferentes variantes del modelo, consulte webllm.prebuiltAppConfig .
Nota: No necesita construir desde la fuente a menos que desee modificar el paquete WEBLLM. Para usar el NPM, simplemente siga, comience o cualquiera de los ejemplos.
Para construir desde la fuente, simplemente ejecute:
npm install
npm run build Luego, para probar los efectos de su cambio de código en un ejemplo, examples/get-started/package.json , cambie de "@mlc-ai/web-llm": "^0.2.77" a "@mlc-ai/web-llm": ../..
Luego corre:
cd examples/get-started
npm install
npm start Tenga en cuenta que a veces necesitaría cambiar entre file:../.. y ../.. para activar NPM para reconocer nuevos cambios. En el peor de los casos, puede ejecutar:
cd examples/get-started
rm -rf node_modules dist package-lock.json .parcel-cache
npm install
npm startEl tiempo de ejecución de WEBLLM depende en gran medida de TVMJS: https://github.com/apache/tvm/tree/main/web
Si bien también está disponible como un paquete NPM: https://www.npmjs.com/package/@mlc-ai/web-runtime, puede construirlo desde la fuente si es necesario seguir los pasos a continuación.
Instale Emscripten. Es un compilador basado en LLVM que compila el código fuente C/C ++ en WebAssembly.
emsdk_env.sh por source path/to/emsdk_env.sh , de modo que emcc se puede acumular desde la ruta y el comando emcc funciona. Podemos verificar la instalación exitosa probando emcc Terminal.
Nota: Recientemente descubrimos que usar la última versión emcc puede encontrarse con problemas durante el tiempo de ejecución. Use ./emsdk install 3.1.56 en lugar de ./emsdk install latest por ahora como una solución. El error puede parecer
Init error, LinkError: WebAssembly.instantiate(): Import #6 module="wasi_snapshot_preview1"
function="proc_exit": function import requires a callable
En ./package.json , cambie de "@mlc-ai/web-runtime": "0.18.0-dev2", a "@mlc-ai/web-runtime": "file:./tvm_home/web", .
Configuración del entorno necesario
Prepare todas las dependencias necesarias para la compilación web:
./scripts/prep_deps.sh En este paso, si $TVM_SOURCE_DIR no se define en el entorno, ejecutaremos la siguiente línea para crear dependencia tvmjs :
git clone https://github.com/mlc-ai/relax 3rdparty/tvm-unity --recursive Esto clama la actual cabeza de mlc-ai/relax . Sin embargo, puede que no siempre sea la rama correcta o se comprometa con el clon. Para construir una versión específica de NPM a partir de la fuente, consulte la versión Bump PR, que establece que se ramifica (es decir, mlc-ai/relax o apache/tvm ) y que depende de la versión actual de WEBLLM. Por ejemplo, la versión 0.2.52, de acuerdo con su versión Bump PR #521, se construye al verificar el siguiente confirmación https://github.com/apache/tvm/commit/e6476847753c80e054719ac47bc2091c888418b6 en apache/tvm , en lugar del head de mlc-ai/relax .
Además, --recursive es necesario e importante. De lo contrario, puede encontrar errores como fatal error: 'dlpack/dlpack.h' file not found .
Construir paquete WEBLLM
npm run buildValidar algunos de los subgrupos
Luego puede ir a las subcarpetas en ejemplos para validar algunos de los subgrupos. Usamos PARCELV2 para la agrupación. Aunque la parcela no es muy buena para rastrear los cambios en el directorio de los padres a veces. Cuando realice un cambio en el paquete WEBLLM, intente editar el package.json de la subcarpeta y guárdelo, lo que activará el paquete para reconstruir.
Este proyecto es iniciado por miembros de CMU Catalyst, UW Sample, SJTU, Octoml y la comunidad MLC. Nos encantaría continuar desarrollando y apoyando a la comunidad de ML de código abierto.
Este proyecto solo es posible gracias a los ecosistemas de código abierto de los hombros en los que nos enfrentamos. Queremos agradecer a la comunidad de Apache TVM y a los desarrolladores del esfuerzo de unidad TVM. Los miembros de la comunidad de ML de código abierto pusieron a disposición públicamente estos modelos. Pytorch y abrazando comunidades faciales hacen que estos modelos sean accesibles. Nos gustaría agradecer a los equipos detrás de Vicuna, SentencePiece, Llama y Alpaca. También nos gustaría agradecer a las comunidades WebAssembly, Emscripten y WebGPU. Finalmente, gracias a los desarrolladores de Dawn y WebGPU.
Si encuentra que este proyecto es útil, cite:
@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},
}
⬆ Volver a arriba ⬆