使用AmazonInferentia - Amazon EKS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用AmazonInferentia

本主题介绍如何创建具有运行Amazon EC2 Inf1实例,然后(可选)部署示例应用程序。Amazon EC2 Inf1 实例由AmazonInferentia芯片,这是自定义建Amazon,可在云中提供高性能和最低成本的推理。机器学习模型部署到容器使用AmazonNeuron,由编译器、运行时工具和分析工具组成,可用于优化 Inferentia 芯片的机器学习推理性能。AmazonNeuron 支持常用的机器学习框架,例如 TensorFlow、PyTorch 和 MXNet。

Considerations

  • Neuron 设备逻辑 ID 必须是连续的。如果在 inf1.6xlargeinf1.24xlarge 实例类型(具有多个 Neuron 设备)上调度请求多个 Neuron 设备的 pod,则当 Kubernetes 调度程序选择不连续的设备 ID 时,该 pod 将无法启动。有关更多信息,请参阅 GitHub 上的设备逻辑 ID 必须是连续的

  • 托管节点组当前不支持 Amazon EC2 Inf1 实例。

Prerequisites

  • 在计算机上安装 eksctl。如果未安装,请参阅 eksctl 命令行实用程序 查看安装说明。

  • 在计算机上安装 kubectl。有关更多信息,请参阅 安装 kubectl

  • (可选)在计算机上安装 python3。如果未安装,请参阅 Python 下载以查看安装说明。

创建集群

使用 Inf1 Amazon EC2 实例节点创建集群

  1. 使用 Inf1 Amazon EC2 实例节点创建集群。您可以将<inf1.2xlarge>与任何Inf1 实例类型Eksctl检测到您正在启动具有Inf1实例类型,并将使用亚马逊 EKS 优化加速亚马逊 Linux AMI

    注意

    您不能将服务账户的 IAM 角色与 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 \ --managed
    注意

    请记住下一个输出行的值。在后面的(可选)步骤中将使用该值。

    [9] adding identity "arn:aws:iam::<111122223333>:role/eksctl-<inferentia>-<nodegroup-ng-in>-NodeInstanceRole-<FI7HIYS3BS09>" to auth ConfigMap

    在启动节点组时Inf1实例,eksctl自动安装Amazon神经元 Kubernetes 设备插件。此插件将 Neuron 设备作为系统资源传播到 Kubernetes 调度程序,以供容器请求。除了默认的 Amazon EKS 节点 IAM 策略之外,还添加了 Amazon S3 只读访问策略,以便后一个步骤中涵盖的示例应用程序能够从 Amazon S3 加载经过训练的模型。

  2. 确保所有 pod 已正常启动。

    kubectl get pods -n kube-system

    缩减的输出

    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

(可选)部署 TensorFlow Serving 应用程序映像

经过训练的模型必须先编译为 Inferentia 目标,才能部署在 Inferentia 实例上。要继续,您将需要经过优化的 TensorFlow模型保存在 Amazon S3 中。如果您还没有 SavedModel,请按照创建一个神经元兼容的 Resnet50 模型并将生成的 SavedModel 上传到 S3。ResNE-50 是一种常用的机器学习模型,用于图像识别任务。有关编译 Neuron 模型的更多信息,请参阅这些区域有:Amazon带有 DLAMI 的推理芯片中的Amazon深度学习 AMI 开发人员指南。

示例部署清单管理一个预构建的推理服务容器,用于AmazonDeep Learning Containers。容器内部是Amazon神经元运行时和 TensorFlow 服务应用程序。针对神经元优化的预构建 Deep Learning Containers 的完整列表在 GitHub 上维护可用映像。在启动时,DLC 将从 Amazon S3 中提取您的模型,使用保存的模型启动 Neuron TensorFlow 服务,然后等待预测请求。

分配给您的服务应用程序的神经元设备数量可以通过更改aws.amazon.com/neuron资源中的部署 yaml。请注意,TensorFlow 服务和神经元运行时之间的通信发生在 GRPC 上,这需要传递IPC_LOCK功能添加到容器。

  1. AmazonS3ReadOnlyAccessIAM 策略到已在创建集群。必须执行此操作,示例应用程序才能从 Amazon S3 加载经过训练的模型。

    aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \ --role-name eksctl-<inferentia>-<nodegroup-ng-in>-NodeInstanceRole-<FI7HIYS3BS09>
  2. 使用以下内容创建名为 rn50_deployment.yaml 的文件。更新区域代码和模型路径以匹配所需的设置。当客户端向 TensorFlow 服务器发出请求时,模型名称用于标识目的。此示例使用模型名称匹配将在稍后的步骤中用于发送预测请求的示例 ResNet50 客户端脚本。

    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
  3. 部署模型。

    kubectl apply -f rn50_deployment.yaml
  4. 使用以下内容创建名为 rn50_service.yaml 的文件。这将打开 HTTP 和 gRPC 端口以接受预测请求。

    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
  5. 为 TensorFlow 模型 Serving 应用程序创建 Kubernetes 服务。

    kubectl apply -f rn50_service.yaml

(可选)根据 TensorFlow Serving 服务进行预测

  1. 要在本地进行测试,请将 gRPC 端口转发到 eks-neuron-test 服务。

    kubectl port-forward service/eks-neuron-test 8500:8500 &
  2. 创建名为tensorflow-model-server-infer.py,其中包含以下内容。该脚本通过 GRPC(这是一个服务框架)运行推理过程。

    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))
  3. 运行脚本以将预测数据提交给服务。

    python3 tensorflow-model-server-infer.py

    输出

    [[(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)]]