性能 - Amazon EKS

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

性能

应用程序扩展和性能

管理 ML 构件、提供框架和启动优化

在 Amazon EKS 上部署机器学习 (ML) 模型需要仔细考虑如何将模型集成到容器映像和运行时环境中。这确保了可扩展性、可重复性和高效的资源利用率。本主题介绍了处理机器学习模型工件、选择服务框架以及通过预缓存等技术优化容器启动时间的不同方法,所有这些方法都是为减少容器启动时间而量身定制的。

缩小容器镜像大小

  • 在启动期间减小容器镜像的大小是缩小镜像的另一种方法。您可以在容器镜像构建过程的每个步骤中进行缩减。首先,请选择包含所需依赖项最少的基础映像。在映像构建过程中,仅包含必需的基本库和工件。构建图像时,请尝试组合多个 RUN 或 COPY 命令来创建较少数量的较大图层。构建较小的图像有以下优点和缺点:

  • 优点:

    • 图像提取速度更快,总体上需要的存储空间也更少。

    • 较小的图像具有较少的攻击向量。

  • 缺点:

    • 随着容器映像的简化,您将需要创建多个映像以满足在不同环境中运行的需求。

    • 通过组合命令节省的大小有时可以忽略不计,因此您应该测试不同的构建方法,以了解哪些方法可以带来最佳结果。对于 AI/ML 框架,请选择诸如仅限运行时的图像之类的变体(例如,3.03 GB,pytorch/pytorch:2.7.1-cuda11.8-cudnn9-runtime而 devel 为 6.66 GB),但是作为较小的图像对工作负载进行基准测试可能会跳过 JIT 编译,从而导致代码路径变慢。使用多阶段构建将构建和运行时分开,仅复制所需的工件(例如,通过注册表或本地上下文的 COPY —from=)。通过在装配阶段组合 COPY 来实现层优化,从而减少层数,但要降低缓存效率和延长构建时间。

在部署中处理 ML 模型构件

一个关键的决定是如何自己处理机器学习模型工件(例如权重、配置)。选择会影响映像大小、部署速度、模型更新频率和操作开销。并不是说在提及存储 “模型” 时,我们指的是模型工件(例如,训练过的参数、模型权重)。在 Amazon EKS 上处理机器学习模型工件的方法有三种。每种方法都有其权衡取舍,最佳选择取决于您的模型的大小、更新节奏和基础架构需求——从最少到最推荐的顺序列出:

将模型烘焙到容器镜像中在映像构建过程中将模型文件(例如.safetensors、.pth、.h5)复制到容器镜像(例如 Dockerfile)中。该模型是不可变图像的一部分。对于更新频率较低的小型号,我们建议使用这种方法。

  • 优点:确保一致性和可重复性,无加载延迟,简化依赖管理。

  • 缺点:导致图像尺寸变大,构建和推送速度变慢,需要重新构建和重新部署才能更新模型,由于注册表拉取吞吐量,因此不适合大型模型。此外,由于设置更为复杂,这可能会导致用于实验、调试和测试的反馈回路更长,并且如果在不同的图像上共置,则可能会增加存储成本。

在运行时下载模型容器启动时,应用程序通过初始化容器或入口点中的脚本从外部存储(例如由 S3 CRT 支持的 Amazon S3,使用适用于 S3 CSI 驱动程序的 Mountpoint、AWS S3 CLI 或 s5cmd OSS CLI 等方法)下载模型,以优化高吞吐量传输。对于经常更新的大型模型,我们建议从这种方法开始。

  • 优点:使容器映像专注于code/runtime, enables easy model updates without rebuilds, supports versioning via storage metadata. It also allows for A/B测试、热交换或回滚模型,而不会增加容器映像的大小,并且能够在不同的应用程序之间共享模型,而无需将其打包到所有容器映像中。此外,它对机器学习或应用程序团队的工作流程进行了最少的更改,并且可以更快地构建容器,以帮助实验和测试。使用 AWS CLI、s5cmd 或 M ountpoint S3 CSI 驱动程序等 S3 CRT 支持的工具可以显著减少下载延迟并提高大型文件的性能,与从 ECR 等注册表中提取大型烘焙容器映像相比,通常可以缩短 Pod 的总体启动时间,具体取决于网络和注册表性能。

  • 缺点:引入潜在的网络故障(需要重试逻辑),需要身份验证和缓存。额外的操作复杂性来自于处理下载过程,包括重试、错误处理和退缩,以及复制 ECR 功能的额外存储和清理管理。

通过永久卷装载模型将模型存储在外部存储中(例如, FSx 适用于 NetApp ONTAP 的 Amazon EFS、EBS、Lustre、OpenZFS 或通过 Mountpoint S3 CSI 驱动程序的 S3),然后将其作 FSx 为 Kubernetes (PV) 挂载。 FSx PersistentVolume 这些是在模型训练过程中生成的文件和数据,允许模型进行预测或推断。我们建议将这种方法用于跨容器或集群的共享模型。

  • 优点:将模型与图像解耦以实现共享访问,无需重启即可进行更新(如果您的框架支持),可以高效处理大型数据集。它还通过克隆、共享和快照等功能支持 Kubernetes 驱动的配置和访问控制,从而减少了复制模型和创建新操作的需求。基于POSIX的模型访问控制是可能的,并且能够在不重建容器映像的情况下与应用程序分开更新模型版本,并且可以更快地构建容器以进行实验和测试。对于将工件读入内存的 AI/ML 推理应用程序,这允许直接从外部文件系统加载数据,而无需将其中间存储在节点的本地磁盘上,从而提高了负载性能。此外,为了大规模存储大型模型,诸 FSx 如 NetApp ONTAP、 FSx for Lustre 之类的服务提供了存储优化技术(例如重复数据删除、压缩、精简配置)、通过快照进行版本控制,并支持在不浪费存储空间的情况下重复使用同一文件。其他服务(例如 S3)提供本机版本控制。根据复制配置(例如,S3 和 EFS 中的异步复制 FSx 或 EFS 中的跨区域复制),这种方法也可以跨集群和潜在的区域。

  • 缺点:如果连接网络,需要存储配置和访问控制,则可能会增加 I/O 延迟,如果存储是特定于群集的,则便携性可能会降低(例如 EBS)。权衡包括 CI/CD 变更和维护加载程序流程会增加操作复杂性,需要自定义 TTL/retention 机制来降低存储成本,以及更复杂的跨区域复制。应根据容器镜像下载时间来衡量模型工件的读取性能。

提供机器学习模型

在 Amazon EKS 上部署和提供机器学习 (ML) 模型需要选择适当的模型服务方法来优化延迟、吞吐量、可扩展性和操作简便性。选择取决于您的模型类型(例如语言、视觉模型)、工作负载需求(例如实时推理)和团队专业知识。常见的方法包括基于 Python 的原型设计设置、用于生产级功能的专用模型服务器以及用于实现高性能和效率的专用推理引擎。每种方法都需要权衡设置复杂性、性能和资源利用率。请注意,由于依赖关系,服务框架可能会增加容器映像的大小(多个 GBs),这可能会影响启动时间,请考虑使用构件处理技术进行解耦来缓解这种情况。从最少到最推荐的选项按推荐顺序列出:

使用 Python 框架(例如 FastAPI、 HuggingFace Transformers with PyTorch)使用 Python 框架开发自定义应用程序,将模型文件(权重、配置、标记器)嵌入到容器化节点设置中。

  • 优点:原型设计简单,仅限 Python,无需额外基础架构,与所有 HuggingFace 模型兼容,Kubernetes 部署简单。

  • 缺点:仅限于单 request/simple 批处理、令牌生成速度慢(没有经过优化的内核)、内存效率低下、缺乏扩展/监控以及启动时间长。

  • 建议:用于需要自定义逻辑集成的初始原型设计或单节点任务。

使用专用的模型服务框架(例如 Tensorrt-LLM、TGI)采用像 Tensorrt-llm 或 TGI 这样的专用服务器进行机器学习推理、管理模型加载、路由和优化。这些支持诸如 safetensors 之类的格式,以及可选的编译或插件。

  • 优点:提供批处理(static/in-flight or continuous), quantization (INT8, FP8, GPTQ), hardware optimizations (NVIDIA, AMD, Intel, Inferentia), and multi-GPU support (Tensor/Pipeline并行性)。Tensorrt-LLM 支持不同的模型(编码器-解码器)LLMs,而 TGI 则利用集成。 HuggingFace

  • 缺点:Tensorrt-LLM 需要编译并且仅限 Nvidia;TGI 的批处理效率可能较低;两者都会增加配置开销,并且可能不适合所有模型类型(例如,非变压器)。

  • 建议:适用于需要生产能力(例如 A/B 测试或具有兼容硬件的高吞吐量)的 PyTorch/TensorFlow 型号。

使用专门的高吞吐量推理引擎(例如 vLLM)利用高级推理引擎,例如 vLLM,优化 LLM 服务、飞行中批处理和量化( PagedAttentionINT8、-KV、AWQ),可与 EKS 自动缩放集成。 FP8

  • 优点:高吞吐量和内存效率(可节省 40-60% 的 VRAM)、动态请求处理、令牌流、单节点 Tensor 并行多 GPU 支持以及广泛的硬件兼容性。

  • 缺点:针对仅限解码器的变压器(例如 LLa MA)进行了优化,对非变压器型号效果较差,需要兼容的硬件(例如 NVIDIA GPUs)和设置工作。

  • 建议:在 EKS 上进行大容量、低延迟 LLM 推理的首选,可最大限度地提高可扩展性和性能。

预缓存容器镜像

大型容器镜像(例如类似的模型 PyTorch)可能会导致冷启动延迟,从而影响延迟。对于延迟敏感型工作负载,例如水平扩展的实时推理工作负载以及 pod 的快速启动至关重要,我们建议您预加载容器镜像以最大限度地减少初始化延迟。请考虑以下方法,从最低到最受推荐:

使用容器运行时缓存预拉镜像

  • 你可以使用 Kubernetes 资源(例如 DaemonSet 或 Deployment)将容器镜像预拉到节点上,以填充节点的容器运行时缓存。容器运行时缓存是由容器运行时管理的本地存储(例如,[containerd] (https://containerd.io/)),从注册表中提取图像后存储在那里。预拉可确保图像在本地可用,从而避免 pod 启动期间的下载延迟。当未预配置 EBS 快照或首选预提取图像时,此方法非常有用。有关预提取图像的示例,请参阅 [AWS 示例 GitHub 存储库] (https://github.com/aws-samples/aws-do-eks/tree/main/Container-Root/eks/deployment/prepull)。请注意,使用 [SOCI Snapshotter](soc https://github.com/awslabs/i-snapshotter)(用于部分图像拉取的 containerd 插件)延迟加载等替代方法可以补充这些方法,尽管它需要自定义设置,可能并不适合所有场景。使用容器运行时缓存具有以下优缺点:

  • 优点:

    • 无需管理 EBS 快照。

    • DaemonSets 随之而来的是最新的容器镜像版本。

    • 更灵活,因为无需重新创建快照即可更新图像。

    • 通过确保图像已在节点上,仍然可以缩短 pod 的启动时间。

  • 缺点:

    • 初始提取大图像仍可能需要一些时间,尽管这是事先完成的。

    • 对于非常大的图像(超过 10 GB),可能不如 EBS 快照那样高效,因为尽管在 pod 启动时不需要,但仍然需要拉取。

    • 使用 DaemonSets,图像会被预先拉取到 Pod 可能运行的所有节点。例如,如果 1000 个节点只运行一个 Pod 的一个实例,则仅在一个节点上运行一个实例就会消耗所有 1000 个节点上的空间。

    • 对于节点向内/向外扩展的实时推理工作负载,由 Cluster Autoscaler 等工具添加的新节点可能会在预拉取完成图像拉取之前调度工作负载 pod。 DaemonSet 无论如何,这都可能导致新节点上的初始 Pod 触发拉动,从而可能延迟启动并影响低延迟要求。

    • 当磁盘使用率超过特定阈值或超过配置的最大未使用年限时,Kubelet 图像垃圾回收会通过删除未使用的图像来影响预拉取的图像。在向内向外扩展模式中,这可能会驱逐空闲节点上的图像,这需要在随后的扩展过程中重新拉取,从而降低缓存对于突发性工作负载的可靠性。

使用 EBS 快照

  • 您可以为缓存的容器映像拍摄 Amazon Elastic Block Store (EBS) 快照,然后在 EKS 工作节点上重复使用此快照。这样可以确保在节点启动时在本地预取图像,从而缩短 pod 初始化时间。有关使用 Karpenter 和适用于托管节点组的 EKS Terraform 蓝图的更多信息,请参阅使用 Bottlerocket 数据量缩短 Amazon E KS 上的容器启动时间。我们建议在 CI/CD 管道中自动创建 EBS 快照,以使它们 up-to-date保持最新的容器映像版本。使用 EBS 快照具有以下优缺点:

  • 优点:

    • 无需在 pod 启动时提取大型容器映像,从而大大缩短了启动时间(例如,对于大于 10 GB 的映像,从 10-15 分钟缩短到几秒)。

    • 确保节点启动时图像在本地可用。

    • 对于具有大型容器镜像的推理工作负载特别有用。

  • 缺点:

    • 每次镜像或版本升级都需要维护和更新 EBS 快照。

    • 需要额外的步骤来确保您的所有工作负载都使用最新的容器映像版本。

    • 涉及创建和管理快照所需的额外操作活动。

    • 如果管理不当,可能会包含不必要的映像,但可以通过适当的节点池配置来缓解这种情况。

优化图像拉取性能

我们强烈建议优化运行 AI/ML 工作负载的 Amazon EKS 集群的容器映像拉取性能。使用未经优化的大型基础映像或低效的层排序可能会导致 pod 启动时间变慢、资源消耗增加和推理延迟降低。要解决这个问题,请采用针对您的工作负载量身定制且依赖性最小的轻量级基础映像。您也可以考虑 AWS Deep Learning Containers (DLCs),它们是预先构建的容器镜像,可以更轻松地运行常用的深度学习框架(例如PyTorchTensorFlow)。要了解有关构建自定义镜像的更多信息,请参阅自定义 Dee p Learning Container s。构建自定义映像时,请考虑使用轻量级基础映像,并仅添加必要的库以保持图像精简。使用多阶段构建来减小图层大小并优化图层顺序以实现高效缓存。有关更多详细信息,请参阅 Docker 构建镜像的最佳实践

通过将容器镜像预加载到数据卷中来缩短容器启动时间

对于需要低 pod 启动延迟的机器学习工作负载(例如实时推理),我们建议您预加载容器镜像以最大限度地减少初始化延迟。大型容器镜像会减慢 Pod 的启动速度,尤其是在带宽有限的节点上。除了使用最少的基础映像、多阶段构建和延迟加载技术外,还可以考虑使用以下方法在 Amazon EKS 中预加载图像。除了使用最少的基础映像、多阶段构建和延迟加载技术外,还可以考虑以下选项:

  • 使用 EBS 快照预加载图像:为缓存的容器映像拍摄亚马逊弹性块存储 (EBS) 快照,然后将此快照重复用于 EKS 工作节点。尽管这增加了额外的操作活动,但它可以确保在节点启动时在本地预取图像,从而缩短 pod 初始化时间。有关使用 Karpenter 和适用于托管节点组的 EKS Terraform 蓝图的更多信息,请参阅使用 Bottlerocket 数据量缩短 Amazon E KS 上的容器启动时间

  • 将@@ 镜像预拉到容器运行时缓存中:使用 Kubernetes 资源(例如, DaemonSet 或 Deployment)将容器镜像预拉到节点上,以填充节点的容器运行时缓存。容器运行时缓存是由容器运行时(例如 c ontainerd)管理的本地存储,从注册表中提取图像后存储在那里。预拉可确保图像在本地可用,从而避免 pod 启动期间的下载延迟。当未预配置 EBS 快照或首选预提取图像时,此方法非常有用。在暂存环境中测试此方法,以验证延迟的改善情况。有关预提取图像的示例,请参阅 AWS 示例 GitHub 存储库