图龙网络科技

问答社区

原创作者: 图龙网络科技 发布时间: 2023-09-23 229.8K 人阅读

WebLLM与OpenAI API完全兼容。 本地任何开源模型上使用相同的 OpenAI API

太极混元 发布于 1个月前 分类:语言模型

WebLLM与OpenAI API完全兼容。 也就是说,您可以在本地任何开源模型上使用相同的 OpenAI API ,其功能包括流式处理、JSON 模式、函数调用 (WIP) 等。

我们可以带来很多有趣的机会,为每个人构建人工智能助手,并在享受 GPU 加速的同时实现隐私。

您可以使用 WebLLM 作为基础npm 包,并按照以下示例在其上构建您自己的 Web 应用程序。该项目是MLC LLM的姊妹项目,可实现跨硬件环境的 LLM 通用部署。

主要特点

  • 浏览器内推理:WebLLM 是一种高性能、浏览器内语言模型推理引擎,利用 WebGPU 进行硬件加速,直接在 Web 浏览器中实现强大的 LLM 操作,无需服务器端处理。

  • 完全 OpenAI API 兼容性:使用 OpenAI API 将您的应用程序与 WebLLM 无缝集成,并具有流式传输、JSON 模式、logit 级别控制、播种等功能。

  • 结构化 JSON 生成:WebLLM 支持最先进的 JSON 模式结构化生成,在模型库的 WebAssembly 部分中实现,以实现最佳性能。检查HuggingFace 上的WebLLM JSON Playground,尝试使用自定义 JSON 模式生成 JSON 输出。

  • 广泛的模型支持:WebLLM 原生支持一系列模型,包括 Llama 3、Phi 3、Gemma、Mistral、Qwen(通义千问)等,使其适用于各种 AI 任务。有关完整支持的型号列表,请查看MLC 型号

  • 自定义模型集成:轻松集成和部署 MLC 格式的自定义模型,让您能够根据特定需求和场景调整 WebLLM,增强模型部署的灵活性。

  • 即插即用集成:使用 NPM 和 Yarn 等包管理器或直接通过 CDN 轻松将 WebLLM 集成到您的项目中,并提供全面的示例和用于连接 UI 组件的模块化设计。

  • 流式传输和实时交互:支持流式聊天完成,允许实时输出生成,从而增强聊天机器人和虚拟助手等交互式应用程序。

  • Web Worker 和 Service Worker 支持:通过将计算卸载到单独的工作线程或服务工作线程,优化 UI 性能并有效管理模型的生命周期。

  • Chrome 扩展支持:使用 WebLLM 通过自定义 Chrome 扩展来扩展 Web 浏览器的功能,并提供可用于构建基本和高级扩展的示例。

内置型号

检查MLC 型号上可用型号的完整列表。 WebLLM 支持这些可用模型的子集,可以在 访问该列表prebuiltAppConfig.model_list

以下是当前支持的主要模型系列:

  • 羊驼:羊驼 3、羊驼 2、Hermes-2-Pro-Llama-3
  • Φ:Φ3、Φ2、Φ1.5
  • 杰玛:杰玛-2B
  • 米斯特拉尔:米斯特拉尔-7B-v0.3、Hermes-2-Pro-Mistral-7B、NeuralHermes-2.5-Mistral-7B、OpenHermes-2.5-Mistral-7B
  • Qwen (通义千问) : Qwen2 0.5B, 1.5B, 7B

如果您需要更多模型,请通过打开问题请求新模型,或检查自定义模型以了解如何通过 WebLLM 编译和使用您自己的模型。

通过示例快速入门

了解如何使用 WebLLM 将大型语言模型集成到您的应用程序中,并通过这个简单的聊天机器人示例生成聊天完成:

有关更大、更复杂项目的高级示例,请查看WebLLM 聊天

示例文件夹中提供了不同用例的更多示例。

开始使用

WebLLM 提供了一个极简且模块化的界面来访问浏览器中的聊天机器人。该包以模块化方式设计,可以连接到任何 UI 组件。

安装

包管理器

# npm
npm install @mlc-ai/web-llm
# yarn
yarn add @mlc-ai/web-llm
# or pnpm
pnpm install @mlc-ai/web-llm

然后将模块导入到您的代码中。

// Import everything
import * as webllm from "@mlc-ai/web-llm";
// Or only import what you need
import { CreateMLCEngine } from "@mlc-ai/web-llm";

CDN 交付

感谢jsdelivr.com ,WebLLM 可以直接通过 URL 导入,并在jsfiddle.netCodepen.ioScribbler等云开发平台上开箱即用:

import * as webllm from "https://esm.run/@mlc-ai/web-llm";

它也可以动态导入为:

const webllm = await import ("https://esm.run/@mlc-ai/web-llm");

创建MLC引擎

WebLLM 中的大多数操作都是通过MLCEngine接口调用的。您可以MLCEngine通过调用工厂函数来创建实例并加载模型CreateMLCEngine()

(请注意,加载模型需要下载,并且在之前没有缓存的情况下首次运行可能会花费大量时间。您应该正确处理此异步调用。)

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
);

在底层,该工厂函数执行以下步骤,首先创建引擎实例(同步),然后加载模型(异步)。您也可以在您的应用程序中单独执行它们。

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);

聊天完成

成功初始化引擎后,您现在可以通过界面使用 OpenAI 风格的聊天 API 调用聊天完成engine.chat.completions。有关参数及其描述的完整列表,请查看下面的部分OpenAI API 参考

(注意:该model参数不受支持,此处将被忽略。而是调用CreateMLCEngine(model)或 ,engine.reload(model)如上面的创建 MLCEngine所示。)

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 还支持流式聊天完成生成。要使用它,只需传递stream: trueengine.chat.completions.create调用即可。

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);

高级用法

使用工人

您可以将繁重的计算放入工作脚本中以优化应用程序性能。为此,您需要:

  1. 在工作线程中创建一个处理程序,在处理请求时与前端进行通信。
  2. 在主应用程序中创建一个工作引擎,该引擎在幕后将消息发送到工作线程中的处理程序。

有关不同类型 Worker 的详细实现,请查看以下部分。

专用网络工作者

WebLLM 附带了对 WebWorker 的 API 支持,因此您可以将生成过程挂钩到单独的工作线程中,这样工作线程中的计算就不会破坏 UI。

我们在工作线程中创建一个处理程序,在处理请求时与前端进行通信。

// 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);
};

在主逻辑中,我们创建一个WebWorkerMLCEngine实现相同的MLCEngineInterface.其余逻辑保持不变。

// 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 附带对 ServiceWorker 的 API 支持,因此您可以将生成过程挂接到 Service Worker 中,以避免在每次页面访问时重新加载模型,并优化应用程序的离线体验。

(请注意,Service Worker 的生命周期由浏览器管理,可以随时终止,而无需通知 Web 应用程序。ServiceWorkerMLCEngine将尝试通过定期发送心跳事件来保持 Service Worker 线程处于活动状态,但您的应用程序还应包括适当的错误处理。检查keepAliveMsmissedHeatbeat了解ServiceWorkerMLCEngine更多详情。)

我们在工作线程中创建一个处理程序,在处理请求时与前端进行通信。

// 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");
});

然后在主逻辑中,我们注册 Service Worker 并使用函数创建引擎 CreateServiceWorkerMLCEngine。其余逻辑保持不变。

// 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
  );

您可以在example/service-worker中找到有关如何在服务工作线程中运行 WebLLM 的完整示例。

Chrome 扩展程序

您还可以在example/chrome-extensionExamples/chrome-extension-webgpu-service-worker中找到使用 WebLLM 构建 Chrome 扩展程序的示例。后一种利用服务工作者,因此扩展在后台持久存在。

完全兼容 OpenAI

WebLLM 的设计与OpenAI API完全兼容。因此,除了构建一个简单的聊天机器人外,您还可以使用 WebLLM 获得以下功能:

  • Streaming:以 AsyncGenerator 的形式实时返回输出块
  • json-mode:有效确保输出为 JSON 格式,请参阅OpenAI 参考了解更多信息。
  • 种子繁殖:使用播种来确保田地的可重复输出seed
  • 函数调用(WIP):使用字段tools和进行函数调用tool_choice(初步支持);或不带toolsor的手动函数调用tool_choice(保持最大的灵活性)。

定制型号

WebLLM 作为MLC LLM的配套项目,支持 MLC 格式的自定义模型。它重用模型工件并构建 MLC LLM 流程。要通过 WebLLM 编译和使用您自己的模型,请查看 MLC LLM 文档, 了解如何编译新模型权重和库并将其部署到 WebLLM。

在这里,我们回顾一下高层的想法。 WebLLM 包中有两个元素可实现新模型和权重变体。

  • model:包含模型工件的 URL,例如权重和元数据。
  • model_lib:Web 程序集库(即 wasm 文件)的 URL,其中包含加速模型计算的可执行文件。

两者均可在 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,
  );
}

在许多情况下,我们只想提供模型权重变体,但不一定是新模型(例如NeuralHermes-Mistral可以重用Mistral的模型库)。有关不同模型变体如何共享模型库的示例,请参阅webllm.prebuiltAppConfig

从源代码构建 WebLLM 包

注意:除非您想修改 WebLLM 包,否则您不需要从源代码构建。要使用 npm,只需按照入门或任何示例进行操作即可。

要从源代码构建,只需运行:

npm install
npm run build

然后,要测试示例中代码更改的效果,请在 内部examples/get-started/package.json从 更改"@mlc-ai/web-llm": "^0.2.73""@mlc-ai/web-llm": ../..

然后运行:

cd examples/get-started
npm install
npm start

请注意,有时您需要在file:../..和之间切换../..以触发 npm 来识别新更改。在最坏的情况下,你可以运行:

cd examples/get-started
rm -rf node_modules dist package-lock.json .parcel-cache
npm install
npm start

如果您需要从源代码构建 TVMjs

WebLLM的运行时很大程度上取决于TVMjs:https://github.com/apache/tvm/tree/main/web

虽然它也可以作为 npm 包提供:https://www.npmjs.com/package/@mlc-ai/web-runtime,但如果需要,您可以按照以下步骤从源代码构建它。

  1. 安装emscripten。它是一个基于 LLVM 的编译器,可将 C/C++ 源代码编译为 WebAssembly。

    • 按照安装说明安装最新的 emsdk。
    • 源由,以便emsdk_env.sh可以从 PATH 访问并且该命令有效。source path/to/emsdk_env.shemccemcc

    我们可以通过终端测试来验证安装是否成功emcc

    注意:我们最近发现使用最新emcc版本可能会在运行时遇到问题。现在使用./emsdk install 3.1.56而不是作为解决方法。./emsdk install latest错误可能看起来像

    Init error, LinkError: WebAssembly.instantiate(): Import #6 module="wasi_snapshot_preview1"
    function="proc_exit": function import requires a callable
    
  2. 在 中./package.json,从 更改"@mlc-ai/web-runtime": "0.18.0-dev2","@mlc-ai/web-runtime": "file:./tvm_home/web",

  3. 设置必要的环境

    准备 Web 构建所需的所有依赖项:

    ./scripts/prep_deps.sh

    在这一步中,如果$TVM_SOURCE_DIR环境中没有定义,我们将执行以下行来构建tvmjs依赖关系:

    git clone https://github.com/mlc-ai/relax 3rdparty/tvm-unity --recursive

    这会克隆 的当前 HEAD mlc-ai/relax。但是,它可能并不总是正确的分支或提交克隆。要从源代码构建特定的 npm 版本,请参阅版本升级 PR,其中说明当前 WebLLM 版本依赖于哪个分支(即mlc-ai/relax或)以及哪个提交。apache/tvm例如,版本 0.2.52,根据其版本凹凸 PR #521,是通过检查 中的以下提交https://github.com/apache/tvm/commit/e6476847753c80e054719ac47bc2091c888418b6而构建的apache/tvm,而不是mlc-ai/relax.

    除此之外,--recursive是必要且重要的。否则,您可能会遇到类似的错误fatal error: 'dlpack/dlpack.h' file not found

  4. 构建WebLLM包

    npm run build
  5. 验证一些子包

    然后,您可以转到示例中的子文件夹来验证某些子包。我们使用 Parcelv2 进行捆绑。尽管 Parcel 有时不太擅长跟踪父目录的更改。当您在 WebLLM 包中进行更改时,尝试编辑package.json 子文件夹并保存它,这将触发 Parcel 重建。

0个回复

  • 龙族们都在等待回复

提供中小企业建站高端正版精品系统

正品模板 购买协议