Ayude a mejorar esta página
¿Quiere contribuir a esta guía del usuario? Desplácese hasta el final de esta página y seleccione Editar esta página en GitHub. Sus contribuciones ayudarán a que nuestra guía del usuario sea mejor para todos.
Utilice instancias de AWS Inferentia con el clúster de EKS para el machine learning
En este tema se describe cómo crear un clúster de Amazon EKS con nodos que ejecutan instancias Inf1 de Amazon EC2
nota
Los identificadores lógicos de los dispositivos Neuron deben ser contiguos. Si un Pod que solicita varios dispositivos Neuron está programado en un tipo de instancia inf1.6xlarge
o inf1.24xlarge
(que tiene más de un dispositivo Neuron), ese Pod no se iniciará si el programador de Kubernetes selecciona identificadores de dispositivo no contiguos. Para obtener más información, consulte Device logical IDs must be contiguous
Requisitos previos
-
Debe tener
eksctl
instalado en el equipo. Si no lo tiene instalado, consulte la sección de Instalaciónen la documentación de eksctl
. -
Debe tener
kubectl
instalado en el equipo. Para obtener más información, consulte Configure kubectl y eksctl. -
(Opcional) Debe tener instalado
python3
en su equipo. Si no lo tiene instalado, consulte Descargas de Pythonpara obtener instrucciones de instalación.
Creación de un clúster
-
Cree un clúster con nodos Inf1 de instancias de Amazon EC2. Puede reemplazar
inf1.2xlarge
con cualquier tipo de instancia Inf1. La utilidad eksctl
detecta que va a lanzar un grupo de nodos con un tipo de instanciaInf1
e iniciará sus nodos utilizando uno de las AMI optimizadas de Amazon Linux acelerado de Amazon EKS.nota
No puede usar roles de IAM para cuentas de servicio con TensorFlow Serving.
eksctl create cluster \ --name inferentia \ --region region-code \ --nodegroup-name ng-inf1 \ --node-type inf1.2xlarge \ --nodes 2 \ --nodes-min 1 \ --nodes-max 4 \ --ssh-access \ --ssh-public-key your-key \ --with-oidc
nota
Tenga en cuenta el valor de la siguiente línea de la salida. Se usa en un paso posterior (opcional).
[9] adding identity "arn:aws:iam::111122223333:role/eksctl-inferentia-nodegroup-ng-in-NodeInstanceRole-FI7HIYS3BS09" to auth ConfigMap
Al lanzar un grupo de nodos con instancias
Inf1
,eksctl
instala automáticamente el complemento de dispositivo de Kubernetes de AWS Neuron. Este complemento anuncia dispositivos Neuron como un recurso del sistema al programador de Kubernetes, que puede solicitar un contenedor. Además de las políticas de IAM de nodos de Amazon EKS predeterminadas, se agrega la política de acceso de solo lectura de Amazon S3 para que la aplicación de ejemplo, que se trató en un paso posterior, pueda cargar un modelo entrenado desde Amazon S3. -
Asegúrese de que todos los Pods se hayan iniciado correctamente.
kubectl get pods -n kube-system
Salida abreviada:
NAME READY STATUS RESTARTS AGE [...] neuron-device-plugin-daemonset-6djhp 1/1 Running 0 5m neuron-device-plugin-daemonset-hwjsj 1/1 Running 0 5m
(Opcional) Implementar una imagen de aplicación TensorFlow Serving
Un modelo entrenado debe compilarse en un destino de Inferentia antes de poder implementarlo en instancias Inferentia. Para continuar, necesitará un modelo TensorFlow optimizado para Neuron
El manifiesto de implementación de ejemplo administra un contenedor de servicio de inferencia preconstruido para TensorFlow proporcionado por AWS Deep Learning Containers. Dentro del contenedor está el Runtime (Tiempo de ejecución) de AWS Neuron y la aplicación TensorFlow Serving. Una lista completa de contenedores de aprendizaje profundo preconstruidos optimizados para Neuron se mantiene en GitHub en Available Images
El número de dispositivos de Neuron asignados a su aplicación de servicio se puede ajustar cambiando el recurso aws.amazon.com/neuron
en el yaml de implementación. Tenga en cuenta que la comunicación entre TensorFlow Serving y el tiempo de ejecución de Neuron ocurre a través de GRPC, lo que requiere pasar la capacidad de IPC_LOCK
al contenedor.
-
Agregue la política de IAM de
AmazonS3ReadOnlyAccess
al rol de instancia de nodo que se creó en el paso 1 de Crear un clúster. Esto es necesario para que la aplicación de muestra pueda cargar un modelo entrenado desde Amazon S3.aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \ --role-name eksctl-inferentia-nodegroup-ng-in-NodeInstanceRole-FI7HIYS3BS09
-
Cree un archivo denominado
rn50_deployment.yaml
con el siguiente contenido. Actualice el código de región y la ruta del modelo para que coincida con la configuración deseada. El nombre del modelo es para fines de identificación cuando un cliente realiza una solicitud al servidor TensorFlow. En este ejemplo se utiliza un nombre de modelo para que coincida con un script de cliente ResNet50 de ejemplo que se utilizará en un paso posterior para enviar solicitudes de predicción.aws ecr list-images --repository-name neuron-rtd --registry-id 790709498068 --region us-west-2
kind: Deployment apiVersion: apps/v1 metadata: name: eks-neuron-test labels: app: eks-neuron-test role: master spec: replicas: 2 selector: matchLabels: app: eks-neuron-test role: master template: metadata: labels: app: eks-neuron-test role: master spec: containers: - name: eks-neuron-test image: 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference-neuron:1.15.4-neuron-py37-ubuntu18.04 command: - /usr/local/bin/entrypoint.sh args: - --port=8500 - --rest_api_port=9000 - --model_name=resnet50_neuron - --model_base_path=s3://your-bucket-of-models/resnet50_neuron/ ports: - containerPort: 8500 - containerPort: 9000 imagePullPolicy: IfNotPresent env: - name: AWS_REGION value: "us-east-1" - name: S3_USE_HTTPS value: "1" - name: S3_VERIFY_SSL value: "0" - name: S3_ENDPOINT value: s3.us-east-1.amazonaws.com - name: AWS_LOG_LEVEL value: "3" resources: limits: cpu: 4 memory: 4Gi aws.amazon.com/neuron: 1 requests: cpu: "1" memory: 1Gi securityContext: capabilities: add: - IPC_LOCK
-
Implemente el modelo.
kubectl apply -f rn50_deployment.yaml
-
Cree un archivo denominado
rn50_service.yaml
con el siguiente contenido. Los puertos HTTP y gRPC están abiertos para aceptar solicitudes de predicción.kind: Service apiVersion: v1 metadata: name: eks-neuron-test labels: app: eks-neuron-test spec: type: ClusterIP ports: - name: http-tf-serving port: 8500 targetPort: 8500 - name: grpc-tf-serving port: 9000 targetPort: 9000 selector: app: eks-neuron-test role: master
-
Cree un servicio de Kubernetes para su aplicación de distribución de modelos de TensorFlow.
kubectl apply -f rn50_service.yaml
(Opcional) Haga predicciones contra su servicio de distribución de TensorFlow
-
Para realizar pruebas localmente, reenvíe el puerto gRPC al servicio
eks-neuron-test
.kubectl port-forward service/eks-neuron-test 8500:8500 &
-
Cree un script de Python denominado
tensorflow-model-server-infer.py
con el siguiente contenido. Este script ejecuta la inferencia a través de gRPC, que es el marco de trabajo de servicio.import numpy as np import grpc import tensorflow as tf from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.resnet50 import preprocess_input from tensorflow_serving.apis import predict_pb2 from tensorflow_serving.apis import prediction_service_pb2_grpc from tensorflow.keras.applications.resnet50 import decode_predictions if __name__ == '__main__': channel = grpc.insecure_channel('localhost:8500') stub = prediction_service_pb2_grpc.PredictionServiceStub(channel) img_file = tf.keras.utils.get_file( "./kitten_small.jpg", "https://raw.githubusercontent.com/awslabs/mxnet-model-server/master/docs/images/kitten_small.jpg") img = image.load_img(img_file, target_size=(224, 224)) img_array = preprocess_input(image.img_to_array(img)[None, ...]) request = predict_pb2.PredictRequest() request.model_spec.name = 'resnet50_inf1' request.inputs['input'].CopyFrom( tf.make_tensor_proto(img_array, shape=img_array.shape)) result = stub.Predict(request) prediction = tf.make_ndarray(result.outputs['output']) print(decode_predictions(prediction))
-
Ejecute el script para enviar predicciones a su servicio.
python3 tensorflow-model-server-infer.py
Un ejemplo de salida sería el siguiente.
[[(u'n02123045', u'tabby', 0.68817204), (u'n02127052', u'lynx', 0.12701613), (u'n02123159', u'tiger_cat', 0.08736559), (u'n02124075', u'Egyptian_cat', 0.063844085), (u'n02128757', u'snow_leopard', 0.009240591)]]