像您所期望的那样扩展 AI 模型

张开发
2026/6/9 21:21:39 15 分钟阅读
像您所期望的那样扩展 AI 模型
原文towardsdatascience.com/scaling-ai-models-like-you-mean-it-3afa56c1e14b?sourcecollection_archive---------5-----------------------#2024-04-10克服在生产环境中扩展开源 AI 模型挑战的策略https://medium.com/ssheng?sourcepost_page---byline--3afa56c1e14b--------------------------------https://towardsdatascience.com/?sourcepost_page---byline--3afa56c1e14b-------------------------------- Sean Sheng·发布于 Towards Data Science ·11 分钟阅读·2024 年 4 月 10 日–如果你正在阅读这篇文章可能不需要我再介绍部署开源模型的优势。在过去几年里我们已经见证了开源模型在数量和质量上的惊人增长。像 Hugging Face 这样的平台使得各种模型的访问变得更加民主化包括大型语言模型LLMs和扩散模型这使得开发者能够自由高效地进行创新。开发者享有更大的自主性因为他们可以自由地微调和组合不同的模型从而推动创新方法的出现比如检索增强生成RAG和创建先进的智能体。从经济角度来看开源模型提供了可观的成本节省使得使用较小、专用的模型成为可能这些模型相较于像 GPT-4 这样的通用模型更加节省预算。开源模型呈现出一种有吸引力的解决方案但下一个难题是什么呢与使用像 OpenAI 这样的模型端点不同后者的模型是 API 背后的可扩展黑箱部署自己的开源模型则引入了扩展问题。确保你的模型能够有效扩展以应对生产流量并在流量激增期间保持无缝体验至关重要。此外合理管理成本也很重要这样你只需为实际使用的部分付费避免在月底遇到财务上的意外。真正的方向面向 GPU 的无服务器函数有趣的是这听起来像是现代无服务器架构如 AWS Lambda已经解决的挑战——这是一个已经存在近十年的解决方案。然而当涉及到 AI 模型部署时情况并非完全如此。无服务器函数在 AI 部署中的局限性是多方面的。没有 GPU 支持。像 AWS Lambda 这样的平台不支持 GPU。这不仅仅是一个技术疏漏而是由于架构和实际考虑所致。GPU 无法轻松共享。虽然 GPU 作为设备具有高度并行性但它在同时处理不同模型的多个推理任务时灵活性不如其他技术。GPU 昂贵。GPU 在模型推理任务中表现出色但维护成本高昂尤其是在不被持续使用的情况下。接下来让我们来看看我们的扩展历程以及我们在过程中学到的重要经验。冷启动问题在我们开始扩展工作之前首先面临的是臭名昭著的“冷启动”问题。这个问题在三个不同的阶段表现出来https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a91758d3ec08a5076eb6b8d716db9fef.png冷启动问题的分析。图像来源作者。云资源配置这一阶段涉及云提供商为我们分配实例并将其整合进集群所需的时间。这个过程差异很大通常从 30 秒到几分钟不等有时甚至会延长到几个小时特别是对于需求量大的实例如 Nvidia A100 和 H100 GPU。容器镜像拉取与简单的 Python 作业镜像不同AI 模型服务镜像非常复杂因其依赖关系和所需的自定义库。尽管云提供商宣称拥有多吉比特的网络带宽但我们的经验表明下载速度往往远低于这一标准镜像拉取时间大约为 3 分钟。模型加载。所需时间主要取决于模型的大小像 LLM 和扩散模型这样的大型模型由于拥有数十亿个参数需要显著更长的时间。例如加载一个 5GB 的模型如 Stable Diffusion 2可能需要大约 1.3 分钟前提是网络带宽为 1Gbps而更大的模型如 Llama 13B 和 Mixtral 8x7B 则分别需要 3.5 分钟和 12.5 分钟。冷启动问题的每个阶段都需要采取特定的策略来最小化延迟。在接下来的章节中我们将更详细地探讨每个阶段分享我们的策略和解决方案。云资源配置与无服务器 CPU 的同质化环境不同管理多种计算实例类型在处理 GPU 时至关重要因为每种 GPU 都针对特定的使用案例进行优化。例如IO 密集型的 LLM 模型需要较高的 GPU 内存带宽和容量而生成式模型则需要更强大的 GPU 计算能力。在流量高峰期间确保可用性通过保持所有 GPU 实例类型可能会导致不可承受的高成本。为了避免空闲实例带来的财务压力我们实施了“备用实例”机制。我们没有为最大潜在负载做准备而是维护了一个与增量扩展步长相匹配的计算备用实例数量。例如如果我们一次扩展两个 GPU我们就需要准备两个备用实例。这使我们能够在需求激增时迅速向服务队列中添加资源显著减少等待时间同时保持成本可控。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f06c07c4b29d12ce233597218a55b698.png图片来源作者。在多租户环境中多个团队或在我们的案例中多个组织共享一个公共资源池我们可以实现更高效的资源利用率。这个共享环境使我们能够平衡不同的资源需求有助于提高成本效率。然而管理多租户环境也带来了挑战例如强制执行配额和确保网络隔离这可能会增加集群的复杂性。容器镜像拉取无服务器 CPU 工作负载通常使用轻量级镜像如 Python slim 镜像约 154 MB。相比之下为了提供 LLM 服务的容器镜像可能要大得多6.7 GB其中大部分大小来自于运行 AI 模型所需的各种依赖项。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/46e47cc296d52e7e9f4085be53b44b34.png图片来源作者。尽管云服务提供商宣传了高带宽网络实际情况往往远低于预期实际下载速度仅为承诺速度的一个小部分。实际上很多文件根本没有被使用。一种方式是优化容器镜像本身但这很快证明是不可管理的。相反我们将注意力转向按需文件拉取方法。具体来说我们首先只下载镜像元数据实际的远程文件则在需要时再拉取。此外我们利用集群中的点对点网络来大幅提高拉取效率。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ae31e765f9e62607e7e19c9024344b48.png容器镜像元数据可以在几秒钟内拉取。图片来源作者。通过这些优化我们将镜像拉取时间从几分钟减少到几秒钟。然而大家都知道这个测量实际上是在“作弊”因为实际的文件并没有在此阶段被拉取。真正的文件拉取发生在服务运行时。因此拥有一个允许在各生命周期阶段定义行为的服务框架至关重要例如初始化和服务。在初始化阶段完成所有引导工作后我们可以确保拉取所有文件依赖项。这样在服务时就不会因拉取文件而产生延迟。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/afd20effc8387a63201471c4453e6382.png启动服务框架并定义 API 的服务框架。图片来源作者。在上述示例中模型加载是在__init__初始化生命周期中完成的服务则在bentoml.api命名的txt2img中进行。模型加载最初最直接的模型加载方法是从远程存储如 Hugging Face中直接获取。通过使用内容分发网络CDN、NVMe SSD 和共享内存我们能够消除一些瓶颈。尽管这种方法可行但远未达到最优。为了改善这一过程我们考虑了使用区域内网络带宽。我们在分布式文件系统中预先加载模型并将其分割成较小的块允许并行下载。这大大提高了性能但我们仍然遇到了云服务商网络带宽的瓶颈。为此我们进一步优化了利用集群内网络带宽的方法通过使用点对点共享和利用本地缓存。虽然这些改进显著但它们增加了处理过程的复杂性我们需要将其从开发人员的操作中抽象出来。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2ed77644411ae062984ed93fc5af4986.png图片来自作者。即使采用了上述做法我们仍然面临着一个顺序瓶颈每个步骤完成后才能进行下一个步骤的等待问题。模型必须完全下载到持久化驱动器中然后加载到 CPU 内存中再加载到 GPU 内存。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d24c7294db86b83eabfdd2ec71787907.png图片来自作者。我们转向了一种基于流的模型权重加载方法利用我们现有的分布式文件缓存系统。该系统允许程序像所有文件都逻辑上存储在磁盘上一样进行操作。实际上所需的数据是按需从远程存储中获取从而避免了磁盘写入。通过利用像Safetensors这样的格式我们可以通过内存映射mmap将模型权重高效加载到主内存中然后以流式方式加载到 GPU 内存中。此外我们还采用了异步磁盘写入。通过这样做我们在本地磁盘上创建了一个更快速访问的缓存层。因此只有代码更改的新部署可以绕过较慢的远程存储获取阶段直接从本地缓存读取模型权重。总结来说我们成功优化了冷启动时间并对结果感到满意没有云提供商延迟配备待命实例。更快的容器镜像拉取通过按需和点对点流式传输。通过分布式文件系统、点对点缓存和流式加载到 GPU 内存中加速了模型加载。服务框架启用了并行图像拉取和模型加载。扩展指标接下来我们需要确定在 GPU 上扩展 AI 模型部署的最具指示性的信号。资源利用率指标最初我们考虑了 CPU 利用率。它直观且有一个默认的阈值例如 80%。然而显而易见的缺点是CPU 度量无法捕捉 GPU 的利用情况。此外Python 中的全局解释器锁GIL限制了并行性阻止了多核实例上的高 CPU 利用率这使得 CPU 利用率成为一个不太可行的度量。我们还探索了 GPU 利用率作为衡量模型工作负载的更直接指标。然而我们遇到了一个问题工具如nvml报告的 GPU 利用率并未准确反映 GPU 的实际利用情况。该度量是通过一定时间段内对内核使用情况的采样来计算的如果至少有一个内核在执行GPU 就被认为是被利用的。这与我们的观察一致即通过改进批处理尽管 GPU 设备已经报告为高利用率但通常可以实现更好的性能。注意*根据NVIDIA 文档utilization.gpu 表示“过去采样周期内一个或多个内核在 GPU 上执行的时间百分比。采样周期可能是 1 秒到 1/6 秒具体取决于产品。”基于资源的度量本质上是回顾性的因为它们只反映在资源被消耗后才会出现的使用情况。它们也被限制在 100%这带来了一个问题当根据这些度量进行扩展时调整的最大比例通常是当前利用率与所需阈值之间的比例见下面的扩展公式。这导致了一种保守的扩展行为未必能准确匹配生产流量的实际需求。desiredReplicasceil[currentReplicas*(currentMetricValue/desiredMetricValue)]基于请求的度量我们转向了基于请求的度量作为更主动的信号它们也不受 100%限制。QPS 是一个被广泛认可的度量因其简单性。然而它在生成式 AI 中的应用如 LLM仍然存在疑问。QPS 的配置并不容易并且由于每个请求的成本变化取决于处理和生成的标记数量使用 QPS 作为扩展度量可能会导致不准确。另一方面并发性被证明是反映系统实际负载的理想度量。它代表了排队或正在处理的活跃请求的数量。这个度量精确反映系统的负载。小洛特法则指出QPS 乘以平均延迟等于并发性提供了一种优雅的方式来理解 QPS 和并发性之间的关系。在实际操作中模型服务中每个请求的平均延迟是相对未知的。然而通过测量并发性我们无需计算平均延迟。使用扩展公式准确计算所需的副本数。允许部署直接扩展到理想规模而无需中间步骤。基于批次大小易于配置。对于不能批处理的模型只需配置 GPU 数量因为每个 GPU 一次只能处理一个生成任务。对于支持批处理的模型批次大小决定了并发级别。为了使并发有效我们需要服务框架的支持自动将并发作为度量标准并将其作为扩展信号提供给部署平台。我们还必须建立正确的扩展策略以防在流量激增时过度扩展或者在流量稀少时过早缩减。请求队列另一个我们与并发集成的重要机制是请求队列。它充当缓冲区和调度器确保传入的请求得到高效处理并且不会使任何单一服务器副本过载。在没有请求队列的情况下所有传入请求都会直接分配给服务器如下图所示6 个请求。如果多个请求同时到达而只有一个活跃的服务器副本那么它会成为瓶颈。服务器会尝试按照先来先服务的方式处理每个请求这通常会导致超时并影响客户端体验。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fbca33197fc380dd90ab8b0fc7f2b698.png图片由作者提供。相反使用请求队列时服务器按最优速率消费请求基于为服务定义的并发速率处理。当额外的服务器副本扩展时它们也会开始从队列中拉取请求。该机制防止任何单一服务器过载并且能够更平滑、更可管理地分配请求到可用的基础设施上。结论我们在探索 AI 模型扩展解决方案的过程中经历了一次冒险这最终使我们创造了 BentoCloud 上的扩展体验——一个囊括了我们所有学习成果的平台。为了避免给人宣传的印象我们将通过一张千言万语的图片来说明我们的观点。下面的监控仪表板展示了传入请求与服务器实例扩展之间的关系。与扩展能力同样重要的是缩放的能力。当请求减少到零时部署会相应地减少活跃实例的数量。这一能力确保了不会因未使用的资源而产生不必要的成本使开支与实际使用情况相符。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7aedb48ff2a14a63c2d7a79d5738bd22.pngBentoCloud 监控仪表板。图片由作者提供。我们希望大家能从中获得的启示是模型部署的扩展应被视为生产应用中的一个重要方面。与扩展 CPU 工作负载不同在 GPU 上扩展模型部署面临独特的挑战包括冷启动时间、配置扩展指标和调度请求等。在评估部署平台时应彻底评估它们应对这些挑战的解决方案。

更多文章