• <xmp id="om0om">
  • <table id="om0om"><noscript id="om0om"></noscript></table>
  • 3 月 19 日下午 2 點,鎖定 NVIDIA AI 網絡中文專場。立即注冊觀看
    人工智能/深度學習

    使用 MIG 和 Kubernetes 大規模部署 MIG Triton

    NVIDIA Triton 推理服務器是一款開源人工智能模型服務軟件,可簡化在生產中大規模部署經過培訓的人工智能模型。對于服務器管理的任何模型,客戶端可以遠程向提供的 HTTP 或 gRPC 端點發送推斷請求。

    NVIDIA Triton 可以管理任意數量和混合型號(受系統磁盤和內存資源的限制)。它還支持多種深度學習框架,如 TensorFlow 、 PyTorch 、 NVIDIA TensorRT 等。這為開發者和數據科學家提供了靈活性,他們不再需要使用特定的模型框架。 NVIDIA Triton 旨在輕松與 Kubernetes 集成,以便在數據中心進行大規模部署。

    多實例并行運行多個工作負載( MIG )可以最大化 A100 GPU 和新發布的 A30 GPU 的 GPU 利用率。它還可以讓多個用戶通過 GPU 共享一個 GPU ,就像有多個更小的 GPU 一樣。 MIG 功能可以將單個 GPU 劃分為多個 GPU 分區,稱為 GPU 實例。每個實例都有專用的內存和計算資源,因此硬件級別的隔離可以確保同時執行工作負載,同時保證服務質量和故障隔離。

    在本文中,我們分享以下最佳實踐:

    • 在 A100 上使用 MIG 并行部署多個 Triton 推理服務器
    • 使用 Kubernetes 和 Prometheus 監控堆棧根據推理請求的數量自動調整 Triton 推理服務器的數量。
    • 使用 NGINX Plus 負載平衡器在不同的 Triton 推理服務器之間均勻分配推理負載。

    這一思想可以應用于單個節點或多個節點上的多個 A100 或 A30 GPU ,以便在生產中自動縮放 NVIDIA Triton 部署。例如, DGX A100 允許在 Kubernetes 吊艙上運行多達 56 個 Triton 推理服務器(每個 A100 最多有七個使用 MIG 的服務器)。

    硬件和軟件先決條件

    要使用 MIG ,必須啟用 MIG 模式并在A100或A30 GPU 上創建 MIG 設備。您可以使用nvidia-smi創建 GPU 實例并手動計算實例。或者,使用 NVIDIA 新的 MIG 分離工具nvidia-mig-parted,該工具允許管理員定義一組可能的 Clara 配置,以應用于節點上的所有 GPU 。

    在運行時,將nvidia-mig-parted指向其中一個配置,nvidia-mig-parted負責應用它。通過這種方式,相同的配置文件可以分布在集群中的所有節點上,并且可以使用運行時標志來決定將哪些配置應用于節點。因為如果重新啟動機器, MIG 配置將消失,nvidia-mig-parted還使重新啟動后創建 MIG 實例變得更容易。

    在 Kubernetes 環境中,必須安裝 NVIDIA 設備插件和 GPU 功能發現插件才能使用 MIG 。您可以單獨安裝每個插件,或者使用云本機 NVIDIA GPU 運算符,它是一個包,包含在 Kubernetes 中啟用 GPU 的所有內容。您還可以使用 NVIDIA 部署工具DeepOps,該工具負責安裝和插件,以及普羅米修斯監控堆棧,包括kube-prometheus、普羅米修斯和普羅米修斯適配器,您應將其用于自動校準 Triton 推理服務器。

    您可以在 Kubernetes 中使用 MIG 的單一策略或混合策略中的任意一個。在本文中,我們建議采用混合策略,因為一個 A100 GPU 有七個 MIG 設備,而另一個 A100 MIG 被禁用。

    使用花卉演示,它使用 ResNet50 對花卉圖像進行分類。 NVIDIA Triton 推理服務器容器映像可以從NGC中提取。為 Flower 演示準備服務器的模型文件(*.plan, config.pbtxt)和客戶端。有關更多信息,請參閱使用 NVIDIA 多實例 GPU 最小化深度學習推理延遲

    庫伯內特斯花卉演示

    設置 flower 演示后,您希望將其擴展到 Kubernetes 環境中的部署。這樣可以根據推理請求自動調整 Triton 推理服務器的數量,并在所有服務器之間分配推理負載。因為 A100 上最多允許七個 MIG 設備,所以您最多可以有七個 Kubernetes 吊艙,每個吊艙都有一個 Triton 推理服務器在 MIG 設備上運行。以下是部署具有自動縮放和負載平衡的 Triton 推理服務器的主要步驟:

    1. 為 Triton 推理服務器創建 Kubernetes 部署。
    2. 創建 Kubernetes 服務以將 Triton 推理服務器公開為網絡服務。
    3. 使用 kube Prometheus 和 PodMonitor 向 Prometheus 公開 NVIDIA Triton 度量。
    4. 創建 ConfigMap 以定義自定義度量。
    5. 部署 Prometheus 適配器并將自定義度量公開為注冊的 Kubernetes API 服務。
    6. 創建 HPA (水平吊艙自動縮放)以使用自定義度量。
    7. 使用 NGINX Plus 負載平衡器在所有 Triton 推理服務器之間分配推理請求。

    以下各節提供了實現這些目標的分步指南。

    為 Triton 推理服務器創建 Kubernetes 部署

    第一步是為 Triton 推理服務器創建庫伯內特斯部署。部署為PodsReplicaSets提供了動態更新。Kubernetes中的復制集同時啟動同一Pod的多個實例。

    以下flower-replicas3.yml文件創建了三個復制的 POD ,由.spec.replicas字段指示,該字段可以是 1 到 7 之間的任意數字。.spec.selector字段定義部署如何查找要管理的 POD 。每個 Pod 運行一個名為 flower 的容器,該容器運行版本為 20 . 12-py3 的 Triton 推理服務器映像。與 NVIDIA Triton 端口號相同,集裝箱端口 8000 、 8001 、 8002 分別保留用于 HTTP 、 gRPC 和 NVIDIA Triton 度量。

    .resources.limits字段使用混合策略為每個 Pod 指定具有 5 GB 內存的 MIG 設備。符號nvidia.com/mig-1g.5gb特定于混合策略,必須根據 Kubernetes 集群進行相應調整。在本例中, NVIDIA Triton 的模型使用 NFS 協議存儲在共享文件系統上。如果沒有共享文件系統,則必須確保將模型加載到所有工作節點,以便 Kubernetes 啟動的 POD 可以訪問。

    apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: flower
       labels:
         app: flower
     spec:
       replicas: 3
       selector:
         matchLabels:
           app: flower
       template:
         metadata:
           labels:
             app: flower
         spec:
           volumes:
           - name: models
             nfs:
               server: <IP address of the server>
               path: <path/to/flowerdemo/model/files>
               readOnly: false
           containers:
             - name: flower
               ports:
               - containerPort: 8000
                 name: http-triton
               - containerPort: 8001
                 name: grpc-triton
               - containerPort: 8002
                 name: metrics-triton
               image: "nvcr.io/nvidia/tritonserver:20.12-py3"
               volumeMounts:
               - mountPath: /models
                 name: models
               command: ["/bin/sh", "-c"]
               args: ["cd /models /opt/tritonserver/bin/tritonserver --model-repository=/models --allow-gpu-metrics=false --strict-model-config=false"]
               resources:
                 limits:
                   nvidia.com/mig-1g.5gb: 1  

    使用命令kubectl apply創建 Kubernetes 部署:

     $ kubectl apply -f flower-replicas3.yml
     deployment.apps/flower created 

    確認創建了三個吊艙:

     $ kubectl get pods
     NAME                               READY  STATUS  RESTARTS   AGE
     flower-5cf8b78894-2qqz8   1/1     Running            0          5s
     flower-5cf8b78894-g679c   1/1     Running            0          5s
     flower-5cf8b78894-xswwj   1/1     Running            0          5s 

    因為在這一步中部署了 ReplicaSet ,所以可以使用命令kubectl scale手動向上或向下縮放 Pod 編號:

    $ kubectl scale deployment flower --replicas=7
     deployment.apps/flower scaled
     $ kubectl get pods
     NAME                              READY   STATUS     RESTARTS   AGE
     flower-5cf8b78894-2qqz8   1/1     Running             0          69s
     flower-5cf8b78894-5znzt   1/1       Running            0          5s
     flower-5cf8b78894-g679c   1/1     Running            0          69s
     flower-5cf8b78894-gwgm6   1/1     Running            0          5s
     flower-5cf8b78894-shm2s   1/1     Running            0          5s
     flower-5cf8b78894-wrn9p   1/1     Running            0          5s
     flower-5cf8b78894-xswwj   1/1     Running            0          69s 

    為 Triton 推理服務器創建 Kubernetes 服務

    第二步是創建一個庫伯內特斯服務,將 Triton 推理服務器作為網絡服務公開,以便客戶端可以向服務器發送推理請求。創建服務時,選擇自動創建外部負載平衡器的選項,如.type字段所示。這提供了一個外部可訪問的 IP 地址,可將流量發送到節點上的正確端口。以下代碼示例是flower-service.yml文件:

    apiVersion: v1
     kind: Service
     metadata:
       name: flower
       labels:
         app: flower
     spec:
       selector:
         app: flower
       ports:
         - protocol: TCP
           port: 8000
           name: http
           targetPort: 8000
         - protocol: TCP
           port: 8001
           name: grpc
           targetPort: 8001
         - protocol: TCP
           port: 8002
           name: metrics
           targetPort: 8002
       type: LoadBalancer 

    類似地,使用以下命令創建 Kubernetes 服務:

    $ kubectl apply -f flower-service.yml
     service/flower created 

    確認已創建服務:

    $ kubectl get svc
     NAME    TYPE               CLUSTER-IP EXTERNAL-IP   PORT(S)       AGE
     flower   LoadBalancer   10.233.24.169   <pending>     8000:31268/TCP,8001:32231/TCP,8002:30499/TCP                            69s 

    創建服務的另一種方法是使用命令kubectl expose。可通過kubectl edit svc metrics命令編輯服務文件:

    $ kubectl expose deployment flower --type=LoadBalancer --name=metrics
     service/metrics exposed 

    現在, Triton 推理服務器已準備好接收來自遠程客戶端的推理請求(圖 1 )。如果客戶端發送推斷請求,客戶端可以查看花卉圖像的分類結果以及每個推斷請求的吞吐量和端到端延遲。

    NVIDIA Triton servers and clients
    圖 1 .(左)向 Kubernetes 中 MIG 設備上運行的 Triton 推理服務器發送推理請求的客戶端 ( 右)獲得分類結果和性能編號的客戶。

    到目前為止,您在 Kubernetes 環境中的 MIG 設備上運行多個 Triton 推理服務器,對客戶端發送的花朵圖像進行推理,您可以手動更改服務器數量。在接下來的部分中,您將對其進行改進,以便可以根據客戶機請求自動調整服務器的數量。

    使用普羅米修斯刮取 NVIDIA Triton 指標

    要自動更改 Kubernetes 吊艙上運行的 Triton 推理服務器的數量,請首先收集可用于定義自定義度量的 NVIDIA Triton 度量。因為多個 Kubernetes 吊艙中有多組 NVIDIA Triton 度量,所以您應該部署一個PodMonitor,告訴Prometheus從所有吊艙中獲取度量。

    Prometheus 是一個開源的系統監控和警報工具包,提供由度量名稱和鍵/值對標識的時間序列數據。PromQL,一種靈活的查詢語言,用于從 Prometheus 查詢度量。

    為普羅米修斯創建 PodMonitor

    PodMonitor定義了一組吊艙的監控,用于普羅米修斯發現目標。在flower-pod-monitor.yml文件中,您可以定義一個 PodMonitor 來監視服務器的 pod ,如.spec.selector字段所示。您還需要kube-prometheus,它包括普羅米修斯的部署,并將普羅米修斯鏈接到各種度量端點的目標配置刮取,如.spec.podMetricsEndpoints字段所示。普羅米修斯每 10 秒從這些端點刮取 NVIDIA Triton 度量,這些度量由.interval字段定義。

     apiVersion: monitoring.coreos.com/v1
     kind: PodMonitor
     metadata:
       name: kube-prometheus-stack-tritonmetrics
       namespace: monitoring
       labels:
           release: kube-prometheus-stack
     spec:
        selector:
           matchLabels:
              app: flower
        namespaceSelector:
           matchNames:
              - default
        podMetricsEndpoints:
        - port: metrics-triton
           interval: 10s
           path: /metrics 

    與普羅米修斯的 PodMonitor 標識相關的一個常見問題與不符合普羅米修斯自定義資源定義范圍的錯誤標記有關。要匹配 NVIDIA Triton 部署的標簽,請確保.spec.selector.matchLabels字段為app:flower,而.spec.namespaceSelector.matchNames字段為-default。兩者都應與 NVIDIA Triton 部署位于同一命名空間下。這可以通過檢查flower-replicas3.yml文件中的相關標簽來確認。要匹配kube-prometheus的標簽,還要確保.metadata.labels字段為release: kube-prometheus-stack。使用以下命令檢查標簽:

    $ kubectl get Prometheus -n monitoring
        NAME                                                 VERSION   REPLICAS   AGE
        kube-prometheus-stack-prometheus   v2.21.0               1          56d
        $ kubectl describe Prometheus kube-prometheus-stack-prometheus -n monitoring
        Name:         kube-prometheus-stack-prometheus
        Namespace:    monitoring
        Labels:       app=kube-prometheus-stack-prometheus
                   chart=kube-prometheus-stack-10.0.2
                   heritage=Helm
                   release=kube-prometheus-stack
        Annotations:  <none>
        API Version:  monitoring.coreos.com/v1
        Kind:         Prometheus  
        Metadata: 
        ……
      
           Pod Monitor Namespace Selector:
           Pod Monitor Selector:
              Match Labels:
                 Release:   kube-prometheus-stack 

    使用命令kubectl apply -f flower-pod-monitor.yml部署 PodMonitor 并確認:

    $ kubectl get PodMonitor -n monitoring
         NAME                                                  AGE
         kube-prometheus-stack-tritonmetrics   20s 

    使用 Prometheus 查詢 NVIDIA Triton 度量

    默認情況下, Prometheus 附帶一個用戶界面,可以在 Prometheus 服務器的 9090 端口上訪問該界面。在 web 瀏覽器中打開普羅米修斯并選擇StatusTargets。您可以看到kube-prometheus正確地檢測到了三臺服務器的指標,并將其添加到 Prometheus 中進行報廢。

    您可以單獨查詢任何 NVIDIA Triton 度量,例如nv_inference_queue_duration_usnv_inference_request_success,或者使用 ProMQ 查詢以下自定義度量,并獲得由 Prometheus 計算的三個值(圖 2 )。添加avg以獲得三個吊艙的平均值:

    avg(delta(nv_inference_queue_duration_us[30s])/(1+delta(nv_inference_request_success[30s]))).

    當您選擇Graph時,普羅米修斯還以圖形的形式提供時間序列數據。我們將在下一節中提供有關此度量的更多信息。

    Prometheus can calculate the three values of the customer metric from three Pods.]

    圖 2 .在 Prometheus 圖形用戶界面中使用 PromQL 查詢自定義度量

    自動縮放 Triton 推理服務器

    Diagram shows workflow between the Kubernetes Deployment, Service, and APIService for the Prometheus adapter.
    圖 3 .普羅米修斯適配器與庫伯內特斯和普羅米修斯通信

    既然普羅米修斯在監視服務器,那么應該部署普羅米修斯適配器,它知道如何與庫伯內特斯和普羅米修斯通信(圖 3 )。適配器幫助您使用普羅米修斯收集的指標來做出縮放決策。適配器定期從普羅米修斯收集可用度量的名稱,然后只公開遵循特定形式的度量。這些度量由 API 服務公開, HPA 可以輕松使用。

    可選:啟用許可綁定

    在 Kubernetes 集群中,基于角色的訪問控制( RBAC )是調節對不同對象訪問的常用方法。對于本例,必須允許在不同命名空間中運行的 HPA 訪問 metrics API 提供的度量。 RBAC 的配置與 Kubernetes 集群的配置有很大不同。有關如何使用基于角色的訪問控制的更多信息,請參閱使用 RBAC 授權

    在演示中,您可以通過發出以下命令創建一個具有許可綁定的ClusterRoleBinding對象,以允許 kubelet 用戶訪問所有 POD 。這將有效地禁用 Kubernetes 集群中的任何類型的安全性,并且不得用于生產環境。

    $kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts 

    創建 ConfigMap 以定義自定義度量

    首先,告訴普羅米修斯適配器如何收集特定指標。您使用兩個 NVIDIA Triton 度量來定義ConfigMap中的自定義度量avg_time_queue_us,其中HPA執行自動縮放。ConfigMap有一個鍵,該值看起來像配置格式的片段。在ConfigMap文件custom-metrics-server-config.yml中,使用以下值:

    • nv_inference_request_success[30]是過去 30 秒內成功的推理請求數。
    • nv_inference_queue_duration_us是以微秒為單位的累計推理排隊持續時間。

    自定義度量是指過去 30 秒內每個推斷請求的平均隊列時間, HPA 根據該時間決定是否更改副本號。

    在配置 Prometheus 適配器時,重要的是這些指標要有一個命名端點,例如要尋址的 Pod 。以后無法從 metrics API 查詢未尋址的度量。添加.overrides字段以強制要求podnamespace稍后在 API 中公開。

    apiVersion: v1
     kind: ConfigMap
     metadata:
       name: adapter-config
       namespace: monitoring
     data:
       triton-adapter-config.yml: |
         rules:
         - seriesQuery: 'nv_inference_queue_duration_us{namespace="default",pod!=""}'
           resources:
             overrides:
               namespace:
                 resource: "namespace"
               pod:
                 resource: "pod"
           name:
             matches: "nv_inference_queue_duration_us"
             as: "avg_time_queue_us"
          metricsQuery: 'avg(delta(nv_inference_queue_duration_us{<<.LabelMatchers>>}[30s])/
     (1+delta(nv_inference_request_success{<<.LabelMatchers>>}[30s]))) by (<<.GroupBy>>)'
      
          Create the ConfigMap and confirm it:
     $ kubectl apply -f custom-metrics-server-config.yml
     configmap/adapter-config created
     $ kubectl get configmap -n monitoring
     NAME                                                      DATA   AGE
     adapter-config                                            1        22s 

    為 Kubernetes metrics API 創建 Prometheus 適配器

    要使 HPA 對該自定義指標作出反應,必須為 Prometheus 適配器創建 Kubernetes 部署、服務和APIService。下面的代碼示例是部署文件custom-metrics-server-deployment.yml。它使用上一步中的ConfigMap,它告訴適配器收集自定義度量。它還創建了一個部署,生成適配器盒,從普羅米修斯那里獲取自定義度量。.containers.config字段必須與.mountPath字段和上一步ConfigMap中創建的文件名triton-adapter-configl.yml匹配。

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: triton-custom-metrics-apiserver
       namespace: monitoring
       labels:
         app: triton-custom-metris-apiserver
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: triton-custom-metrics-apiserver
       template:
         metadata:
           labels:
             app: triton-custom-metrics-apiserver
         spec:
           containers:
           - name: custom-metrics-server
             image: quay.io/coreos/k8s-prometheus-adapter-amd64:v0.4.1
             args:
             - --cert-dir=/tmp
             - --prometheus-url=<IP address:9090>
             - --metrics-relist-interval=30s
             - --v=10
             - --config=/etc/config/triton-adapter-config.yml
             - --secure-port=6443
             ports:
             - name: main-port
               containerPort: 6443
             volumeMounts:
             - name: config-volume
               mountPath: /etc/config
               readOnly: false
           volumes:
           - name: config-volume
             configMap:
               name: adapter-config

    為 Prometheus 適配器創建 Kubernetes 服務。在以下文件custom-metrics-server-service.yml中,.spec.selector。字段必須與部署中的標簽app: triton-custom-metris-apiserver匹配,以指定提供服務的 Pod 。

    apiVersion: v1
     kind: Service
     metadata:
       name: triton-custom-metrics-api
       namespace: monitoring
     spec:
       selector:
         app: triton-custom-metrics-apiserver
       ports:
       - port: 443
         targetPort: 6443 

    接下來,創建一個 APIService ,以便 Kubernetes 可以訪問 Prometheus 適配器。然后,可以通過 HPA 獲取自定義度量。以下代碼塊是 APIService 文件custom-metrics-server-apiservice.yml.spec.service字段必須與服務文件的. metadata 字段匹配。要允許 autoscaler 訪問自定義度量,您應該向API 聚合器注冊度量。這里需要使用的 API 是custom.metrics.k8s.io/v1beta1

     apiVersion: apiregistration.k8s.io/v1beta1
     kind: APIService
     metadata:
       name: v1beta1.custom.metrics.k8s.io
     spec:
       insecureSkipTLSVerify: true
       group: custom.metrics.k8s.io
       groupPriorityMinimum: 100
       versionPriority: 5
       service:
         name: triton-custom-metrics-api
         namespace: monitoring
       version: v1beta1 

    在部署 Prometheus 適配器之前,您可以看到在 API 點沒有可用的指標:

     $ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq
     Error from server (NotFound): the server could not find the requested resource 

    使用命令kubectl apply在前面提到的三個. yml 文件中應用配置。為 Prometheus 適配器創建 APIService 后,您可以看到自定義指標可用:

     $ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq .
     {
       "kind": "APIResourceList",
       "apiVersion": "v1",
       "groupVersion": "custom.metrics.k8s.io/v1beta1",
       "resources": [
         {
           "name": "namespaces/avg_time_queue_us",
           "singularName": "",
           "namespaced": false,
           "kind": "MetricValueList",
          "verbs": [
          "get"
          ]
          },
          {
           "name": "pods/avg_time_queue_us",
           "singularName": "",
           "namespaced": true,
           "kind": "MetricValueList",
          "verbs": [
          "get"
          ]
          }
       ]
     }  
     $ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq .
     {
       "kind": "APIResourceList",
       "apiVersion": "v1",
       "groupVersion": "custom.metrics.k8s.io/v1beta1",
       "resources": [
         {
           "name": "namespaces/avg_time_queue_us",
           "singularName": "",
           "namespaced": false,
           "kind": "MetricValueList",
          "verbs": [
          "get"
          ]
          },
          {
           "name": "pods/avg_time_queue_us",
           "singularName": "",
           "namespaced": true,
           "kind": "MetricValueList",
          "verbs": [
          "get"
          ]
          }
       ]
     } 

    您還可以檢查此自定義度量的當前值,即 0 ,因為當前沒有來自客戶端的推斷請求。在這里,您將從default命名空間中選擇所有 POD , flower 演示部署在該命名空間中:

    $ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/avg_time_queue_us | jq .
     {
       "kind": "MetricValueList",
       "apiVersion": "custom.metrics.k8s.io/v1beta1",
       "metadata": {
         "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/avg_time_queue_us"
       },
       "items": [
          {
           "describedObject": {
          "kind": "Pod",
          "namespace": "default",
          "name": "flower-5cf8b78894-jng2g",
             "apiVersion": "/v1"
          },
           "metricName": "avg_time_queue_us",
          "timestamp": "2021-03-25T15:49:10Z",
          "value": "0"
          }
       ]
     } 

    部署 HPA

    HPA 根據觀察到的指標自動縮放復制控制器、部署、復制集或有狀態集中的 POD 數量。現在,您可以創建使用自定義度量的 HPA 。 HPA 根據以下等式控制部署在 Kubernetes 中的副本數量。它根據所需度量值和當前度量值之間的比率進行操作,并返回所需副本的數量:

    R = ceil\left (CR\cdot \frac {CV}{DV} \right )

    在該公式中,使用以下公式:

    • R是 Kubernetes 擁有的副本數。
    • CR是當前的副本數。
    • CV是當前度量:在這種情況下,來自所有服務器的自定義度量值的平均值。
    • DV是所需的度量值。

    WhenR與 CR 不同, HPA 通過作用于 Kubernetes 部署( Pods )來增加或減少副本的數量。基本上,只要當前度量值與所需度量值之間的比率大于 1 ,就可以部署新的副本。

    圖 4 . HPA 比例 NVIDIA Triton 部署

    以下 HPA 文件flower-hpa.yml自動縮放 Triton 推理服務器的部署。它使用由.sepc.metrics字段指示的 Pods 度量,該字段獲取自動縮放目標控制的所有 Pods 中給定度量的平均值。.spec.metrics.targetAverageValue字段是通過考慮來自所有 POD 的自定義度量的值范圍來指定的。該字段觸發 HPA 定期調整副本的數量,以使觀察到的自定義度量與目標值相匹配。

      apiVersion: autoscaling/v2beta1
     kind: HorizontalPodAutoscaler
     metadata:
         name: flower-hpa
     spec:
         scaleTargetRef:
           apiVersion: apps/v1beta1
           kind: Deployment
           name: flower
         minReplicas: 1
         maxReplicas: 7
         metrics:
         - type: Pods
           pods:
             metricName: avg_time_queue_ms
             targetAverageValue: 50 

    使用命令kubectl apply -f flower-hpa.yml創建 HPA 并確認:

     $ kubectl get hpa
     NAME         REFERENCE      TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
     flower-hpa   Deployment/flower   0/50              1                 7                    1              22s 

    如果客戶端開始向服務器發送推斷請求,新的 HPA 可以獲取部署的自定義指標并確定所需的 POD 數量。例如,當推理請求增加時, HPA 會將 POD 的數量從 1 增加到 2 ,然后逐漸增加到 7 ,這是 A100 GPU 上的最大 POD 數量。最后,當客戶端停止發送推斷請求時, HPA 將副本數減少到僅 1 (圖 5 )。

    圖 5 .使用命令 kubectl 描述 hpa 花 hpa 檢查 HPA 如何增加或減少 Pod 數量 s 。

    使用 NGINX Plus 實現負載平衡

    負載平衡用于將來自客戶端的負載以最佳方式分布在可用服務器上。在前面,您選擇了 Kubernetes 內置負載平衡器,這是一個第 4 層(傳輸層)負載平衡器,它很容易部署,但是使用gRPClimitation可以實現。

    在這個演示中,使用 Prometheus ,您會發現 autoscaler 新添加的 POD 無法使用 Kubernetes 內置的負載平衡器獲得工作負載。要改進這一點,請使用NGINX Plus,它是第 7 層(應用程序層)負載平衡器。工作負載均勻地分布在所有 POD 中,包括新擴展的 POD 。

    首先,您應該創建 NGINX Plus 映像,因為 Docker Hub 無法提供 NGINX Plus 的商業產品。在 Docker 容器中創建 NGINX 實例使用 Docker Hub 的 NGINX 開源映像。然后,將本地映像推送到私有 Docker 注冊表。

    接下來,要部署 NGINX Plus ,請使用以下命令使用role=nginxplus 標記要在其上部署 NGINX Plus 的節點:

    $ kubectl label node <IP address or node name> role=nginxplus

    修改服務,將clusterIP設置為none,,以便所有副本端點都由 NGINX Plus 公開和標識。為避免混淆,請創建一個新的服務文件flower-service-nginx.yml,并應用它:

     apiVersion: v1
     kind: Service
     metadata:
       name: flower-nginx
       labels:
         app: flower
     Spec:
       clusterIP: None 
       selector:
         app: flower
       ports:
         - protocol: TCP
           port: 8000
           name: http
           targetPort: 8000
         - protocol: TCP
           port: 8001
           name: grpc
           targetPort: 8001 

    接下來,為 NGINX 創建一個配置文件。下面的代碼示例假定您正在使用位置/path/to/nginx/config/nginx.conf

     resolver <K8s DNS server IP> valid=5s;
     upstream backend {
        zone upstream-backend 64k;
        server <clusterIP FQDN: 8000> resolve;
     }
      
     upstream backendgrpc {
        zone upstream-backend 64k;
        server <clusterIP FQDN:8001> resolve;
     }
      
     server {
        listen 80;
        status_zone backend-servers;
      
        location / {
          proxy_pass http://backend;
          health_check uri=/v2/health/ready;
        }
     }
      
     server {
             listen 89 http2;
      
             location / {
                 grpc_pass grpc://backendgrpc;
             }
     }
      
     server {
         listen 8080;
         root /usr/share/nginx/html;
         location = /dashboard.html { }
         location = / {
            return 302 /dashboard.html;
         }
         location /api {
           api write=on;
         }
     } 

    最后,您應該在下面的nginxplus-rc.yml文件中為 NGINX Plus 創建一個ReplicationController。要從私有注冊表中提取映像, Kubernetes 需要credentials。配置文件中的imagePullSecrets字段指定 Kubernetes 應從名為regcred的機密中獲取憑據。在此配置文件中,還必須將上一步創建的 NGINX 配置文件裝載到位置/etc/nginx/conf.d

      apiVersion: v1
     kind: ReplicationController
     metadata:
       name: nginxplus-rc
     spec:
       replicas: 1
       selector:
         app: nginxplus
       template:
         metadata:
           labels:
             app: nginxplus
         spec:
           nodeSelector:
             role: nginxplus
           imagePullSecrets:
           - name: regcred
           containers:
           - name: nginxplus
             command: [ "/bin/bash", "-c", "--" ]
             args: [ "nginx; while true; do sleep 30; done;" ]
             imagePullPolicy: IfNotPresent
             image: nvcr.io/nvidian/swdl/nginxplus:v1
             ports:
               - name: http
                 containerPort: 80
                 hostPort: 8085
               - name: grpc
                 containerPort: 89
                 hostPort: 8087
               - name: http-alt
                 containerPort: 8080
                 hostPort: 8086
               - name: flower-svc
                 containerPort: 8000
                 hostPort: 32309
             volumeMounts:
               - mountPath: "/etc/nginx/conf.d"
                 name: etc-nginx-confd
           volumes:
             - nfs:
                server: <NFS server IP>
                path: </path/to/nginx/config>
                readOnly: false
               name: etc-nginx-confd 

    使用以下命令創建 ReplicationController :

    kubectl create -f nginxplus-rc.yml  

    驗證部署。您應該發現 NGINX Plus 正在運行:

     $kubectl get pods
     NAME                      READY   STATUS    RESTARTS   AGE
     flower-5cf8b78894-jng2g   1/1     Running   0          8h
     nginxplus-rc-nvj7b        1/1     Running   0          10s 

    現在,當客戶端向服務器發送推斷請求時,您可以看到 NGINX Plus 儀表板(圖 6 ):

    • autoscaler 將豆莢的數量從 1 逐漸增加到 7 。
    • 工作負載在所有 POD 中均勻分布,如流量所示。

    您還可以通過檢查普羅米修斯中所有 POD 的度量值或自定義度量值來確認新添加的 POD 正在工作。

    There are seven NVIDIA Triton servers. Each server’s information includes Requests, Responses, Traffic, Response time, and so on
    圖 6 . NGINX Plus 儀表板顯示了按 HPA 縮放的 NVIDIA Triton 服務器數量和每臺服務器的信息。

    Conclusion

    這篇文章展示了在 Kubernetes 環境中使用 MIG 大規模部署 Triton 推理服務器的分步說明和代碼。我們還向您展示了如何使用兩種不同類型的負載平衡器自動調整服務器數量和平衡工作負載。我們有記錄所有步驟和結果,您也可以觀看 Triton 大規模部署,具有多實例 – GPU ( MIG )和 Kubernetes GTC ‘ 21 會話。

    有關使用 MIG 在單個 A100 GPU 上并行運行多個深度學習工作負載的更多信息,請參閱使用 MIG 充分利用 MIG A100 GPU

    ?

    +2

    標簽

    人人超碰97caoporen国产