全部產品
Search
文件中心

Alibaba Cloud Service Mesh:使用動態子集路由加速模型服務網格推理

更新時間:Nov 20, 2024

本文介紹如何使用服務網格ASM的動態子集路由能力,將請求直接精準路由到正確的運行時環境,以加速模型服務網格的推理過程。

背景資訊

模型服務網格(Model Service Mesh)提供了一個可擴充的、高效能的基礎架構,用於管理、部署和調度多個模型服務。

當您同時在模型服務網格中運行多個不同模型時,特定模型往往只會被載入到特定的運行時中,而Kubernetes Service會隨機將推理請求發送到任意一個運行時,此推理請求可能要經過模型服務網格的多次路由才能發往模型所在的正確運行時。

動態子集路由可以識別模型服務網格中每個運行時工作負載中正在啟動並執行模型,通過ASM網關識別推理請求對應的模型,將請求精準地路由到正確的運行時工作負載,從而最佳化模型服務網格的路由決策,加速對推理請求的響應過程。有關動態子集路由的詳情,請參考動態子集路由

前提條件

步驟一:在模型服務網格中部署tf-mnist模型

由於動態子集路由的精準路由能力主要作用於多模型的情境下,因此本文額外部署tf-mnist模型(TensorFlow實現的mnist模型,由triton運行時提供運行環境)到模型服務網格中。

說明

本文繼續沿用使用模型服務網格進行多模型推理服務中建立的PVC my-models-pvc,將tf-minst模型(mnist目錄中所有的內容都是模型內容)儲存在該PVC中。

  1. 將tf-mnist模型儲存在持久卷上。

    1. 在ACK叢集對應的KubeConfig環境下,執行以下命令,將mnist-svm.joblib模型檔案複製到pvc-access Pod的/mnt/models檔案夾中。

      kubectl -n modelmesh-serving cp mnist pvc-access:/mnt/models/
    2. 執行以下命令,確認Model已經載入成功。

      kubectl -n modelmesh-serving exec -it pvc-access -- ls -alr /mnt/models/

      預期輸出:

      -rw-r--r-- 1  502 staff 344817 Apr 23 08:17 mnist-svm.joblib
      drwxr-xr-x 3 root root    4096 Apr 23 08:23 mnist
      drwxr-xr-x 1 root root    4096 Apr 23 08:17 ..
      drwxrwxrwx 3 root root    4096 Apr 23 08:23 .
  2. 部署推理服務。

    1. 使用以下內容建立tf-mnist.yaml。

      apiVersion: serving.kserve.io/v1beta1
      kind: InferenceService
      metadata:
        name: tf-mnist
        namespace: modelmesh-serving
        annotations:
          serving.kserve.io/deploymentMode: ModelMesh
      spec:
        predictor:
          model:
            modelFormat:
              name: tensorflow
            storage:
              parameters:
                type: pvc
                name: my-models-pvc
              path: mnist
    2. 在ACK叢集對應的KubeConfig環境下,執行以下命令,部署tf-mnist推理服務。

      kubectl apply -f tf-mnist.yaml
    3. 等待片刻後(時間取決於鏡像拉取速度),執行以下命令,查看tf-mnist推理服務是否部署成功。

      kubectl get isvc -n modelmesh-serving

      預期輸出:

      NAME            URL                                               READY
      sklearn-mnist   grpc://modelmesh-serving.modelmesh-serving:8033   True
      tf-mnist        grpc://modelmesh-serving.modelmesh-serving:8033   True

      由預期輸出可知,模型服務網格中已經部署了sklearn-mnist和tf-mnist兩個不同架構的模型。

步驟二(可選):測試模型服務網格推理請求處理時延

  1. 參考fortio專案的安裝說明,安裝fortio壓力測試工具。

  2. 使用fortio工具發送推理請求到tf-mnist模型。ASM網關IP地址的擷取請參考ASM整合KServe實現雲原生AI模型推理服務

    ASM_GW_IP="ASM網關IP地址"
    fortio load -jitter=False -H 'model: tf-mnist' -c 1 -qps 100 -t 60s -payload '{"inputs": [{ "name": "inputs", "shape": [1, 784], "datatype": "FP32", "contents": { "fp32_contents": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01176471, 0.07058824, 0.07058824, 0.07058824, 0.49411765, 0.53333336, 0.6862745, 0.10196079, 0.6509804, 1.0, 0.96862745, 0.49803922, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.11764706, 0.14117648, 0.36862746, 0.6039216, 0.6666667, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.88235295, 0.6745098, 0.99215686, 0.9490196, 0.7647059, 0.2509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.19215687, 0.93333334, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.9843137, 0.3647059, 0.32156864, 0.32156864, 0.21960784, 0.15294118, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.85882354, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7764706, 0.7137255, 0.96862745, 0.94509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3137255, 0.6117647, 0.41960785, 0.99215686, 0.99215686, 0.8039216, 0.04313726, 0.0, 0.16862746, 0.6039216, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.05490196, 0.00392157, 0.6039216, 0.99215686, 0.3529412, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.54509807, 0.99215686, 0.74509805, 0.00784314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04313726, 0.74509805, 0.99215686, 0.27450982, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.13725491, 0.94509804, 0.88235295, 0.627451, 0.42352942, 0.00392157, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.31764707, 0.9411765, 0.99215686, 0.99215686, 0.46666667, 0.09803922, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1764706, 0.7294118, 0.99215686, 0.99215686, 0.5882353, 0.10588235, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0627451, 0.3647059, 0.9882353, 0.99215686, 0.73333335, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9764706, 0.99215686, 0.9764706, 0.2509804, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.18039216, 0.50980395, 0.7176471, 0.99215686, 0.99215686, 0.8117647, 0.00784314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.15294118, 0.5803922, 0.8980392, 0.99215686, 0.99215686, 0.99215686, 0.98039216, 0.7137255, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09411765, 0.44705883, 0.8666667, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7882353, 0.30588236, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.09019608, 0.25882354, 0.8352941, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7764706, 0.31764707, 0.00784314, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07058824, 0.67058825, 0.85882354, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.7647059, 0.3137255, 0.03529412, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.21568628, 0.6745098, 0.8862745, 0.99215686, 0.99215686, 0.99215686, 0.99215686, 0.95686275, 0.52156866, 0.04313726, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.53333336, 0.99215686, 0.99215686, 0.99215686, 0.83137256, 0.5294118, 0.5176471, 0.0627451, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }}]}' -a ${ASM_GW_IP}:8008/v2/models/tf-mnist/infer

    預期輸出:

    展開查看預期輸出

    16:06:53.107 r1 [INF] scli.go:125> Starting, command="Φορτίο", version="1.63.7 h1:S6e+z36nV6o8RYQSUI9EWYxhCoPJy4VdAB2HQROUqMg= go1.22.2 amd64 linux", go-max-procs=8
    Fortio 1.63.7 running at 100 queries per second, 8->8 procs, for 1m0s: 192.168.0.7:8008/v2/models/tf-mnist/infer
    16:06:53.107 r1 [INF] httprunner.go:121> Starting http test, run=0, url="192.168.0.7:8008/v2/models/tf-mnist/infer", threads=1, qps="100.0", warmup="parallel", conn-reuse=""
    16:06:53.107 r1 [WRN] http_client.go:170> Assuming http:// on missing scheme for '192.168.0.7:8008/v2/models/tf-mnist/infer'
    Starting at 100 qps with 1 thread(s) [gomax 8] for 1m0s : 6000 calls each (total 6000)
    16:07:53.172 r1 [INF] periodic.go:851> T000 ended after 1m0.007662555s : 6000 calls. qps=99.98723070575699
    Ended after 1m0.007716622s : 6000 calls. qps=99.987
    16:07:53.172 r1 [INF] periodic.go:581> Run ended, run=0, elapsed=60007716622, calls=6000, qps=99.98714061718327
    Sleep times : count 5999 avg 0.0021861297 +/- 0.001025 min -0.011550303 max 0.003734337 sum 13.1145918
    Aggregated Function Time : count 6000 avg 0.0072130591 +/- 0.0007502 min 0.006125677 max 0.020551562 sum 43.2783545
    # range, mid point, percentile, count
    >= 0.00612568 <= 0.007 , 0.00656284 , 35.88, 2153
    > 0.007 <= 0.008 , 0.0075 , 90.85, 3298
    > 0.008 <= 0.009 , 0.0085 , 97.77, 415
    > 0.009 <= 0.01 , 0.0095 , 99.42, 99
    > 0.01 <= 0.011 , 0.0105 , 99.68, 16
    > 0.011 <= 0.012 , 0.0115 , 99.77, 5
    > 0.012 <= 0.014 , 0.013 , 99.90, 8
    > 0.014 <= 0.016 , 0.015 , 99.95, 3
    > 0.016 <= 0.018 , 0.017 , 99.97, 1
    > 0.018 <= 0.02 , 0.019 , 99.98, 1
    > 0.02 <= 0.0205516 , 0.0202758 , 100.00, 1
    # target 50% 0.00725682
    # target 75% 0.00771164
    # target 90% 0.00798454
    # target 99% 0.00974747
    # target 99.9% 0.014
    Error cases : no data
    # Socket and IP used for each connection:
    [0]   1 socket used, resolved to 192.168.0.7:8008, connection timing : count 1 avg 0.004218262 +/- 0 min 0.004218262 max 0.004218262 sum 0.004218262
    Connection time histogram (s) : count 1 avg 0.004218262 +/- 0 min 0.004218262 max 0.004218262 sum 0.004218262
    # range, mid point, percentile, count
    >= 0.00421826 <= 0.00421826 , 0.00421826 , 100.00, 1
    # target 50% 0.00421826
    # target 75% 0.00421826
    # target 90% 0.00421826
    # target 99% 0.00421826
    # target 99.9% 0.00421826
    Sockets used: 1 (for perfect keepalive, would be 1)
    Uniform: false, Jitter: false, Catchup allowed: true
    IP addresses distribution:
    192.168.0.7:8008: 1
    Code 200 : 6000 (100.0 %)
    Response Header Sizes : count 6000 avg 233.00067 +/- 0.02581 min 233 max 234 sum 1398004
    Response Body/Total Sizes : count 6000 avg 454.00067 +/- 0.02581 min 454 max 455 sum 2724004
    All done 6000 calls (plus 1 warmup) 7.213 ms avg, 100.0 qps
    Successfully wrote 11561 bytes of Json data to 2024-04-24-160653_192_168_0_7_8008_v2_models_tf_mnist_infer_iZbp1jfq2w26u2kpxa9r3dZ.json
  3. 查看fortio可視化壓力測試結果。

    1. 運行以下命令,開啟fortio本機伺服器。

      fortio server
    2. 使用瀏覽器訪問localhost:8080,單擊介面中的saved results,在跳轉後的介面選擇fortio工具輸出的JSON檔案名稱,查看壓力測試的可視化結果。

      image

      由上圖可發現,發送到模型服務網格的部分推理請求有延遲增加的情況,此時請求經過了模型服務網格的重新路由,響應速度有所下降。

步驟三:對模型服務網格啟用動態子集路由

模型服務網中啟動並執行所有模型都通過modelmesh-serving命名空間下modelmesh-serving服務統一進行訪問,本節示範通過配置modelmesh-serving服務的動態子集路由來實現針對不同模型運行時的精確路由。

  1. 使用以下內容,為模型服務網格的modelmesh-serving服務配置動態分組。具體操作請參見管理目標規則

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: modelmesh-serving
      namespace: modelmesh-serving
    spec:
      host: modelmesh-serving
      trafficPolicy:
        loadBalancer:
          dynamicSubset:
            subsetSelectors:
              - fallbackPolicy: ANY_ENDPOINT
                keys:
                  - modelmesh.asm.alibabacloud.com

    上述的目標規則基於modelmesh.asm.alibabacloud.com標籤對模型運行時進行動態分組,模型服務網格將根據運行時中實際載入的模型動態更新運行時的標籤。

  2. 使用以下內容,變更虛擬服務vs-modelmesh-serving-service的內容。具體操作,請參見管理虛擬服務

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: vs-modelmesh-serving-service
      namespace: modelmesh-serving
    spec:
      gateways:
        - grpc-gateway
      hosts:
        - '*'
      http:
        - headerToDynamicSubsetKey:
            - header: model
              key: modelmesh.asm.alibabacloud.com
          match:
            - port: 8008
          name: default
          route:
            - destination:
                host: modelmesh-serving
                port:
                  number: 8033

    上述的虛擬服務基於動態子集路由的要求,添加了headerToDynamicSubsetKey欄位,此後ASM網關將把推理請求中的model請求轉化成請求中繼資料,匹配模型服務網格的動態子集。

步驟四(可選):測試最佳化後的模型服務網格推理請求處理時延

參見步驟二,重新使用fortio執行測試,並查看可視化結果。

image

由預期結果可知,經過ASM動態子集路由最佳化後,所有的推理請求訪問時延都落在較小的區間,推理請求的時延表現得到很大程度的最佳化。