在某些場景下,您可能需要將多個模型推理任務共享在同一塊GPU以提高GPU的利用率。本文以模型類型為Qwen1.5-0.5B-Chat,GPU類型為V100卡為例,演示如何使用KServe部署GPU共享的模型推理服務。
前提條件
已創建托管GPU集群或專有GPU集群,且集群版本需為1.22及以上,并指定CUDA版本為12.0及以上。具體操作,請參見創建GPU集群或創建專有GPU集群。
建議GPU節點使用525版本驅動,您可以通過為GPU節點池添加標簽
ack.aliyun.com/nvidia-driver-version:525.105.17
指定驅動版本為525.105.17。具體操作,請參見通過指定版本號自定義節點GPU驅動版本。已安裝共享GPU組件,并開啟GPU共享調度能力。具體操作,請參見安裝共享GPU調度組件。
已安裝Arena客戶端,且版本不低于0.9.15。具體操作,請參見配置Arena客戶端。
已安裝cert-manager和ack-kserve?組件,且ack-kserve?組件的部署模式為Raw Deployment。具體操作,請參見安裝ack-kserve?。
步驟一:準備模型數據
您可以使用OSS或NAS準備模型數據,具體操作,請參見使用OSS靜態存儲卷、使用NAS靜態存儲卷。本文以OSS為例說明如何準備模型數據。
下載模型。本文以Qwen1.5-0.5B-Chat模型為例。
執行以下命令,安裝Git。
sudo yum install git
執行以下命令,安裝Git LFS(Large File Support)插件。
sudo yum install git-lfs
執行以下命令,將ModelScope上的Qwen1.5-0.5B-Chat倉庫克隆到本地。
GIT_LFS_SKIP_SMUDGE=1 git clone https://www.modelscope.cn/qwen/Qwen1.5-0.5B-Chat.git
執行以下命令,進入Qwen1.5-0.5B-Chat倉庫目錄。
cd Qwen1.5-0.5B-Chat
執行以下命令,在Qwen1.5-0.5B-Chat目錄下,下載LFS管理的大文件。
git lfs pull
將下載的Qwen1.5-0.5B-Chat文件上傳至OSS。
為目標集群配置名為llm-model的存儲卷PV和存儲聲明PVC。具體操作,請參見使用OSS靜態存儲卷。
以下為示例PV的基本配置信息:
配置項
說明
存儲卷類型
OSS
名稱
llm-model
訪問證書
配置用于訪問OSS的AccessKey ID和AccessKey Secret。
Bucket ID
選擇上一步所創建的OSS Bucket。
OSS Path
選擇模型所在的路徑,如/Qwen1.5-0.5B-Chat。
以下為示例PVC的基本配置信息:
配置項
說明
存儲聲明類型
OSS
名稱
llm-model
分配模式
選擇已有存儲卷。
已有存儲卷
單擊選擇已有存儲卷鏈接,選擇已創建的存儲卷PV。
步驟二:部署推理服務
執行以下命令,檢查集群中可用的GPU資源。
arena top node
確保集群中有可用于運行推理服務的GPU節點。
執行以下命令,啟動兩個Qwen推理服務,每個推理服務需使用6 GB顯存。
啟動第一個Qwen推理服務。
arena serve kserve \ --name=qwen1 \ --image=kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm:0.4.1 \ --gpumemory=6 \ --cpu=3 \ --memory=8Gi \ --data="llm-model:/mnt/models/Qwen1.5-0.5B-Chat" \ "python3 -m vllm.entrypoints.openai.api_server --port 8080 --trust-remote-code --served-model-name qwen --model /mnt/models/Qwen1.5-0.5B-Chat --dtype=half --max-model-len=4096"
預期輸出:
inferenceservice.serving.kserve.io/qwen1 created INFO[0003] The Job qwen1 has been submitted successfully INFO[0003] You can run `arena serve get qwen1 --type kserve -n default` to check the job status
輸出結果表明已經成功部署推理服務。
啟動第二個Qwen推理服務。
arena serve kserve \ --name=qwen2 \ --image=kube-ai-registry.cn-shanghai.cr.aliyuncs.com/kube-ai/vllm:0.4.1 \ --gpumemory=6 \ --cpu=3 \ --memory=8Gi \ --data="llm-model:/mnt/models/Qwen1.5-0.5B-Chat" \ "python3 -m vllm.entrypoints.openai.api_server --port 8080 --trust-remote-code --served-model-name qwen --model /mnt/models/Qwen1.5-0.5B-Chat --dtype=half --max-model-len=4096"
預期輸出:
inferenceservice.serving.kserve.io/qwen2 created INFO[0001] The Job qwen2 has been submitted successfully INFO[0001] You can run `arena serve get qwen2 --type kserve -n default` to check the job status
輸出結果表明已經成功部署推理服務。
參數說明如下所示:
參數
是否必選
說明
--name
是
提交的推理服務名稱,全局唯一。
--image
是
推理服務的鏡像地址。
--gpumemory
否
申請顯存的大小。
為了優化資源分配,請確保各個推理服務申請的顯存之和不超過GPU的總顯存量。例如,若某GPU具備8 GB顯存,首次部署的推理服務請求分配3 GB(
--gpumemory=3
),則剩余5 GB顯存可用。接著,若有第二個推理服務同樣考慮運行于該GPU上并申請4 GB顯存(--gpumemory=4
),由于兩者總申請量(3 GB + 4 GB = 7 GB)未超出GPU的8 GB顯存限制,因此這兩個服務能夠共存于同一張GPU卡上,實現了顯存的有效共享。--cpu
否
推理服務需要使用的CPU數。
--memory
否
推理服務需要使用的內存數。
--data
否
推理服務的模型地址,本文指定模型的存儲卷為
llm-model
,掛載到容器的/mnt/models/
目錄下。
步驟三:驗證推理服務
執行以下命令,查看兩個Qwen推理服務部署情況。
kubectl get pod -owide |grep qwen
預期輸出:
qwen1-predictor-856568bdcf-5pfdq 1/1 Running 0 7m10s 10.130.XX.XX cn-beijing.172.16.XX.XX <none> <none> qwen2-predictor-6b477b587d-dpdnj 1/1 Running 0 4m3s 10.130.XX.XX cn-beijing.172.16.XX.XX <none> <none>
預期輸出表明,qwen1和qwen2被成功部署到同一個GPU節點
cn-beijing.172.16.XX.XX
上。分別執行以下兩條命令,進入兩個推理服務所在的Pod中,查看Pod所分配的GPU顯存大小。
kubectl exec -it qwen1-predictor-856568bdcf-5pfdq -- nvidia-smi # 進入第一個推理服務所在的pod。 kubectl exec -it qwen2-predictor-6b477b587d-dpdnj -- nvidia-smi # 進入第二個推理服務所在的pod。
預期輸出:
Fri Jun 28 06:20:43 2024 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.161.07 Driver Version: 535.161.07 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla V100-SXM2-16GB On | 00000000:00:07.0 Off | 0 | | N/A 39C P0 53W / 300W | 5382MiB / 6144MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| +---------------------------------------------------------------------------------------+
Fri Jun 28 06:40:17 2024 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.161.07 Driver Version: 535.161.07 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 Tesla V100-SXM2-16GB On | 00000000:00:07.0 Off | 0 | | N/A 39C P0 53W / 300W | 5382MiB / 6144MiB | 0% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| +---------------------------------------------------------------------------------------+
輸出結果表明,兩個Pod內部顯存上限均為6 GB,由于節點的GPU顯存為16 GB,可以判斷出節點GPU顯存已被成功分配給了這兩個推理服務所在的Pod。
執行以下命令,使用獲取到的Nginx Ingress網關地址訪問推理服務。
# 獲取Nginx ingress的IP地址。 NGINX_INGRESS_IP=$(kubectl -n kube-system get svc nginx-ingress-lb -ojsonpath='{.status.loadBalancer.ingress[0].ip}') # 獲取Inference Service的Hostname。 SERVICE_HOSTNAME=$(kubectl get inferenceservice qwen1 -o jsonpath='{.status.url}' | cut -d "/" -f 3) # 發送請求訪問推理服務。 curl -H "Host: $SERVICE_HOSTNAME" -H "Content-Type: application/json" http://$NGINX_INGRESS_IP:80/v1/chat/completions -d '{"model": "qwen", "messages": [{"role": "user", "content": "測試一下"}], "max_tokens": 10, "temperature": 0.7, "top_p": 0.9, "seed": 10}'
預期輸出:
{"id":"cmpl-bbca59499ab244e1aabfe2c354bf6ad5","object":"chat.completion","created":1719303373,"model":"qwen","choices":[{"index":0,"message":{"role":"assistant","content":"好的,請問您需要測試什么內容呢?"},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":21,"total_tokens":31,"completion_tokens":10}}
輸出結果表明模型可以根據給定的輸入(在這個例子中是一條測試消息)生成相應的回復。
(可選)步驟四:清理環境
如果不再使用已創建的資源,請及時清理。
執行以下命令,刪除已部署的模型推理服務。
arena serve delete qwen1 arena serve delete qwen2
執行以下命令,刪除已創建的PV和PVC。
kubectl delete pvc llm-model kubectl delete pv llm-model