使用客户端技术构建基于 LLM 的 Web 应用
2023 年 10 月 13 日
这是一篇由 Jacob Lee 的客座博客文章,他是 @LangChainAI 的 JS/TS 维护者,曾任 @Autocode 的联合创始人兼首席技术官,也是 Google 照片的工程师。
这篇博客文章的初始版本是 2023 年 Google 内部 WebML 峰会的演讲,您可以在这里查看。
众所周知,机器学习长期以来一直主要由 Python 掌控,但 ChatGPT 近期的流行吸引了许多新开发者加入该领域。JavaScript 是使用最广泛的编程语言,因此自然吸引了许多 Web 开发者,他们尝试构建 Web 应用也就不足为奇了。
人们已经写了很多关于通过 API 调用 OpenAI、Anthropic、Google 等公司提供的 LLM 来构建应用的内容,所以我认为可以尝试另一种方法,尝试使用完全本地的模型和技术构建 Web 应用,最好是在浏览器中运行的那些技术!
为什么呢?
这种构建方式有一些主要优势:
- 成本。由于所有计算和推理都在客户端完成,因此除了(非常便宜的)托管之外,开发人员构建应用程序不会产生任何额外成本。
- 隐私。任何信息都不会离开用户的本地机器!
- 由于没有 HTTP 调用开销,因此有可能提高速度。
- 这可能会被由于用户硬件限制导致的推理速度较慢所抵消。
项目
我决定尝试使用开源的、本地运行的软件重现最流行的 LangChain 用例之一:一个执行检索增强生成(简称 RAG)的链,允许您“与文档聊天”。这使您可以从各种非结构化格式的锁定数据中获取信息。
数据摄取
第一步是加载我们的数据,并以一种使用自然语言可查询的格式对其进行格式化。这包括以下步骤:
- 将文档(PDF、网页或其他一些数据)拆分成语义块
- 使用嵌入模型创建每个块的向量表示
- 将块和向量加载到称为向量存储的专用数据库中
这些第一步需要一些组件:文本拆分器、嵌入模型和向量存储。幸运的是,这些组件已经存在于浏览器友好的 JS 中!
LangChain 处理了文档加载和拆分。对于嵌入,我使用了一个小的 HuggingFace 嵌入模型,该模型被量化为使用 Xenova 的 Transformers.js 包 在浏览器中运行,而对于向量存储,我使用了一个非常棒的 WebAssembly 向量存储,名为 Voy。
检索和生成
现在我已经设置了加载数据的管道,下一步就是查询它。
这里的一般思路是获取用户的输入问题,在准备好的向量存储中搜索与查询在语义上最相似的文档块,然后使用检索到的块加上原始问题来指导 LLM 根据我们的输入数据生成最终答案。
对于后续问题,还需要进行额外的步骤,这些问题可能包含代词或对先前聊天记录的其他引用。由于向量存储通过语义相似性执行检索,因此这些引用会影响检索结果。因此,我们添加了一个额外的反引用步骤,将初始步骤重新表述为一个“独立”的问题,然后再使用该问题搜索我们的向量存储。
找到可以在浏览器中运行的 LLM 证明是困难的——强大的 LLM 非常庞大,通过 HuggingFace 提供的 LLM 无法生成良好的响应。还有 机器学习编译的 WebLLM 项目,它看起来很有希望,但需要在页面加载时进行大量的多 GB 下载,这会导致大量延迟。
我之前曾尝试使用 Ollama 作为一种简单的开箱即用的方法,用于在本地运行模型,当我听说 Ollama 支持通过 shell 命令将本地运行的模型公开给 Web 应用时,感到很惊讶。我把它连接起来,事实证明它是缺失的环节!我启动了最近更新的、最先进的 Mistral 7B 模型,它在我的 16GB M2 Macbook Pro 上运行良好,最终得到了以下本地堆栈:
结果
您可以在 Vercel 上尝试使用 Next.js 应用的实时版本
您需要在本地机器上通过 Ollama 运行 Mistral 实例,并通过运行以下命令使其可供目标域访问,以避免 CORS 问题:
$ ollama run mistral
$ OLLAMA_ORIGINS=https://webml-demo.vercel.app OLLAMA_HOST=127.0.0.1:11435 ollama serve
以下是一些在我们的可观察性和跟踪平台 LangSmith 中,针对几个问题的一些示例跟踪。我使用我的个人简历作为输入文档
- “这是关于谁的?”
- “他们会 JavaScript 吗?”
结论
总的来说,效果不错。以下是一些观察结果:
- 开源模型发展迅速——我使用 Llama 2 构建了该应用的初始版本,Mistral 在仅仅几周后就发布了。
- 越来越多的消费级硬件制造商在其产品中包含 GPU。
- 随着 OSS 模型变得越来越小、越来越快,使用 Ollama 等工具在本地硬件上运行这些模型将变得越来越普遍。
- 虽然用于向量存储、嵌入和其他特定于任务的模型的浏览器友好技术在过去几个月里取得了惊人的进步,但 LLM 仍然过于庞大,无法在 Web 应用中进行捆绑。
Web 应用利用本地模型的唯一可行解决方案似乎是我上面使用的方法,其中一个强大的预安装 LLM 公开给应用使用。
新的浏览器 API 吗?
由于非技术 Web 终端用户不会习惯运行 shell 命令,因此这里最好的解决方案似乎是新的浏览器 API,其中 Web 应用可以请求访问本地运行的 LLM,例如通过弹出窗口,然后使用该功能以及其他浏览器中的特定于任务的模型和技术。
感谢阅读!
我对基于 LLM 的 Web 应用的未来以及 Ollama 和 LangChain 等技术如何促进令人难以置信的新用户交互感到非常兴奋。
以下是应用中使用的各个组件的一些链接:
- 演示应用:https://webml-demo.vercel.app/
- 演示应用 GitHub 仓库:https://github.com/jacoblee93/fully-local-pdf-chatbot
- Voy:https://github.com/tantaraio/voy
- Ollama:https://github.com/jmorganca/ollama/
- LangChain.js:https://js.langchain.ac.cn/
- Transformers.js:https://hugging-face.cn/docs/transformers.js/index
请与 Jacob Lee 和 @LangChainAI 在 X/Twitter 上保持联系。