Reduzindo o tempo de cold start de containers com SOCI no DLAMI e DLC

A AWS anunciou suporte ao SOCI snapshotter e ao índice SOCI nas Deep Learning AMIs (DLAMI) e nos AWS Deep Learning Containers. A novidade resolve um problema bastante concreto para equipes que trabalham com cargas de trabalho de inteligência artificial (IA) e aprendizado de máquina (ML) em escala: o tempo gasto fazendo o download de imagens de container gigantes antes de qualquer trabalho começar de fato.

O problema do cold start em containers de deep learning

Imagens de container para deep learning não são pequenas. É comum encontrar imagens de 15 a 20 GB comprimidas, que podem ocupar 30 a 60 GB em disco após a extração. Com o Docker padrão, todo esse conteúdo precisa ser baixado e descomprimido antes que o container possa iniciar — um processo que facilmente consome entre 4 e 7 minutos por instância.

Durante o desenvolvimento, alguns minutos de espera são toleráveis. Em produção, esse tempo se multiplica rapidamente. Alguns dos impactos mais críticos identificados pela AWS incluem:

  • Cold starts prolongados: pulls de imagens Docker de 15 a 20 GB podem levar de 4 a 6 minutos por instância, atrasando jobs de treinamento e endpoints de inferência durante eventos de escalonamento.
  • Desperdício de recursos computacionais: instâncias com GPU ficam ociosas durante o pull da imagem, consumindo horas de computação cara sem executar nenhuma carga útil.
  • Gargalos de escalonamento: quando picos de demanda disparam o auto scaling, o tempo lento de inicialização impede uma resposta rápida, degradando a performance ou causando perda de requisições.
  • Saturação de banda: múltiplas instâncias fazendo pull simultâneo de imagens pesadas podem saturar a largura de banda da rede, criando atrasos em cascata.
  • Perda de produtividade: cientistas de dados e engenheiros de ML perdem tempo valioso esperando containers iniciarem durante ciclos iterativos de desenvolvimento.

O que é o SOCI e como ele resolve isso

O Seekable OCI (SOCI) é uma tecnologia que permite o gerenciamento eficiente de imagens de container por meio de download seletivo de arquivos. Ele utiliza um sistema de indexação baseado em camadas para mapear a localização dos arquivos dentro da imagem, permitindo que o container inicie com apenas os arquivos necessários já carregados — o chamado lazy loading. As demais camadas são buscadas sob demanda, em segundo plano, conforme o container precisa delas.

Essa abordagem reduz o uso de largura de banda de rede e melhora significativamente o tempo de inicialização dos containers, sendo especialmente valiosa para organizações que gerenciam imagens grandes em ambientes de nuvem.

Três mecanismos de pull disponíveis

Ao fazer o pull de um container nas DLAMIs ou nos Deep Learning Containers, a AWS disponibiliza três opções: o pull padrão do Docker, o pull paralelo SOCI e o lazy loading SOCI via índice SOCI. Pense neles como uma escala de tradeoffs:

  • Docker pull padrão: download sequencial e descompressão sequencial. É o comportamento tradicional — lento, mas sem dependências adicionais.
  • SOCI parallel pull: faz o download da imagem completa antes de iniciar, mas com maior concorrência do que o Docker padrão. Ideal quando você precisa da imagem completa disponível antes de começar o trabalho.
  • SOCI lazy loading: inicia o container quase imediatamente, buscando apenas os arquivos necessários no momento, com o restante carregado em segundo plano sob demanda. Requer que a imagem tenha um índice SOCI no registry.
Imagem original — fonte: Aws

A escolha entre lazy loading e parallel pull depende da imagem, das especificações da instância e da configuração de armazenamento. Instâncias com especificações mais modestas se beneficiam do lazy loading para conservar recursos, enquanto instâncias de alta performance com múltiplos vCPUs e alta largura de banda de rede se saem melhor com o parallel pull. Em relação ao armazenamento, volumes EBS são limitados pelo IOPS provisionado e pelo tipo do volume — o que pode criar gargalos durante a descompressão —, enquanto o NVMe instance store entrega máxima performance de I/O, porém sem persistência de dados entre ciclos de stop/start da instância.

Arquitetura da solução

Imagem original — fonte: Aws

A arquitetura envolve uma instância EC2 de computação acelerada com uma DLAMI (Amazon Linux 2023 ou Ubuntu 24.04), sobre a qual os componentes SOCI (Fuse, SOCI CLI e Container Client) são instalados. Em cima dessa camada, rodam os Deep Learning Containers com suporte a SOCI — incluindo frameworks como PyTorch, TensorFlow, vLLM e sgLang.

Lazy loading na prática: de quase 7 minutos para 21 segundos

O modo de lazy loading inicia o container imediatamente, buscando apenas os dados necessários sob demanda, com as camadas restantes sendo carregadas em segundo plano conforme necessário.

Pré-requisito: índice SOCI

O lazy loading exige que a imagem de container tenha um índice SOCI armazenado no registry. Sem ele, o snapshotter recai no comportamento padrão de pull e nenhuma melhoria de performance é obtida. Os AWS Deep Learning Containers com o sufixo -soci na tag já vêm com índices SOCI pré-criados e enviados ao registry, habilitando o lazy loading imediatamente. Para imagens customizadas, é necessário criar e enviar os índices SOCI manualmente.

Ambiente de teste (lazy loading)

  • Tipo de instância: g5.2xlarge
  • EBS: 500 GiB, 3000 IOPS, 125 MB/s de throughput
  • AMI: Deep Learning Base OSS Nvidia Driver GPU AMI (Ubuntu 24.04) 20260413
  • Imagem Docker: public.ecr.aws/deep-learning-containers/vllm:0.19.0-gpu-py312-ec2-soci
  • Tamanho da imagem: 9,72 GB (comprimida), 32,7 GB (uso em disco)

Iniciando o container com Docker padrão

Com o Docker padrão, como nenhuma imagem existe localmente, o Docker faz o pull e extrai a imagem completa antes de iniciar o container. Tempo total: 6m59.099s.

#!/bin/bash
time docker run \
  --gpus all \
  -d \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HUGGING_FACE_HUB_TOKEN=$HUGGING_FACE_HUB_TOKEN" \
  -p 8000:8000 \
  --ipc=host \
  public.ecr.aws/deep-learning-containers/vllm:0.19.0-gpu-py312-ec2-soci \
  --model mistralai/Mistral-7B-v0.1

# output
Unable to find image 'public.ecr.aws/deep-learning-containers/vllm:0.19.0-gpu-py312-ec2-soci' locally
0.19.0-gpu-py312-ec2-soci: Pulling from deep-learning-containers/vllm
340d44d2921c: Pull complete
....2001a2421bf1: Pull complete
Digest: sha256:a6344c96a33ef98a32a27f89b41b8c0529d4fbbba248eb57f811725d415f68fc
Status: Downloaded newer image for public.ecr.aws/deep-learning-containers/vllm:0.19.0-gpu-py312-ec2-soci
e12d969eb71517d9a6a23b9b11cfa22ddda26a95f6a0f0d8df00cd5c4fdfe912

real	6m59.099s
user	0m0.391s
sys	0m0.452s

Iniciando o container com SOCI snapshotter (lazy loading)

Com o nerdctl e o SOCI snapshotter, a imagem indexada permite que apenas o índice e as camadas necessárias sejam baixados para iniciar o container. As camadas restantes são carregadas sob demanda. Tempo total: 21.125s.

#!/bin/bash
time sudo nerdctl run \
  --snapshotter soci \
  --gpus all \
  -d \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HUGGING_FACE_HUB_TOKEN=$HUGGING_FACE_HUB_TOKEN" \
  -p 8000:8000 \
  --ipc=host \
  public.ecr.aws/deep-learning-containers/vllm:0.19.0-gpu-py312-ec2-soci \
  --model mistralai/Mistral-7B-v0.1

# output
public.ecr.aws/deep-learning-containers/vllm:0.19.0-gpu-py312-ec2-soci:                    resolved       |++++++++++++++++++++++++++++++++++++++|
index-sha256:a6344c96a33ef98a32a27f89b41b8c0529d4fbbba248eb57f811725d415f68fc:    done           |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:d91ad3b46204eace6de2fb27c46d9600337fa9c124b4c82fe0f335d391017daa: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:886ed36d57c44081a74a0ab052f57366d96ab2c0fe39bb3e2f8a46cc20db8ec2:   done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 10.5s                                                                    total:  48.1 K (4.6 KiB/s)
189307b7899438415f3df4288b3fbb26bcc4cd43678e88ec3b062bc6330e3e3b

real	0m21.125s
user	0m0.004s
sys	0m0.011s

O container iniciou em 21,125 segundos com SOCI lazy loading, contra 6 minutos e 59 segundos com o Docker padrão — uma melhoria de aproximadamente 20x.

Parallel pull: 2,2x mais rápido para imagens completas

Enquanto o lazy loading inicia o container imediatamente buscando apenas o necessário, o modo de parallel pull faz o download da imagem completa antes da inicialização, mas com concorrência muito maior do que o Docker padrão. Esse modo é ideal quando você precisa da imagem completa disponível no início ou quando executa cargas de trabalho intensivas em I/O.

Ambiente de teste (parallel pull)

  • Tipo de instância: g5.4xlarge
  • EBS: 500 GiB gp3, 16.000 IOPS, 1.000 MB/s de throughput
  • AMI: Deep Learning Base OSS Nvidia Driver GPU AMI (Ubuntu 24.04) 20260413
  • Imagem Docker: 763104351884.dkr.ecr.us-east-1.amazonaws.com/sglang:0.5.10-gpu-py312-cu129-ubuntu24.04-sagemaker
  • Tamanho da imagem: 19,32 GB (comprimida), 60,4 GB (uso em disco)

Observação: o benchmark usa uma imagem privada do ECR porque o ECR público é servido pelo Amazon CloudFront, o que limita a largura de banda de rede e afeta a performance no modo paralelo. O ECR privado é servido diretamente pelo Amazon Simple Storage Service (Amazon S3), oferecendo maior throughput.

Habilitando o modo parallel pull

O SOCI snapshotter nas DLAMIs usa lazy loading por padrão. Para habilitar o parallel pull, é necessário modificar o arquivo de configuração em /etc/soci-snapshotter-grpc/config.toml:

# Parallel Pull Mode - significantly improves image pull times for large AI/ML images
# These are conservative defaults recommended by AWS for ECR
[pull_modes.parallel_pull_unpack]
enable = true                          # false(default): lazy loading/true: parallel mode
max_concurrent_downloads = -1          # unlimited global cap across all images
max_concurrent_downloads_per_image = 20  # per-image download connections
concurrent_download_chunk_size = "16mb"
max_concurrent_unpacks = -1            # unlimited global cap across all images
max_concurrent_unpacks_per_image = 10  # per-image parallel unpack threads
discard_unpacked_layers = true

Após editar o arquivo, aplique a configuração reiniciando o serviço:

sudo systemctl restart soci-snapshotter.service

Dica: é possível ajustar max_concurrent_downloads_per_image e max_concurrent_unpacks_per_image conforme o tipo de instância e a largura de banda disponível. Para orientações detalhadas de tuning, consulte o post Introducing Seekable OCI Parallel Pull Mode for Amazon EKS.

Verificando se o modo paralelo está ativo

Para confirmar que o parallel pull está habilitado, monitore os logs do SOCI snapshotter durante o pull da imagem:

journalctl -u soci-snapshotter -f

Procure por entradas de log indicando pull/unpack paralelo:

Apr 16 23:59:08 ip-172-31-86-91 soci-snapshotter-grpc[3108]: {"layerDigest":"sha256:e87500e698966458d9dfc34df84602985c9821f39666619792fe6282aa6df5d4", "level":"info", "msg":"preparing snapshot with parallel pull/unpack", "time":"2026-04-16T23:59:08.654819383Z"}

Resultados do parallel pull

Com o Docker padrão, o pull da imagem de 19,32 GB levou 4 minutos e 44 segundos. Com o SOCI em modo parallel pull, o mesmo pull foi concluído em 2 minutos e 12 segundos — uma melhoria de 2,2x na performance de download.

Resumo dos resultados

O SOCI snapshotter entrega melhorias expressivas tanto na inicialização de containers quanto no pull de imagens:

  • Lazy loading: melhoria de 20x no tempo de inicialização do container (de mais de 6 minutos para aproximadamente 21 segundos).
  • Parallel pull: melhoria de 2,2x no tempo de pull da imagem (de 4 minutos e 44 segundos para 2 minutos e 12 segundos).

A regra de escolha é direta: use o lazy loading quando precisar da inicialização mais rápida possível do container; use o parallel pull quando precisar que a imagem completa esteja disponível antes de começar o trabalho.

Disponibilidade e próximos passos

As DLAMIs e os Deep Learning Containers já estão disponíveis com suporte ao SOCI snapshotter e ao índice SOCI. Para começar, consulte o SOCI Index DLAMI para selecionar as imagens que suportam SOCI, e o repositório de Deep Learning Containers para obter mais informações sobre as imagens suportadas com índice SOCI. Para orientações detalhadas de configuração e boas práticas, consulte a documentação do SOCI e a documentação SOCI para Deep Learning Containers.

Se você lançou instâncias EC2 para testar o SOCI snapshotter, lembre-se de encerrá-las para evitar cobranças contínuas. Exclua também as imagens de container enviadas ao Amazon Elastic Container Registry (Amazon ECR) durante os testes e remova os índices SOCI que não forem mais necessários.

Fonte

Reducing container cold start times using SOCI index on DLAMI and DLC (https://aws.amazon.com/blogs/machine-learning/reducing-container-cold-start-times-using-soci-index-on-dlami-and-dlc/)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *