2.12. 使用多个 GPU 节点部署模型
在多个 GPU 节点间部署模型以处理大型模型,如大型语言模型(LLM)。
此流程演示了如何使用 vLLM 服务框架在多个 GPU 节点上提供 Red Hat OpenShift AI 的模型。多节点推断使用 vllm-multinode-runtime
自定义运行时。vllm-multinode-runtime
运行时使用与 VLLM ServingRuntime for KServe 运行时相同的镜像,同时还包括多GPU推断所需的信息。
目前,Red Hat OpenShift AI 作为技术预览功能通过多个 GPU 节点部署模型。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围
先决条件
- 具有集群管理员特权。
- 您已下载并安装 OpenShift 命令行界面 (CLI)。如需更多信息,请参阅安装 OpenShift CLI (Red Hat OpenShift Dedicated)或 安装 OpenShift CLI (Red Hat OpenShift Service on AWS)。
您已为 GPU 类型启用了 Operator,如 Node Feature Discovery Operator、Nvidia GPU Operator。有关启用加速器的更多信息,请参阅启用加速器。
-
您使用 NVIDIA GPU (
nvidia.com/gpu
)。 -
您已通过
ServingRuntime
或InferenceService
指定 GPU 类型。如果ServingRuntime
中指定的 GPU 类型与InferenceService
中设置的不同,则两个 GPU 类型都会分配给资源,并可能导致错误。
-
您使用 NVIDIA GPU (
- 您已在集群中启用了 KServe。
-
您设置中只有一个 head pod。不要在
InferenceService
中使用min_replicas
或max_replicas
设置来调整副本数。创建其他 head pod 可能会导致它们排除在 Ray 集群中。 - 您已为 ReadWriteMany (RWX)访问模式设置并配置了持久性卷声明(PVC)。
流程
在一个终端窗口中,如果您还没有以集群管理员登录到 OpenShift 集群,请登录 OpenShift CLI,如下例所示:
$ oc login <openshift_cluster_url> -u <admin_username> -p <password>
选择或创建用于部署模型的命名空间。例如,您可以运行以下命令来创建
kserve-demo
命名空间:oc new-project kserve-demo
从您要部署模型的命名空间中,为模型存储创建一个 PVC。使用
Filesystem volumeMode
创建存储类。将这个存储类用于 PVC。存储大小必须大于磁盘上模型文件的大小。例如:注意如果您已经配置了 PVC,您可以跳过这一步。
kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: granite-8b-code-base-pvc spec: accessModes: - ReadWriteMany volumeMode: Filesystem resources: requests: storage: <model size> storageClassName: <storage class>
要将模型下载到 PVC,请修改提供的 YAML 示例:
apiVersion: v1 kind: Pod metadata: name: download-granite-8b-code labels: name: download-granite-8b-code spec: volumes: - name: model-volume persistentVolumeClaim: claimName: granite-8b-code-claim restartPolicy: Never initContainers: - name: fix-volume-permissions image: quay.io/quay/busybox@sha256:92f3298bf80a1ba949140d77987f5de081f010337880cd771f7e7fc928f8c74d command: ["sh"] args: ["-c", "mkdir -p /mnt/models/$(MODEL_PATH) && chmod -R 777 /mnt/models"] 1 volumeMounts: - mountPath: "/mnt/models/" name: model-volume env: - name: MODEL_PATH value: <model path> 2 containers: - resources: requests: memory: 40Gi name: download-model imagePullPolicy: IfNotPresent image: quay.io/opendatahub/kserve-storage-initializer:v0.14 3 args: - 's3://$(BUCKET_NAME)/$(MODEL_PATH)/' - /mnt/models/$(MODEL_PATH) env: - name: AWS_ACCESS_KEY_ID value: <id> 4 - name: AWS_SECRET_ACCESS_KEY value: <secret> 5 - name: BUCKET_NAME value: <bucket_name> 6 - name: MODEL_PATH value: <model path> 7 - name: S3_USE_HTTPS value: "1" - name: AWS_ENDPOINT_URL value: <AWS endpoint> 8 - name: awsAnonymousCredential value: 'false' - name: AWS_DEFAULT_REGION value: <region> 9 - name: S3_VERIFY_SSL value: 'true' 10 volumeMounts: - mountPath: "/mnt/models/" name: model-volume
- 1
- 只有在 pod 以 root 用户身份运行时,才允许
chmod
操作。如果您没有以 root 身份运行 pod,请从参数中删除'chmod -R 777'。 - 2 7
- 指定到模型的路径。
- 3
containers.image
的值,位于您的InferenceService
中。要访问这个值,请运行以下命令:oc get configmap inferenceservice-config -n redhat-ods-operator -oyaml | grep kserve-storage-initializer:
- 4
- S3 存储桶的访问密钥 ID。
- 5
- S3 存储桶的 secret 访问密钥。
- 6
- S3 存储桶的名称。
- 8
- S3 存储桶的端点。
- 9
- 如果使用 AWS S3 存储桶,则 S3 存储桶的区域。如果使用其他 S3 兼容存储,如 ODF 或 Minio,您可以删除
AWS_DEFAULT_REGION
环境变量。 - 10
- 如果您遇到 SSL 错误,请将
S3_VERIFY_SSL
更改为false
。
创建
vllm-multinode-runtime
自定义运行时:oc process vllm-multinode-runtime-template -n redhat-ods-applications|oc apply -n kserve-demo -f -
使用以下
InferenceService
配置部署模型:apiVersion: serving.kserve.io/v1beta1 kind: InferenceService metadata: annotations: serving.kserve.io/deploymentMode: RawDeployment serving.kserve.io/autoscalerClass: external name: <inference service name> spec: predictor: model: modelFormat: name: vLLM runtime: vllm-multinode-runtime storageUri: pvc://<pvc name>/<model path> workerSpec: {}
以下配置可以添加到
InferenceService
中:-
workerSpec.tensorParallelSize
:确定每个节点使用多少个 GPU。head 和 worker 节点部署资源中的 GPU 类型计数会自动更新。确保workerSpec.tensorParallelSize
的值至少为1
。 -
workerSpec.pipelineParallelSize
: 确定使用多少个节点来平衡部署中的模型。此变量代表节点总数,包括头和 worker 节点。确保workerSpec.pipelineParallelSize
的值至少为2
。不要在生产环境中修改这个值。
-
根据环境和模型大小,您可能需要指定其他参数。
验证
要确认您已将环境设置为在多个 GPU 节点上部署模型,请检查 GPU 资源状态、InferenceService
状态、ray 集群状态,并将请求发送到模型。
检查 GPU 资源状态:
检索 head 和 worker 节点的 pod 名称:
# Get pod name podName=$(oc get pod -l app=isvc.granite-8b-code-base-pvc-predictor --no-headers|cut -d' ' -f1) workerPodName=$(oc get pod -l app=isvc.granite-8b-code-base-pvc-predictor-worker --no-headers|cut -d' ' -f1) oc wait --for=condition=ready pod/${podName} --timeout=300s # Check the GPU memory size for both the head and worker pods: echo "### HEAD NODE GPU Memory Size" kubectl exec $podName -- nvidia-smi echo "### Worker NODE GPU Memory Size" kubectl exec $workerPodName -- nvidia-smi
响应示例
+-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | 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 NVIDIA A10G On | 00000000:00:1E.0 Off | 0 | | 0% 33C P0 71W / 300W |19031MiB / 23028MiB <1>| 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ ... +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | 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 NVIDIA A10G On | 00000000:00:1E.0 Off | 0 | | 0% 30C P0 69W / 300W |18959MiB / 23028MiB <2>| 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+
通过检查 <1> 和 <2> 的值来确认模型是否已正确加载。如果模型没有加载,则这些字段的值为
0MiB
。
使用以下命令验证
InferenceService
的状态: 注意:在技术预览中,您只能使用端口转发来推断。oc wait --for=condition=ready pod/${podName} -n $DEMO_NAMESPACE --timeout=300s export MODEL_NAME=granite-8b-code-base-pvc
响应示例
NAME URL READY PREV LATEST PREVROLLEDOUTREVISION LATESTREADYREVISION AGE granite-8b-code-base-pvc http://granite-8b-code-base-pvc.default.example.com
向模型发送请求,以确认模型可用于推测:
oc wait --for=condition=ready pod/${podName} -n vllm-multinode --timeout=300s oc port-forward $podName 8080:8080 & curl http://localhost:8080/v1/completions \ -H "Content-Type: application/json" \ -d "{ 'model': "$MODEL_NAME", 'prompt': 'At what temperature does Nitrogen boil?', 'max_tokens': 100, 'temperature': 0 }"