Zephyrnet Logo

Uso de imagens de contêiner para executar modelos TensorFlow no AWS Lambda

Data:

TensorFlow é uma biblioteca de aprendizado de máquina de código aberto (ML) amplamente usada para desenvolver redes neurais e modelos de ML. Esses modelos são geralmente treinados em várias instâncias de GPU para acelerar o treinamento, resultando em tempo de treinamento caro e tamanhos de modelo de até alguns gigabytes. Depois de treinados, esses modelos são implantados na produção para produzir inferências. Eles podem ser cargas de trabalho síncronas, assíncronas ou baseadas em lote. Esses terminais precisam ser altamente escaláveis ​​e resilientes para processar de zero a milhões de solicitações. Aqui é onde AWS Lambda pode ser um serviço de computação atraente para inferência de ML síncrona e assíncrona escalonável, econômica e confiável. Lambda oferece benefícios como escalonamento automático, sobrecarga operacional reduzida e cobrança de pagamento por inferência.

Esta postagem mostra como usar qualquer modelo do TensorFlow com Lambda para inferências escalonáveis ​​em produção com até 10 GB de memória. Isso nos permite usar modelos de ML em funções Lambda de até alguns gigabytes. Para esta postagem, usamos TensorFlow-Keras pré-treinado ResNet50 para classificação de imagens.

Visão geral da solução

Lambda é um serviço de computação sem servidor que permite executar código sem provisionar ou gerenciar servidores. O Lambda dimensiona automaticamente seu aplicativo executando o código em resposta a cada evento, permitindo arquiteturas e soluções baseadas em eventos. O código é executado em paralelo e processa cada evento individualmente, escalando com o tamanho da carga de trabalho, de algumas solicitações por dia a centenas de milhares de cargas de trabalho. O diagrama a seguir ilustra a arquitetura de nossa solução.

O diagrama a seguir ilustra a arquitetura de nossa solução.

Você pode empacotar seu código e dependências como um imagem do recipiente usando ferramentas como o Docker CLI. O tamanho máximo do contêiner é 10 GB. Depois que o modelo para inferência é encaixado, você pode fazer upload da imagem para Registro do Amazon Elastic Container (Amazon ECR). Você pode então criar a função Lambda a partir da imagem do contêiner armazenado no Amazon ECR.

Pré-requisitos

Para este passo a passo, você deve ter os seguintes pré-requisitos:

Implementando a solução

Usamos um modelo pré-treinado do TensorFlow Hub para classificação de imagens. Quando uma imagem é enviada para um Serviço de armazenamento simples da Amazon (Amazon S3), uma função Lambda é invocada para detectar a imagem e imprimi-la no Amazon CloudWatch Histórico. O diagrama a seguir ilustra esse fluxo de trabalho.

O diagrama a seguir ilustra esse fluxo de trabalho.

Para implementar a solução, conclua as seguintes etapas:

  1. Em sua máquina local, crie uma pasta com o nome lambda-tensorflow-example.
  2. Crie uma requirements.txt arquivo nesse diretório.
  3. Adicione todas as bibliotecas necessárias para seu modelo de ML. Para esta postagem, usamos o TensorFlow 2.4.
  4. Crie uma app.py script que contém o código para a função Lambda.
  5. Crie um Dockerfile no mesmo diretório.

O texto a seguir é um exemplo do arquivo requirements.txt para executar o código do TensorFlow para nosso caso de uso:

# List all python libraries for the lambda
tensorflow==2.4.0
tensorflow_hub==0.11
Pillow==8.0.1

Estamos usando a versão 2.4 do TensorFlow com suporte para CPU apenas porque, no momento em que este livro foi escrito, Lambda oferece suporte apenas para CPU. Para obter mais informações sobre as versões somente para CPU do TensorFlow, consulte Localização do pacote.

O código Python é colocado em app.py. A função de inferência em app.py precisa seguir uma estrutura específica a ser invocada pelo Tempo de execução Lambda. Para obter mais informações sobre manipuladores para Lambda, consulte Manipulador de função AWS Lambda em Python. Veja o seguinte código:

import json
import boto3
import numpy as np
import PIL.Image as Image import tensorflow as tf
import tensorflow_hub as hub IMAGE_WIDTH = 224
IMAGE_HEIGHT = 224 IMAGE_SHAPE = (IMAGE_WIDTH, IMAGE_HEIGHT)
model = tf.keras.Sequential([hub.KerasLayer("model/")])
model.build([None, IMAGE_WIDTH, IMAGE_HEIGHT, 3]) imagenet_labels= np.array(open('model/ImageNetLabels.txt').read().splitlines())
s3 = boto3.resource('s3') def lambda_handler(event, context): bucket_name = event['Records'][0]['s3']['bucket']['name'] key = event['Records'][0]['s3']['object']['key'] img = readImageFromBucket(key, bucket_name).resize(IMAGE_SHAPE) img = np.array(img)/255.0 prediction = model.predict(img[np.newaxis, ...]) predicted_class = imagenet_labels[np.argmax(prediction[0], axis=-1)] print('ImageName: {0}, Prediction: {1}'.format(key, predicted_class)) def readImageFromBucket(key, bucket_name): bucket = s3.Bucket(bucket_name) object = bucket.Object(key) response = object.get() return Image.open(response['Body'])

O seguinte Dockerfile para Python 3.8 usa o código aberto fornecido pela AWS imagens de base que pode ser usado para criar imagens de contêiner. As imagens de base são pré-carregadas com tempos de execução de linguagem e outros componentes necessários para executar uma imagem de contêiner no Lambda.

# Pull the base image with python 3.8 as a runtime for your Lambda
FROM public.ecr.aws/lambda/python:3.8 # Install tar and gzip
RUN yum -y install tar gzip zlib # Copy the earlier created requirements.txt file to the container
COPY requirements.txt ./ # Install the python requirements from requirements.txt
RUN python3.8 -m pip install -r requirements.txt # Copy the earlier created app.py file to the container
COPY app.py ./ # Download ResNet50 and store it in a directory
RUN mkdir model
RUN curl -L https://tfhub.dev/google/imagenet/resnet_v1_50/classification/4?tf-hub-format=compressed -o ./model/resnet.tar.gz
RUN tar -xf model/resnet.tar.gz -C model/
RUN rm -r model/resnet.tar.gz # Download ImageNet labels
RUN curl https://storage.googleapis.com/download.tensorflow.org/data/ImageNetLabels.txt -o ./model/ImageNetLabels.txt # Set the CMD to your handler
CMD ["app.lambda_handler"]

Sua estrutura de pastas deve ser semelhante à seguinte captura de tela.

Sua estrutura de pastas deve ser semelhante à seguinte captura de tela.

Você pode criar e enviar a imagem do contêiner para o Amazon ECR com os seguintes comandos bash. Substitua o com seu próprio ID de conta da AWS e também especificar um .

# Build the docker image
docker build -t lambda-tensorflow-example . # Create a ECR repository
aws ecr create-repository --repository-name lambda-tensorflow-example --image-scanning-configuration scanOnPush=true --region <REGION> # Tag the image to match the repository name
docker tag lambda-tensorflow-example:latest <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/lambda-tensorflow-example:latest # Register docker to ECR
aws ecr get-login-password --region <REGION> | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com # Push the image to ECR
docker push <AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/lambda-tensorflow-example:latest

Se você quiser testar a inferência de seu modelo localmente, as imagens de base para Lambda incluem um Runtime Interface Emulator (RIE) que permite que você também teste local sua função Lambda empacotada como uma imagem de contêiner para acelerar os ciclos de desenvolvimento.

Criando um bucket S3

Como uma próxima etapa, criamos um bucket S3 para armazenar as imagens usadas para prever a classe da imagem.

  1. No console do Amazon S3, escolha Criar balde.
  2. Dê um nome ao intervalo S3, como tensorflow-images-for-inference-<Random_String> e substituir o com um valor aleatório.
  3. Escolha Criar balde.

Criação da função Lambda com o código TensorFlow

Para criar sua função Lambda, conclua as seguintes etapas:

  1. No console do Lambda, escolha Funções.
  2. Escolha Criar função.
  3. Selecionar Imagem de contêiner.
  4. Escolha Nome da função, insira um nome, como tensorflow-endpoint.
  5. Escolha URI da imagem do contêiner, insira o criado anteriormente lambda-tensorflow-example repositório.

  1. Escolha Navegue pelas imagens para escolher a imagem mais recente.
  2. Clique Criar função para inicializar a criação dele.
  3. Para melhorar o tempo de execução do Lambda, aumente a memória da função para pelo menos 6 GB e o tempo limite para 5 minutos no Configurações básicas.

Para obter mais informações sobre a memória de funções e configurações de tempo limite, consulte Novo para AWS Lambda - funções com até 10 GB de memória e 6 vCPUs.

Conectando o balde S3 à sua função Lambda

Após a criação bem-sucedida da função Lambda, precisamos adicionar um gatilho a ela para que, sempre que um arquivo for carregado para o depósito S3, a função seja chamada.

  1. No console Lambda, escolha sua função.
  2. Escolha Adicionar gatilho.

Escolha Adicionar gatilho.

  1. Escolha S3.
  2. Escolha Balde, escolha o intervalo que você criou anteriormente.

Para Bucket, escolha o bucket que você criou anteriormente.

Depois que o gatilho é adicionado, você precisa permitir que a função Lambda se conecte ao balde S3, definindo o apropriado Gerenciamento de acesso e identidade da AWS (IAM) para sua função de execução.

  1. No Permissões guia para a sua função, escolha a função IAM.
  2. Escolha Anexar políticas.
  3. Procurar por AmazonS3ReadOnlyAccess e anexá-lo à função IAM.

Agora você configurou todos os serviços necessários para testar seu funcionamento. Faça upload de uma imagem JPG para o intervalo S3 criado abrindo o intervalo no console de gerenciamento AWS e clicando em Escolher arquivo. Depois de alguns segundos, você pode ver o resultado da predição nos logs do CloudWatch. Como uma etapa de acompanhamento, você pode armazenar as previsões em um Amazon DynamoDB tabela.

Após fazer o upload de uma imagem JPG para o balde S3, obteremos a classe de imagem prevista como resultado impresso no CloudWatch. A função Lambda será acionada por EventBridge e extrairá a imagem do balde. Como exemplo, vamos usar a imagem deste papagaio para ser previsto por nosso ponto de extremidade de inferência.

Nos logs do CloudWatch, a classe prevista é impressa. Na verdade, o modelo prevê a classe correta para a imagem (arara):

Performance

Para atingir o desempenho ideal, você pode tentar vários níveis de configuração de memória (que altera linearmente a vCPU atribuída; para saber mais, leia isto Blog de notícias da AWS) No caso de nosso modelo implantado, percebemos a maioria dos ganhos de desempenho com configuração de cerca de 3 GB - 4 GB (~ 2vCPUs) e os ganhos além disso são relativamente baixos. Diferentes modelos veem diferentes níveis de melhoria de desempenho por aumento da quantidade de CPU, portanto, é melhor determinar isso experimentalmente para seu próprio modelo. Além disso, é altamente recomendável que você compile seu código-fonte para aproveitar Extensões de vetor avançadas 2 (AVX2) no Lambda que aumenta ainda mais o desempenho, permitindo que as vCPUs executem um número maior de operações inteiras e de ponto flutuante por ciclo de clock.

Conclusão

O suporte de imagem de contêiner para Lambda permite que você personalize sua função ainda mais, abrindo muitos novos casos de uso para ML sem servidor. Você pode trazer seus modelos personalizados e implantá-los no Lambda usando até 10 GB para o tamanho da imagem do contêiner. Para modelos menores que não precisam de muito poder de computação, você pode realizar treinamento online e inferência puramente em Lambda. Quando o tamanho do modelo aumenta, os problemas de inicialização a frio se tornam cada vez mais importantes e precisam ser mitigado. Também não há restrição na estrutura ou linguagem com imagens de contêiner; outros frameworks de ML, como PyTorch, Apache MX Net, XGBoostNameou Scikit-learn pode ser usado também!

Se você precisar de GPU para sua inferência, pode considerar o uso de serviços de contêineres, como Serviço Amazon Elastic Container (Amazon ECS), Kubernetes ou implante o modelo em um Amazon Sage Maker Ponto final.


Sobre o autor

Jan Bauer é desenvolvedor de aplicativos em nuvem na AWS Professional Services. Seus interesses são computação sem servidor, aprendizado de máquina e tudo o que envolve computação em nuvem.

Fonte: https://aws.amazon.com/blogs/machine-learning/using-container-images-to-run-tensorflow-models-in-aws-lambda/

local_img

Inteligência mais recente

local_img

Fale Conosco

Olá! Como posso ajudá-lo?