最佳实践:在 Cloud Run 上使用 GPU 进行 AI 推理

本页面介绍了使用带有 GPU 的 Cloud Run 服务进行 AI 推理时优化性能的最佳实践,重点关注大语言模型 (LLM)。

您需要构建和部署一个 Cloud Run 服务,该服务能够实时响应扩缩事件。这意味着您需要:

  • 使用加载速度快且只需进行极少转换即可获得适合 GPU 的结构的模型,并优化其加载方式。
  • 使用允许最大、高效、并发执行的配置来减少每秒响应一个目标请求所需的 GPU 数量,同时降低成本。

在 Cloud Run 上加载大型机器学习模型的推荐方法

Google 建议您在容器映像中存储机器学习模型,或者优化从 Cloud Storage 加载模型

存储和加载机器学习模型的权衡

以下是各个选项的比较:

模型位置 部署时间 开发体验 容器启动时间 存储费用
容器映像 慢。包含大型模型的映像需要更长的时间才能导入到 Cloud Run 中。 更改容器映像后,需要重新部署;对于大型映像,重新部署的速度可能会很慢。 取决于模型的大小。对于超大型模型,请使用 Cloud Storage 以获得更可预测的性能,但速度会较慢。 Artifact Registry 中可能有多个副本。
Cloud Storage,使用 Cloud Storage FUSE 卷装载加载 快速。在容器启动期间下载的模型。 设置难度不高,无需更改 Docker 映像。 网络优化后速度很快。不会并行下载。 Cloud Storage 中有一份副本。
Cloud Storage,使用 Google Cloud CLI 命令 gcloud storage cp 或 Cloud Storage API 并发下载,如传输管理器并发下载代码示例所示。 快速。在容器启动期间下载的模型。 设置稍微困难,因为您需要在映像上安装 Google Cloud CLI,或者更新代码以使用 Cloud Storage API。 网络优化后速度很快。Google Cloud CLI 会并行下载模型文件,因此速度比 FUSE 装载更快。 Cloud Storage 中有一份副本。
互联网 快速。在容器启动期间下载的模型。 通常更简单(许多框架都会从中央仓库下载模型)。 通常较差且不可预测:
  • 框架可能会在初始化期间应用模型转换。(您应在构建时执行此操作)。
  • 用于下载模型的模型主机和库可能效率不高。
  • 从互联网下载存在可靠性风险。如果下载目标出现故障,您的服务可能无法启动,而下载的底层模型可能会改变,从而降低质量。我们建议您在自己的 Cloud Storage 存储桶中托管。
取决于模型托管服务提供商。

将模型存储在容器映像中

将机器学习模型存储在部署到 Cloud Run 的容器映像中可受益于 Cloud Run 的内置容器映像流式传输优化,无需额外的网络优化即可最大限度地缩短文件加载时间。

构建包含机器学习模型的容器可能需要一段时间才能完成。如果使用 Cloud Build,您可以将 Cloud Build 配置为使用更大的机器来加快构建速度。为此,请使用 build 配置文件通过以下步骤构建映像:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'IMAGE', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'IMAGE']
images:
- IMAGE
options:
 machineType: 'E2_HIGHCPU_32'
 diskSizeGb: '500'
 

如果包含模型的层在映像之间有所不同(不同的哈希值),则可以为每个映像创建一个模型副本。如果您的模型层在每个映像上都是唯一的,那么可能会有额外的 Artifact Registry 费用,因为每个映像可能有一个模型副本。

将模型存储在 Cloud Storage 中

如需在从 Cloud Storage 加载机器学习模型时优化机器学习模型加载(无论是使用 Cloud Storage 卷装载还是直接使用 Cloud Storage API 或命令行),您都必须使用出站流量设置值设为 all-traffic直接 VPC 以及 Private Service Connect

构建、部署、运行时和系统设计注意事项

以下部分介绍了构建、部署、运行时和系统设计的注意事项。

在构建时

以下列表显示了您在规划构建时需要注意的事项:

  • 选择合适的基础映像。您应从 Deep Learning ContainersNVIDIA 容器注册表中针对您所使用的机器学习框架的映像入手。这些映像安装了最新的性能相关软件包。我们不建议创建自定义映像。
  • 选择 4 位量化模型以最大限度地提高并发性,除非您能够证明它们会影响结果质量。量化可生成体积更小、速度更快的模型,从而减少提供模型所需的 GPU 内存量,并可提高运行时的并行性。理想情况下,模型应在目标位深度进行训练,而不是向下量化到该位深度。
  • 选择加载速度较快的模型格式(例如 GGUF),以最大限度地缩短容器启动时间。这些格式可以更准确地反映目标量化类型,并且在加载到 GPU 上时需要更少的转换。出于安全考虑,请勿使用 pickle 格式的检查点。
  • 在构建时创建和预热 LLM 缓存。构建 Docker 映像时,在构建机器上启动 LLM。启用提示缓存并提供常见或示例提示,以帮助预热缓存以供实际使用。保存它生成的输出,以便在运行时加载。
  • 保存您在构建时生成的专属推理模型。与加载效率较低的存储模型以及在容器启动时应用量化等转换相比,这样可以节省大量时间。

部署时

  1. 请确保在 Cloud Run 中准确设置服务并发性
  2. 根据您的配置调整启动探测

启动探测确定容器是否已启动并已准备好接受流量。配置启动探测时,请考虑以下要点:

  • 充足的启动时间:为容器(包括模型)留出足够的时间来完全初始化和加载。
  • 模型就绪性验证:将探测配置为仅在应用准备好处理请求时通过。大多数服务引擎会在模型加载到 GPU 显存时自动实现这一点,从而防止过早发出请求。

请注意,Ollama 可以在加载模型之前打开 TCP 端口。解决方法:

  • 预加载模型:如需了解如何在启动期间预加载模型,请参阅 Ollama 文档

在运行时

  • 主动管理支持的上下文长度。您支持的上下文窗口越小,您可以支持并行运行的查询就越多。具体实现方法取决于框架。
  • 使用您在构建时生成的 LLM 缓存。提供您在构建期间生成提示和前缀缓存时使用的相同标志。
  • 从您刚刚编写的已保存模型加载。如需了解如何加载模型,请参阅存储和加载模型的权衡
  • 如果您的框架支持量化键值对缓存,请考虑使用。这样可以减少每个查询的内存要求,并允许配置更多并行性。但是,这也会影响质量。
  • 调整为模型权重、激活和键值对缓存预留的 GPU 内存量。设置尽可能高的值,但不会发生内存不足的错误。
  • 在服务代码中正确配置并发性。确保您的服务代码已配置为与您的 Cloud Run 服务并发性设置配合使用。
  • 检查您的框架是否提供了任何用于提升容器启动性能的选项(例如,使用模型加载并行化)。

在系统设计层面

  • 在适当的情况下添加语义缓存。在某些情况下,缓存整个查询和响应可能是限制常见查询费用的绝佳方式。
  • 控制序言中的方差。提示缓存仅在按顺序包含提示时才有用。缓存实际上进行前缀缓存。在序列中插入或修改意味着它们未缓存或仅部分存在。

自动扩缩和 GPU

Cloud Run 会根据 CPU 利用率和请求并发等因素自动扩缩每个修订版本的实例数。但是,Cloud Run 不会根据 GPU 利用率自动扩缩实例数。

对于具有 GPU 的修订版本,如果修订版本的 CPU 使用率不高,则 Cloud Run 会将请求并发横向扩容。如需针对请求并发实现最佳扩缩,您必须设置每个实例的并发请求数上限最佳值,如下一部分所述。

每个实例的并发请求数上限

每个实例的并发请求数上限设置用于控制 Cloud Run 一次向单个实例发送的请求数上限。您必须调整并发,使其与每个实例中的代码能够以良好性能处理的并发数上限相匹配。

最大并发数和 AI 工作负载

在每个实例的 GPU 上运行 AI 推理工作负载时,代码能够以良好性能处理的最大并发度取决于具体框架和实现细节。以下各项会影响您设置最佳并发请求数上限设置的方式:

  • 加载到 GPU 上的模型实例数
  • 每个模型的并行查询数
  • 使用批处理
  • 特定的批处理配置参数
  • 非 GPU 工作量

如果并发请求数上限设置得过高,则请求最终可能会在实例内等待访问 GPU,从而导致延迟时间增加。如果将最大并发请求数设置得过低,GPU 可能未得到充分利用,导致 Cloud Run 扩缩的实例数超出必要值。

为 AI 工作负载配置并发请求数上限的经验法则如下:

(Number of model instances * parallel queries per model) + (number of model instances * ideal batch size)

例如,假设某个实例将 3 个模型实例加载到 GPU 上,并且每个模型实例可以处理 4 个并行查询。理想的批量大小也是 4,因为这是每个模型实例可以处理的并行查询数量。根据经验法则,您可以将并发请求数上限 24 设置为:(3 * 4) + (3 * 4)。

请注意,此公式只是一个经验法则。理想的并发请求数上限设置取决于实现的具体细节。为了实现实际最佳性能,我们建议您使用不同的并发请求数上限设置对服务进行负载测试,以评估哪个方案性能最佳。

吞吐量、延迟时间与费用权衡

如需了解并发请求数上限对吞吐量、延迟时间和费用的影响,请参阅吞吐量、延迟时间与费用权衡。请注意,所有使用 GPU 的 Cloud Run 服务始终分配 CPU。