• <xmp id="om0om">
  • <table id="om0om"><noscript id="om0om"></noscript></table>
  • Uncategorized

    使用 NVIDIA NIM 在阿里云容器服務(ACK)中加速 LLM 推理

    大語言模型(LLM)是近年來發展迅猛并且激動人心的熱點話題,引入了許多新場景,滿足了各行各業的需求。隨著開源模型能力的不斷增強,越來越多的企業開始嘗試在生產環境中部署開源模型,將AI模型接入到現有的基礎設施,優化系統延遲和吞吐量,完善監控和安全等方面。然而要在生產環境中部署這一套模型推理服務過程復雜且耗時。為了簡化流程,幫助企業客戶加速部署生成式 AI 模型,本文結合 NVIDIA NIM (一套專為安全、可靠地部署高性能 AI 模型推理而設計的微服務,是一套易于使用的預構建容器化工具)和阿里云容器服務 ACK 等產品,提供了一套開箱即用,可以快速構建一個高性能、可觀測、靈活彈性的 LLM 模型推理服務的操作指南。

    阿里云容器服務 (ACK) 云原生 AI 套件

    阿里云容器服務 Kubernetes 版 ACK(Container Service for Kubernetes)是全球首批通過Kubernetes一致性認證的服務平臺,提供高性能的容器應用管理服務,支持企業級 Kubernetes 容器化應用的生命周期管理,讓您輕松高效地在云端運行 Kubernetes 容器化應用。

    云原生 AI 套件是阿里云容器服務 ACK 提供的云原生 AI 技術和產品方案。使用云原生 AI 套件,您可以充分利用云原生架構和技術,在 Kubernetes 容器平臺上快速定制化構建 AI 生產系統,并為 AI/ML 應用和系統提供全棧優化。云原生 AI 套件支持使用 Kubeflow 社區開源的命令行工具 Arena,對深度學習核心生產環節(包括數據管理、模型訓練、模型評估、推理服務部署等)任務進行簡單抽象和高效管理,同時降低 Kubernetes 復雜概念帶來的使用復雜度。Arena可以實現分布式訓練任務的快速提交,并進行任務的生命周期管理。此外,云原生 AI 套件還提供針對分布式場景優化的調度策略,例如 Binpack 算法分配策略,提升 GPU 利用率,還支持自定義的任務優先級管理和租戶彈性資源配額控制,在確保用戶資源分配的基礎上,通過資源共享的方式來提升集群的整體資源利用率。

    方案介紹

    本文將介紹如何在阿里云 ACK 集群上,使用云原生 AI 套件集成開源推理服務框架 KServe,快速部署 NVIDIA NIM。同時,結合阿里云的 Prometheus 和 Grafana 服務,快速搭建監控大盤,實時觀測推理服務狀態。利用 NVIDIA NIM 提供豐富的監控指標,如num_requests_waiting,配置推理服務彈性擴縮容策略。當有突發流量導致推理服務處理請求排隊時,能自動擴容新的實例來應對高峰流量。整體解決方案架構如下所示。

    NVIDIA NIM on ACK

    本文將介紹在 ACK 集群上部署 NVIDIA NIM 的步驟,總體步驟如下:

    1. 創建 ACK 集群并安裝云原生 AI 套件,ack-kserve 等組件。
    2. 使用 Arena 提交 KServe 推理服務,使用 NIVDIA NIM 容器,部署 Llama3-8B 模型。
    3. 為推理服務配置監控,實時觀測推理服務狀態。
    4. 基于排隊中請求數指標配置彈性擴縮容策略,自動靈活地調整模型服務實例的規模。

    部署流程

    首先需要創建包含 GPU 的 Kubernetes 集群,并部署云原生 AI 套件。為了在集群中使用 KServe 管理推理服務,還需要安裝 ack-kserve?。集群環境準備好后,就可以參考下列步驟開始部署服務了。

    重要

    • 您應自覺遵守第三方模型的用戶協議、使用規范和相關法律法規,并就使用第三方模型的合法性、合規性自行承擔相關責任。
    1. 參考NVIDIA NIM 文檔,生成 NVIDIA NGC API key,訪問需要部署的模型鏡像,比如本文中使用的 Llama3-8b-instruct。請閱讀并承諾遵守 Llama 模型的自定義可商用開源協議
    2. 創建imagePullSecret,用于從 NGC 私有倉庫拉取 NIM 鏡像。
    export NGC_API_KEY=<your-ngc-api-key>
    kubectl create secret docker-registry ngc-secret \
    ?--docker-server=nvcr.io\
    ?--docker-username='$oauthtoken'\
    ?--docker-password=${NGC_API_KEY}
    kubectl apply -f-<<EOF
    apiVersion: v1
    kind: Secret
    metadata:
    ? name: nvidia-nim-secrets
    stringData:
    ? NGC_API_KEY: <your-ngc-api-key>
    EOF
    
    • 為目標集群配置存儲卷 PV 和存儲聲明 PVC,后續模型文件將會下載到創建的共享存儲中。具體操作,請參見使用 NAS 靜態存儲卷
    • 以下為示例 PV 的配置信息:
    配置項說明
    存儲卷類型NAS
    名稱nim-model
    訪問模式ReadWriteMany
    掛載點域名您可以通過選擇掛載點或者自定義的方式定義集群在 NAS 文件系統中掛載點的掛載地址。關于如何查看掛載點地址,請參見查看掛載點地址
    掛載路徑指定模型所在的路徑,如 /nim-model
    • 以下為示例 PVC 的配置信息:
    配置項說明
    存儲聲明類型NAS
    名稱nim-model
    分配模式選擇已有存儲卷。
    已有存儲卷單擊選擇已有存儲卷鏈接,選擇已創建的存儲卷 PV。
    • 執行下列命令,部署一個 KServe 推理服務,使用 NVIDIA NIM 提供的鏡像,指定使用一個 NVIDIA GPU,將 PVC 掛載到容器內的 /mnt/models 目錄用于保存模型文件,配置 autoscalerClass=external 指定使用自定義 HPA 策略,同時還開啟 Prometheus 采集推理服務監控指標,用于后續在 Grafana 中搭建監控大盤。等待容器啟動后,即可使用 Llama3-8b-instruct 模型提供推理服務。
    arena serve kserve \
    ??? --name=llama3-8b-instruct \
    ??? --image=nvcr.io/nim/meta/llama3-8b-instruct:1.0.0 \
    ??? --image-pull-secret=ngc-secret \
    ??? --gpus=1 \
    ??? --cpu=8 \
    ??? --memory=32Gi \
    ??? --share-memory=32Gi \
    ??? --port=8000 \
    ??? --security-context runAsUser=0 \
    ??? --annotation=serving.kserve.io/autoscalerClass=external \
    ??? --env NIM_CACHE_PATH=/mnt/models \
    ??? --env-from-secret NGC_API_KEY=nvidia-nim-secrets \
    ??? --enable-prometheus=true \
    ??? --metrics-port=8000 \
    ??? --data=nim-model:/mnt/models

    預期輸出:

    INFO[0004] The Job llama3-8b-instruct has been submitted successfully
    INFO[0004] You can run `arena serve get llama3-8b-instruct --type kserve -n default` to check the job status
    

    輸出結果表明推理服務已部署成功。

    • 推理部署完成后,可通過執行以下命令,查看 KServe 推理服務的部署情況。
    arena serve get llama3-8b-instruct
    

    預期輸出:

    Name:?????? llama3-8b-instruct
    Namespace:? default
    Type:?????? KServe
    Version:??? 1
    Desired:??? 1
    Available:? 1
    Age:??????? 24m
    Address:??? http://llama3-8b-instruct-default.example.com
    Port:?????? :80
    GPU:??????? 1
    
    Instances:
    ? NAME?????????????????????????????????????????? STATUS?? AGE? READY? RESTARTS? GPU? NODE
    ? ----?????????????????????????????????????????? ------?? ---? -----? --------? ---? ----
    ? llama3-8b-instruct-predictor-545445b4bc-97qc5? Running? 24m? 1/1??? 0???????? 1??? ap-southeast-1.172.16.xx.xxx
    

    輸出結果表明,KServe 推理服務部署成功,模型訪問地址為http://llama3-8b-instruct-default.example.com

    • 接下來就可以訪問推理服務了,可通過使用獲取到的 Nginx Ingress 網關地址訪問推理服務。
    # Obtain the IP address of the Nginx ingress.
    NGINX_INGRESS_IP=$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}')
    # Obtain the Hostname of the Inference Service.
    SERVICE_HOSTNAME=$(kubectl get inferenceservice llama3-8b-instruct -o jsonpath='{.status.url}' | cut -d "/" -f 3)
    # Send a request to access the inference service.
    curl -H "Host: $SERVICE_HOSTNAME" -H "Content-Type: application/json" http://$NGINX_INGRESS_IP:80/v1/chat/completions -d '{"model": "meta/llama3-8b-instruct", "messages": [{"role": "user", "content": "Once upon a time"}], "max_tokens": 64, "temperature": 0.7, "top_p": 0.9, "seed": 10}'

    預期輸出:

    {"id":"cmpl-70af7fa8c5ba4fe7b903835e326325ce","object":"chat.completion","created":1721557865,"model":"meta/llama3-8b-instruct","choices":[{"index":0,"message":{"role":"assistant","content":"It sounds like you're about to tell a story! I'd love to hear it. Please go ahead and continue with \"Once upon a time...\""},"logprobs":null,"finish_reason":"stop","stop_reason":128009}],"usage":{"prompt_tokens":14,"total_tokens":45,"completion_tokens":31}}

    輸出結果表明,已經能夠通過 Nginx Ingress 網關地址訪問推理服務,并成功返回推理結果。

    監控

    NVIDIA NIM 提供了豐富的 Prometheus 監控指標,比如首 token 時延、當前正在運行的請求數、請求 token 數、生成 token 數等指標。結合阿里云 Prometheus 和 Grafana 服務,可以快速在 Grafana 中搭建監控大盤,實時觀測推理服務狀態。

    1. 已開啟阿里云 Prometheus 監控組件。具體操作,請參見開啟阿里云 Prometheus 監控
    2. 創建grafana 工作區,登錄 Grafana 的 Dashboards 頁面。
    3. 導入NVIDIA NIM 提供的 dashboard 樣例
    • 成功導入后,dashboard 示例如下

     

    彈性伸縮

    在部署與管理 KServe 模型服務過程中,需應對模型推理服務面臨的高度動態負載波動。KServe 通過集成 Kubernetes 原生的 HPA(Horizontal Pod Autoscaler)技術及擴縮容控制器,實現了根據 CPU 利用率、內存占用情況、GPU 利用率以及自定義性能指標,自動靈活地調整模型服務 Pod 的規模,以確保服務效能與穩定性。

    基于排隊請求數配置自定義指標的彈性擴縮容策略

    自定義指標的擴縮容依賴 ACK 提供的 ack-alibaba-cloud-metrics-adapter 組件與 Kubernetes HPA 機制實現。詳細信息,請參見基于阿里云 Prometheus 指標的容器水平伸縮

    以下示例演示如何基于 NVIDIA NIM 提供的 num_requests_waiting 指標配置擴縮容策略。

    1. 已部署阿里云 Prometheus 和 ack-alibaba-cloud-metrics-adapter,請參見基于阿里云 Prometheus 指標的容器水平伸縮
    • 在Helm 列表的操作列,單擊 ack-alibaba-cloud-metrics-adapter 對應的更新。在 custom字段下添加如下 rules。
    - seriesQuery: num_requests_waiting{namespace!="",pod!=""}
    ? resources:
    ??? overrides:
    ????? namespace: {resource: "namespace"}
    ????? pod: {resource: "pod"}
    ? metricsQuery: sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)
    • 通過Custom Metrics 進行容器伸縮,示例配置了當等待中的請求數超過 10 則進行擴容。
      • 使用以下內容,創建 hpa.yaml 文件。
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
    ? name: llama3-8b-instruct-hpa
    ? namespace: default
    spec:
    ? # The minReplicas and maxReplicas for the HPA.
    ? minReplicas: 1
    ? maxReplicas: 3
    ? # An array of monitoring metrics that supports the coexistence of multiple types of metrics.
    ? metrics:
    ? - pods:
    ????? metric:
    ??????? name: num_requests_waiting
    ????? target:
    ??????? averageValue: 10
    ??????? type: AverageValue
    ??? type: Pods
    ? # The scaling target description for the HPA, which dynamically adjusts the number of Pods for the target object.
    ? scaleTargetRef:
    ??? apiVersion: apps/v1
    ??? kind: Deployment
    ??? name: llama3-8b-instruct-predictor
    • 執行以下命令,創建HPA應用。
    kubectl apply -f hpa.yaml
    • 執行以下命令,創建 HPA 應用。
    kubectl? get hpa llama3-8b-instruct-hpa

    預期輸出:

    NAME???????????????????? REFERENCE???????????????????????????????? TARGETS?? MINPODS?? MAXPODS?? REPLICAS?? AGE
    llama3-8b-instruct-hpa?? Deployment/llama3-8b-instruct-predictor?? 0/10????? 1???????? 3???????? 1????????? 34s

    • 執行以下命令,對服務進行壓測。

    說明 Hey 壓測工具的詳細介紹,請參見 Hey

    hey -z 5m -c 400 -m POST -host $SERVICE_HOSTNAME -H "Content-Type: application/json" -d '{"model": "meta/llama3-8b-instruct", "messages": [{"role": "user", "content": "Once upon a time"}], "max_tokens": 64}' http://$NGINX_INGRESS_IP:80/v1/chat/completions

    • 在壓測期間,重新打開一個終端,執行以下命令查看服務的擴縮容情況。
    kubectl describe hpa llama3-8b-instruct-hpa
    

    預期輸出包含如下內容:

    Events:
    ? Type??? Reason???????????? Age?? From?????????????????????? Message
    ? —-??? ——???????????? —-? —-?????????????????????? ——-
    ? Normal? SuccessfulRescale? 52s?? horizontal-pod-autoscaler? New size: 3; reason: pods metric num_requests_waiting above target

    預期輸出表明在壓測期間 Pod 數會擴容到 2,而當壓測結束后,經過一段時間(約為 5 分鐘),Pod 縮容到 1。即可以實現自定義指標的擴縮容。

    總結

    本文通過在阿里云容器服務 ACK 上部署 NVIDIA NIM,結合阿里云 Prometheus 和 Grafana 服務,快速在 Grafana 中搭建監控大盤,實時觀測推理服務狀態。為應對模型推理服務面臨的動態負載波動,基于排隊中的請求數配置自定義指標的彈性擴縮容策略,使模型推理服務實例根據等待中的請求數動態擴縮容。通過以上方式,可以快速構建一個高性能、可觀測、極致彈性的模型推理服務。

    +6

    標簽

    人人超碰97caoporen国产