Skalieren Sie YOLOv5-Inferenz mit Amazon SageMaker-Endpunkten und AWS Lambda PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.

Skalieren Sie die YOLOv5-Inferenz mit Amazon SageMaker-Endpunkten und AWS Lambda

Nachdem Data Scientists sorgfältig ein zufriedenstellendes Modell für maschinelles Lernen (ML) entwickelt haben, muss das Modell so bereitgestellt werden, dass es für andere Mitglieder der Organisation leicht zugänglich ist. Die Bereitstellung von Modellen in großem Maßstab mit optimierten Kosten und Recheneffizienz kann jedoch eine entmutigende und umständliche Aufgabe sein. Amazon Sage Maker Endpunkte bieten eine leicht skalierbare und kostenoptimierte Lösung für die Modellbereitstellung. Das YOLOv5-Modell, das unter der GPLv3-Lizenz vertrieben wird, ist ein beliebtes Objekterkennungsmodell, das für seine Laufzeiteffizienz und Erkennungsgenauigkeit bekannt ist. In diesem Beitrag zeigen wir, wie Sie ein vortrainiertes YOLOv5-Modell auf SageMaker-Endpunkten hosten und verwenden AWS Lambda Funktionen zum Aufrufen dieser Endpunkte.

Lösungsüberblick

Das folgende Bild skizziert die AWS-Services, die verwendet werden, um das YOLOv5-Modell mit einem SageMaker-Endpunkt zu hosten und den Endpunkt mit Lambda aufzurufen. Das SageMaker-Notebook greift auf ein YOLOv5-PyTorch-Modell von einer zu Amazon Simple Storage-Service (Amazon S3) Bucket, konvertiert ihn in YOLOv5 TensorFlow SavedModel Format und speichert es zurück in den S3-Bucket. Dieses Modell wird dann beim Hosten des Endpunkts verwendet. Wenn ein Bild auf Amazon S3 hochgeladen wird, fungiert es als Auslöser zum Ausführen der Lambda-Funktion. Die Funktion verwendet OpenCV Lambda-Schichten um das hochgeladene Bild zu lesen und die Inferenz mithilfe des Endpunkts auszuführen. Nachdem die Inferenz ausgeführt wurde, können Sie die daraus erhaltenen Ergebnisse nach Bedarf verwenden.

In diesem Beitrag gehen wir durch den Prozess der Verwendung eines YOLOv5-Standardmodells in PyTorch und dessen Umwandlung in einen TensorFlow SavedModel. Dieses Modell wird über einen SageMaker-Endpunkt gehostet. Dann erstellen und veröffentlichen wir eine Lambda-Funktion, die den Endpunkt aufruft, um die Inferenz auszuführen. Vortrainierte YOLOv5-Modelle sind auf verfügbar GitHub. Für diesen Beitrag verwenden wir die yolov5l Modell.

Voraussetzungen:

Als Voraussetzung müssen wir Folgendes einrichten AWS Identity and Access Management and (IAM) Rollen mit entsprechenden Zugriffsrichtlinien für SageMaker, Lambda und Amazon S3:

  • SageMaker-IAM-Rolle - Dies erfordert AmazonS3FullAccess Angehängte Richtlinien zum Speichern und Zugreifen auf das Modell im S3-Bucket
  • Lambda-IAM-Rolle – Diese Rolle benötigt mehrere Richtlinien:
    • Um auf Bilder zuzugreifen, die in Amazon S3 gespeichert sind, benötigen wir die folgenden IAM-Richtlinien:
      • s3:GetObject
      • s3:ListBucket
    • Um den SageMaker-Endpunkt auszuführen, benötigen wir Zugriff auf die folgenden IAM-Richtlinien:
      • sagemaker:ListEndpoints
      • sagemaker:DescribeEndpoint
      • sagemaker:InvokeEndpoint
      • sagemaker:InvokeEndpointAsync

Sie benötigen außerdem die folgenden Ressourcen und Dienste:

  • Das AWS-Befehlszeilenschnittstelle (AWS CLI), die wir zum Erstellen und Konfigurieren von Lambda verwenden.
  • Eine SageMaker-Notebookinstanz. Diese werden mit vorinstalliertem Docker geliefert, und wir verwenden dies, um die Lambda-Ebenen zu erstellen. Führen Sie die folgenden Schritte aus, um die Notebook-Instance einzurichten:
    • Erstellen Sie in der SageMaker-Konsole eine Notebook-Instance und geben Sie den Notebook-Namen, den Instance-Typ (für diesen Beitrag verwenden wir ml.c5.large), die IAM-Rolle und andere Parameter an.
    • Klonen Sie die öffentliches Repository und fügen Sie die YOLOv5-Repository bereitgestellt von Ultralytics.

Hosten Sie YOLOv5 auf einem SageMaker-Endpunkt

Bevor wir das vortrainierte YOLOv5-Modell auf SageMaker hosten können, müssen wir es exportieren und in die richtige Verzeichnisstruktur darin packen model.tar.gz. Für diesen Beitrag demonstrieren wir, wie man YOLOv5 in der hostet saved_model Format. Das YOLOv5-Repo bietet eine export.py Datei, die das Modell auf viele verschiedene Arten exportieren kann. Nachdem Sie YOLOv5 geklont und das YOLOv5-Verzeichnis über die Befehlszeile eingegeben haben, können Sie das Modell mit dem folgenden Befehl exportieren:

$ cd yolov5
$ pip install -r requirements.txt tensorflow-cpu
$ python export.py --weights yolov5l.pt --include saved_model --nms

Dieser Befehl erstellt ein neues Verzeichnis namens yolov5l_saved_model innerhalb der yolov5 Verzeichnis. Innerhalb der yolov5l_saved_model Verzeichnis, sollten wir die folgenden Elemente sehen:

yolov5l_saved_model
    ├─ assets
    ├─ variables
    │    ├── variables.data-00000-of-00001
    │    └── variables.index
    └── saved_model.pb

So erstellen Sie ein model.tar.gz Datei, verschieben Sie den Inhalt von yolov5l_saved_model zu export/Servo/1. Von der Befehlszeile aus können wir die komprimieren export Verzeichnis, indem Sie den folgenden Befehl ausführen und das Modell in den S3-Bucket hochladen:

$ mkdir export && mkdir export/Servo
$ mv yolov5l_saved_model export/Servo/1
$ tar -czvf model.tar.gz export/
$ aws s3 cp model.tar.gz "<s3://BUCKET/PATH/model.tar.gz>"

Dann können wir einen SageMaker-Endpunkt von einem SageMaker-Notebook bereitstellen, indem wir den folgenden Code ausführen:

import os
import tensorflow as tf
from tensorflow.keras import backend
from sagemaker.tensorflow import TensorFlowModel

model_data = '<s3://BUCKET/PATH/model.tar.gz>'
role = '<IAM ROLE>'

model = TensorFlowModel(model_data=model_data,
                        framework_version='2.8', role=role)

INSTANCE_TYPE = 'ml.m5.xlarge'
ENDPOINT_NAME = 'yolov5l-demo'

predictor = model.deploy(initial_instance_count=1,
                            instance_type=INSTANCE_TYPE,
                            endpoint_name=ENDPOINT_NAME)

Das vorhergehende Skript benötigt etwa 2–3 Minuten, um das Modell vollständig auf dem SageMaker-Endpunkt bereitzustellen. Sie können den Status der Bereitstellung auf der SageMaker-Konsole überwachen. Nachdem das Modell erfolgreich gehostet wurde, ist das Modell bereit für die Inferenz.

Testen Sie den SageMaker-Endpunkt

Nachdem das Modell erfolgreich auf einem SageMaker-Endpunkt gehostet wurde, können wir es testen, was wir mit einem leeren Image tun. Der Testcode lautet wie folgt:

import numpy as np

ENDPOINT_NAME = 'yolov5l-demo'

modelHeight, modelWidth = 640, 640
blank_image = np.zeros((modelHeight,modelWidth,3), np.uint8)
data = np.array(resized_image.astype(np.float32)/255.)
payload = json.dumps([data.tolist()])
response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME,
ContentType='application/json',
Body=payload)

result = json.loads(response['Body'].read().decode())
print('Results: ', result)

Richten Sie Lambda mit Ebenen und Triggern ein

Wir verwenden OpenCV, um das Modell zu demonstrieren, indem wir ein Bild übergeben und die Inferenzergebnisse erhalten. Lambda wird nicht mit vorgefertigten externen Bibliotheken wie OpenCV geliefert, daher müssen wir es erstellen, bevor wir den Lambda-Code aufrufen können. Darüber hinaus möchten wir sicherstellen, dass wir nicht jedes Mal, wenn Lambda aufgerufen wird, externe Bibliotheken wie OpenCV erstellen. Zu diesem Zweck bietet Lambda eine Funktionalität zum Erstellen von Lambda-Layern. Wir können definieren, was in diese Schichten gehört, und sie können bei jedem Aufruf vom Lambda-Code verwendet werden. Wir zeigen auch, wie man die Lambda-Layer für OpenCV erstellt. Für diesen Beitrag verwenden wir eine Amazon Elastic Compute-Cloud (Amazon EC2)-Instanz zum Erstellen der Ebenen.

Nachdem wir die Ebenen eingerichtet haben, erstellen wir die app.py -Skript, bei dem es sich um den Lambda-Code handelt, der die Ebenen verwendet, die Inferenz ausführt und Ergebnisse abruft. Das folgende Diagramm veranschaulicht diesen Workflow.

Lambda-Erlaubnis

Erstellen Sie Lambda-Layer für OpenCV mit Docker

Verwenden Sie Dockerfile wie folgt, um das Docker-Image mit Python 3.7 zu erstellen:

FROM amazonlinux

RUN yum update -y
RUN yum install gcc openssl-devel bzip2-devel libffi-devel wget tar gzip zip make -y

# Install Python 3.7
WORKDIR /
RUN wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz
RUN tar -xzvf Python-3.7.12.tgz
WORKDIR /Python-3.7.12
RUN ./configure --enable-optimizations
RUN make altinstall

# Install Python packages
RUN mkdir /packages
RUN echo "opencv-python" >> /packages/requirements.txt
RUN mkdir -p /packages/opencv-python-3.7/python/lib/python3.7/site-packages
RUN pip3.7 install -r /packages/requirements.txt -t /packages/opencv-python-3.7/python/lib/python3.7/site-packages

# Create zip files for Lambda Layer deployment
WORKDIR /packages/opencv-python-3.7/
RUN zip -r9 /packages/cv2-python37.zip .
WORKDIR /packages/
RUN rm -rf /packages/opencv-python-3.7/

Erstellen und führen Sie Docker aus und speichern Sie die Ausgabe-ZIP-Datei im aktuellen Verzeichnis unter layers:

$ docker build --tag aws-lambda-layers:latest <PATH/TO/Dockerfile>
$ docker run -rm -it -v $(pwd):/layers aws-lambda-layers cp /packages/cv2-python37.zip /layers

Jetzt können wir die Artefakte der OpenCV-Ebene in Amazon S3 hochladen und die Lambda-Ebene erstellen:

$ aws s3 cp layers/cv2-python37.zip s3://<BUCKET>/<PATH/TO/STORE/ARTIFACTS>
$ aws lambda publish-layer-version --layer-name cv2 --description "Open CV" --content S3Bucket=<BUCKET>,S3Key=<PATH/TO/STORE/ARTIFACTS>/cv2-python37.zip --compatible-runtimes python3.7

Nachdem die vorherigen Befehle erfolgreich ausgeführt wurden, haben Sie eine OpenCV-Schicht in Lambda, die Sie auf der Lambda-Konsole überprüfen können.

Lambda-Konsole

Erstellen Sie die Lambda-Funktion

Wir nutzen die app.py -Skript, um die Lambda-Funktion zu erstellen und OpenCV zu verwenden. Ändern Sie im folgenden Code die Werte für BUCKET_NAME und IMAGE_LOCATION zum Speicherort für den Zugriff auf das Bild:

import os, logging, json, time, urllib.parse
import boto3, botocore
import numpy as np, cv2

logger = logging.getLogger()
logger.setLevel(logging.INFO)
client = boto3.client('lambda')

# S3 BUCKETS DETAILS
s3 = boto3.resource('s3')
BUCKET_NAME = "<NAME OF S3 BUCKET FOR INPUT IMAGE>"
IMAGE_LOCATION = "<S3 PATH TO IMAGE>/image.png"

# INFERENCE ENDPOINT DETAILS
ENDPOINT_NAME = 'yolov5l-demo'
config = botocore.config.Config(read_timeout=80)
runtime = boto3.client('runtime.sagemaker', config=config)
modelHeight, modelWidth = 640, 640

# RUNNING LAMBDA
def lambda_handler(event, context):
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')

    # INPUTS - Download Image file from S3 to Lambda /tmp/
    input_imagename = key.split('/')[-1]
    logger.info(f'Input Imagename: {input_imagename}')
    s3.Bucket(BUCKET_NAME).download_file(IMAGE_LOCATION + '/' + input_imagename, '/tmp/' + input_imagename)

    # INFERENCE - Invoke the SageMaker Inference Endpoint
    logger.info(f'Starting Inference ... ')
    orig_image = cv2.imread('/tmp/' + input_imagename)
    if orig_image is not None:
        start_time_iter = time.time()
        # pre-processing input image
        image = cv2.resize(orig_image.copy(), (modelWidth, modelHeight), interpolation = cv2.INTER_AREA)
        data = np.array(image.astype(np.float32)/255.)
        payload = json.dumps([data.tolist()])
        # run inference
        response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)
        # get the output results
        result = json.loads(response['Body'].read().decode())
        end_time_iter = time.time()
        # get the total time taken for inference
        inference_time = round((end_time_iter - start_time_iter)*100)/100
    logger.info(f'Inference Completed ... ')

    # OUTPUTS - Using the output to utilize in other services downstream
    return {
        "statusCode": 200,
        "body": json.dumps({
                "message": "Inference Time:// " + str(inference_time) + " seconds.",
                "results": result
                }),
            }

Stellen Sie die Lambda-Funktion mit dem folgenden Code bereit:

$ zip app.zip app.py
$ aws s3 cp app.zip s3://<BUCKET>/<PATH/TO/STORE/FUNCTION>
$ aws lambda create-function --function-name yolov5-lambda --handler app.lambda_handler --region us-east-1 --runtime python3.7 --environment "Variables={BUCKET_NAME=$BUCKET_NAME,S3_KEY=$S3_KEY}" --code S3Bucket=<BUCKET>,S3Key="<PATH/TO/STORE/FUNCTION/app.zip>"

Hängen Sie die OpenCV-Ebene an die Lambda-Funktion an

Nachdem wir die Lambda-Funktion und -Ebene eingerichtet haben, können wir die Ebene wie folgt mit der Funktion verbinden:

$ aws lambda update-function-configuration --function-name yolov5-lambda --layers cv2

Wir können die Ebeneneinstellungen über die Lambda-Konsole überprüfen.

Lambda-Einstellungen

Lösen Sie Lambda aus, wenn ein Bild auf Amazon S3 hochgeladen wird

Wir verwenden einen Bild-Upload zu Amazon S3 als Auslöser, um die Lambda-Funktion auszuführen. Anweisungen finden Sie unter Tutorial: Verwenden eines Amazon S3-Triggers zum Aufrufen einer Lambda-Funktion.

Sie sollten die folgenden Funktionsdetails auf der Lambda-Konsole sehen.

Funktionsübersicht

Inferenz ausführen

Nachdem Sie Lambda und den SageMaker-Endpunkt eingerichtet haben, können Sie die Ausgabe testen, indem Sie die Lambda-Funktion aufrufen. Wir verwenden einen Bild-Upload zu Amazon S3 als Auslöser zum Aufrufen von Lambda, das wiederum den Endpunkt für die Inferenz aufruft. Als Beispiel laden wir das folgende Bild auf den Amazon S3-Standort hoch <S3 PATH TO IMAGE>/test_image.png im vorherigen Abschnitt konfiguriert.

Testbild

Nachdem das Bild hochgeladen wurde, wird die Lambda-Funktion ausgelöst, um die Bilddaten herunterzuladen und zu lesen und sie zur Inferenz an den SageMaker-Endpunkt zu senden. Das Ausgabeergebnis vom SageMaker-Endpunkt wird von der Funktion im JSON-Format abgerufen und zurückgegeben, das wir auf unterschiedliche Weise verwenden können. Das folgende Bild zeigt eine Beispielausgabe, die dem Bild überlagert ist.

Folgerungsergebnis

Aufräumen

Je nach Instance-Typ können SageMaker-Notebooks erhebliche Rechenleistung und Kosten erfordern. Um unnötige Kosten zu vermeiden, empfehlen wir, die Notebook-Instance zu stoppen, wenn sie nicht verwendet wird. Darüber hinaus fallen für Lambda-Funktionen und SageMaker-Endpunkte nur Gebühren an, wenn sie aufgerufen werden. Daher ist für diese Dienste keine Bereinigung erforderlich. Wenn ein Endpunkt jedoch nicht mehr verwendet wird, empfiehlt es sich, den Endpunkt und das Modell zu entfernen.

Zusammenfassung

In diesem Beitrag haben wir gezeigt, wie Sie ein vortrainiertes YOLOv5-Modell auf einem SageMaker-Endpunkt hosten und Lambda verwenden, um Inferenzen aufzurufen und die Ausgabe zu verarbeiten. Den detaillierten Code finden Sie unter GitHub.

Weitere Informationen zu SageMaker-Endpunkten finden Sie unter Erstellen Sie Ihren Endpunkt und stellen Sie Ihr Modell bereit und Erstellen, testen und stellen Sie Ihre Amazon SageMaker-Inferenzmodelle für AWS Lambda bereit, das hervorhebt, wie Sie den Prozess der Bereitstellung von YOLOv5-Modellen automatisieren können.


Über die Autoren

Skalieren Sie YOLOv5-Inferenz mit Amazon SageMaker-Endpunkten und AWS Lambda PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.Kevin Lied ist IoT Edge Data Scientist bei AWS Professional Services. Kevin hat einen Doktortitel in Biophysik von der University of Chicago. Er verfügt über mehr als 4 Jahre Branchenerfahrung in den Bereichen Computer Vision und maschinelles Lernen. Er ist daran beteiligt, Kunden in der Sport- und Life-Sciences-Branche bei der Bereitstellung von Modellen für maschinelles Lernen zu unterstützen.

Skalieren Sie YOLOv5-Inferenz mit Amazon SageMaker-Endpunkten und AWS Lambda PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.Romil Schah ist IoT Edge Data Scientist bei AWS Professional Services. Romil verfügt über mehr als 6 Jahre Branchenerfahrung in den Bereichen Computer Vision, maschinelles Lernen und IoT-Edge-Geräte. Er ist daran beteiligt, Kunden bei der Optimierung und Bereitstellung ihrer Machine Learning-Modelle für Edge-Geräte für die industrielle Einrichtung zu unterstützen.

Zeitstempel:

Mehr von AWS Maschinelles Lernen