使用客户端技术构建 LLM 驱动的 Web 应用程序

2023 年 10 月 13 日

这是一篇客座博文,作者是 Jacob Lee,他是 @LangChainAI 的 JS/TS 维护者,曾是 @Autocode 的联合创始人兼 CTO,也是 Google Photos 的工程师。

这篇博文的初始版本是 Google 内部 WebML Summit 2023 的一个演讲,您可以在这里查看

Google’s internal WebML Summit 2023

长期以来,机器学习主要是一个 Python 的领域,这已经不是什么秘密了,但 ChatGPT 最近的流行将许多新的开发者带入了该领域。JavaScript 是使用最广泛的编程语言,因此毫不奇怪,这也包括了许多 Web 开发者,他们自然会尝试构建 Web 应用程序。

关于通过 API 调用 OpenAI、Anthropic、Google 等公司的 LLM 构建应用程序的文章已经很多了,所以我想尝试一种不同的方法,尝试完全使用本地模型和技术来构建 Web 应用程序,最好是那些可以在浏览器中运行的!

为什么?

以这种方式构建的一些主要优势是

  1. 成本。由于所有的计算和推理都将在客户端完成,除了(非常便宜的)托管之外,开发者构建应用程序不会产生额外的成本。
  2. 隐私。任何东西都不需要离开用户的本地机器!
  3. 由于没有 HTTP 调用开销,潜在的速度提升。
    1. 这可能会因为用户硬件的限制导致推理速度变慢而抵消。

项目

我决定尝试使用开源、本地运行的软件重新创建 LangChain 最流行的用例之一:执行检索增强生成 (Retrieval-Augmented Generation) 的链,简称 RAG,并允许您“与您的文档聊天”。这使您可以从各种非结构化格式的数据中获取信息。

architecture of this example project

数据摄取

第一步是加载我们的数据,并以一种可以使用自然语言进行查询的方式来格式化它。这包括以下步骤

  1. 将文档(PDF、网页或其他一些数据)拆分为语义块
  2. 使用嵌入模型创建每个块的向量表示
  3. 将块和向量加载到一种称为向量存储的专用数据库中

这些第一步需要几个部分:文本分割器、嵌入模型和向量存储。幸运的是,这些都已经在浏览器友好的 JS 中存在了!

LangChain 负责文档的加载和分割。对于嵌入,我使用了一个小型 HuggingFace 嵌入模型,该模型经过量化,可以使用 Xenova 的 Transformers.js 包 在浏览器中运行,对于向量存储,我使用了一个非常棒的 Web Assembly 向量存储,名为 Voy

检索和生成

既然我已经建立了一个加载数据的管道,下一步就是查询它

diagram explaining retrival and generation

这里的一般想法是获取用户输入的问题,在我们准备好的向量存储中搜索与查询语义上最相似的文档块,并使用检索到的块加上原始问题来引导 LLM 根据我们的输入数据得出最终答案。

后续问题还需要一个额外的步骤,这些问题可能包含代词或对之前聊天记录的其他引用。因为向量存储通过语义相似性执行检索,所以这些引用可能会干扰检索。因此,我们添加了一个额外的解引用步骤,将初始步骤改写成一个“独立的”问题,然后再使用该问题搜索我们的向量存储。

事实证明,找到一个可以在浏览器中运行的 LLM 很难 - 强大的 LLM 非常庞大,并且通过 HuggingFace 提供的 LLM 无法生成良好的响应。还有 机器学习编译的 WebLLM 项目,该项目看起来很有希望,但需要在页面加载时进行大规模的、多 GB 的下载,这增加了很多延迟。

screenshot of Jacob's terminal

我过去曾尝试过 Ollama,它是一种简单、开箱即用的方式来运行本地模型,当我听说它支持通过 shell 命令将本地运行的模型暴露给 Web 应用程序时,我感到非常惊喜。我将它插入并发现它是缺失的一环!我启动了更新、最先进的 Mistral 7B 模型,该模型在我的 16GB M2 Macbook Pro 上运行良好,最终得到了以下本地堆栈

diagram of what's possible with all local RAG with langchain and ollama

结果

您可以在 Vercel 上尝试 Next.js 应用程序的实时版本

https://webml-demo.vercel.app

您需要在本地机器上通过 Ollama 运行 Mistral 实例,并通过运行以下命令使其可以访问相关域,以避免 CORS 问题

$ ollama run mistral
$ OLLAMA_ORIGINS=https://webml-demo.vercel.app OLLAMA_HOST=127.0.0.1:11435 ollama serve

以下是 LangSmith(我们的可观测性和跟踪平台)中一些问题的示例跟踪。我使用了我的个人简历作为输入文档

  1. “这是关于谁的?”
    1. https://smith.langchain.com/public/2386b1de-7afb-48a2-8c83-205162bfcac0/r
  2. “他们懂 JavaScript 吗?”
    1. https://smith.langchain.com/public/18cec162-d12c-4034-aa9a-39b1cd2011ea/r

结论

总的来说,这进展顺利。一些观察结果

  • 开源模型正在迅速发展 - 我使用 Llama 2 构建了该应用程序的初始版本,而 Mistral 几周后才发布。
  • 越来越多的消费硬件制造商在其产品中包含 GPU。
  • 随着 OSS 模型变得越来越小、越来越快,在本地硬件上使用 Ollama 等工具运行这些模型将变得越来越普遍。
  • 虽然用于向量存储、嵌入和其他特定任务模型的浏览器友好技术在过去几个月中取得了一些令人难以置信的进步,但 LLM 仍然过于庞大,无法切实地捆绑在 Web 应用程序中。

Web 应用程序利用本地模型的唯一可行解决方案似乎是我上面使用的流程,即一个强大的、预安装的 LLM 被暴露给应用程序。

新的浏览器 API?

由于非技术 Web 终端用户不会习惯于运行 shell 命令,因此这里最好的答案似乎是新的浏览器 API,Web 应用程序可以通过该 API 请求访问本地运行的 LLM,例如通过弹出窗口,然后将该功能与其他浏览器内特定任务的模型和技术一起使用。

Diagram showing Chrome and Ollama interacting with each other

感谢阅读!

我对 LLM 驱动的 Web 应用程序的未来以及 Ollama 和 LangChain 等技术如何促进令人难以置信的全新用户交互感到非常兴奋。

以下是应用程序中使用的各个部分的链接

请与 Jacob Lee@LangChainAI 在 X/Twitter 上保持联系。