Logo Zéphyrnet

Utilisation d'images de conteneur pour exécuter des modèles TensorFlow dans AWS Lambda

Date :

TensorFlow est une bibliothèque d'apprentissage automatique (ML) open source largement utilisée pour développer des réseaux de neurones et des modèles de ML. Ces modèles sont généralement formés sur plusieurs instances de GPU pour accélérer la formation, ce qui entraîne des temps de formation coûteux et des tailles de modèle allant jusqu'à quelques gigaoctets. Une fois formés, ces modèles sont déployés en production pour produire des inférences. Il peut s'agir de charges de travail synchrones, asynchrones ou basées sur des lots. Ces points de terminaison doivent être hautement évolutifs et résilients afin de traiter de zéro à des millions de demandes. C'est ici que AWS Lambda peut être un service de calcul convaincant pour l'inférence ML synchrone et asynchrone évolutive, rentable et fiable. Lambda offre des avantages tels que la mise à l'échelle automatique, la réduction des frais généraux d'exploitation et la facturation par déduction.

Cet article vous montre comment utiliser n'importe quel modèle TensorFlow avec Lambda pour des inférences évolutives en production avec jusqu'à 10 Go de mémoire. Cela nous permet d'utiliser des modèles ML dans les fonctions Lambda jusqu'à quelques gigaoctets. Pour cet article, nous utilisons TensorFlow-Keras pré-entraîné ResNet50 pour la classification des images.

Présentation de la solution

Lambda est un service de calcul sans serveur qui vous permet d'exécuter du code sans provisionnement ni gestion de serveurs. Lambda met automatiquement à l'échelle votre application en exécutant du code en réponse à chaque événement, permettant des architectures et des solutions basées sur les événements. Le code s'exécute en parallèle et traite chaque événement individuellement, en fonction de la taille de la charge de travail, de quelques demandes par jour à des centaines de milliers de charges de travail. Le schéma suivant illustre l'architecture de notre solution.

Le schéma suivant illustre l'architecture de notre solution.

Vous pouvez empaqueter votre code et vos dépendances sous forme de image du conteneur en utilisant des outils tels que la CLI Docker. La taille maximale du conteneur est de 10 Go. Une fois le modèle d'inférence ancré, vous pouvez télécharger l'image sur Registre des conteneurs élastiques Amazon (Amazon ECR). Vous pouvez ensuite créer la fonction Lambda à partir de l'image du conteneur stockée dans Amazon ECR.

Pré-requis

Pour cette procédure pas à pas, vous devez disposer des prérequis suivants:

Mettre en œuvre la solution

Nous utilisons un modèle pré-entraîné du TensorFlow Hub pour la classification des images. Lorsqu'une image est téléchargée sur un Service de stockage simple Amazon (Amazon S3), une fonction Lambda est appelée pour détecter l'image et l'imprimer sur le Amazon Cloud Watch journaux. Le diagramme suivant illustre ce flux de travail.

Le diagramme suivant illustre ce flux de travail.

Pour implémenter la solution, procédez comme suit:

  1. Sur votre ordinateur local, créez un dossier avec le nom lambda-tensorflow-example.
  2. Créer un requirements.txt fichier dans ce répertoire.
  3. Ajoutez toutes les bibliothèques nécessaires pour votre modèle ML. Pour cet article, nous utilisons TensorFlow 2.4.
  4. Créer un app.py script contenant le code de la fonction Lambda.
  5. Créez un Dockerfile dans le même répertoire.

Le texte suivant est un exemple du fichier requirements.txt pour exécuter le code TensorFlow pour notre cas d'utilisation:

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

Nous utilisons la version TensorFlow 2.4 avec la prise en charge du processeur uniquement car, à ce jour, Lambda ne propose que la prise en charge du processeur. Pour plus d'informations sur les versions CPU uniquement de TensorFlow, consultez Emplacement du colis.

Le code Python est placé dans app.py. La fonction d'inférence dans app.py doit suivre une structure spécifique pour être appelée par le Runtime Lambda. Pour plus d'informations sur les gestionnaires pour Lambda, consultez Gestionnaire de fonctions AWS Lambda en Python. Voir le code suivant:

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'])

Le Dockerfile pour Python 3.8 suivant utilise l'open source fourni par AWS images de base qui peut être utilisé pour créer des images de conteneur. Les images de base sont préchargées avec les environnements d'exécution du langage et d'autres composants requis pour exécuter une image de conteneur sur 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"]

La structure de vos dossiers doit ressembler à la capture d'écran suivante.

La structure de vos dossiers doit ressembler à la capture d'écran suivante.

Vous pouvez créer et pousser l'image de conteneur vers Amazon ECR avec les commandes bash suivantes. Remplace le avec votre propre ID de compte AWS et spécifiez également un .

# 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

Si vous souhaitez tester votre inférence de modèle localement, les images de base pour Lambda incluent un émulateur d'interface d'exécution (RIE) qui vous permet également tester localement votre fonction Lambda présentée sous forme d'image de conteneur pour accélérer les cycles de développement.

Créer un compartiment S3

Comme étape suivante, nous créons un compartiment S3 pour stocker les images utilisées pour prédire la classe d'image.

  1. Sur la console Amazon S3, choisissez Créer un seau.
  2. Donnez un nom au compartiment S3, tel que tensorflow-images-for-inference-<Random_String> et remplacer le avec une valeur aléatoire.
  3. Selectionnez Créer un seau.

Création de la fonction Lambda avec le code TensorFlow

Pour créer votre fonction Lambda, procédez comme suit:

  1. Sur la console Lambda, choisissez Les fonctions.
  2. Selectionnez Créer une fonction.
  3. Sélectionnez Image du conteneur.
  4. Pour Nom de la fonction, entrez un nom, tel que tensorflow-endpoint.
  5. Pour URI de l'image du conteneur, entrez le plus tôt créé lambda-tensorflow-example dépôt.

  1. Selectionnez Parcourir les images pour choisir la dernière image.
  2. Cliquez Créer une fonction pour en initialiser la création.
  3. Pour améliorer l'exécution Lambda, augmentez la mémoire des fonctions à au moins 6 Go et le délai d'expiration à 5 minutes dans le Paramètres de base.

Pour plus d'informations sur la mémoire des fonctions et les paramètres de temporisation, voir Nouveau pour AWS Lambda - Fonctions avec jusqu'à 10 Go de mémoire et 6 processeurs virtuels.

Connexion du compartiment S3 à votre fonction Lambda

Après la création réussie de la fonction Lambda, nous devons lui ajouter un déclencheur afin que chaque fois qu'un fichier est téléchargé dans le compartiment S3, la fonction soit appelée.

  1. Sur la console Lambda, choisissez votre fonction.
  2. Selectionnez Ajouter un déclencheur.

Choisissez Ajouter un déclencheur.

  1. Selectionnez S3.
  2. Pour Sac Seau, choisissez le bucket que vous avez créé précédemment.

Pour Bucket, choisissez le bucket que vous avez créé précédemment.

Une fois le déclencheur ajouté, vous devez autoriser la fonction Lambda à se connecter au compartiment S3 en définissant le paramètre approprié Gestion des identités et des accès AWS (IAM) pour son rôle d'exécution.

  1. Sur le Permissions pour votre fonction, choisissez le rôle IAM.
  2. Selectionnez Joindre des politiques.
  3. Rechercher AmazonS3ReadOnlyAccess et attachez-le au rôle IAM.

Vous avez maintenant configuré tous les services nécessaires pour tester votre fonction. Téléchargez une image JPG dans le compartiment S3 créé en ouvrant le compartiment dans la console de gestion AWS et en cliquant sur Téléchargement. Après quelques secondes, vous pouvez voir le résultat de la prédiction dans les journaux CloudWatch. Comme étape de suivi, vous pouvez stocker les prédictions dans un Amazon DynamoDB tableau.

Après avoir téléchargé une image JPG dans le compartiment S3, nous obtiendrons la classe d'image prédite en conséquence imprimée sur CloudWatch. La fonction Lambda sera déclenchée par EventBridge et extraira l'image du compartiment. À titre d'exemple, nous allons utiliser l'image de ce perroquet pour être prédit par notre point de terminaison d'inférence.

Dans les journaux CloudWatch, la classe prédite est imprimée. En effet, le modèle prédit la classe correcte pour l'image (ara):

Performance

Pour obtenir des performances optimales, vous pouvez essayer différents niveaux de paramètres de mémoire (qui modifient linéairement le processeur virtuel attribué, pour en savoir plus, lisez ceci Blog d'actualités AWS). Dans le cas de notre modèle déployé, nous réalisons la plupart des gains de performances à environ 3 Go - 4 Go (~ 2vCPU) et les gains au-delà sont relativement faibles. Différents modèles voient différents niveaux d'amélioration des performances en augmentant la quantité de CPU, il est donc préférable de le déterminer expérimentalement pour votre propre modèle. De plus, il est fortement recommandé de compiler votre code source pour tirer parti de Extensions vectorielles avancées 2 (AVX2) sur Lambda qui augmente encore les performances en permettant aux processeurs virtuels d'exécuter un nombre plus élevé d'opérations en nombre entier et en virgule flottante par cycle d'horloge.

Conclusion

La prise en charge des images de conteneur pour Lambda vous permet de personnaliser encore plus votre fonction, ouvrant de nombreux nouveaux cas d'utilisation pour le ML sans serveur. Vous pouvez apporter vos modèles personnalisés et les déployer sur Lambda en utilisant jusqu'à 10 Go pour la taille de l'image du conteneur. Pour les modèles plus petits qui n'ont pas besoin de beaucoup de puissance de calcul, vous pouvez effectuer une formation et une inférence en ligne uniquement dans Lambda. Lorsque la taille du modèle augmente, les problèmes de démarrage à froid deviennent de plus en plus importants et doivent être atténué. Il n'y a également aucune restriction sur le cadre ou la langue avec les images de conteneur; d'autres frameworks ML tels que PyTorch, Apache MXNet, XGBoostou Scikit-apprendre peut également être utilisé!

Si vous avez besoin d'un GPU pour votre inférence, vous pouvez envisager d'utiliser des services de conteneurs tels que Service de conteneur élastique Amazon (Amazon ECS), Kubernetes ou déployez le modèle sur un Amazon Sage Maker point final.


À propos de l’auteur

Jean Bauer est un développeur d'applications cloud chez AWS Professional Services. Ses intérêts sont l'informatique sans serveur, l'apprentissage automatique et tout ce qui implique le cloud computing.

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

spot_img

Dernières informations

spot_img

Discutez avec nous

Salut! Comment puis-je t'aider?