As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Adapte seu próprio contêiner de inferência para a Amazon AI SageMaker
Se você não puder usar nenhuma das imagens listadas na Imagens SageMaker AI Docker pré-construídas Amazon SageMaker AI para seu caso de uso, você pode criar seu próprio contêiner Docker e usá-lo dentro da SageMaker IA para treinamento e inferência. Para ser compatível com a SageMaker IA, seu contêiner deve ter as seguintes características:
-
Seu contêiner deve ter uma listagem de servidores web na porta
8080
. -
Seu contêiner deve aceitar solicitações
POST
para os endpoints/invocations
e/ping
em tempo real. As solicitações que você envia para esses endpoints devem ser retornadas com 60 segundos para respostas regulares e 8 minutos para respostas de streaming e ter um tamanho máximo de 25 MB.
Para obter mais informações e um exemplo de como criar seu próprio contêiner do Docker para treinamento e inferência com SageMaker IA, consulte Como criar seu próprio contêiner de algoritmo
O guia a seguir mostra como usar um JupyterLab
espaço com o Amazon SageMaker Studio Classic para adaptar um contêiner de inferência para funcionar com hospedagem de SageMaker IA. O exemplo usa um servidor da web NGINX, Gunicorn como uma interface de gateway de servidor da web Python e Flask como uma estrutura de aplicação web. Você pode usar aplicações diferentes para adaptar o contêiner, desde que ele atenda aos requisitos listados anteriormente. Para obter mais informações sobre como usar seu próprio código de inferência, consulteCódigo de inferência personalizado com serviços de host.
Adaptar seu contêiner de inferência
Use as etapas a seguir para adaptar seu próprio contêiner de inferência para funcionar com a hospedagem de SageMaker IA. O exemplo mostrado nas seguintes etapas usa um Modelo pré-treinado de Reconhecimento de Entidade Nomeada (NER)Python
e para o seguinte:
-
Um Dockerfile para criar o contêiner que contém o modelo NER.
-
Scripts de inferência para servir ao modelo NER.
Se você adaptar esse exemplo para seu caso de uso, deverá usar Dockerfile e scripts de inferência necessários para implantar e servir seu modelo.
-
Crie JupyterLab espaço com o Amazon SageMaker Studio Classic (opcional).
Você pode usar qualquer notebook para executar scripts e adaptar seu contêiner de inferência com a hospedagem de SageMaker IA. Este exemplo mostra como usar um JupyterLab espaço no Amazon SageMaker Studio Classic para iniciar um JupyterLab aplicativo que vem com uma imagem de distribuição de SageMaker IA. Para obter mais informações, consulte SageMaker JupyterLab.
-
Enviar um arquivo Docker e scripts de inferência.
-
Criar uma nova pasta no seu diretório inicial. Se você estiver usando o JupyterLab, no canto superior esquerdo, escolha o ícone Nova pasta e insira um nome de pasta para conter o Dockerfile. Para este exemplo, a pasta é chamada
docker_test_folder
. -
Enviar um arquivo de texto Dockerfile em sua nova pasta. Veja a seguir um exemplo do Dockerfile que cria um contêiner do Docker com um modelo pré-treinado de reconhecimento de entidades nomeadas (NER)
da spaCy , as aplicações e as variáveis de ambiente necessárias para executar o exemplo: FROM python:3.8 RUN apt-get -y update && apt-get install -y --no-install-recommends \ wget \ python3 \ nginx \ ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN wget https://bootstrap.pypa.io/get-pip.py && python3 get-pip.py && \ pip install flask gevent gunicorn && \ rm -rf /root/.cache #pre-trained model package installation RUN pip install spacy RUN python -m spacy download en # Set environment variables ENV PYTHONUNBUFFERED=TRUE ENV PYTHONDONTWRITEBYTECODE=TRUE ENV PATH="/opt/program:${PATH}" COPY NER /opt/program WORKDIR /opt/program
No exemplo de código anterior, a variável de ambiente
PYTHONUNBUFFERED
evita que Python armazene em buffer o fluxo de saída padrão, o que permite uma entrega mais rápida de logs ao usuário. A variável de ambientePYTHONDONTWRITEBYTECODE
evita que Python grave os arquivos.pyc
de bytecode compilados, que são desnecessários para esse caso de uso. A variável de ambientePATH
é usada para identificar a localização dos programastrain
eserve
quando o contêiner é invocado. -
Crie um novo diretório dentro de sua nova pasta para conter scripts para servir ao seu modelo. Este exemplo usa um diretório chamado
NER
, que contém os seguintes scripts necessários para executar este exemplo:-
predictor.py
: um script Python que contém a lógica para enviar e realizar inferências com seu modelo. -
nginx.conf
: um script para configurar um servidor web. -
serve
: um script que inicia um servidor de inferência. -
wsgi.py
: um script auxiliar para servir a um modelo.
Importante
Se você copiar seus scripts de inferência em um caderno que termina em
.ipynb
e renomeá-los, seu script pode conter caracteres de formatação que impedirão a implantação do endpoint. Em vez disso, crie um arquivo de texto e renomeie-o. -
-
Enviar um script para disponibilizar seu modelo para inferência. A seguir está um exemplo de script chamado
predictor.py
que usa Flask para fornecer os endpoints/ping
e/invocations
:from flask import Flask import flask import spacy import os import json import logging #Load in model nlp = spacy.load('en_core_web_sm') #If you plan to use a your own model artifacts, #your model artifacts should be stored in /opt/ml/model/ # The flask app for serving predictions app = Flask(__name__) @app.route('/ping', methods=['GET']) def ping(): # Check if the classifier was loaded correctly health = nlp is not None status = 200 if health else 404 return flask.Response(response= '\n', status=status, mimetype='application/json') @app.route('/invocations', methods=['POST']) def transformation(): #Process input input_json = flask.request.get_json() resp = input_json['input'] #NER doc = nlp(resp) entities = [(X.text, X.label_) for X in doc.ents] # Transform predictions to JSON result = { 'output': entities } resultjson = json.dumps(result) return flask.Response(response=resultjson, status=200, mimetype='application/json')
O endpoint
/ping
no exemplo de script anterior retorna um código de status200
se o modelo foi enviado corretamente e404
se o modelo foi enviado incorretamente. O endpoint/invocations
processa uma solicitação formatada em JSON, extrai o campo de entrada e usa o modelo NER para identificar e armazenar entidades nas entidades variáveis. A aplicação Flask retorna a resposta que contém essas entidades. Para obter mais informações sobre essas solicitações de integridade necessárias, consulte Como o contêiner deve responder a solicitações de verificação de integridade (ping). -
Enviar um script para iniciar um servidor de inferência. O exemplo de script a seguir chama
serve
usado Gunicorn como servidor de aplicações e Nginx como servidor web:#!/usr/bin/env python # This file implements the scoring service shell. You don't necessarily need to modify it for various # algorithms. It starts nginx and gunicorn with the correct configurations and then simply waits until # gunicorn exits. # # The flask server is specified to be the app object in wsgi.py # # We set the following parameters: # # Parameter Environment Variable Default Value # --------- -------------------- ------------- # number of workers MODEL_SERVER_WORKERS the number of CPU cores # timeout MODEL_SERVER_TIMEOUT 60 seconds import multiprocessing import os import signal import subprocess import sys cpu_count = multiprocessing.cpu_count() model_server_timeout = os.environ.get('MODEL_SERVER_TIMEOUT', 60) model_server_workers = int(os.environ.get('MODEL_SERVER_WORKERS', cpu_count)) def sigterm_handler(nginx_pid, gunicorn_pid): try: os.kill(nginx_pid, signal.SIGQUIT) except OSError: pass try: os.kill(gunicorn_pid, signal.SIGTERM) except OSError: pass sys.exit(0) def start_server(): print('Starting the inference server with {} workers.'.format(model_server_workers)) # link the log streams to stdout/err so they will be logged to the container logs subprocess.check_call(['ln', '-sf', '/dev/stdout', '/var/log/nginx/access.log']) subprocess.check_call(['ln', '-sf', '/dev/stderr', '/var/log/nginx/error.log']) nginx = subprocess.Popen(['nginx', '-c', '/opt/program/nginx.conf']) gunicorn = subprocess.Popen(['gunicorn', '--timeout', str(model_server_timeout), '-k', 'sync', '-b', 'unix:/tmp/gunicorn.sock', '-w', str(model_server_workers), 'wsgi:app']) signal.signal(signal.SIGTERM, lambda a, b: sigterm_handler(nginx.pid, gunicorn.pid)) # Exit the inference server upon exit of either subprocess pids = set([nginx.pid, gunicorn.pid]) while True: pid, _ = os.wait() if pid in pids: break sigterm_handler(nginx.pid, gunicorn.pid) print('Inference server exiting') # The main routine to invoke the start function. if __name__ == '__main__': start_server()
O exemplo de script anterior define uma função de manipulador de sinal
sigterm_handler
, que desliga os subprocessos Nginx e Gunicorn quando recebe um sinalSIGTERM
. Uma funçãostart_server
inicia o manipulador de sinal, inicia e monitora os subprocessos Nginx e Gunicorn e captura fluxos de log. -
Enviar um script para configurar seu servidor web. O exemplo de script a seguir chamado
nginx.conf
configura um servidor web Nginx usando Gunicorn como servidor de aplicações para servir seu modelo para inferência:worker_processes 1; daemon off; # Prevent forking pid /tmp/nginx.pid; error_log /var/log/nginx/error.log; events { # defaults } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log combined; upstream gunicorn { server unix:/tmp/gunicorn.sock; } server { listen 8080 deferred; client_max_body_size 5m; keepalive_timeout 5; proxy_read_timeout 1200s; location ~ ^/(ping|invocations) { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://gunicorn; } location / { return 404 "{}"; } } }
O exemplo de script anterior configura Nginx para ser executado em primeiro plano, define o local para capturar o
error_log
e defineupstream
como o soquete do servidor Gunicorn. O servidor configura o bloco do servidor para escutar na porta8080
, define limites no tamanho do corpo da solicitação do cliente e nos valores de tempo limite. O bloco do servidor encaminha solicitações contendo caminhos/ping
ou/invocations
para Gunicornserver http://gunicorn
e retorna um erro404
para outros caminhos. -
Enviar todos os outros scripts necessários para atender ao seu modelo. Este exemplo precisa do seguinte exemplo de script chamado
wsgi.py
para ajudar o Gunicorn encontrar sua aplicação:import predictor as myapp # This is just a simple wrapper for gunicorn to find your app. # If you want to change the algorithm file, simply change "predictor" above to the # new file. app = myapp.app
Na pasta
docker_test_folder
, sua estrutura de diretórios deve conter Dockerfile e a pasta NER. A pasta NER deve conter os arquivosnginx.conf
,predictor.py
,serve
ewsgi.py
da seguinte forma: -
-
Criar seu próprio contêiner.
Na pasta
docker_test_folder
, crie seu contêiner do Docker. O seguinte comando de exemplo criará o contêiner do Docker que está configurado no Dockerfile:! docker build -t byo-container-test .
O comando anterior criará um contêiner chamado
byo-container-test
no diretório de trabalho atual. Para obter mais informações sobre os parâmetros de criação Docker, consulte Argumentos de criação. nota
Se você receber a mensagem de erro a seguir informando que o Docker não consegue encontrar o Dockerfile, verifique se o Dockerfile tem o nome correto e foi salvo no diretório.
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /home/ec2-user/SageMaker/docker_test_folder/Dockerfile: no such file or directory
O Docker procura especificamente um arquivo chamado Dockerfile sem nenhuma extensão no diretório atual. Se você deu outro nome, poderá transmitir o nome de arquivo manualmente com a sinalização -f. Por exemplo, se você nomeou seu Dockerfile como Dockerfile-text.txt, crie seu contêiner do Docker usando a sinalização
-f
seguida pelo seu arquivo da seguinte forma:! docker build -t byo-container-test -f Dockerfile-text.txt .
-
Enviar a imagem do Docker para o Amazon Elastic Container Registry (Amazon ECR)
Em uma célula de caderno, envie sua imagem do Docker para um ECR. O seguinte exemplo de código mostra como criar o contêiner localmente, fazer login e enviá-lo para um ECR:
%%sh # Name of algo -> ECR algorithm_name=sm-pretrained-spacy #make serve executable chmod +x NER/serve account=$(aws sts get-caller-identity --query Account --output text) # Region, defaults to us-west-2 region=$(aws configure get region) region=${region:-us-east-1} fullname="${account}.dkr.ecr.${region}.amazonaws.com/${algorithm_name}:latest" # If the repository doesn't exist in ECR, create it. aws ecr describe-repositories --repository-names "${algorithm_name}" > /dev/null 2>&1 if [ $? -ne 0 ] then aws ecr create-repository --repository-name "${algorithm_name}" > /dev/nullfi # Get the login command from ECR and execute it directly aws ecr get-login-password --region ${region}|docker login --username AWS --password-stdin ${fullname} # Build the docker image locally with the image name and then push it to ECR # with the full name. docker build -t ${algorithm_name} . docker tag ${algorithm_name} ${fullname} docker push ${fullname}
O exemplo anterior mostra como executar as seguintes etapas necessárias para enviar o contêiner do Docker de exemplo para um ECR:
-
Defina o nome do algoritmo como
sm-pretrained-spacy
. -
Torne executável o arquivo
serve
dentro da pasta NER. -
Defina Região da AWS o.
-
Crie um ECR se ele ainda não existir.
-
Faça login no ECR.
-
Construa o contêiner do Docker localmente.
-
Envie a imagem do Docker por push ao ECR.
-
-
Configurar o cliente de SageMaker IA
Se quiser usar serviços de hospedagem de SageMaker IA para inferência, você deve criar um modelo, criar uma
configuração de endpoint e criar um endpoint. Para obter inferências do seu endpoint, você pode usar o cliente SageMaker AI boto3 Runtime para invocar seu endpoint. O código a seguir mostra como configurar o cliente SageMaker AI e o cliente SageMaker Runtime usando o cliente SageMaker AI boto3: import boto3 from sagemaker import get_execution_role sm_client = boto3.client(service_name='sagemaker') runtime_sm_client = boto3.client(service_name='sagemaker-runtime') account_id = boto3.client('sts').get_caller_identity()['Account'] region = boto3.Session().region_name #used to store model artifacts which SageMaker AI will extract to /opt/ml/model in the container, #in this example case we will not be making use of S3 to store the model artifacts #s3_bucket = '<S3Bucket>' role = get_execution_role()
No exemplo de código anterior, o bucket do Amazon S3 não é usado, mas inserido como um comentário para mostrar como armazenar artefatos do modelo.
Se você receber um erro de permissão depois de executar o exemplo de código anterior, talvez seja necessário adicionar permissões ao seu perfil do IAM. Para obter mais informações sobre perfis do IAM, consulte Gerente de SageMaker funções da Amazon. Para obter mais informações sobre como adicionar permissões à sua função atual, consulte AWS políticas gerenciadas para Amazon SageMaker AI.
-
Criar seu modelo.
Se você quiser usar serviços de hospedagem de SageMaker IA para inferência, deverá criar um modelo em SageMaker IA. O exemplo de código a seguir mostra como criar o spaCy NER modelo dentro da SageMaker IA:
from time import gmtime, strftime model_name = 'spacy-nermodel-' + strftime("%Y-%m-%d-%H-%M-%S", gmtime()) # MODEL S3 URL containing model atrifacts as either model.tar.gz or extracted artifacts. # Here we are not #model_url = 's3://{}/spacy/'.format(s3_bucket) container = '{}.dkr.ecr.{}.amazonaws.com/sm-pretrained-spacy:latest'.format(account_id, region) instance_type = 'ml.c5d.18xlarge' print('Model name: ' + model_name) #print('Model data Url: ' + model_url) print('Container image: ' + container) container = { 'Image': container } create_model_response = sm_client.create_model( ModelName = model_name, ExecutionRoleArn = role, Containers = [container]) print("Model Arn: " + create_model_response['ModelArn'])
O exemplo de código anterior mostra como definir um
model_url
usando os3_bucket
se você fosse usar o bucket do Amazon S3 a partir dos comentários na Etapa 5 e definir o URI do ECR para a imagem do contêiner. Os exemplos de código anteriores definemml.c5d.18xlarge
como o tipo de instância. Também é possível escolher um tipo de instância diferente. Para obter mais informações sobre os tipos de instância disponíveis, consulte Tipos de EC2 instância da Amazon. No exemplo de código anterior, a chave
Image
aponta para o URI da imagem do contêiner. A definiçãocreate_model_response
usa ocreate_model method
para criar um modelo e retornar o nome do modelo, a função e uma lista contendo as informações do contêiner.Exemplo de saída do script anterior a seguir:
Model name: spacy-nermodel-YYYY-MM-DD-HH-MM-SS Model data Url: s3://spacy-sagemaker-us-east-1-bucket/spacy/ Container image: 123456789012.dkr.ecr.us-east-2.amazonaws.com/sm-pretrained-spacy:latest Model Arn: arn:aws:sagemaker:us-east-2:123456789012:model/spacy-nermodel-YYYY-MM-DD-HH-MM-SS
-
-
Configurar e criar um endpoint
Para usar a hospedagem de SageMaker IA para inferência, você também deve configurar e criar um endpoint. SageMaker A IA usará esse endpoint para inferência. O exemplo de configuração a seguir mostra como gerar e configurar um endpoint com o tipo de instância e o nome do modelo que você definiu anteriormente:
endpoint_config_name = 'spacy-ner-config' + strftime("%Y-%m-%d-%H-%M-%S", gmtime()) print('Endpoint config name: ' + endpoint_config_name) create_endpoint_config_response = sm_client.create_endpoint_config( EndpointConfigName = endpoint_config_name, ProductionVariants=[{ 'InstanceType': instance_type, 'InitialInstanceCount': 1, 'InitialVariantWeight': 1, 'ModelName': model_name, 'VariantName': 'AllTraffic'}]) print("Endpoint config Arn: " + create_endpoint_config_response['EndpointConfigArn'])
No exemplo de configuração anterior,
create_endpoint_config_response
associa omodel_name
a um nome de configuração de endpointendpoint_config_name
exclusivo criado com um carimbo de data/hora.Exemplo de saída do script anterior a seguir:
Endpoint config name: spacy-ner-configYYYY-MM-DD-HH-MM-SS Endpoint config Arn: arn:aws:sagemaker:us-east-2:123456789012:endpoint-config/spacy-ner-config-MM-DD-HH-MM-SS
Para obter mais informações sobre erros de endpoint, consulte Por que meu endpoint Amazon SageMaker AI entra em estado de falha quando eu crio ou atualizo um
endpoint? -
Crie um endpoint e aguarde até que o endpoint esteja em serviço.
O seguinte exemplo de código cria o endpoint usando a configuração do exemplo de configuração anterior e implanta o modelo:
%%time import time endpoint_name = 'spacy-ner-endpoint' + strftime("%Y-%m-%d-%H-%M-%S", gmtime()) print('Endpoint name: ' + endpoint_name) create_endpoint_response = sm_client.create_endpoint( EndpointName=endpoint_name, EndpointConfigName=endpoint_config_name) print('Endpoint Arn: ' + create_endpoint_response['EndpointArn']) resp = sm_client.describe_endpoint(EndpointName=endpoint_name) status = resp['EndpointStatus'] print("Endpoint Status: " + status) print('Waiting for {} endpoint to be in service...'.format(endpoint_name)) waiter = sm_client.get_waiter('endpoint_in_service') waiter.wait(EndpointName=endpoint_name)
No exemplo de código anterior, o método
create_endpoint
cria o endpoint com o nome do endpoint gerado criado no exemplo de código anterior e imprime o Nome do Recurso da Amazon do endpoint. O métododescribe_endpoint
retorna informações sobre o endpoint e seu status. Um garçom de SageMaker IA espera que o endpoint esteja em serviço.
-
-
Teste seu endpoint.
Quando seu endpoint estiver em serviço, envie uma solicitação de invocação
para seu endpoint. O seguinte exemplo de código mostra como enviar uma solicitação de teste para o endpoint a seguir: import json content_type = "application/json" request_body = {"input": "This is a test with NER in America with \ Amazon and Microsoft in Seattle, writing random stuff."} #Serialize data for endpoint #data = json.loads(json.dumps(request_body)) payload = json.dumps(request_body) #Endpoint invocation response = runtime_sm_client.invoke_endpoint( EndpointName=endpoint_name, ContentType=content_type, Body=payload) #Parse results result = json.loads(response['Body'].read().decode())['output'] result
No exemplo de código anterior, o método
json.dumps
serializa orequest_body
em uma string formatada em JSON e a salva na carga útil da variável. Em seguida, o cliente SageMaker AI Runtime usa o método invoke endpointpara enviar a carga para seu endpoint. O resultado contém a resposta do seu endpoint após extrair o campo de saída. O exemplo de código anterior deve retornar o seguinte resultado:
[['NER', 'ORG'], ['America', 'GPE'], ['Amazon', 'ORG'], ['Microsoft', 'ORG'], ['Seattle', 'GPE']]
-
Excluir seu endpoint
Depois de concluir suas invocações, exclua seu endpoint para conservar recursos. O seguinte exemplo de código mostra como excluir um endpoint:
sm_client.delete_endpoint(EndpointName=endpoint_name) sm_client.delete_endpoint_config(EndpointConfigName=endpoint_config_name) sm_client.delete_model(ModelName=model_name)
Para obter um caderno completo contendo o código deste exemplo, consulte BYOC-Single-Model
.