我们如何通过大规模部署低成本开源人工智能技术节省数万美元

 提示:点击图片可以放大
来源:优游ub8平台    发布时间:2025-01-20 09:20:17

  当第一次使用生成式 AI 构建 AI 应用程序时,你可能会在项目的某个阶段使用 OpenAI API。而且,理由很充分!他们的 API 结构良好,速度快,并且有很棒的支持库。在规模比较小或刚开始时,使用 OpenAI 可能还相对比较经济。也有大量非常好的学习材料可以引导你完成构建 AI 应用程序的过程,借助 OpenAI API 理解这项复杂的技术。

  最近,我个人最喜欢的其中一种 OpenAI 资源是 OpenAI Cookbook:其中的内容很适合初学者,他们能够从这里学习不同的模型是如何工作的,学习怎么样利用 AI 领域的诸多前沿技术,以及如何将数据与 AI 工作负载相集成。

  然而,一旦你需要扩展生成式 AI 的操作,你很快就会遇到一个相当大的障碍:成本。一旦你开始通过 GPT-4 甚至成本更低的 GPT-3.5 模型生成数千(最终数万)条文本,你很快就会发现,你的 OpenAI 账单也会增长到每月数千美元。

  值得庆幸的是,对于小型敏捷团队来说,有很多很好的低成本开源技术可供他们选择。他们能够部署这些技术,利用其中最新、最好且非常可靠的开源模型重新实现与 OpenAI 兼容的 API(在许多情况下,可以与 GPT 3.5 类模型的性能相媲美)。

  在 OpenSauced,我们在为 人工智能新产品 StarSearch 构建基础设施时就遇到了这样的情况:我们应该一个数据管道,它可以不断地获取 GitHub 问题及 pull 请求的摘要和向量嵌入。这样,我们就可以在我们的向量存储中进行“大海捞针”似的余弦相似度搜索,并将其作为检索增强生成(RAG)流程的一部分。RAG 是一种很流行的技术,通过它可以为大型语言模型提供额外的上下文和搜索出来的结果,而它的基础数据中并没有包含这一些信息。通过这一种方式,LLM 就能够正常的使用你提供的上下文数据来“增强”查询,并提供更准确的答案。

  基于向量存储的余弦相似度搜索能更加进一步增强 RAG 流:因我们的大部分数据是非结构化的,很难通过全文搜索进行解析,所以对于数据库中我们想要搜索的行,我们利用 AI 生成了相关行的摘要,并以此为基础创建了向量嵌入。向量实际上只是一个数字列表,但它们代表了 embedding 机器学习模型的“理解”,搭配查询向量嵌入就可以针对终端用户的问题找出“最近邻”数据。

  最初,对于 RAG 数据管道的摘要生成部分,我们直接用了 OpenAI。我们大家都希望借此了解 GitHub 上排名前 4 万多的存储库的相关事件和社区动态。这样一来,任何人就都可以查询获得有关开源ECO中最杰出项目的独特见解。但是,由于新增的问题和 pull 请求事件总是流经这个管道,所以这 4 万多个存储库每天会有超过 10 万个新事件流过,我们应该为它们生成摘要:大量的 OpenAI API 调用!

  在这种规模下,我们很快就遇到了“成本”瓶颈:我们考虑逐步优化对 OpenAI API 的使用,减少总体使用量。但我们觉得,我们大家可以使用开源技术以更低的成本实现同样的目标规模。

  虽然这篇文章不会太深入地介绍我们如何实现 StarSearch 的 RAG 部分,但我将介绍下我们如何赋能我们的基础设施,使它能够使用成千上万的 GitHub 事件生成 AI 摘要,并使其成为使用 vLLM 和 Kubernetes 进行最近邻搜索的一部分。这是 StarSearch 能够揭示各种技术的相关信息并“了解”整个开源生态系统动态的关键所在。

  如今,得益于开源生态系统的强大功能和独创性,我们可以在自己的硬件上运行 AI 模型并进行“生成式推理”,而且有很多很好的选择。

  更重要的也许是,这些软件针对在消费级硬件(如个人笔记本电脑和游戏电脑)上运行模型做了很好地的优化:不需要企业级 GPU 集群或昂贵的第三方服务来生成文本!你今天就可以开始使用开源技术在笔记本电脑上构建 AI 应用程序,无需第三方 API。

  对于 StarSearch,我们就是这样将生成式 AI 管道从 OpenAI 转移到我们在 Kubernetes 上运行的服务:我从简单的 Ollama 开始,在我的笔记本电脑本地运行一个 Mistral 模型。然后,我开始改造 OpenAI 数据管道,从我们的数据库读取数据并开始使用本地的 Ollama 服务器生成摘要。与许多其他推理引擎一样,Ollama 提供了与 OpenAI 兼容的 API。使用它,我不需要重写很多客户端代码:只需将 OpenAI API 端点替换为指向 Ollama 的localhost。

  最后,我在使用 Ollama 时遇到了一个真正的瓶颈:它不支持客户端并发。而且,在我们的目标规模下,在任何给定的时间,我们可能需要几十个数据管道微服务运行器同时处理来自生成式 AI 服务的批量摘要。这样我们才能跟上 GitHub 上 4 万多个存储库的持续负载。显然,OpenAI API 可以处理这种负载,但我们如何使自己的服务也具备这项能力呢?

  最终,我找到了 vLLM(一个快速的推理运行器)。它可以在与 OpenAI 兼容的 API 后面为多个客户端提供服务,并在推理时利用给定计算机上的多个 GPU 进行请求批处理及有效使用“PagedAttention”。和 Ollama 一样,vLLM 社区也提供了一个容器运行时镜像,使用户可以很容易地在许多不同的生产平台上使用它。这太好了!

  请注意 :Ollama 最近合并了一些更改以支持并发客户端。在撰写本文时,主上游镜像尚未提供这方面的支持,但我非常期待看看它与其他多客户端推理引擎相比会有怎样的表现!

  要在本地运行 vLLM,你需要一个 Linux 系统和一个 Python 运行时:

  上述命令会启动一个与 OpenAI 兼容的服务器,稍后你可以通过 8000 端口访问它:

  此外,还可以在容器中运行与 OpenAI 兼容的 API。在 Linux 系统上,你能够正常的使用 docker:

  上述代码会在我的 Linux 机器上挂载本地 Huggingface 缓存,并使用主机网络。然后,还是使用 localhost,我们就可以访问运行在 Docker 中的与 OpenAI 兼容的服务器。现在,让我们聊个天:

  在本地运行 vLLM,对于测试、开发和推理实验来说都没有问题,但是在我们的目标规模下,我知道我们需要某种环境,可以轻松地处理任意数量的 GPU 计算实例,还可以按需扩展,并且要用一个模型无关的服务对 vLLM 进行负载均衡,使数据管道微服务可以以生产速率访问这个服务:Kubernetes 登场,一个为人熟知的流行的容器编排系统!

  在我看来,这对 Kubernetes 来说是一个完美的用例,它可以相对完美地扩展类似 OpenAI API 的内部 AI 服务。

  在节点池中部署任意数量的 Kubernetes 节点,每个节点配有任意数量的 GPU

  根据托管 Kubernetes 服务提供程序说明安装 GPU 驱动程序。我们使用了 Azure AKS,他们 对在集群上利用 GPU 做了这些说明。

  如果你按照上面介绍的内容做了,那么现在你应该已经启动并运行了一个 Kubernetes 集群,就像通过一个托管 Kubernetes 提供程序一样,并且还在配有 GPU 的节点上安装了必要的 GPU 驱动程序。

  我们的服务是在 Azure AKS 上部署的,我们需要运行一个 daemonset 在每个带有 GPU 的节点上安装 Nvidia 驱动程序:

  这个 daemonset 在每个具有节点选择器accelerator: nvidia的节点上安装 Nvidia 设备插件 pod,并且可以容忍系统的一些污点(taints)。同样,这或多或少是特定于平台的,但这使我们的 AKS 集群能够为带有 GPU 的节点提供必要的驱动程序,以便 vLLM 可以充分利用这些计算单元。

  最终,我们得到了一个集群节点配置,其中包含默认节点和带有 GPU 的节点:

  每个节点都有一个 GPU 设备插件 pod,由 daemonset 管理,其中安装了驱动程序:

  对于这个设置,有一点需要注意:每个 GPU 节点都有一个accelerator: nvidia标签和nvidia.com/gpu污点 。这是为了确保其他 pod 不会被调度到这些节点上,因为 vLLM 预计会消耗每个节点上的所有计算和 GPU 资源。

  首先,我们为集群上的 vLLM daemonset pod 创建元数据和标签选择器。然后,在容器规范中,我们把参数提供给在集群上运行的 vLLM 容器。这里你会注意到:我们的这个部署使用了大约 95% 的 GPU 内存,我们使用了 CUDA 饥渴模式(这有助于在减少内存消耗的同时权衡推理性能)。我喜欢 vLLM 的一个原因是,它有许多调优选项,并且可以在不同的硬件上运行:有许多功能可用于调整推理方式或硬件的使用方式。要了解更多信息,请 阅读 vLLM 文档。

  接下来,你会注意到,我们提供了一个 Huggingface token:这样 vLLM 就可以从 Huggingface 的 API 中拉取模型,在我们已经获得访问权限的时候绕过“门禁”模型。

  接下来,我们为该 pod 暴露端口 8000。稍后,服务能够正常的使用该端口来选择这些 pod,这样就可以提供一种模型无关的方法通过 8000 端口访问负载均衡端点,进而访问我们部署的任何 vLLM pod。然后,个人会使用了一个nvidia.com/gpu资源(它是由 Nvidia 设备插件 daemonset 作为节点级资源提供的——同样,这取决于你的 Kubernetes 提供方和安装 GPU 驱动程序的方式,这可能会有所不同)。最后,咱们提供了相同的节点选择器和 taint toleration,以确保 vLLM 仅在 GPU 节点上运行!现在,当部署完成时,我们将看到 vLLM daemonset 已成功部署到每个 GPU 节点上:

  最终,无需使用昂贵的第三方 API,我们就为在集群上运行的内部微服务提供了一种生成摘要的方法:我们得知,使用 Mistral 模型得到的结果非常好。对这种规模的用例,使用我们自己在 GPU 上运行的服务明显更划算。

  你可以在此基础上进行扩展,为内部服务提供一些额外的网络策略或配置,甚至添加一个入口控制器,将其作为服务提供给集群外的其他服务。能做的事情很多!祝你好运!

  特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

  最高院:2 年放贷超10次即涉非法经营罪,年利率高于 36%可判 5 年!

  上海险胜深圳6连胜:周鹏25+8三分总分超巴特尔 洛夫顿22+18+10

  搭载鲲鹏超能混动C-DM 奇瑞风云T11PT车下线PLUS Ultra官图发布 预计12月上市

  《编码物候》展览开幕 北京时代美术馆以科学艺术解读数字与生物交织的宇宙节律