在 GKE 中使用单个 GPU 提供模型


本教程介绍了如何在 Google Kubernetes Engine (GKE) 模式下使用 GPU 提供简单模型。本教程会创建一个使用单个 L4 Tensor Core GPU 的 GKE 集群,并准备 GKE 基础设施以进行在线推理。本教程使用两种最常用的框架进行在线传送:

目标

本教程适用于希望在 GKE 集群中托管预训练的机器学习 (ML) 模型的基础架构工程师、MLOps 工程师、DevOps 工程师或集群管理员。

本教程介绍以下步骤:

  1. 创建 GKE Autopilot 或 Standard 集群。
  2. 配置 Cloud Storage 存储桶,即预训练模型。
  3. 部署您选择的在线推理框架。
  4. 向已部署的服务发出测试请求。

费用

本教程使用 Google Cloud 的以下收费组件:

  • GKE
  • Cloud Storage
  • L4 GPU 加速器
  • 出站流量

您可使用价格计算器根据您的预计使用情况来估算费用。

完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理

准备工作

设置项目

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 启用 GKE API。

    启用 API

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. 确保您的 Google Cloud 项目已启用结算功能

  7. 启用 GKE API。

    启用 API

设置 Google Cloud CLI 的默认值

  1. 在 Google Cloud 控制台中,启动 Cloud Shell 实例:
    打开 Cloud Shell

  2. 下载此示例应用的源代码:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/ai-ml/gke-online-serving-single-gpu
    
  3. 设置默认环境变量:

    gcloud config set project PROJECT_ID
    gcloud config set compute/region COMPUTE_REGION
    

    替换以下值:

    • PROJECT_ID:您的 Google Cloud 项目 ID
    • COMPUTE_REGION:支持要使用的加速器类型的 Compute Engine 区域,例如适用于 L4 GPU 的 us-central1
  4. 在 Cloud Shell 中,创建以下环境变量:

    export PROJECT_ID=$(gcloud config get project)
    export REGION=$(gcloud config get compute/region)
    export K8S_SA_NAME=gpu-k8s-sa
    export GSBUCKET=$PROJECT_ID-gke-bucket
    export MODEL_NAME=mnist
    export CLUSTER_NAME=online-serving-cluster
    

创建 GKE 集群

您可以在 GKE Autopilot 或 Standard 集群中的单个 GPU 上提供模型。我们建议您使用 Autopilot 集群获得全托管式 Kubernetes 体验。借助 GKE Autopilot,资源会根据模型请求自动扩缩。

如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式

Autopilot

运行以下命令创建 GKE Autopilot 集群:

  gcloud container clusters create-auto ${CLUSTER_NAME} \
      --region=${REGION} \
      --project=${PROJECT_ID} \
      --release-channel=rapid

GKE 会根据所部署的工作负载的请求,创建具有所需 CPU 和 GPU 节点的 Autopilot 集群。

标准

  1. 运行以下命令创建 GKE Standard 集群:

      gcloud container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID}  \
        --region=${REGION}  \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --addons GcsFuseCsiDriver \
        --release-channel=rapid \
        --num-nodes=1
    

    集群创建可能需要几分钟的时间。

  2. 运行以下命令创建节点池:

      gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --node-locations=${REGION}-a \
        --cluster=${CLUSTER_NAME} \
        --machine-type=g2-standard-8 \
        --num-nodes=1
    

    GKE 会创建一个节点池,其中每个节点都有一个 L4 GPU。

创建 Cloud Storage 存储桶

创建 Cloud Storage 存储桶以存储将要提供的预训练模型。

在 Cloud Shell 中,运行以下命令:

gcloud storage buckets create gs://$GSBUCKET

配置集群以使用适用于 GKE 的工作负载身份联合访问存储桶

如需允许集群访问 Cloud Storage 存储桶,请执行以下操作:

  1. 创建 Google Cloud 服务账号。
  2. 在集群中创建 Kubernetes ServiceAccount。
  3. 将 Kubernetes ServiceAccount 绑定到 Google Cloud 服务账号。

创建 Google Cloud 服务账号

  1. 在 Google Cloud 控制台中,转到创建服务账号页面:

    转到“创建服务账号”

  2. 服务账号 ID 字段中,输入 gke-ai-sa

  3. 点击创建并继续

  4. 角色列表中,选择 Cloud Storage > Storage Insights Collector Service 角色。

  5. 点击添加其他角色

  6. 选择角色列表中,选择 Cloud Storage > Storage Object Admin 角色。

  7. 点击继续,然后点击完成

在集群中创建 Kubernetes ServiceAccount

在 Cloud Shell 中,执行以下操作:

  1. 创建 Kubernetes 命名空间:

    kubectl create namespace gke-ai-namespace
    
  2. 在该命名空间中创建 Kubernetes ServiceAccount:

    kubectl create serviceaccount gpu-k8s-sa --namespace=gke-ai-namespace
    

将 Kubernetes ServiceAccount 绑定到 Google Cloud 服务账号

在 Cloud Shell 中,运行以下命令:

  1. 向 Google Cloud 服务账号添加 IAM 绑定:

    gcloud iam service-accounts add-iam-policy-binding gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-ai-namespace/gpu-k8s-sa]"
    

    --member 标志提供 Google Cloud 中 Kubernetes ServiceAccount 的完整身份。

  2. 为 Kubernetes ServiceAccount 添加注解:

    kubectl annotate serviceaccount gpu-k8s-sa \
        --namespace gke-ai-namespace \
        iam.gke.io/gcp-service-account=gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com
    

部署在线推理服务器

每个在线推理框架都希望以特定格式查找预训练的机器学习模型。以下部分介绍如何根据要使用的框架部署推理服务器:

海卫一

  1. 在 Cloud Shell 中,将预训练的机器学习模型复制到 Cloud Storage 存储桶:

    gsutil cp -r src/triton-model-repository gs://$GSBUCKET
    
  2. 在 Kubernetes 上部署该框架:

    envsubst < src/gke-config/deployment-triton.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. 验证 GKE 是否已部署框架:

    kubectl get deployments --namespace=gke-ai-namespace
    

    框架准备就绪后,输出将类似于以下内容:

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    triton-deployment    1/1     1            1           5m29s
    
  4. 部署 Service 以访问部署

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-triton.yaml
    
  5. 检查是否已分配外部 IP 地址:

    kubectl get services --namespace=gke-ai-namespace
    

    输出类似于以下内容:

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    triton-server   LoadBalancer   34.118.227.176   35.239.54.228   8000:30866/TCP,8001:31035/TCP,8002:30516/TCP   5m14s
    

    记下 EXTERNAL-IP 列中 triton-server 的 IP 地址。

  6. 检查服务和部署是否正常运行:

    curl -v EXTERNAL_IP:8000/v2/health/ready
    

    输出类似于以下内容:

    ...
    < HTTP/1.1 200 OK
    < Content-Length: 0
    < Content-Type: text/plain
    ...
    

TF 传送

  1. 在 Cloud Shell 中,将预训练的机器学习模型复制到 Cloud Storage 存储桶:

    gsutil cp -r src/tfserve-model-repository gs://$GSBUCKET
    
  2. 在 Kubernetes 上部署该框架:

    envsubst < src/gke-config/deployment-tfserve.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. 验证 GKE 是否已部署框架:

    kubectl get deployments --namespace=gke-ai-namespace
    

    框架准备就绪后,输出将类似于以下内容:

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    tfserve-deployment   1/1     1            1           5m29s
    
  4. 部署 Service 以访问部署

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-tfserve.yaml
    
  5. 检查是否已分配外部 IP 地址:

    kubectl get services --namespace=gke-ai-namespace
    

    输出类似于以下内容:

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    tfserve-server  LoadBalancer   34.118.227.176   35.239.54.228   8500:30003/TCP,8000:32194/TCP                  5m14s
    

    记下 EXTERNAL-IP 列中 tfserve-server 的 IP 地址。

  6. 检查服务和部署是否正常运行:

    curl -v EXTERNAL_IP:8000/v1/models/mnist
    

    EXTERNAL_IP 替换为您的外部 IP 地址。

    输出类似于以下内容:

    ...
    < HTTP/1.1 200 OK
    < Content-Type: application/json
    < Date: Thu, 12 Oct 2023 19:01:19 GMT
    < Content-Length: 154
    <
    {
      "model_version_status": [
            {
            "version": "1",
            "state": "AVAILABLE",
            "status": {
              "error_code": "OK",
              "error_message": ""
            }
          }
        ]
    }
    

应用模型

海卫一

  1. 在 Cloud Shell 中创建 Python 虚拟环境。

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. 安装必需的 Python 软件包。

    pip install -r src/client/triton-requirements.txt
    
  3. 通过加载图片来测试 Triton 推断服务器:

    cd src/client
    python triton_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

    替换以下内容:

    • EXTERNAL_IP:您的外部 IP 地址。
    • TEST_IMAGE:与要测试的映像对应的文件的名称。您可以使用存储在 src/client/images 中的映像。

    输出内容如下所示(具体取决于您使用的映像):

    Calling Triton HTTP Service      ->      Prediction result: 7
    

TF 传送

  1. 在 Cloud Shell 中创建 Python 虚拟环境。

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. 安装必需的 Python 软件包。

    pip install -r src/client/tfserve-requirements.txt
    
  3. 使用几张图片测试 TensorFlow Serving。

    cd src/client
    python tfserve_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

替换以下内容:

  • EXTERNAL_IP:您的外部 IP 地址。
  • TEST_IMAGE:一个介于 09 之间的值。您可以使用存储在 src/client/images 中的映像。

根据您使用的图片,您将获得类似如下所示的输出:

  Calling TensorFlow Serve HTTP Service    ->      Prediction result: 5

清理

为避免系统因您在本指南中创建的资源而向您的 Google Cloud 账号收取费用,请执行以下操作之一:

  • 保留 GKE 集群:删除集群中的 Kubernetes 资源以及 Google Cloud 资源
  • 保留 Google Cloud 项目:删除 GKE 集群和 Google Cloud 资源
  • 删除项目

删除集群中的 Kubernetes 资源以及 Google Cloud 资源

  1. 删除 Kubernetes 命名空间和您部署的工作负载:

海卫一

kubectl -n gke-ai-namespace delete -f src/gke-config/service-triton.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-triton.yaml
kubectl delete namespace gke-ai-namespace

TF 传送

kubectl -n gke-ai-namespace delete -f src/gke-config/service-tfserve.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-tfserve.yaml
kubectl delete namespace gke-ai-namespace
  1. 删除 Cloud Storage 存储桶:

    1. 转至存储桶页面:

      进入“存储桶”

    2. 选择 PROJECT_ID-gke-bucket 对应的复选框。

    3. 点击 删除

    4. 要确认删除,请输入 DELETE,然后点击删除

  2. 删除 Google Cloud 服务账号:

    1. 转到服务账号页面:

      转到“服务账号”

    2. 选择您的项目。

    3. 选择 gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com 对应的复选框。

    4. 点击 删除

    5. 如需确认删除,请点击删除

删除 GKE 集群和 Google Cloud 资源

  1. 删除 GKE 集群:

    1. 转到集群页面:

      转到“集群”

    2. 选择 online-serving-cluster 对应的复选框。

    3. 点击 删除

    4. 要确认删除,请输入 online-serving-cluster,然后点击删除

  2. 删除 Cloud Storage 存储桶:

    1. 转至存储桶页面:

      进入“存储桶”

    2. 选择 PROJECT_ID-gke-bucket 对应的复选框。

    3. 点击 删除

    4. 要确认删除,请输入 DELETE,然后点击删除

  3. 删除 Google Cloud 服务账号:

    1. 转到服务账号页面:

      转到“服务账号”

    2. 选择您的项目。

    3. 选择 gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com 对应的复选框。

    4. 点击 删除

    5. 如需确认删除,请点击删除

删除项目

  1. 在 Google Cloud 控制台中,进入管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤