Escale a inferência YOLOv5 com endpoints do Amazon SageMaker e AWS Lambda PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.

Dimensione a inferência do YOLOv5 com endpoints do Amazon SageMaker e AWS Lambda

Depois que os cientistas de dados criam cuidadosamente um modelo de aprendizado de máquina (ML) satisfatório, o modelo deve ser implantado para ser facilmente acessível para inferência por outros membros da organização. No entanto, implantar modelos em escala com custo otimizado e eficiência de computação pode ser uma tarefa assustadora e complicada. Amazon Sage Maker endpoints fornecem uma solução facilmente escalável e com custo otimizado para implantação de modelo. O modelo YOLOv5, distribuído sob a licença GPLv3, é um modelo popular de detecção de objetos conhecido por sua eficiência de tempo de execução e precisão de detecção. Neste post, demonstramos como hospedar um modelo YOLOv5 pré-treinado em terminais SageMaker e usar AWS Lambda funções para invocar esses pontos de extremidade.

Visão geral da solução

A imagem a seguir descreve os serviços da AWS usados ​​para hospedar o modelo YOLOv5 usando um endpoint SageMaker e invocar o endpoint usando o Lambda. O notebook SageMaker acessa um modelo YOLOv5 PyTorch de um Serviço de armazenamento simples da Amazon (Amazon S3), converte-o em YOLOv5 TensorFlow SavedModel formato e armazena-o de volta no bucket do S3. Esse modelo é então usado ao hospedar o endpoint. Quando uma imagem é carregada no Amazon S3, ela atua como um gatilho para executar a função do Lambda. A função utiliza OpenCV Camadas lambda para ler a imagem carregada e executar a inferência usando o endpoint. Depois que a inferência for executada, você poderá usar os resultados obtidos dela conforme necessário.

Neste post, percorremos o processo de utilização de um modelo padrão YOLOv5 no PyTorch e convertê-lo em um TensorFlow SavedModel. Este modelo é hospedado usando um endpoint SageMaker. Em seguida, criamos e publicamos uma função do Lambda que invoca o endpoint para executar a inferência. Modelos YOLOv5 pré-treinados estão disponíveis em GitHub. Para o propósito deste post, usamos o yolov5l modelo.

Pré-requisitos

Como pré-requisito, precisamos configurar o seguinte Gerenciamento de acesso e identidade da AWS (IAM) papéis com políticas de acesso para SageMaker, Lambda e Amazon S3:

  • Função de IAM do SageMaker - Isto exige AmazonS3FullAccess políticas anexadas para armazenar e acessar o modelo no bucket do S3
  • Função do Lambda IAM – Essa função precisa de várias políticas:
    • Para acessar imagens armazenadas no Amazon S3, exigimos as seguintes políticas do IAM:
      • s3:GetObject
      • s3:ListBucket
    • Para executar o endpoint do SageMaker, precisamos acessar as seguintes políticas do IAM:
      • sagemaker:ListEndpoints
      • sagemaker:DescribeEndpoint
      • sagemaker:InvokeEndpoint
      • sagemaker:InvokeEndpointAsync

Você também precisa dos seguintes recursos e serviços:

  • A Interface de linha de comando da AWS (AWS CLI), que usamos para criar e configurar o Lambda.
  • Uma instância de notebook SageMaker. Eles vêm com o Docker pré-instalado e usamos isso para criar as camadas do Lambda. Para configurar a instância do notebook, conclua as etapas a seguir:
    • No console do SageMaker, crie uma instância de notebook e forneça o nome do notebook, tipo de instância (para esta postagem, usamos ml.c5.large), função do IAM e outros parâmetros.
    • Clone o repositório público e adicione o repositório YOLOv5 fornecido pela Ultralytics.

Hospedar YOLOv5 em um endpoint do SageMaker

Antes de podermos hospedar o modelo YOLOv5 pré-treinado no SageMaker, devemos exportá-lo e empacotá-lo na estrutura de diretórios correta dentro model.tar.gz. Para este post, demonstramos como hospedar o YOLOv5 no saved_model formato. O repositório YOLOv5 fornece uma export.py arquivo que pode exportar o modelo de muitas maneiras diferentes. Depois de clonar o YOLOv5 e inserir o diretório YOLOv5 na linha de comando, você pode exportar o modelo com o seguinte comando:

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

Este comando cria um novo diretório chamado yolov5l_saved_model no interior da yolov5 diretório. Dentro de yolov5l_saved_model diretório, devemos ver os seguintes itens:

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

Para criar um model.tar.gz arquivo, mova o conteúdo de yolov5l_saved_model para export/Servo/1. A partir da linha de comando, podemos compactar o export executando o seguinte comando e faça upload do modelo para o bucket do S3:

$ 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>"

Em seguida, podemos implantar um endpoint SageMaker de um notebook SageMaker executando o seguinte código:

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)

O script anterior leva aproximadamente 2 a 3 minutos para implantar totalmente o modelo no endpoint do SageMaker. Você pode monitorar o status da implantação no console do SageMaker. Depois que o modelo é hospedado com sucesso, o modelo está pronto para inferência.

Testar o endpoint do SageMaker

Depois que o modelo é hospedado com sucesso em um endpoint do SageMaker, podemos testá-lo, o que fazemos usando uma imagem em branco. O código de teste é o seguinte:

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)

Configure o Lambda com camadas e gatilhos

Usamos o OpenCV para demonstrar o modelo passando uma imagem e obtendo os resultados da inferência. O Lambda não vem com bibliotecas externas como OpenCV pré-criadas, portanto, precisamos construí-lo antes de podermos invocar o código Lambda. Além disso, queremos ter certeza de que não construímos bibliotecas externas como OpenCV toda vez que o Lambda está sendo invocado. Para isso, o Lambda fornece uma funcionalidade para criar camadas Lambda. Podemos definir o que vai nessas camadas e elas podem ser consumidas pelo código Lambda toda vez que é invocado. Também demonstramos como criar as camadas Lambda para OpenCV. Para este post, usamos um Amazon Elastic Compute Nuvem (Amazon EC2) para criar as camadas.

Depois de ter as camadas no lugar, criamos o app.py script, que é o código Lambda que usa as camadas, executa a inferência e obtém resultados. O diagrama a seguir ilustra esse fluxo de trabalho.

Permissão lambda

Crie camadas Lambda para OpenCV usando o Docker

Use o Dockerfile da seguinte maneira para criar a imagem do Docker usando o Python 3.7:

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/

Compile e execute o Docker e armazene o arquivo ZIP de saída no diretório atual em 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

Agora podemos fazer upload dos artefatos da camada OpenCV para o Amazon S3 e criar a camada Lambda:

$ 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

Depois que os comandos anteriores forem executados com êxito, você terá uma camada OpenCV no Lambda, que pode ser analisada no console do Lambda.

Console lambda

Criar a função Lambda

Nós utilizamos o app.py script para criar a função Lambda e usar OpenCV. No código a seguir, altere os valores para BUCKET_NAME e IMAGE_LOCATION para o local de acesso à imagem:

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
                }),
            }

Implante a função Lambda com o seguinte código:

$ 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>"

Anexe a camada OpenCV à função Lambda

Depois de ter a função e a camada do Lambda no lugar, podemos conectar a camada à função da seguinte maneira:

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

Podemos revisar as configurações da camada por meio do console do Lambda.

Configurações do Lambda

Acionar o Lambda quando uma imagem é carregada no Amazon S3

Usamos um upload de imagem para o Amazon S3 como um gatilho para executar a função do Lambda. Para obter instruções, consulte Tutorial: como usar um gatilho do Amazon S3 para invocar uma função do Lambda.

Você deve ver os seguintes detalhes da função no console do Lambda.

visão geral da função

Executar inferência

Depois de configurar o Lambda e o endpoint do SageMaker, você pode testar a saída invocando a função do Lambda. Usamos um upload de imagem para o Amazon S3 como um gatilho para invocar o Lambda, que por sua vez invoca o endpoint para inferência. Como exemplo, fazemos upload da seguinte imagem para o local do Amazon S3 <S3 PATH TO IMAGE>/test_image.png configurado na seção anterior.

imagem de teste

Depois que a imagem é carregada, a função Lambda é acionada para baixar e ler os dados da imagem e enviá-los ao endpoint do SageMaker para inferência. O resultado de saída do endpoint do SageMaker é obtido e retornado pela função no formato JSON, que podemos usar de diferentes maneiras. A imagem a seguir mostra a saída de exemplo sobreposta na imagem.

resultado de inferência

limpar

Dependendo do tipo de instância, os notebooks SageMaker podem exigir uso e custo de computação significativos. Para evitar custos desnecessários, recomendamos interromper a instância do notebook quando não estiver em uso. Além disso, as funções do Lambda e os endpoints do SageMaker são cobrados somente quando são invocados. Portanto, nenhuma limpeza é necessária para esses serviços. No entanto, se um endpoint não estiver mais sendo usado, é uma boa prática remover o endpoint e o modelo.

Conclusão

Neste post, demonstramos como hospedar um modelo YOLOv5 pré-treinado em um endpoint SageMaker e usar o Lambda para invocar a inferência e processar a saída. O código detalhado está disponível em GitHub.

Para saber mais sobre os endpoints do SageMaker, confira Crie seu endpoint e implante seu modelo e Crie, teste e implante seus modelos de inferência do Amazon SageMaker no AWS Lambda, que destaca como você pode automatizar o processo de implantação de modelos YOLOv5.


Sobre os autores

Escale a inferência YOLOv5 com endpoints do Amazon SageMaker e AWS Lambda PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.Canção de Kevin é um cientista de dados do IoT Edge na AWS Professional Services. Kevin é PhD em Biofísica pela Universidade de Chicago. Ele tem mais de 4 anos de experiência na indústria em Visão Computacional e Aprendizado de Máquina. Ele está envolvido em ajudar clientes do setor de esportes e ciências da vida a implantar modelos de Machine Learning.

Escale a inferência YOLOv5 com endpoints do Amazon SageMaker e AWS Lambda PlatoBlockchain Data Intelligence. Pesquisa Vertical. Ai.Romil Xá é um cientista de dados do IoT Edge na AWS Professional Services. Romil tem mais de 6 anos de experiência no setor em Visão Computacional, Machine Learning e dispositivos de ponta IoT. Ele está envolvido em ajudar os clientes a otimizar e implantar seus modelos de Machine Learning para dispositivos de ponta para configuração industrial.

Carimbo de hora:

Mais de Aprendizado de máquina da AWS