全部產品
Search
文件中心

Platform For AI:部署非同步推理服務

更新時間:Apr 09, 2025

在AIGC、視頻處理等複雜模型推理情境中,同步請求易引發連線逾時及負載不均等問題,PAI非同步推理服務推出獨立的佇列服務架構,支援根據執行個體負載情況分發請求、異常執行個體任務自動遷移至健康節點,有效避免資源爭搶與服務中斷。本文詳解如何使用非同步推理服務。

實現原理

  • 建立非同步推理服務時,會在服務內部整合推理子服務隊列子服務。隊列子服務有輸入(input)和輸出(sink)兩個內建的訊息佇列。服務要求會先發送到輸入隊列,推理子服務執行個體中的EAS服務架構會自動訂閱隊列以流式的方式擷取請求資料,調用推理子服務中的介面對收到的請求資料進行推理,並將響應結果寫入到輸出隊列中。

  • 當輸出隊列滿時,即無法向輸出隊列中寫入資料時,服務架構也會停止從輸入隊列接收資料,避免無法將推理結果寫入輸出隊列。

    如果不需要輸出隊列,例如將推理結果直接輸出到OSS或者自己的訊息中介軟體中,可在同步的HTTP推理介面中返回空,此時輸出隊列會被忽略。

  • 建立高可用的隊列子服務接收用戶端請求。推理子服務的執行個體根據自己所能承受的並發度來訂閱指定個數的請求,隊列子服務會保證每個推理子服務執行個體上處理的請求不會超過訂閱的視窗大小,避免執行個體過載,最終將訂閱或查詢的資料返回給用戶端。

    說明

    比如每個推理子服務執行個體只能處理5路語音流,則從隊裡子服務中訂閱訊息時,將window size配置為5。當推理子服務執行個體處理完一路語音流後將結果commit,隊列子服務會為推理子服務執行個體重新推送一路新的語音流,保證該執行個體上處理的語音流最多不超過5路。

  • 隊列子服務通過檢測推理子服務執行個體的串連狀態進行健全狀態檢查,若該執行個體異常導致串連斷開,隊列子服務會將其標記為異常,並將已經分發給該執行個體的請求重新推送給其他正常執行個體進行處理,確保在異常情況下請求資料不會丟失。

建立非同步推理服務

在建立非同步推理服務時,系統會自動建立和非同步推理服務同名的服務群組。同時,隊列子服務會隨非同步推理服務自動建立,並整合到非同步推理服務內。隊列子服務預設啟動1個執行個體,並根據推理子服務的執行個體數量動態伸縮,但最多不超過2個執行個體,每個執行個體預設配置為1核和4 GB記憶體。如果隊列子服務的執行個體數的預設配置不能滿足您的需求,請參照隊列子服務參數配置及說明進行調整。

EAS的非同步推理服務可以實現同步推理邏輯到非同步推理的轉換,支援以下兩種部署方式:

通過控制台部署服務

  1. 進入自訂部署頁面,並配置以下關鍵參數,其他參數配置詳情,請參見控制台自訂部署參數說明

    • 部署方式:選擇鏡像部署processor部署

    • 非同步服務:選中非同步服務

    image

  2. 參數配置完成後,單擊部署

通過eascmd用戶端部署服務

  1. 準備服務的設定檔service.json。

    • 部署方式為processor部署

      {
        "processor": "pmml",
        "model_path": "http://example.oss-cn-shanghai.aliyuncs.com/models/lr.pmml",
        "metadata": {
          "name": "pmmlasync",
          "type": "Async",
          "cpu": 4,
          "instance": 1,
          "memory": 8000
        }
      }

      其中關鍵參數說明如下。其他參數配置說明,請參見JSON部署參數說明

      • type:配置為Async,即可建立非同步推理服務。

      • model_path:替換為您的模型的地址。

    • 部署方式為鏡像部署服務

      {
          "metadata": {
              "name": "image_async",
              "instance": 1,
              "rpc.worker_threads": 4,
              "type": "Async"
          },
          "cloud": {
              "computing": {
                  "instance_type": "ecs.gn6i-c16g1.4xlarge"
              }
          },
          "queue": {
              "cpu": 1,
              "min_replica": 1,
              "memory": 4000,
              "resource": ""
          },
          "containers": [
              {
                  "image": "eas-registry-vpc.cn-beijing.cr.aliyuncs.com/pai-eas/chat-llm-webui:3.0.1",
                  "script": "python webui/webui_server.py --port=8000 --model-path=Qwen/Qwen-7B-Chat",
                  "port": 8000
              }
          ]
      }

      其中關鍵參數說明如下。其他參數配置說明,請參見JSON部署參數說明

      • type:配置該參數為Async,即可建立非同步推理服務。

      • instance:推理子服務的執行個體數量,不包含隊列子服務的執行個體。

      • rpc.worker_threads:為非同步推理服務中EAS服務架構的線程數,該參數與訂閱隊列資料的視窗大小一致。線程數設定為4,即一次最多隻能從隊列中訂閱4條資料,在這4條資料處理完成前,隊列子服務不會給推理子服務推送新資料。

        例如:某視頻流處理服務,單個推理子服務執行個體一次只能處理2條視頻流,則該參數可以設定為2,隊列子服務最多將2個視頻流的地址推送給推理子服務,在推理子服務返回結果前,不會再推送新的視頻流地址。如果推理子服務完成了其中一個視頻流的處理並返回結果,則隊列子服務會繼續再推送一個新的視頻流地址給該推理子服務的執行個體,保證一個推理子服務的執行個體最多同時處理不超過2個視頻流。

  2. 建立服務。

    您可以登入eascmd用戶端後使用create命令建立非同步推理服務,如何登入eascmd用戶端,請參見下載並認證用戶端,使用樣本如下。

    eascmd create service.json

訪問非同步推理服務

如上文介紹,系統會預設為您建立與非同步推理服務同名的服務群組,因群組內的隊列子服務擁有群組流量入口,您可以直接通過下述路徑訪問隊列子服務,詳情請參見訪問佇列服務

地址類型

地址格式

樣本

輸入隊列地址

{domain}/api/predict/{service_name}

xxx.cn-shanghai.pai-eas.aliyuncs.com/api/predict/{service_name}

輸出隊列地址

{domain}/api/predict/{service_name}/sink

xxx.cn-shanghai.pai-eas.aliyuncs.com/api/predict/{service_name}/sink

管理非同步推理服務

您可以像管理普通服務一樣管理非同步推理服務,該服務的子服務會由系統自動管理。比如,當您刪除非同步推理服務時,隊列子服務和推理子服務會同時刪除;更新推理子服務時,隊列子服務維持不變以擷取最大的可用性。

由於採用了子服務架構,雖然您為非同步推理子服務配置了1個執行個體,執行個體列表中仍會額外顯示一個隊列子服務執行個體。

image

非同步推理服務的執行個體數量指的是推理子服務執行個體的數量,隊列子服務的執行個體數量會隨著推理子服務的執行個體數量自動變化。比如,當您將推理子服務執行個體數量擴容到3時,隊列子服務的執行個體數量擴容到了2。

image

兩個子服務間的執行個體數量配比規則如下:

  • 停止非同步推理服務時,隊列子服務和推理子服務的執行個體數量均會縮容到0,執行個體列表為空白。

  • 推理子服務的執行個體數量為1時,隊列子服務的執行個體數量也為1,除非配置了隊列子服務的參數。

  • 推理子服務的執行個體數量超過2時,隊列子服務的執行個體數量將保持為2,除非配置了隊列子服務的參數。

  • 當您為非同步推理服務配置了自動擴縮容功能,且配置了最小的執行個體數量為0時,當推理子服務縮容到0時,隊列子服務將保持1個執行個體待命。

隊列子服務參數配置及說明

隊列子服務通常使用預設配置即可。如果有特殊需求,您可以在JSON檔案的queue配置塊進行自訂配置。樣本如下:

{  
  "queue": {
     "sink": {
        "memory_ratio": 0.3
     },
     "source": {
        "auto_evict": true
     }
 }

下面介紹具體的配置項。

配置隊列子服務資源

隊列子服務的資源預設按照metadata中的欄位進行配置,但在有些情境下,您可以跟進本章節,對隊列子服務的資源進行單獨配置。

  • 通過queue.resource聲明隊列子服務所使用的資源群組。

    {
      "queue": {
        "resource": eas-r-slzkbq4tw0p6xd****  # 預設跟隨推理子服務資源群組。
      }
    }
    • 隊列子服務預設跟隨推理子服務的資源群組。

    • 當您需要使用公用資源群組部署隊列子服務時,可以聲明resource為空白字串(""),這在您的專屬資源群組CPU和記憶體不充足時非常有用。

      說明

      推薦使用公用資源群組部署隊列子服務。

  • 通過queue.cpuqueue.memory聲明每個隊列子服務執行個體所使用的CPU(單位:核心數)和記憶體大小(單位:MB)。

    {
      "queue": {
         "cpu": 2,  # 預設值為1。
         "memory": 8000  # 預設值為4000。
      }
    }

    如果您沒有進行資源配置,隊列子服務將按照1 CPU核、4 GB記憶體進行預設配置。這可以滿足大多數情境的需求。

    重要
    • 如果您的訂閱者(比如推理子服務執行個體的數量)數量超過200時,建議將CPU核心數配置為2核以上。

    • 不建議在生產環境中縮小隊列子服務的記憶體配置。

  • 通過queue.min_replica配置隊列子服務執行個體的最小數量。

    {
      "queue": {
         "min_replica": 3  # 預設為1。
      }
    }

    在使用非同步推理服務時,隊列子服務執行個體的數量將根據推理子服務執行個體的運行時數量自動調整,預設的調整區間為[1, min{2, 推理子服務執行個體的數量}]。特殊情況下,如果配置非同步推理服務的自動擴縮容規則並允許將執行個體數量縮小到0時,將自動保留1個隊列子服務執行個體。您也可以通過queue.min_replica調整最小保留的隊列子服務執行個體數量。

    說明

    增加隊列子服務執行個體的數量可以提高可用性,但不能提高隊列子服務的效能。

配置隊列子服務功能

隊列子服務擁有多項可配置的功能,您可以通過以下配置方法進行調整。

  • 通過queue.sink.auto_evict或者queue.source.auto_evict分別配置輸出/輸入隊列自動資料驅逐功能。

    {
      "queue": {
         "sink": {
            "auto_evict": true  # 輸出隊列開啟自動驅逐,預設為false。
          },
          "source": {
             "auto_evict": true  # 輸入隊列開啟自動驅逐,預設為false。
          }
      }
    }

    預設情況下隊列子服務的自動資料驅逐功能處於關閉狀態,如果您的隊列已滿將無法繼續輸入資料。在某些情境下,如果您允許資料在隊列中溢出,可以選擇開啟自動資料驅逐功能,隊列將自動驅逐最老的資料以允許新資料寫入。

  • 通過queue.max_delivery配置最大投遞次數。

    {
       "queue": {
          "max_delivery": 10  # 最大投遞次數為10,預設值:5。當配置為0時,最大投遞次數關閉, 資料可以被無限次投遞。
       }
    }

    當單條資料的嘗試投遞次數超過設定閾值時,該資料將被視為無法處理,並將其標記為死信。詳情請參見隊列執行個體的死信策略

  • 通過queue.max_idle配置資料的最大處理時間。

    {
        "queue": {
          "max_idle": "1m"  # 配置單條資料最大處理時間長度為1分鐘,如果超過該時間將被投遞給其它訂閱者, 投遞完畢後投遞次數+1。預設值為0,即沒有最大處理時間長度。
        }
    }

    樣本中配置的時間長度為1分鐘,支援多種時間單位,如h(小時)、m(分鐘)、s(秒)。如果單條資料處理的時間超過了這裡配置的時間長度,則有兩種可能:

    • 如果未超過queue.max_delivery設定的閾值,該條資料會被投遞給其他訂閱者。

    • 如果已超過queue.max_delivery設定的閾值,該條資料將會被執行死信策略。

  • 通過queue.dead_message_policy配置死信策略。

    {
        "queue": {
          "dead_message_policy":  "Rear"  # 枚舉值為Rear(預設值)或者Drop, Rear即為放入隊列末尾,Drop將該條資料刪除。 																 
        }
    }

配置隊列最大長度或最巨量資料體積

隊列子服務的最大長度和最巨量資料體積是此消彼長的關係,計算關係如下所示:

隊列子服務執行個體記憶體是固定的,因此如果調整單條資料最大體積,則會導致該隊列最大長度減小。

說明
  • 在4 GB記憶體的預設配置下,由於最巨量資料體積預設為8 KB,則輸入輸出隊列均可以存放230399條資料,如果您需要在隊列子服務中存放更多資料項目,可以參考上文中的記憶體配置,將記憶體大小按照需要提高。系統將佔用總記憶體的10%。

  • 對於同一個隊列,不能同時配置最大長度和最巨量資料體積。

  • 通過queue.sink.max_length或者queue.source.max_length分別配置輸出隊列/輸入隊列的最大長度。

    {
        "queue": {
           "sink": {
              "max_length": 8000  # 配置輸出隊列最大長度為8000條資料。
           },
           "source": {
              "max_length": 2000  # 配置輸入隊列最大長度為2000條資料。
           }
        }
    }
  • 通過queue.sink.max_payload_size_kb或者queue.source.max_payload_size_kb分別配置輸出隊列/輸入隊列單條資料最巨量資料體積。

    {
        "queue": {
           "sink": {
              "max_payload_size_kb": 10  # 配置輸出隊列單條資料最大體積是10 KB, 預設8 kB。
           },
           "source": {
              "max_payload_size_kb": 1024  # 配置輸入隊列單條資料最大體積是1024 KB(1MB), 預設是8 kB。
           }
        }
    }

配置記憶體配置傾斜

  • 通過queue.sink.memory_ratio來調整輸入輸出兩個隊列佔用的記憶體大小。

    {
        "queue": {
           "sink": {
              "memory_ratio": 0.9  # 配置輸出隊列記憶體佔比,預設值為0.5。
           }
        }
    }
    說明

    預設配置下,輸入隊列和輸出隊列均分隊列子服務執行個體的記憶體。如果您的服務需要輸入文本、輸出圖片,並期望在輸出隊列存放更多資料,則可以將queue.sink.memory_ratio相應提高;相反,如果您期望輸入圖片、輸出文本,則可以將queue.sink.memory_ratio相應減小。

配置水平自動擴縮容

非同步推理服務水平自動擴縮容配置方法,請參見自動擴縮容