转载自三人行AI:WebLLM——一款将大语言模型聊天引入浏览器的开源工具
WebLLM 是一个模块化且可定制的 JavaScript 包,可以直接将语言模型聊天引入浏览器,并通过硬件加速。所有操作都在浏览器内完成,无需服务器支持,并通过 WebGPU 加速。
WebLLM 与 OpenAI API 完全兼容。也就是说,您可以在任何开源模型上使用相同的 OpenAI API,功能包括 json 模式、函数调用、流式传输等。
我们可以为每个人构建 AI 助手带来许多有趣的机会,并在享受 GPU 加速的同时保障隐私。
查看我们的演示网页试试看![1]您可以使用 WebLLM 作为基础 npm 包,并通过查阅文档和查看“快速开始”来构建自己的 Web 应用程序。此项目是 MLC LLM 的伴生项目,MLC LLM 可在 iPhone 和其他本地环境上本地运行 LLM。
WebLLM 提供了一个简洁且模块化的接口,可在浏览器中访问聊天机器人。WebLLM 包本身不包含 UI,并以模块化方式设计,可以挂接到任何 UI 组件。以下代码片段展示了在网页上生成流式响应的简单示例。您可以查看 examples/get-started[2] 以查看完整示例。
import * as webllm from "@mlc-ai/web-llm";
async function main() {
const initProgressCallback = (report: webllm.InitProgressReport) => {
const label = document.getElementById("init-label");
label.innerText = report.text;
};
const selectedModel = "Llama-3-8B-Instruct-q4f32_1";
const engine: webllm.EngineInterface = await webllm.CreateEngine(
selectedModel,
/*engineConfig=*/{ initProgressCallback: initProgressCallback }
);
const reply0 = await engine.chat.completions.create({
messages: [{ "role": "user", "content": "Tell me about Pittsburgh." }]
});
console.log(reply0);
console.log(await engine.runtimeStatsText());
}
main();
请注意,如果您需要将 webllm.Engine 的实例化与加载模型分开,您可以将
const engine: webllm.EngineInterface = await webllm.CreateEngine(
selectedModel,
/*engineConfig=*/{ initProgressCallback: initProgressCallback }
);
替换为等效的
const engine: webllm.EngineInterface = new webllm.Engine();
engine.setInitProgressCallback(initProgressCallback);
await engine.reload(selectedModel, chatConfig, appConfig);
WebLLM 支持 WebWorker API,因此您可以将生成过程挂接到单独的工作线程中,这样 webworker 中的计算就不会干扰 UI。
首先,我们创建一个工作线程脚本,该脚本创建一个引擎并将其连接到处理请求的处理器。
// worker.ts
import { EngineWorkerHandler, Engine } from "@mlc-ai/web-llm";
// 将 Engine 挂接到 worker 处理器
const engine = new Engine();
const handler = new EngineWorkerHandler(engine);
self.onmessage = (msg: MessageEvent) => {
handler.onmessage(msg);
};
然后在主逻辑中,我们创建一个实现相同EngineInterface 的 WebWorkerEngine。其余逻辑保持不变。
// main.ts
import * as webllm from "@mlc-ai/web-llm";
async function main() {
// 在此处使用 WebWorkerEngine 而不是 Engine
const engine: webllm.EngineInterface = await webllm.CreateWebWorkerEngine(
/*worker=*/new Worker(
new URL('./worker.ts', import.meta.url),
{ type: 'module' }
),
/*modelId=*/selectedModel,
/*engineConfig=*/{ initProgressCallback: initProgressCallback }
);
// 其余部分保持不变
}
您可以在 examples/simple-chat[3]中找到一个完整的聊天应用示例。
您还可以在 examples/chrome-extension[4] 和 examples/chrome-extension-webgpu-service-worker[5] 中找到使用 WebLLM 构建 Chrome 扩展的示例。后者利用了服务工作线程,因此扩展在后台持续运行。
WebLLM 旨在与 OpenAI API[6] 完全兼容。因此,除了构建简单的聊天机器人外,您还可以使用 WebLLM 实现以下功能:
•流式传输:以实时块的形式返回输出,使用异步生成器(AsyncGenerator)。•json 模式:高效确保输出以 json 格式返回,更多信息请参见 OpenAI 参考文档。•函数调用:通过 tools
和 tool_choice
字段进行函数调用。•种子复现:使用种子确保输出可复现,通过 seed
字段。
我们在 webllm.prebuiltAppConfig
中导出所有支持的模型,在此您可以看到一个模型列表,您可以简单地使用 await webllm.CreateEngine(anyModel)
来调用这些模型。预构建的模型包括:
•Llama-2•Gemma•Phi-1.5 和 Phi-2•Mistral-7B-Instruct•OpenHermes-2.5-Mistral-7B•NeuralHermes-2.5-Mistral-7B•TinyLlama•RedPajama
另外,您可以按照下面的描述编译您自己的模型和权重。
WebLLM 是 MLC LLM[7] 的伴生项目。它重用 MLC LLM 的模型构件和构建流程,请查看 MLC LLM 文档了解如何向 WebLLM 添加新的模型权重和库。
下面,我们将概述高级思想。WebLLM 包的两个元素使得支持新模型和权重变体成为可能:
•model_url:包含模型构件的 URL,如权重和元数据。•model_lib_url:包含加速模型计算的可执行文件的 Web Assembly 库(即 wasm 文件)的 URL。
这两者在 WebLLM 中都是可自定义的。
async function main() {
const appConfig = {
"model_list": [
{
"model_url": "/url/to/my/llama",
"model_id": "MyLlama-3b-v1-q4f32_0"
"model_lib_url": "/url/to/myllama3b.wasm",
}
],
};
// 覆盖默认设置
const chatOpts = {
"repetition_penalty": 1.01
};
const chat = new ChatModule();
// 加载预构建模型
// 使用聊天选项覆盖和应用配置
// 在底层,它将从 myLlamaUrl 加载模型
// 并将其缓存在浏览器缓存中
// 聊天也将从 "/url/to/myllama3b.wasm" 加载模型库,
// 假设它与 myLlamaUrl 中的模型兼容。
const engine = await webllm.CreateEngine(
"MyLlama-3b-v1-q4f32_0",
/*engineConfig=*/{ chatOpts: chatOpts, appConfig: appConfig }
);
}
在许多情况下,我们只想提供模型权重变体,而不必要提供新模型(例如,NeuralHermes-Mistral 可以重用 Mistral 的模型库)。有关模型库如何由不同模型变体共享的示例,请参见 prebuiltAppConfig。
注意:除非您想更改 WebLLM 包,否则无需自行构建。要简单使用 npm,请遵循“快速开始”或任何示例。
WebLLM 包是为 MLC LLM[8] 设计的 Web 运行时。
1.安装编译所需的所有前提条件:
i.emscripten[9]:这是一个基于 LLVM 的编译器,可以将 C/C++ 源代码编译为 WebAssembly。
•按照安装说明[10]安装最新的 emsdk。•通过 source path/to/emsdk_env.sh *源 *emsdk_env.sh,以便 emcc 可从 PATH 访问,并且命令 emcc 起作用。ii.按照官方指南安装 jekyll。如果您使用 nextjs(参见示例中的 next-simple-chat),则不需要此包。iii.通过命令安装 jekyll-remote-theme。如果安装被阻止,尝试使用 gem 镜像。
我们可以通过在终端尝试 emcc 和jekyll来验证安装是否成功。
2.设置必要环境
准备网页构建所需的所有依赖项:
./scripts/prep_deps.sh
3.构建 WebLLM 包
npm run build
4.验证一些子包 然后,您可以前往 examples[11]中的子文件夹验证一些子包。我们使用 Parcelv2 进行打包。尽管 Parcel 有时在跟踪父目录更改方面并不十分理想。当您在 WebLLM 包中进行更改时,尝试编辑子文件夹的 package.json 并保存,这将触发 Parcel 重建。
本文由笔者翻译整理自https://github.com/mlc-ai/web-llm?tab=readme-ov-file,如对你有帮助,请帮忙点赞、转发、关注。
[1]
查看我们的演示网页试试看!: https://webllm.mlc.ai/
[2]
examples/get-started: https://github.com/mlc-ai/web-llm/tree/main/examples/get-started
[3]
examples/simple-chat: https://github.com/mlc-ai/web-llm/tree/main/examples/simple-chat
[4]
examples/chrome-extension: https://github.com/mlc-ai/web-llm/tree/main/examples/chrome-extension
[5]
examples/chrome-extension-webgpu-service-worker: https://github.com/mlc-ai/web-llm/tree/main/examples/chrome-extension-webgpu-service-worker
[6]
OpenAI API: https://platform.openai.com/docs/api-reference/chat/create
[7]
MLC LLM: https://github.com/mlc-ai/mlc-llm
[8]
MLC LLM: https://github.com/mlc-ai/mlc-llm
[9]
emscripten: https://emscripten.org/
[10]
安装说明: https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended
[11]
examples: https://github.com/mlc-ai/web-llm/tree/main/examples