GPU 推理 - Amazon 深度学习容器
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

GPU 推理

本部分介绍如何使用 Apache MXNet(孵化)、PyTorch、TensorFlow 和 TensorFlow 2 在 EKS GPU 集群的 Deep Learning Containers 上运行推理。

有关 Deep Learning Containers 的完整列表,请参阅。可用的 Deep Learning Containers 映像.

注意

MKL 用户:读取 AmazonDeep Learning Containers 英特尔数学核心库 (MKL) 建议以获得最佳训练或推理性能。

Apache MxNet(孵化)GPU 推理

在此方法中,创建一个 Kubernetes 服务和部署。Kubernetes 服务公开了一个进程及其端口。创建 Kubernetes 服务时,可以指定要使用的服务类型ServiceTypes. 默认ServiceTypeClusterIP. 部署负责确保一定数量的 Pod 始终启动并运行。

  1. 对于基于 GPU 的推理,安装适用于 Kubernetes 的 NVIDIA 设备插件:

    $ kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.12/nvidia-device-plugin.yml
  2. 验证 nvidia-device-plugin-daemonset 是否正在正确运行。

    $ kubectl get daemonset -n kube-system

    该输出值将类似于以下内容:

    NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE aws-node 3 3 3 3 3 <none> 6d kube-proxy 3 3 3 3 3 <none> 6d nvidia-device-plugin-daemonset 3 3 3 3 3 <none> 57s
  3. 创建命名空间。您可能需要更改 kubeconfig 以指向正确的集群。验证您已设置“training-gpu-1”或将其更改为您的 GPU 集群的配置。有关如何设置群集的更多信息,请参阅。Amazon EK 设置.

    $ NAMESPACE=mx-inference; kubectl —kubeconfig=/home/ubuntu/.kube/eksctl/clusters/training-gpu-1 create namespace ${NAMESPACE}
  4. (使用公共模型时的可选步骤。) 在可装载的网络位置(如 S3)处设置您的模型。请参阅这些步骤以将训练后的模型上传到“利用 TensorFlow 进行推理”部分中提及的 S3。将密钥应用于您的命名空间。有关密钥的更多信息,请参阅Kubernetes 密钥文档.

    $ kubectl -n ${NAMESPACE} apply -f secret.yaml
  5. 创建 mx_inference.yaml 文件。使用下一个代码块的内容作为其内容。

    --- kind: Service apiVersion: v1 metadata: name: squeezenet-service labels: app: squeezenet-service spec: ports: - port: 8080 targetPort: mms selector: app: squeezenet-service --- kind: Deployment apiVersion: apps/v1 metadata: name: squeezenet-service labels: app: squeezenet-service spec: replicas: 1 selector: matchLabels: app: squeezenet-service template: metadata: labels: app: squeezenet-service spec: containers: - name: squeezenet-service image: 763104351884.dkr.ecr.us-east-1.amazonaws.com/mxnet-inference:1.6.0-gpu-py36-cu101-ubuntu16.04 args: - mxnet-model-server - --start - --mms-config /home/model-server/config.properties - --models squeezenet=https://s3.amazonaws.com/model-server/model_archive_1.0/squeezenet_v1.1.mar ports: - name: mms containerPort: 8080 - name: mms-management containerPort: 8081 imagePullPolicy: IfNotPresent resources: limits: cpu: 4 memory: 4Gi nvidia.com/gpu: 1 requests: cpu: "1" memory: 1Gi
  6. 将配置应用于之前定义的命名空间中的新 pod:

    $ kubectl -n ${NAMESPACE} apply -f mx_inference.yaml

    您的输出应类似于以下内容:

    service/squeezenet-service created deployment.apps/squeezenet-service created
  7. 检查 pod 的状态并等待 pod 处于“RUNNING (正在运行)”状态:

    $ kubectl get pods -n ${NAMESPACE}
  8. 重复检查状态步骤,直到您看到以下“RUNNING (正在运行)”状态:

    NAME READY STATUS RESTARTS AGE squeezenet-service-xvw1 1/1 Running 0 3m
  9. 要进一步描述 pod,您可以运行:

    $ kubectl describe pod <pod_name> -n ${NAMESPACE}
  10. 由于此处的 serviceType 为 ClusterIP,您可以将端口从您的容器转发至您的主机,(& 将在后台中运行此项):

    $ kubectl port-forward -n ${NAMESPACE} `kubectl get pods -n ${NAMESPACE} --selector=app=squeezenet-service -o jsonpath='{.items[0].metadata.name}'` 8080:8080 &
  11. 下载小猫的图像:

    $ curl -O https://s3.amazonaws.com/model-server/inputs/kitten.jpg
  12. 在该模型上运行推理:

    $ curl -X POST http://127.0.0.1:8080/predictions/squeezenet -T kitten.jpg

TensorFlow GPU 推理

在此方法中,创建一个 Kubernetes 服务和部署。Kubernetes 服务公开了一个进程及其端口。创建 Kubernetes 服务时,可以指定要使用的服务类型ServiceTypes. 默认ServiceTypeClusterIP. 部署负责确保一定数量的 Pod 始终启动并运行。

  1. 对于基于 GPU 的推理,安装适用于 Kubernetes 的 NVIDIA 设备插件:

    $ kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.12/nvidia-device-plugin.yml
  2. 验证 nvidia-device-plugin-daemonset 是否正在正确运行。

    $ kubectl get daemonset -n kube-system

    该输出值将类似于以下内容:

    NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE aws-node 3 3 3 3 3 <none> 6d kube-proxy 3 3 3 3 3 <none> 6d nvidia-device-plugin-daemonset 3 3 3 3 3 <none> 57s
  3. 创建命名空间。您可能需要更改 kubeconfig 以指向正确的集群。验证您已设置“training-gpu-1”或将其更改为您的 GPU 集群的配置。有关如何设置群集的更多信息,请参阅。Amazon EK 设置.

    $ NAMESPACE=tf-inference; kubectl —kubeconfig=/home/ubuntu/.kube/eksctl/clusters/training-gpu-1 create namespace ${NAMESPACE}
  4. 用于推理的模型可通过不同的方式进行检索,例如,使用共享卷、S3 等。由于该服务需要访问 S3 和 ECR,您必须存储您的Amazon凭据作为 Kubernetes 秘密。在本示例中,您将使用 S3 来存储和提取训练后的模型。

    检查您的Amazon凭证。这些凭证必须具有 S3 写入访问权限。

    $ cat ~/.aws/credentials
  5. 输出将类似于以下内容:

    $ [default] aws_access_key_id = FAKEAWSACCESSKEYID aws_secret_access_key = FAKEAWSSECRETACCESSKEY
  6. 使用 base64 对这些凭证进行编码。首先编码访问密钥。

    $ echo -n 'FAKEAWSACCESSKEYID' | base64

    接下来编码秘密访问密钥。

    $ echo -n 'FAKEAWSSECRETACCESSKEYID' | base64

    您的输出应类似于以下内容:

    $ echo -n 'FAKEAWSACCESSKEYID' | base64 RkFLRUFXU0FDQ0VTU0tFWUlE $ echo -n 'FAKEAWSSECRETACCESSKEY' | base64 RkFLRUFXU1NFQ1JFVEFDQ0VTU0tFWQ==
  7. 创建 yaml 文件来存储密钥。在您的主目录中将该密钥另存为 secret.yaml。

    apiVersion: v1 kind: Secret metadata: name: aws-s3-secret type: Opaque data: AWS_ACCESS_KEY_ID: RkFLRUFXU0FDQ0VTU0tFWUlE AWS_SECRET_ACCESS_KEY: RkFLRUFXU1NFQ1JFVEFDQ0VTU0tFWQ==
  8. 将密钥应用于您的命名空间:

    $ kubectl -n ${NAMESPACE} apply -f secret.yaml
  9. 在本示例中,您将克隆 tensorflow-serving 存储库并将预训练模型同步到 S3 存储桶。以下示例命名存储桶 tensorflow-serving-models。它还将已保存的模型同步到名 saved_model_half_plus_two_gpu 的 S3 存储桶。

    $ git clone https://github.com/tensorflow/serving/ $ cd serving/tensorflow_serving/servables/tensorflow/testdata/
  10. 同步 CPU 模型。

    $ aws s3 sync saved_model_half_plus_two_gpu s3://<your_s3_bucket>/saved_model_half_plus_two_gpu
  11. 创建 tf_inference.yaml 文件。使用下一个代码块的内容作为其内容,并将 --model_base_path 更新为使用您的 S3 存储桶。您可以将它与 TensorFlow 或 TensorFlow 2 一起使用。要将其与 TensorFlow2 一起使用,请将 Docker 映像更改为 TensorFlow 2 映像。

    --- kind: Service apiVersion: v1 metadata: name: half-plus-two labels: app: half-plus-two spec: ports: - name: http-tf-serving port: 8500 targetPort: 8500 - name: grpc-tf-serving port: 9000 targetPort: 9000 selector: app: half-plus-two role: master type: ClusterIP --- kind: Deployment apiVersion: apps/v1 metadata: name: half-plus-two labels: app: half-plus-two role: master spec: replicas: 1 selector: matchLabels: app: half-plus-two role: master template: metadata: labels: app: half-plus-two role: master spec: containers: - name: half-plus-two image: 763104351884.dkr.ecr.us-east-1.amazonaws.com/tensorflow-inference:1.15.0-gpu-py36-cu100-ubuntu18.04 command: - /usr/bin/tensorflow_model_server args: - --port=9000 - --rest_api_port=8500 - --model_name=saved_model_half_plus_two_gpu - --model_base_path=s3://tensorflow-trained-models/saved_model_half_plus_two_gpu ports: - containerPort: 8500 - containerPort: 9000 imagePullPolicy: IfNotPresent env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: key: AWS_ACCESS_KEY_ID name: aws-s3-secret - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: key: AWS_SECRET_ACCESS_KEY name: aws-s3-secret - name: AWS_REGION value: us-east-1 - name: S3_USE_HTTPS value: "true" - name: S3_VERIFY_SSL value: "true" - name: S3_ENDPOINT value: s3.us-east-1.amazonaws.com resources: limits: cpu: 4 memory: 4Gi nvidia.com/gpu: 1 requests: cpu: "1" memory: 1Gi
  12. 将配置应用于之前定义的命名空间中的新 pod:

    $ kubectl -n ${NAMESPACE} apply -f tf_inference.yaml

    您的输出应类似于以下内容:

    service/half-plus-two created deployment.apps/half-plus-two created
  13. 检查 pod 的状态并等待 pod 处于“RUNNING (正在运行)”状态:

    $ kubectl get pods -n ${NAMESPACE}
  14. 重复检查状态步骤,直到您看到以下“RUNNING (正在运行)”状态:

    NAME READY STATUS RESTARTS AGE half-plus-two-vmwp9 1/1 Running 0 3m
  15. 要进一步描述 pod,您可以运行:

    $ kubectl describe pod <pod_name> -n ${NAMESPACE}
  16. 由于此处的 serviceType 为 ClusterIP,您可以将端口从您的容器转发至您的主机,(& 将在后台中运行此项):

    $ kubectl port-forward -n ${NAMESPACE} `kubectl get pods -n ${NAMESPACE} --selector=app=half-plus-two -o jsonpath='{.items[0].metadata.name}'` 8500:8500 &
  17. 将以下 json 字符串置于名为 half_plus_two_input.json 的文件中

    {"instances": [1.0, 2.0, 5.0]}
  18. 在该模型上运行推理:

    $ curl -d @half_plus_two_input.json -X POST http://localhost:8500/v1/models/saved_model_half_plus_two_cpu:predict

    预期的输出如下所示:

    { "predictions": [2.5, 3.0, 4.5 ] }

PyTorch GPU 推理

在此方法中,创建一个 Kubernetes 服务和部署。Kubernetes 服务公开了一个进程及其端口。创建 Kubernetes 服务时,可以指定要使用的服务类型ServiceTypes. 默认ServiceTypeClusterIP. 部署负责确保一定数量的 Pod 始终启动并运行。

  1. 对于基于 GPU 的推理,安装适用于 Kubernetes 的 NVIDIA 设备插件。

    $ kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v1.12/nvidia-device-plugin.yml
  2. 验证 nvidia-device-plugin-daemonset 是否正在正确运行。

    $ kubectl get daemonset -n kube-system

    该输出值将类似于以下内容。

    NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE aws-node 3 3 3 3 3 <none> 6d kube-proxy 3 3 3 3 3 <none> 6d nvidia-device-plugin-daemonset 3 3 3 3 3 <none> 57s
  3. 创建命名空间。

    $ NAMESPACE=pt-inference; kubectl create namespace ${NAMESPACE}
  4. (使用公共模型时的可选步骤。) 在可装载的网络位置(如 S3)处设置您的模型。请参阅这些步骤以将训练后的模型上传到“利用 TensorFlow 进行推理”部分中提及的 S3。将密钥应用于您的命名空间。有关密钥的更多信息,请参阅Kubernetes 密钥文档.

    $ kubectl -n ${NAMESPACE} apply -f secret.yaml
  5. 创建 pt_inference.yaml 文件。使用下一个代码块的内容作为其内容。

    --- kind: Service apiVersion: v1 metadata: name: densenet-service labels: app: densenet-service spec: ports: - port: 8080 targetPort: mms selector: app: densenet-service --- kind: Deployment apiVersion: apps/v1 metadata: name: densenet-service labels: app: densenet-service spec: replicas: 1 selector: matchLabels: app: densenet-service template: metadata: labels: app: densenet-service spec: containers: - name: densenet-service image: "763104351884.dkr.ecr.us-east-1.amazonaws.com/pytorch-inference:1.3.1-gpu-py36-cu101-ubuntu16.04" args: - mxnet-model-server - --start - --mms-config /home/model-server/config.properties - --models densenet=https://dlc-samples.s3.amazonaws.com/pytorch/multi-model-server/densenet/densenet.mar ports: - name: mms containerPort: 8080 - name: mms-management containerPort: 8081 imagePullPolicy: IfNotPresent resources: limits: cpu: 4 memory: 4Gi nvidia.com/gpu: 1 requests: cpu: "1" memory: 1Gi
  6. 将配置应用于之前定义的命名空间中的新 pod。

    $ kubectl -n ${NAMESPACE} apply -f pt_inference.yaml

    您的输出应类似于以下内容:

    service/densenet-service created deployment.apps/densenet-service created
  7. 检查 pod 的状态并等待 pod 处于“RUNNING (正在运行)”状态。

    $ kubectl get pods -n ${NAMESPACE}

    您的输出应类似于以下内容:

    NAME READY STATUS RESTARTS AGE densenet-service-xvw1 1/1 Running 0 3m
  8. 要进一步描述 pod,您可以运行:

    $ kubectl describe pod <pod_name> -n ${NAMESPACE}
  9. 由于此处的 serviceType 为 ClusterIP,您可以将端口从您的容器转发至您的主机(& 将在后台中运行此项)。

    $ kubectl port-forward -n ${NAMESPACE} `kubectl get pods -n ${NAMESPACE} --selector=app=densenet-service -o jsonpath='{.items[0].metadata.name}'` 8080:8080 &
  10. 在启动您的服务器后,现在您可以从不同的窗口来运行推理。

    $ curl -O https://s3.amazonaws.com/model-server/inputs/flower.jpg curl -X POST http://127.0.0.1:8080/predictions/densenet -T flower.jpg

使用完集群后,请参阅 EKS 清除以获取有关清除集群的信息。

后续步骤

要了解如何在 Amazon EKS 上将自定义入口点与 Deep Learning Containers 结合使用,请参阅自定义入口点.