Speed up training job startup with SOCI-indexed images
A training job downloads its container image before it runs your code. For large images, such as deep learning images, this adds minutes to every training job.
Seekable OCI (SOCI) is an open-source technology from AWS for loading container images on
demand (lazy loading). For the project, see soci-snapshotter
How it works:
-
Most container runtimes download the whole image before they start the container, even though the container needs only a small part of it to start.
-
A SOCI index maps the files inside each layer of the image, so the runtime can read one file without downloading the whole layer.
-
You create the index from your existing image. You don't rebuild the image. The index is stored next to the image in Amazon ECR.
-
When the training job starts, the runtime downloads only the files needed to start the container. The rest is downloaded in the background as your code uses it.
SOCI-indexed images start Amazon SageMaker AI training containers in seconds, cutting GPU idle time during image pulls by up to 90%, with no impact on training performance.
To use it, reference a SOCI-indexed image in your CreateTrainingJob request. Nothing else in
the training job changes.
How it works
When you create a training job, SageMaker AI checks whether the image you specified has a SOCI index and behaves accordingly:
| Scenario | What happens |
|---|---|
| The image includes a SOCI index | SageMaker AI lazy-loads the image and starts your container before the full download completes |
| The image has no SOCI index | Normal download - no change in behavior |
| The index can't be read, or lazy loading doesn't succeed | The training job falls back to a standard download and continues running |
Adding an index never prevents a training job from running. In either case the image download is
reported in the training job's Downloading secondary status.
Considerations
-
Where the image is stored
-
Store the image in an Amazon ECR private repository.
-
Reference the image by tag (
repository:tag). An image referenced by digest (repository@sha256:…) is downloaded normally. -
An image pulled through a private Docker registry in your VPC (
TrainingRepositoryAccessModeset toVpc) is downloaded normally.
-
-
Which index format is detected
-
The tag must point to an image that contains a SOCI index v2 (see SOCI Index Manifest v2
on the GitHub website). nerdctl image convert --sociand the Deep Learning Container-socitags create this format. -
A v1 index isn't detected. A v1 index is stored as a separate artifact next to the image, for example by
nerdctl push --snapshotter=sociorsoci create.
-
-
When the time saved is smaller
-
Files are downloaded the first time your code opens them.
-
If your code reads a large part of the image before training starts (for example, model weights stored in the image), that time moves from the download to the start of training.
-
-
Large datasets
-
In
Fileinput mode, the training job also waits for the dataset download. With a very large dataset, that wait can take longer than the image download. -
Use
FastFileorPipeinput mode to keep the benefit.
-
Use a Deep Learning Container that includes a SOCI index
AWS publishes SOCI-indexed variants of several Deep Learning Containers (DLCs),
identified by a -soci suffix on the tag. To adopt lazy loading, change only the
tag:
763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-training:2.9-gpu-py312-cu130-ubuntu22.04-sagemaker-v1-soci
-
For the current list, see the Deep Learning Containers gallery
on the Amazon ECR Public Gallery website and SOCI index for AWS Deep Learning Containers on the GitHub website. -
An image you build
FROMa DLC doesn't inherit the index. Index your final image as described in the next section.
Create a SOCI index for your own image
You need:
-
A Linux host, such as an Amazon EC2 instance running Amazon Linux 2023.
-
These tools on the host:
-
containerd
on the containerd website -
SOCI snapshotter
0.10.0 or later, on the GitHub website -
nerdctl
2.1.3 or later, on the GitHub website. Finch, which is built on nerdctl, can be used instead; see Lazy loading on the Finch website.
-
-
sudoto run the commands. Rootless mode isn't supported. -
The push permissions in Permissions for the identity on the host.
The procedure creates an indexed copy of an existing image under a new tag; the original image, tag, and digest are unchanged.
To create a SOCI index
-
Set variables for your account, Region, repository, the tag to index, and the tag for the indexed image:
ACCOUNT_ID="111122223333" REGION="us-east-1" REPOSITORY_NAME="repository-name" ORIGINAL_IMAGE_TAG="original-image-tag" SOCI_IMAGE_TAG="soci-indexed-image-tag" REGISTRY="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com" -
Install the tools and start the snapshotter (Amazon Linux 2023; for other distributions see the SOCI snapshotter installation guide
on the GitHub website): sudo dnf install -y containerd soci-snapshotter nerdctl jq sudo systemctl start soci-snapshotter sudo systemctl restart containerd -
Confirm that
sociis listed under Server → Plugins → Storage:sudo nerdctl system info -
Authenticate to Amazon ECR and pull the original image:
aws ecr get-login-password --region "$REGION" | sudo nerdctl login -u AWS --password-stdin "$REGISTRY" sudo nerdctl pull "$REGISTRY/$REPOSITORY_NAME:$ORIGINAL_IMAGE_TAG" -
Create and push the SOCI-indexed image:
sudo nerdctl image convert --soci \ "$REGISTRY/$REPOSITORY_NAME:$ORIGINAL_IMAGE_TAG" \ "$REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG" sudo nerdctl push --platform linux/amd64 "$REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG"Layers below the minimum layer size aren't indexed and are downloaded normally when the container starts (
--soci-min-layer-size, see the nerdctl SOCI documentationon the GitHub website).
After the push:
-
The repository has two new artifacts, both shown on the repository's Images page in the Amazon ECR console:
-
The SOCI index.
-
An OCI image index manifest that links your image and the index under the new tag.
-
-
Amazon ECR doesn't create SOCI indexes on its own. To index images automatically on every push, deploy the CFN ECR SOCI Index Builder
on the GitHub website with SociIndexVersionset toV2. For details, see the Index Builder documentationon the GitHub website. It runs from an Amazon EventBridge rule on Amazon ECR push events.
To run the indexed image on the host the way a training job runs it, and check your entry point for the patterns in Prevent job failures: check your code for Docker-specific assumptions:
sudo nerdctl run --snapshotter soci --rm -it "$REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG" /bin/bash
Verify that an image includes a SOCI index
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}'
-
Indexed: the output lists a child manifest whose
artifactTypebegins withapplication/vnd.amazon.soci.index. -
Not indexed: no such entry. Jobs that use the tag download the image normally.
Use a SOCI-indexed image in a training job
Set the indexed image as TrainingImage in AlgorithmSpecification:
"AlgorithmSpecification": { "TrainingImage": "111122223333.dkr.ecr.us-east-1.amazonaws.com/repository-name:soci-indexed-image-tag", "TrainingInputMode": "File" }
With the SageMaker Python SDK:
from sagemaker.train.model_trainer import ModelTrainer from sagemaker.core.training.configs import Compute trainer = ModelTrainer( training_image="111122223333.dkr.ecr.us-east-1.amazonaws.com/repository-name:soci-indexed-image-tag", role="arn:aws:iam::111122223333:role/execution-role-name", compute=Compute(instance_type="ml.g5.12xlarge", instance_count=2), ) trainer.train()
Permissions
-
To run a training job: the execution role needs the same Amazon ECR actions as for any other image, listed in CreateTrainingJob API: Execution Role Permissions. Lazy loading needs no additional permissions.
-
ecr:GetAuthorizationToken -
ecr:BatchCheckLayerAvailability -
ecr:GetDownloadUrlForLayer -
ecr:BatchGetImage
-
-
To create and push indexes: the identity on the build host needs pull and push permissions on the repository, for example:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ecr:GetAuthorizationToken", "Resource": "*" }, { "Effect": "Allow", "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:GetDownloadUrlForLayer", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload", "ecr:PutImage" ], "Resource": "arn:aws:ecr:us-east-1:111122223333:repository/repository-name" } ] }
See Private repository policies in the Amazon Elastic Container Registry User Guide.
Prevent job failures: check your code for Docker-specific assumptions
SOCI-indexed images run on a containerd-based runtime, not on Docker:
-
Container behavior is the same.
-
Code that detects a container by looking for Docker-specific files can take a different path.
-
Review your entry point, framework launchers, and setup scripts for the patterns in the following table.
| Pattern | Why it matters | Recommendation |
|---|---|---|
Checking for the /.dockerenv file |
Created by the Docker daemon; not part of any container standard | Set your own environment variable, or detect containerization without depending on a runtime |
Matching docker in /proc/self/cgroup or
/proc/1/cgroup |
Cgroup paths differ between runtimes and cgroup versions | Don't branch on the runtime name |
| Deriving a container ID from a cgroup path or the host name format | Runtime-specific formats | Pass identifiers in as environment variables |
Calling the docker CLI or /var/run/docker.sock inside
the container |
Not available | Remove the dependency; SageMaker AI manages the container lifecycle |
-
SageMaker AI mounts a
/.dockerenvmarker in the container so that existing checks keep working. Don't add new dependencies on it. -
If you use the SageMaker distributed data parallel library (SMDDP) or
mpirunlaunchers, use a current Deep Learning Container. Some earlier launcher versions relied on/.dockerenv.
Related resources
-
Speed up processing job startup with SOCI-indexed images - the same feature for processing jobs
-
Speed up container startup with SOCI - SOCI indexing for Studio
-
SOCI index for AWS Deep Learning Containers
on the GitHub website -
AlgorithmSpecification in the API reference
-
Pushing an image and Private registry authentication in the Amazon Elastic Container Registry User Guide
-
SOCI snapshotter
and nerdctl on the GitHub website, and Finch documentation on the Finch website -
Under the hood: Lazy loading container images with Seekable OCI and AWS Fargate
on the AWS Containers Blog