Requisitos previos - Amazon SageMaker

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Requisitos previos

nota

Siga las instrucciones de esta sección si compiló el modelo con AWS SDK for Python (Boto3) AWS CLI, o con la consola. SageMaker

Para crear un modelo SageMaker compilado en NEO, necesita lo siguiente:

  1. Una imagen de Docker Amazon ECRURI. Puede seleccionar uno que se adapte a sus necesidades de esta lista.

  2. Un archivo de guión de punto de entrada:

    1. Para PyTorch y MXNet modelos:

      Si entrenó su modelo con SageMaker, el script de entrenamiento debe implementar las funciones que se describen a continuación. El script de entrenamiento sirve como script de punto de entrada durante la inferencia. En el ejemplo detallado en MNISTEntrenamiento, compilación y despliegue con MXNet Module y SageMaker Neo, el script de entrenamiento (mnist.py) implementa las funciones requeridas.

      Si no entrenó su modelo con él SageMaker, debe proporcionar un archivo script (inference.py) de punto de entrada que pueda usarse en el momento de la inferencia. Según el marco, MXNet o PyTorch la ubicación del script de inferencia debe ajustarse a la estructura de directorios del SDK modelo de SageMaker Python para MxNet o la estructura de directorios del modelo para PyTorch.

      Cuando se utilizan imágenes de contenedor optimizado para inferencias de Neo con tipos de GPU instancia PyTorchCPUy MXNetactivados, el script de inferencia debe implementar las siguientes funciones:

      • model_fn: Carga el modelo. (Opcional)

      • input_fn: Convierte la carga útil de la solicitud entrante en una matriz numpy.

      • predict_fn: Realiza la predicción.

      • output_fn: Convierte el resultado de la predicción en la carga útil de respuesta.

      • Como alternativa, puede transform_fn definir la combinación input_fn, predict_fn y output_fn.

      Los siguientes son ejemplos de inference.py scripts dentro de un directorio denominado code (code/inference.py) for PyTorch y MXNet (Gluon and Module). Los ejemplos cargan primero el modelo y, a continuación, lo muestran en los datos de imagen de unGPU:

      MXNet Module
      import numpy as np import json import mxnet as mx import neomx # noqa: F401 from collections import namedtuple Batch = namedtuple('Batch', ['data']) # Change the context to mx.cpu() if deploying to a CPU endpoint ctx = mx.gpu() def model_fn(model_dir): # The compiled model artifacts are saved with the prefix 'compiled' sym, arg_params, aux_params = mx.model.load_checkpoint('compiled', 0) mod = mx.mod.Module(symbol=sym, context=ctx, label_names=None) exe = mod.bind(for_training=False, data_shapes=[('data', (1,3,224,224))], label_shapes=mod._label_shapes) mod.set_params(arg_params, aux_params, allow_missing=True) # Run warm-up inference on empty data during model load (required for GPU) data = mx.nd.empty((1,3,224,224), ctx=ctx) mod.forward(Batch([data])) return mod def transform_fn(mod, image, input_content_type, output_content_type): # pre-processing decoded = mx.image.imdecode(image) resized = mx.image.resize_short(decoded, 224) cropped, crop_info = mx.image.center_crop(resized, (224, 224)) normalized = mx.image.color_normalize(cropped.astype(np.float32) / 255, mean=mx.nd.array([0.485, 0.456, 0.406]), std=mx.nd.array([0.229, 0.224, 0.225])) transposed = normalized.transpose((2, 0, 1)) batchified = transposed.expand_dims(axis=0) casted = batchified.astype(dtype='float32') processed_input = casted.as_in_context(ctx) # prediction/inference mod.forward(Batch([processed_input])) # post-processing prob = mod.get_outputs()[0].asnumpy().tolist() prob_json = json.dumps(prob) return prob_json, output_content_type
      MXNet Gluon
      import numpy as np import json import mxnet as mx import neomx # noqa: F401 # Change the context to mx.cpu() if deploying to a CPU endpoint ctx = mx.gpu() def model_fn(model_dir): # The compiled model artifacts are saved with the prefix 'compiled' block = mx.gluon.nn.SymbolBlock.imports('compiled-symbol.json',['data'],'compiled-0000.params', ctx=ctx) # Hybridize the model & pass required options for Neo: static_alloc=True & static_shape=True block.hybridize(static_alloc=True, static_shape=True) # Run warm-up inference on empty data during model load (required for GPU) data = mx.nd.empty((1,3,224,224), ctx=ctx) warm_up = block(data) return block def input_fn(image, input_content_type): # pre-processing decoded = mx.image.imdecode(image) resized = mx.image.resize_short(decoded, 224) cropped, crop_info = mx.image.center_crop(resized, (224, 224)) normalized = mx.image.color_normalize(cropped.astype(np.float32) / 255, mean=mx.nd.array([0.485, 0.456, 0.406]), std=mx.nd.array([0.229, 0.224, 0.225])) transposed = normalized.transpose((2, 0, 1)) batchified = transposed.expand_dims(axis=0) casted = batchified.astype(dtype='float32') processed_input = casted.as_in_context(ctx) return processed_input def predict_fn(processed_input_data, block): # prediction/inference prediction = block(processed_input_data) return prediction def output_fn(prediction, output_content_type): # post-processing prob = prediction.asnumpy().tolist() prob_json = json.dumps(prob) return prob_json, output_content_type
      PyTorch 1.4 and Older
      import os import torch import torch.nn.parallel import torch.optim import torch.utils.data import torch.utils.data.distributed import torchvision.transforms as transforms from PIL import Image import io import json import pickle def model_fn(model_dir): """Load the model and return it. Providing this function is optional. There is a default model_fn available which will load the model compiled using SageMaker Neo. You can override it here. Keyword arguments: model_dir -- the directory path where the model artifacts are present """ # The compiled model is saved as "compiled.pt" model_path = os.path.join(model_dir, 'compiled.pt') with torch.neo.config(model_dir=model_dir, neo_runtime=True): model = torch.jit.load(model_path) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) # We recommend that you run warm-up inference during model load sample_input_path = os.path.join(model_dir, 'sample_input.pkl') with open(sample_input_path, 'rb') as input_file: model_input = pickle.load(input_file) if torch.is_tensor(model_input): model_input = model_input.to(device) model(model_input) elif isinstance(model_input, tuple): model_input = (inp.to(device) for inp in model_input if torch.is_tensor(inp)) model(*model_input) else: print("Only supports a torch tensor or a tuple of torch tensors") return model def transform_fn(model, request_body, request_content_type, response_content_type): """Run prediction and return the output. The function 1. Pre-processes the input request 2. Runs prediction 3. Post-processes the prediction output. """ # preprocess decoded = Image.open(io.BytesIO(request_body)) preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize( mean=[ 0.485, 0.456, 0.406], std=[ 0.229, 0.224, 0.225]), ]) normalized = preprocess(decoded) batchified = normalized.unsqueeze(0) # predict device = torch.device("cuda" if torch.cuda.is_available() else "cpu") batchified = batchified.to(device) output = model.forward(batchified) return json.dumps(output.cpu().numpy().tolist()), response_content_type
      PyTorch 1.5 and Newer
      import os import torch import torch.nn.parallel import torch.optim import torch.utils.data import torch.utils.data.distributed import torchvision.transforms as transforms from PIL import Image import io import json import pickle def model_fn(model_dir): """Load the model and return it. Providing this function is optional. There is a default_model_fn available, which will load the model compiled using SageMaker Neo. You can override the default here. The model_fn only needs to be defined if your model needs extra steps to load, and can otherwise be left undefined. Keyword arguments: model_dir -- the directory path where the model artifacts are present """ # The compiled model is saved as "model.pt" model_path = os.path.join(model_dir, 'model.pt') device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = torch.jit.load(model_path, map_location=device) model = model.to(device) return model def transform_fn(model, request_body, request_content_type, response_content_type): """Run prediction and return the output. The function 1. Pre-processes the input request 2. Runs prediction 3. Post-processes the prediction output. """ # preprocess decoded = Image.open(io.BytesIO(request_body)) preprocess = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize( mean=[ 0.485, 0.456, 0.406], std=[ 0.229, 0.224, 0.225]), ]) normalized = preprocess(decoded) batchified = normalized.unsqueeze(0) # predict device = torch.device("cuda" if torch.cuda.is_available() else "cpu") batchified = batchified.to(device) output = model.forward(batchified) return json.dumps(output.cpu().numpy().tolist()), response_content_type
    2. Para instancias inf1 o imágenes de contenedor onnx, xgboost o keras

      Para todos los demás tipos de instancias de inferencia o imágenes de contenedor optimizadas para inferencias de Neo, el guión de punto de entrada debe implementar las siguientes funciones para tiempo de ejecución de aprendizaje profundo de Neo:

      • neo_preprocess: Convierte la carga útil de la solicitud entrante en una matriz numpy.

      • neo_postprocess: Convierte el resultado de la predicción de tiempo de ejecución de aprendizaje profundo de Neo en el cuerpo de la respuesta.

        nota

        Las dos funciones anteriores no utilizan ninguna de las funcionalidades deMXNet, PyTorch, o TensorFlow.

      Para ver ejemplos de cómo utilizar estas funciones, consulte los cuadernos de ejemplo de compilación de modelos de Neo.

    3. Para TensorFlow modelos

      Si su modelo requiere una lógica personalizada de preprocesamiento y posprocesamiento antes de enviar los datos al modelo, debe especificar un archivo inference.py de guión de punto de entrada que pueda usarse en el momento de la inferencia. El script debe implementar un par de funciones input_handler y output_handler o una función de controlador único.

      nota

      Tenga en cuenta que si la función de controlador está implementada input_handler y output_handler se ignoran.

      El siguiente es un ejemplo de código de un guión inference.py que se puede combinar con el modelo de compilación para realizar un procesamiento previo y posterior personalizado en un modelo de clasificación de imágenes. El SageMaker cliente envía el archivo de imagen como un tipo de application/x-image contenido a la input_handler función, donde se convierteJSON. Luego, el archivo de imagen convertido se envía al servidor de modelos de Tensorflow (TFX) mediante. REST API

      import json import numpy as np import json import io from PIL import Image def input_handler(data, context): """ Pre-process request input before it is sent to TensorFlow Serving REST API Args: data (obj): the request data, in format of dict or string context (Context): an object containing request and configuration details Returns: (dict): a JSON-serializable dict that contains request body and headers """ f = data.read() f = io.BytesIO(f) image = Image.open(f).convert('RGB') batch_size = 1 image = np.asarray(image.resize((512, 512))) image = np.concatenate([image[np.newaxis, :, :]] * batch_size) body = json.dumps({"signature_name": "serving_default", "instances": image.tolist()}) return body def output_handler(data, context): """Post-process TensorFlow Serving output before it is returned to the client. Args: data (obj): the TensorFlow serving response context (Context): an object containing request and configuration details Returns: (bytes, string): data to return to client, response content type """ if data.status_code != 200: raise ValueError(data.content.decode('utf-8')) response_content_type = context.accept_header prediction = data.content return prediction, response_content_type

      Si no hay un procesamiento previo o posterior personalizado, el SageMaker cliente convierte la imagen del archivo de forma similar antes de enviarla al punto final. JSON SageMaker

      Para obtener más información, consulte Implementación en puntos finales de TensorFlow servicio en SageMaker Python SDK.

  3. El bucket de Amazon S3 URI que contiene los artefactos del modelo compilado.