天天看點

【假期 AI 充電】KServe + Fluid 加速大模型推理

作者:技術聯盟總壇

馳琳、露營、車漾 阿裡雲雲原生 2023-06-23 11:39 發表于浙江

【假期 AI 充電】KServe + Fluid 加速大模型推理

作者:黃馳琳、露營、車漾

背景

Cloud Native

KServe 是 Kubernetes 上的标準模型推理平台,專為高度可擴充的場景而建構,支援現代 Serverless 推理工作負載,用于在任意架構上提供機器學習(ML)模型服務。它提供高性能、高度抽象的接口,以支援常見的 ML 架構(如Tensorflow、XGBoost、Scikit-Learn、PyTorch 和 ONNX)來解決生産模型服務場景。此外,KServe 封裝了自動縮放、網絡、健康檢查和服務配置的複雜性,支援GPU 自動縮放、歸零縮放和金絲雀釋出等。為生産級别機器學習服務提供了一個簡單、可插拔且完整的支援,包括預測、預處理、後處理和可解釋性的能力。

【假期 AI 充電】KServe + Fluid 加速大模型推理

人工智能生成内容(AIGC)和大型語言模型(LLM)在近一年内方興未艾,進一步提升了了大衆對 AI 的期望值。為了能夠産生新的業務價值,越來越多的公司開始使用 KServe 來部署它們,主要原因是:

  1. 分布式處理:大型語言模型(LLMs)的參數量龐大,需要極高的計算資源,而KServe平台提供了分布式處理能力,可以将計算任務分布到多個節點上進行并行計算,進而加速計算過程。
  2. Serverless:KServe 平台是無伺服器算法的典型代表,可以在需求變化時自動進行擴縮容。這種特性使得部署大型語言模型變得更加靈活和高效,并能夠顯著提升模型的響應速度。
  3. 統一化部署:KServe 平台為使用者提供了一種更加簡便和統一的方式來部署和管理大型語言模型。這樣一來,使用者無需自行設定和配置算法環境,即可開始進行模型的訓練和預測工作。
  4. 監控和管理:KServe 平台具備完備的監控和管理功能,使用者可以清晰地了解到模型的運作狀況和性能表現,并能夠及時調整參數和處理問題,進而保證模型的高效和可靠。

但是在生産實踐中,KServe 對于大型語言模型(LLMs)的支援依然有不小的挑戰。主要問題在于:

  1. 模型啟動時間長:大型語言模型(LLMs)的參數規模相當巨大,體積通常很大甚至達到幾百 GB,導緻拉取到 GPU 顯存的耗時巨大,啟動時間非常慢。此外,KServe 通過存儲初始化器(Storage Initializer)從遠端存儲中拉取模型到本地,這也需要很長時間,對根據流量進行 KServe 無伺服器自動擴縮容功能産生不利影響。
  2. 容器鏡像拉取時間長:大型語言模型(LLMs)的運作時環境依賴 GPU 基礎環境,相應的容器鏡像通常很大,這會導緻拉取時間長,拖慢應用啟動速度。
  3. 模型更新效率低、複雜度高:大型語言模型(LLMs)由多個檔案組成,模型更新時隻需部分更新或添加部分檔案,但 KServe 需要重新開機容器和重新拉取模型,無法支援模型的熱更新,這帶來效率低和複雜度高的問題。

KServe 在 Kubecon 2023 就提到了 Fluid 有可能幫助解決其在彈性上遇到的問題。Fluid 是一個開源的 Kubernetes 原生的分布式資料集編排和加速引擎,主要服務于雲原生場景下的資料密集型應用,例如大資料應用、AI 應用等。參見資料加速 Fluid 概述[1]。

【假期 AI 充電】KServe + Fluid 加速大模型推理

阿裡雲容器服務團隊和 KServe,Fluid 社群的小夥伴一起探索在阿裡雲 Serverless Kubernetes 平台上簡單,友善,高性能,生産級别的支援大型語言模型(LLMs):

  1. 服務托管,産品支援:阿裡雲服務網格(簡稱 ASM)對于 KServe 提供了原生支援,要知道 KServe 依賴于底層Istio的穩定性對于 KServe 來說非常重要,使用托管的服務網格後,高可用、免運維、内建安全最佳實踐;使用者可以更專注于大語言模型相關的工作。除此之外 KServe 和 Fluid 也可以一鍵安裝。
  2. 協同社群優化使用模式:在 KServe 最新版支援除了存儲初始化器(Storage Initializer)外,也支援标準的 PVC 模式,通過避免從遠端存儲中拉取模型到本地,減少存儲不足的風險和提升啟動速度;也可以支援模型熱更新。
  3. 通過彈性分布式緩存加速模型加載流程:Fluid 與 KServe 相結合,通過資料預熱到分布式緩存,縮短 Pod 啟動時間 80% 同時支援模型熱更新,無容器重新開機。
  4. 以上能力完全通過運作阿裡雲無伺服器 Kubernetes 容器服務(ASK)上,在業務沒有運作按需彈性、按秒計費,同時基于請求量的 GPU 無伺服器自動擴充,縮放至零。
【假期 AI 充電】KServe + Fluid 加速大模型推理

一切就緒,我們一起開啟阿裡雲 Kubernetes(ACK) 中 KServe 推理大模型之旅:

實踐步驟

Cloud Native

前提條件

  • 已建立 ACK 叢集,叢集的 Kubernetes 版本 ≥1.18,具體操作,請參見建立 Kubernetes 托管版叢集[2]。

本示範使用的 ACK 叢集包含 3 個 ecs.g7.xlarge 規格的 ecs 和 1 個 ecs.g7.2xlarge 規格的 ecs。您可以在建立時選擇添加 3 個 ecs.g7.xlarge 規格的 ecs,待叢集建立完成後建立一個節點池以增加一個 1 個 ecs.g7.2xlarge 規格的 ecs,關于建立節點池的具體操作請參考建立節點池[3]。

  • 已建立 v1.17 及以上版本的 ASM 執行個體,并已将上述 ACK 叢集添加到該執行個體中。具體操作,請參見建立 ASM 執行個體[4]和添加叢集到 ASM 執行個體[5]。
【假期 AI 充電】KServe + Fluid 加速大模型推理

您可以使用上述配置來建立阿裡雲服務網格 ASM 執行個體,其中:

  • 執行個體規格需要選擇企業版(以啟用資料面叢集 KubeAPI 通路 Istio 資源能力)
  • Istio 版本需要選擇 v1.17 及以上
  • 網格的地域、專有網絡需要與建立的 Kubernetes 叢集保持一緻,以保證網絡暢通
  • 可以視需求選擇是否勾選 “使用 EIP 暴露 API Server”,開啟後将為内網 SLB 執行個體建立并綁定一個 EIP,您将可以從公網通路 ASM 執行個體的 API Server,并操作 Istio CR
  • 可觀測性及網格審計部分依賴日志服務和阿裡雲 Prometheus 監控服務,若依賴服務尚未開通,在建立時您可以不勾選
  • 【重要】必須勾選啟用資料面叢集 KubeAPI 通路 Istio 資源。
  • 叢集本地域名需要與您的 Kubernetes 叢集的本地域名保持一緻。
  • ASM 執行個體已經開啟通過資料面叢集 KubeAPI 通路 Istio 資源能力。具體操作,參考:通過資料面叢集 KubeAPI 通路 Istio 資源[6]。
  • 已為叢集添加入口網關。本執行個體使用 ASM 入口網關作為叢集網關,ASM 入口網關名稱為預設的 ingressgateway,開放端口 80 和 443。具體操作,請參見建立入口網關服務[7]。
  • 已在 ACK 或 ASK 叢集中部署 Knative Serving 元件,并開啟 Knative on ASM 功能。具體操作,參考:使用 Knative on ASM 部署 Serveless 應用[8]中的前提及步驟一。

步驟一:開啟 KServe on ASM 功能

  1. 登入 ASM 控制台[9],在左側導航欄,選擇服務網格 > 網格管理。
  2. 在網格管理頁面,單擊目标執行個體名稱,然後在左側導航欄,選擇生态內建中心 > KServe on ASM。
  3. 在 KServe on ASM 頁面,單擊啟用 KServe on ASM。

說明:KServe on ASM 功能依賴 cert-manager 元件的部署與使用。cert-manager 是一個證書生命周期管理系統,支援證書的申請、部署等功能。如果您沒有在叢集中安裝 cert-manager,您需要在 KServe on ASM 頁面開啟 在叢集中自動安裝 CertManager 元件,以自動為您安裝 cert-manager;否則您需要關閉此項,再單擊啟用 KServe on ASM。

步驟二:安裝 ACK-Fluid 并開啟 AI 模型緩存加速

1. 為您的 ACK 或 ASK 叢集部署 ack-fluid 元件,并保證 ack-fluid 元件的版本在 0.9.10 及以上。

說明:如果您的資料面叢集為 ACK 叢集,您需要在 ACK 叢集中安裝雲原生AI套件并部署 ack-fluid 元件。參考:加速線上應用資料通路[10]。

如果您的資料面叢集為 ASK 叢集,您需要在 ASK 叢集中部署 ack-fluid 元件。參考:加速 Job 應用資料通路[11]。

2. 準備AI模型并上傳至 OSS Bucket。

a. 準備訓練好的 AI 模型儲存資料。本文以基于 pytorch 的開源 transformer 大語言模型 bloom 為例,可以在 hugging face 社群中擷取模型資料:

b. 将下載下傳的模型資料檔案上傳至 OSS Bucket,并記錄模型資料檔案的儲存位置。模型資料檔案的儲存位置格式為 oss://{bucket}/{path}。例如,如果您建立了名為 fluid-demo 的 bucket,并在 bucket 中的 models/bloom 目錄中上傳了所有的模型資料檔案,則模型資料檔案的儲存位置為 oss://fluid-demo/models/bloom

說明:您可以通過 OSS 提供的用戶端工具 ossutil 上傳資料。具體操作,請參見安裝 ossutil[12]。

3. 建立部署 Fluid 及 AI 服務的命名空間,并配置 OSS 通路權限。

a. 使用 kubectl 連接配接到資料面 ACK/ASK 叢集。具體操作,參考:通過 kubectl 連接配接 Kubernetes 叢集[13]。

b. 使用 kubectl 建立命名空間,以部署 Fluid 及 KServe AI 服務。本文以 kserve-fluid-demo 命名空間為例。

kubectl create ns kserve-fluid-demo           

c. 使用 kubectl 為命名空間添加 eci 标簽,以将命名空間中的 Pod 排程到虛拟節點上。

kubectl label namespace kserve-fluid-demo alibabacloud.com/eci=true           

d. 使用以下内容,建立 oss-secret.yaml 檔案。其中 fs.oss.accessKeyId 和 fs.oss.accessKeySecret 分别代表可以通路 OSS 的 accessKeyId 和 accessKeySecret。

apiVersion: v1
kind: Secret
metadata:
  name: access-key
stringData:
  fs.oss.accessKeyId: xxx #替換為可以通路OSS的阿裡雲accessKeyId
  fs.oss.accessKeySecret: xxx #替換為可以通路OSSd的阿裡雲accessKeySecret           

e. 執行以下指令,部署 Secret,配置 OSS 通路秘鑰。

kubectl apply -f oss-secret.yaml -n kserve-fluid-demo           

4. 在 Fluid 中聲明待通路的 AI 模型資料。您需要送出一個 Dataset CR 和一個 Runtime CR。其中,Dataset CR 描述資料在外部存儲系統中的 URL 位置,JindoRuntime CR:描述緩存系統及其具體配置。

a. 使用以下内容,儲存為 oss-jindo.yaml 檔案。

apiVersion: data.fluid.io/v1alpha1

kind: Dataset

metadata:

  name: oss-data

spec:

  mounts:

  - mountPoint: "oss://{bucket}/{path}" # 需要替換為模型資料檔案的儲存位置

    name: bloom-560m

    path: /bloom-560m

    options:

      fs.oss.endpoint: "{endpoint}"  # 需要替換為實際的OSS endpoint位址

    encryptOptions:

      - name: fs.oss.accessKeyId

        valueFrom:

          secretKeyRef:

            name: access-key

            key: fs.oss.accessKeyId

      - name: fs.oss.accessKeySecret

        valueFrom:

          secretKeyRef:

            name: access-key

            key: fs.oss.accessKeySecret

  accessModes:

    - ReadOnlyMany

---

apiVersion: data.fluid.io/v1alpha1

kind: JindoRuntime

metadata:

  name: oss-data

spec:

  replicas: 2

  tieredstore:

    levels:

      - mediumtype: SSD

        volumeType: emptyDir

        path: /mnt/ssd0/cache

        quota: 50Gi

        high: "0.95"

        low: "0.7"

  fuse:

    args:

      - -ometrics_port=-1

  master:

    nodeSelector:

      node.kubernetes.io/instance-type: ecs.g7.xlarge

  worker:

    nodeSelector:

      node.kubernetes.io/instance-type: ecs.g7.xlarge           

說明:您需要将 Dataset CR 中的 oss://{bucket}/{path} 替換為上文中記錄的模型資料檔案的儲存位置。将 Dataset CR 中的 {endpoint}替換為 OSS 的通路域名。如何擷取不同地域 OSS 的通路域名,參考:通路域名和資料中心[14]。

a. 執行以下指令,部署 Dataset 和 JindoRuntime CR。

kubectl create -f oss-jindo.yaml -n kserve-fluid-demo           

b. 執行以下指令,檢視 Dataset 和 JindoRuntime 的部署情況。

kubectl get jindoruntime,dataset -n kserve-fluid-demo           

預期輸出:

NAME                                  MASTER PHASE   WORKER PHASE   FUSE PHASE   AGE
jindoruntime.data.fluid.io/oss-data   Ready          Ready          Ready        3m


NAME                             UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
dataset.data.fluid.io/oss-data   3.14GiB          0.00B    100.00GiB        0.0%                Bound   3m           

由預期輸出中得到,Dataset 的 PHASE為Bound,JindoRuntime 的 FUSE PHASE 為 Ready,代表 Dataset 和 JindoRuntime 都部署成功。

5. 在 Fluid 中進行資料預熱,提升資料通路性能。

a. 使用以下内容,儲存為 oss-dataload.yaml。

apiVersion: data.fluid.io/v1alpha1

kind: DataLoad

metadata:

  name: oss-dataload

spec:

  dataset:

    name: oss-data

    namespace: kserve-fluid-demo

  target:

    - path: /bloom-560m

      replicas: 2           

b. 執行以下指令,部署 Dataload 以預熱資料。

kubectl create -f oss-dataload.yaml -n kserve-fluid-demo           

c. 執行以下指令,檢視資料預熱的進度。

kubectl get dataload -n kserve-fluid-demo           

預期輸出:

NAME           DATASET    PHASE      AGE     DURATION
oss-dataload   oss-data   Complete   1m      45s           

由預期輸出得到,資料預熱耗時約 45s。需要等待一段時間才能使得資料預熱完成。

步驟三:部署 AI 模型推理服務

1. 将以下内容儲存為 oss-fluid-isvc.yaml

apiVersion: "serving.kserve.io/v1beta1"

kind: "InferenceService"

metadata:

  name: "fluid-bloom"

spec:

  predictor:

    timeout: 600

    minReplicas: 0

    nodeSelector:

      node.kubernetes.io/instance-type: ecs.g7.2xlarge

    containers:

      - name: kserve-container

        image: cheyang/kserve-fluid:bloom-gpu

        resources:

          limits:

            cpu: "3"

            memory: 8Gi

          requests:

            cpu: "3"

            memory: 8Gi

        env:

          - name: STORAGE_URI

            value: "pvc://oss-data/bloom-560m"

          - name: MODEL_NAME

            value: "bloom"

            # 如果使用GPU則設定成True,否則設定為False

          - name: GPU_ENABLED

            value: "False"           

說明:本例中的 InferenceService 配置中在 image 字段使用了 cheyang/kserve-fluid:bloom-gpu 示例鏡像,該鏡像提供加載模型及推理服務的接口,您可以在 KServe 開源社群中找到此示例鏡像的代碼,并進行鏡像自定義:

2. 執行以下指令,部署 InferenceService AI 模型推理服務。

kubectl create -f oss-fluid-isvc.yaml -n kserve-fluid-demo           

3. 執行以下指令,檢視 AI 模型推理服務的部署狀态。

kubectl get inferenceservice -n kserve-fluid-demo           

預期輸出:

NAME          URL                                                READY   PREV   LATEST   PREVROLLEDOUTREVISION   LATESTREADYREVISION           AGE
fluid-bloom   http://fluid-bloom.kserve-fluid-demo.example.com   True           100                              fluid-bloom-predictor-00001   2d           

由預期輸出可以看到 READY 字段為 True,證明 AI 模型推理服務已經部署成功。

步驟四:通路 AI 模型推理服務

1. 擷取 ASM 入口網關位址

a. 登入 ASM 控制台,在左側導航欄,選擇服務網格 > 網格管理。

b. 在網格管理頁面,單擊目标執行個體名稱,然後在左側導航欄,選擇 ASM 網關 > 入口網關。

c. 在入口網關頁面找到名為 ingressgateway 的 ASM 入口網關,在服務位址區域,檢視并擷取 ASM 網關服務位址。

2. 通路示例 AI 模型推理服務

執行以下指令,通路示例 AI 模型推理服務 bloom,将其中的 ASM 網關服務位址替換為上文中擷取的 ASM 入口網關位址。

curl -v -H "Content-Type: application/json" -H "Host: fluid-bloom.kserve-fluid-demo.example.com" "http://{ASM網關服務位址}:80/v1/models/bloom:predict" -d '{"prompt": "It was a dark and stormy night", "result_length": 50}'           

預期輸出:

*   Trying xxx.xx.xx.xx :80...

* Connected to xxx.xx.xx.xx  (xxx.xx.xx.xx ) port 80 (#0)

> POST /v1/models/bloom:predict HTTP/1.1

> Host: fluid-bloom-predictor.kserve-fluid-demo.example.com

> User-Agent: curl/7.84.0

> Accept: */*

> Content-Type: application/json

> Content-Length: 65

> 

* Mark bundle as not supporting multiuse

< HTTP/1.1 200 OK

< content-length: 227

< content-type: application/json

< date: Thu, 20 Apr 2023 09:49:00 GMT

< server: istio-envoy

< x-envoy-upstream-service-time: 1142

< 

{

  "result": "It was a dark and stormy night, and the wind was blowing in the\ndirection of the west. The wind was blowing in the direction of the\nwest, and the wind was blowing in the direction of the west. The\nwind was"

}

* Connection #0 to host xxx.xx.xx.xx left intact           

從預期輸出中看到,AI 模型推理服務成功對示例輸入進行了續寫并傳回推理結果。

性能基準測試

Cloud Native

我們的性能基準測試将比較 KServe 使用自身存儲初始化器(OSS Storage Initializer)和 Fluid 的推理服務的擴容時間,測試不同規格模型情況下的擴容時間,即衡量服務從 0 擴充到 1 所需的時間。

我們所選的測試機型為:

  • Fluid 機型:ecs.g7.xlarge
  • 推理機型:ecs.g7.2xlarge

使用的 Fluid Runtime 為:

  • JindoFS

其他前提:

  • OSS 的資料桶和 ACK 叢集在同一個區域
  • 資料預熱提前完成
  • ACK 叢集節點上已經緩存了容器鏡像

性能測試指令:

# Total time includes: pod initialization and running + download model (storage initializer) + load model + inference + network

curl --connect-timeout 3600 --max-time 3600 -o /dev/null -s -w 'Total: %{time_total}s\n' -H "Content-Type: application/json" -H "Host: ${SERVICE_HOSTNAME}" "http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/bloom:predict" -d '{"prompt": "It was a dark and stormy night", "result_length": 50}'

# Total time:           
Model Name Model Size (Snapshot) Machine Type KServe + Storage Initializer KServe + Fluid
bigscience/bloom-560m[15] 3.14GB

ecs.g7.2xlarge

(cpu: 8, memory: 32G)

total: 58.031551s(download:33.866s, load: 5.016s)

total: 8.488353s(load: 2.349s)

(2 workers)

bigscience/bloom-7b1[16] 26.35GB

ecs.g7.4xlarge

(cpu: 16, memory: 64G)

total: 329.019987s(download: 228.440s, load: 71.964s)

total: 27.800123s(load: 12.084s)

(3 workers)

Total:無服務情況下的推理響應時間(從 0 開始擴容),包括容器排程,啟動,模型下載下傳,模型加載到顯存,模型推理和網絡延遲時間。

【假期 AI 充電】KServe + Fluid 加速大模型推理

我們可以觀察到 Fluid 在大語言模型(LLM)的場景下,

  1. 大幅提升 KServe 的冷啟動速度,模型越大啟動時間優化越明顯
  2. 不但大幅度節省模型下載下傳到雲盤(Storage Initializer初始化)的時間,另外也可以通過增加緩存 worker 帶寬的方式突破雲盤的帶寬限制(本例子中從雲盤讀取模型到記憶體的耗時也可以節省一半甚至三分之二)

這樣恰恰可以大幅提升 KServe 在容器場景下的彈性擴縮容能力。

總結和展望

Cloud Native

通過現有的雲原生 AI 架構支援大模型這種新物種還需要不斷地改善和優化,但是道阻且長,行則将至。阿裡雲容器服務團隊願意和社群的小夥伴一起探索如何能夠用更低的成本支援更好的 LLM 推理場景,提供标準開放的方案,産品化的能力。我們後續會提供通過計算彈性擴縮容的規律觸發資料緩存的彈性擴縮容來控制成本,以及大模型的熱更新方法。

相關連結:

[1] 資料加速 Fluid 概述

[2] 建立 Kubernetes 托管版叢集

[3] 建立節點池

[4] 建立 ASM 執行個體

[5] 添加叢集到 ASM 執行個體

[6] 通過資料面叢集 KubeAPI 通路 Istio 資源

[7] 建立入口網關服務

[8] 使用 Knative on ASM 部署 Serveless 應用

[9] ASM 控制台

[10] 加速線上應用資料通路

[11] 加速 Job 應用資料通路

[12] 安裝 ossutil

[13] 通過 kubectl 連接配接 Kubernetes 叢集

[14] 通路域名和資料中心

[15] bigscience/bloom-560m

[16] bigscience/bloom-7b1

繼續閱讀