AWS Machine Learning Blog

Announcing SOCI-indexed images for faster SageMaker AI jobs

8.5内容质量
Announcing SOCI-indexed images for faster SageMaker AI jobs

TL;DR · AI 摘要

AWS推出SOCI-indexed镜像技术,使SageMaker AI作业启动时间从分钟级缩短至秒级,减少GPU空闲时间达90%。

核心要点

  • SOCI索引技术可减少镜像下载时间90%,显著降低GPU空闲时间
  • 支持使用预索引的AWS DLC镜像或自定义镜像添加索引
  • 无需修改作业定义、入口点或数据通道即可启用

结构提纲

按章节快速跳转。

  1. 容器镜像下载时间直接影响AI作业成本与效率,AWS推出SOCI索引技术解决此问题。

  2. 传统镜像需完整下载导致AI作业启动延迟,尤其影响大规模训练任务。

  3. 通过索引实现按需加载,仅下载启动所需文件,其余后台流式传输。

  4. SOCI索引作为独立OCI合规工件存储于ECR,不影响原镜像签名有效性。

  5. 基准测试显示减少GPU空闲时间达90%,作业启动时间从分钟级降至秒级。

  6. 支持使用预索引DLC镜像或自行添加索引,无需修改作业配置。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • SOCI-indexed镜像技术
    • 核心优势
      • 启动时间缩短90%
      • 成本降低
    • 实现方式
      • 预索引DLC镜像
      • 自定义镜像添加索引
    • 技术原理
      • 按需加载机制
      • OCI合规索引存储

金句 / Highlights

值得收藏与分享的关键句。

#AWS#SageMaker#容器镜像#SOCI#AI训练
打开原文

深度学习容器镜像每多花一分钟下载时间,就意味着您多支付一分钟的费用,团队也多等待一分钟。容器镜像下载是纯粹的开销:产生模型进展的可计费任务时间。对于现代深度学习镜像,这种开销在每个任务中可能需要数分钟。今天,我们非常高兴地宣布 _Amazon SageMaker AI 训练和 Amazon SageMaker AI 处理任务的可寻址 OCI (SOCI) 索引_,该功能将完整容器镜像下载完全移出每个任务的关键路径。

通过 SOCI 索引,SageMaker AI 对容器镜像进行延迟加载。它仅获取启动容器所需的文件,并在代码运行时在后台流式传输其余文件,因此您的任务可在数秒内启动,而不是数分钟。您只需指向预索引的 AWS Deep Learning Container (DLC) 或为自己的镜像添加索引即可采用该功能。这两种方法都不需要修改任务定义、入口点或数据通道。结果是任务启动更快、任务成本更低,以及更多时间用于构建模型而非等待基础设施。

SOCI 索引镜像可在数秒内启动 Amazon SageMaker AI 训练容器,且对训练性能没有任何影响。正如我们在 _我们测量的结果_ 部分所展示的,这在我们的基准测试中将镜像拉取期间的 GPU 空闲时间减少了高达 90%。

本文展示了如何采用 SOCI 索引:它的原理、我们测量的结果,以及如何为您的任务启用该功能。

挑战

SageMaker AI 训练和处理任务在 Amazon Elastic Container Registry (Amazon ECR) 中存储的容器镜像内运行。在任务执行您的代码之前,服务会将整个镜像下载到实例中。它会解压缩并写入每个镜像层到磁盘。

对于小镜像,这只需几秒钟。但深度学习镜像通常超过 10 GB 或更多。这种下载为每个任务增加了数分钟的耗时,您需要为此支付任务时间费用。影响最大的地方正是迭代速度最关键的地方:数百个任务的超参数调优扫描、快速实验和短处理任务,其中镜像下载可能占总运行时间的主导部分。

SOCI 索引的工作原理

Seekable OCI (SOCI) 是一种开源技术,用于对容器镜像进行延迟加载。与在启动前下载整个镜像不同,运行时使用 SOCI 索引仅获取立即启动容器所需的文件。然后在您的代码访问时,在后台流式传输其余文件。

SOCI 索引是映射镜像内每个文件的元数据。您将其存储在 Amazon ECR 中作为与原始镜像关联的 OCI 合规工件。由于索引是独立工件,您的镜像摘要和任何现有签名仍然有效。

SageMaker AI 自动检查索引

当您创建训练或处理任务时,SageMaker AI 会检查您指定的镜像是否有 SOCI 索引,并相应地进行处理:

/think

场景 会发生什么 镜像包含 SOCI 索引 SageMaker AI 会延迟加载镜像,并在完整下载完成前启动容器 镜像没有 SOCI 索引 标准下载,行为无变化 索引无法读取,或延迟加载失败 任务回退到标准下载并继续运行

由于任务在需要时总会回退到标准下载,添加 SOCI 索引永远不会阻止任务运行。你仅能获得更快的启动速度,而不会影响现有工作流。

我们测量的内容

我们在真实的 SageMaker AI 训练任务中,通过两种方式拉取相同容器镜像:标准下载和 SOCI 索引延迟加载。随后从两种方式运行完整的训练任务,以衡量对训练速度的影响。

设置

  • 8 个镜像,压缩后大小为 1.8–35.4 GB
  • GPU 和 CPU 实例:ml.g4dn、ml.g5、ml.g6、ml.g6e、ml.g7、ml.g7e、ml.p4d、ml.p5 和 ml.m7i,实例大小从 xlarge 到 48xlarge,位于美国西部(俄勒冈)区域(us-west-2)和美国东部(北弗吉尼亚)区域(us-east-1)
  • 下载时间:从镜像拉取开始到容器准备运行为止。所有数据均为多次运行的中位数

结果 1:所有镜像尺寸的下载时间从分钟级降至秒级

压缩后镜像大小 标准下载 延迟加载 提升 1.8 GB 48 秒 3-11 秒 ~8x 13.2 GB 3 分 42 秒 ~6 秒 ~34x 35.4 GB 7 分 17 秒 3-11 秒 ~38x

下图对比了标准 Docker 拉取与 SOCI 延迟加载在 8 个镜像尺寸(1.8 GB 至 35.4 GB)下的容器镜像下载时间。

每个镜像尺寸显示两根柱状条。Docker 下载时间条(蓝色)随镜像尺寸增长,从 1.8 GB 的 48 秒增长到 35.4 GB 的 7 分 17 秒。

每对柱状条上方的加速标签显示 Docker 时间与 SOCI 时间的比值。加速比从最小镜像的约 10x 到最大镜像的 35x 以上。

图 1:柱状图对比 Docker 拉取和 SOCI 延迟加载在 8 个镜像尺寸下的下载时间,加速比从约 10x 到 35x 以上
图 1:柱状图对比 Docker 拉取和 SOCI 延迟加载在 8 个镜像尺寸下的下载时间,加速比从约 10x 到 35x 以上

图 1:8 个镜像尺寸下容器镜像下载时间,标准 Docker 拉取与 SOCI 延迟加载对比

标准下载时间随镜像尺寸增长,因为每个文件都需要解压缩和写入。延迟加载在所有尺寸下均保持在 3-11 秒,提升 8x 至 46x。镜像越大,节省的时间越多。

结果 2:所有实例类型和尺寸均能实现节省

在 13 种实例类型/尺寸组合上运行 13.2 GB 镜像时,标准下载耗时从 3 分 16 秒到 4 分 20 秒不等,而延迟加载保持在 6-8 秒。在所有配置中,速度提升约 34x。无需更改实例类型或尺寸即可受益。

图 2:图表对比 13.2 GB 镜像在 13 种实例类型和尺寸组合下的标准下载与 SOCI 延迟加载,每种配置均提升约 34x
图 2:图表对比 13.2 GB 镜像在 13 种实例类型和尺寸组合下的标准下载与 SOCI 延迟加载,每种配置均提升约 34x

图 2:13.2 GB 镜像在 13 种实例类型和尺寸组合下的下载时间

结果 3:第一个 epoch 的惩罚之后训练性能不受影响

我们从通过 Docker 拉取的镜像和通过 SOCI 索引的镜像中运行了两种类型的完整训练任务,并对每个 epoch 进行了比较:

  • 在 Imagenette(9,469 张图像)上使用 ResNet-50 进行图像分类
  • 容器镜像:PyTorch(13.2 GB DLC)和 TensorFlow(9.9 GB DLC)
  • 实例类型:ml.p5.48xlarge、ml.p4d.24xlarge、ml.g7e.48xlarge、ml.g7.48xlarge、ml.g6e.12xlarge、ml.g6e.24xlarge 和 ml.g6e.48xlarge。
  • 大型语言模型(LLM)微调:使用 alpaca-cleaned(51,760 个示例)对 Qwen2.5-0.5B 进行全参数监督微调(SFT),使用 Hugging Face Trainer。
  • 容器镜像:9.4 GB Hugging Face PyTorch DLC。
  • 实例类型:ml.p5.48xlarge、ml.p4d.24xlarge、ml.g6.48xlarge。

下图将任务启动时间拆分为镜像下载时间和第一个训练 epoch 时间,并在两种工作负载的 GPU 和 CPU 配置中,将标准 Docker 拉取与 SOCI 索引镜像进行对比。

图 3:将任务启动时间拆分为镜像下载时间和第一个训练 epoch 时间,对比标准 Docker 拉取与 SOCI 索引镜像在 GPU 和 CPU 配置中的表现
图 3:将任务启动时间拆分为镜像下载时间和第一个训练 epoch 时间,对比标准 Docker 拉取与 SOCI 索引镜像在 GPU 和 CPU 配置中的表现

图 3:任务启动时间拆分为镜像下载时间和第一个训练 epoch 时间,标准 Docker 拉取与 SOCI 索引镜像的对比

  • 从第二个 epoch 开始,所有实例在两个工作负载上的每个 epoch 所需时间相同(在运行间差异范围内)。
  • 从懒加载镜像启动时,第一个 epoch 会额外花费 3–16 秒,用于首次访问框架所需文件。这个首次 epoch 的成本在所有实例规模上保持一致。
  • 总体来看,每个任务提前 1-6 分钟完成。这是下载节省时间减去一次性首次 epoch 成本后的净收益,属于每个任务的固定节省时间。

在您自己的工作负载上进行测试

这些数据来自前述两个工作负载。首次 epoch 的成本取决于您的镜像以及代码在启动时访问的内容:

  • 当首次训练步骤只需镜像中的一小部分,其余内容在训练过程中逐步加载时,懒加载方式表现更优。
  • 如果入口点在训练开始前已读取镜像的大部分内容(例如扫描、校验和或预加载内容),首次 epoch 的等待时间将与完整拉取所需时间相近。此时净收益将非常有限。
  • 在我们的测试中,前置加载方式仍具有优势:
  • torch.compile 和即时(JIT)构建的 CUDA 扩展使首次 epoch 增加了 7-15 秒(净节省时间仍为 3 分 25 秒–3 分 56 秒)
  • 一个 6 GB 模型内置于镜像中,在加载时流式传输权重,增加了 2-3.5 分钟,但整体任务在索引镜像上仍提前 2-2.5 分钟完成。

入门指南

您可以通过两种方式采用 SOCI 索引:使用预索引的 AWS 深度学习容器,或为自定义镜像创建索引。

选项 1:使用预索引的 AWS 深度学习容器

AWS 发布了多个流行深度学习容器的 SOCI 索引版本,这些镜像通过标签中的 -soci 后缀进行标识:

763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:2.9-gpu-py312-cu130-ubuntu22.04-sagemaker-v1-soci

纯文本

PyTorch Training、TensorFlow Training、vLLM 和 SGLang 提供了预索引变体,部分框架还包含 arm64 变体。要启用延迟加载,请将作业定义中的镜像标签更新为 -soci 变体。完整列表请参阅 AWS Deep Learning Containers Gallery。

注意:如果你从 DLC 基础镜像构建自定义镜像,必须为最终镜像创建 SOCI 索引。基础镜像的索引不会继承到衍生镜像中。

选项 2:为自定义镜像创建 SOCI 索引

要为自定义镜像创建索引,需要一个安装了 containerd、SOCI snapshotter 以及 Finch 或 nerdctl 的 Linux 主机(例如运行 Amazon Linux 2023 的 Amazon EC2 实例)。

  1. 设置环境变量。 ```

ACCOUNT_ID="111122223333" REGION="us-east-1" REPOSITORY_NAME="my-training-image" ORIGINAL_IMAGE_TAG="v1.0" SOCI_IMAGE_TAG="v1.0-soci" REGISTRY="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com"

code
Bash  
2. **安装所需工具**。 ```
sudo dnf install -y containerd fuse soci-snapshotter runfinch-finch
sudo systemctl start soci-snapshotter
sudo systemctl restart containerd

Bash

  1. 认证到 Amazon ECR。 ```

aws ecr get-login-password --region "$REGION" \ | sudo nerdctl login -u AWS --password-stdin "$REGISTRY"

code
Bash  
4. **拉取原始镜像**。 `sudo nerdctl pull "$REGISTRY/$REPOSITORY_NAME:$ORIGINAL_IMAGE_TAG"`Bash  
5. **创建 SOCI 索引镜像**。 ```
sudo nerdctl image convert --soci \
  "$REGISTRY/$REPOSITORY_NAME:$ORIGINAL_IMAGE_TAG" \
  "$REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG"

Bash

  1. 推送索引镜像。 ```

sudo nerdctl push --platform linux/amd64 \ "$REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG"

code
Bash  

这会在你的仓库中创建两个制品:SOCI 索引和一个 OCI 兼容的镜像索引清单,将你的镜像链接到索引。原始镜像及其摘要保持不变。

## 在 CI/CD 中自动化索引创建

要在每次推送时自动生成索引,请部署 [CFN ECR SOCI Index Builder](https://github.com/aws-ia/cfn-ecr-aws-soci-index-builder)。它使用 [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) 规则检测 Amazon ECR 镜像推送事件并构建索引。无需更改构建流水线。

## 在 SageMaker AI 作业中使用索引镜像

引用 SOCI 索引镜像的方式与其他镜像完全相同。无需更改 API,仅需调整标签。

## 训练示例(SageMaker Python SDK)

from sagemaker.train import ModelTrainer from sagemaker.train.configs import Compute

trainer = ModelTrainer( training_image="111122223333.dkr.ecr.us-east-1.amazonaws.com/my-training-image:v1.0-soci", role="arn:aws:iam::111122223333:role/SageMakerExecutionRole", compute=Compute( instance_type="ml.g5.12xlarge", instance_count=2, ), )

trainer.train()

code

Python

## 验证镜像是否包含 SOCI 索引

启动前确认标签指向的是索引镜像:

aws ecr batch-get-image \ --repository-name "$REPOSITORY_NAME" \ --image-ids imageTag="$SOCI_IMAGE_TAG" \ --accepted-media-types \ "application/vnd.oci.image.index.v1+json" \ --query 'images[0].imageManifest' --output text \ | jq '.manifests[] | {mediaType, artifactType}'

code

Bash

查找一个 artifactType 以 application/vnd.amazon.soci.index. 开头的子清单,该清单应与您的平台清单并列。如果没有找到,说明该标签未指向索引图像。

## 需注意的事项

*   **仅限 Amazon ECR 私有仓库**。其他仓库中的图像,或通过私有 Docker 仓库(TrainingRepositoryAccessMode 设置为 Vpc)拉取的图像,均不符合懒加载条件。
*   **优化效果与图像大小相关**。小于约 4 GB 的图像改进幅度相对较小。
*   **检查 Docker 特定假设**。SOCI 索引图像需要在基于 containerd 的运行时上运行。请检查入口点和设置脚本中是否存在调用 Docker CLI、读取 /var/run/docker.sock 或从 cgroup 路径派生标识符的代码。SageMaker AI 为向后兼容性挂载了 /.dockerenv 标记,但应避免新增对此的依赖。
*   SageMaker AI 作业的 SOCI 索引功能已在所有 AWS 区域提供。

## 结论

通过 SOCI 索引功能,您可以最大限度缩短 SageMaker AI 训练和处理作业的容器镜像下载时间。为您的镜像添加 SOCI 索引,或切换至预索引的 AWS 深度学习容器。无论哪种方式,均可将启动时间从分钟级缩短至秒级,降低作业总成本,并加速机器学习(ML)迭代周期。同时,您现有的作业定义、API 调用和数据流水线将保持完全不变。

如需了解更多关于 [Amazon SageMaker AI](https://aws.amazon.com/sagemaker/ai/) 的信息并开始使用 SOCI 索引功能,请查阅以下资源:

1. **选择一个带有 SOCI 索引的深度学习容器。** 浏览 [深度学习容器画廊](https://gallery.ecr.aws/deep-learning-containers),并将 -soci 追加到您的镜像标签中。如需针对特定框架的指导,请参阅 [AWS 深度学习容器的 SOCI 索引](https://aws.github.io/deep-learning-containers/tutorials/SOCI/)。
2. **为自定义镜像创建索引。** 按照 [SageMaker AI 开发者指南](https://docs.aws.amazon.com/sagemaker/latest/dg/soci-indexing.html) 中的分步操作指南进行操作,或参考 [SOCI 快照工具的入门指南](https://github.com/awslabs/soci-snapshotter/blob/main/docs/getting-started.md) 获取高级选项。
3. **在 CI/CD 管道中自动化索引生成。** 部署 [CFN ECR SOCI 索引构建器](https://github.com/aws-ia/cfn-ecr-aws-soci-index-builder),在每次推送镜像时自动生成索引。无需对管道进行任何修改。
4. **使用 Finch 在本地进行测试。** 通过 [Finch 懒加载操作指南](https://runfinch.com/docs/container-images/lazy-loading/) 验证镜像,在提交任务前于基于 containerd 的运行时环境中进行测试。
5. **深入探索相关技术。** 在 [AWS 机器学习博客](https://aws.amazon.com/blogs/machine-learning/reducing-container-cold-start-times-using-soci-index-on-dlami-and-dlc/) 阅读《使用 SOCI 索引降低 DLAMI 和 DLC 容器冷启动时间》了解基准测试,或在 [AWS 容器博客](https://aws.amazon.com/blogs/containers/under-the-hood-lazy-loading-container-images-with-seekable-oci-and-aws-fargate/) 阅读《深入解析:使用可寻址 OCI 和 AWS Fargate 实现容器镜像懒加载》以详细了解懒加载机制。

只需更改一个镜像标签,即可实现更快的容器启动速度。在下一个 SageMaker AI 任务中尝试使用,体验其带来的差异。

* * *

## 作者简介