2.12. 使用多个 GPU 节点部署模型


在多个 GPU 节点间部署模型以处理大型模型,如大型语言模型(LLM)。

您可以使用 vLLM 服务框架在多个 GPU 节点上提供 Red Hat OpenShift AI 的模型。多节点 inferencing 使用 vllm-multinode-runtime 自定义运行时,它使用与 vLLM NVIDIA GPU ServingRuntime for KServe 运行时相同的镜像,还包括多 GPU 推断所需的信息。

您可以从持久性卷声明(PVC)或开放容器项目(OCI)容器镜像部署模型。

重要

目前,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)。
    • 您已通过 ServingRuntimeInferenceService 指定 GPU 类型。如果 ServingRuntime 中指定的 GPU 类型与 InferenceService 中设置的不同,则两个 GPU 类型都会分配给资源,并可能导致错误。
  • 您已在集群中启用了 KServe。
  • 您设置中只有一个 head pod。不要在 InferenceService 中使用 min_replicasmax_replicas 设置来调整副本数。创建其他 head pod 可能会导致它们排除在 Ray 集群中。
  • 要从 PVC 部署 :您为 ReadWriteMany (RWX)访问模式设置并配置了持久性卷声明(PVC)。
  • 从 OCI 容器镜像部署

    • 您已在 OCI 容器镜像中存储了一个模型。
    • 如果模型存储在私有 OCI 存储库中,则代表您配置了镜像 pull secret。

流程

  1. 在一个终端窗口中,如果您还没有以集群管理员登录到 OpenShift 集群,请登录 OpenShift CLI,如下例所示:

    $ oc login <openshift_cluster_url> -u <admin_username> -p <password>
    Copy to Clipboard Toggle word wrap
  2. 选择或创建用于部署模型的命名空间。例如,运行以下命令来创建 kserve-demo 命名空间:

    oc new-project kserve-demo
    Copy to Clipboard Toggle word wrap
  3. (仅从 PVC 部署模型) 在要部署模型的命名空间中为模型存储创建一个 PVC。使用 Filesystem volumeMode 创建存储类,并将这个存储类用于 PVC。存储大小必须大于磁盘上模型文件的大小。例如:

    注意

    如果您已经配置了 PVC 或从 OCI 容器镜像部署模型,您可以跳过此步骤。

    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>
    Copy to Clipboard Toggle word wrap
    1. 创建 pod,将模型下载到您创建的 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-base-pvc
        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
      Copy to Clipboard Toggle word wrap
      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
  4. 在项目命名空间中创建 vllm-multinode-runtime 自定义运行时:

    oc process vllm-multinode-runtime-template -n redhat-ods-applications|oc apply -n kserve-demo -f -
    Copy to Clipboard Toggle word wrap
  5. 使用以下 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: <storage_uri_path> 
    1
    
        workerSpec: {} 
    2
    Copy to Clipboard Toggle word wrap
    1
    根据您的部署方法指定模型的路径:
    • 对于 PVC:pvc://<pvc_name>/<model_path>
    • 对于 OCI 容器镜像oci://<registry_host>/<org_or_username>/<repository_name><tag_or_digest>
    2
    以下配置可以添加到 InferenceService 中:
    • workerSpec.tensorParallelSize :确定每个节点使用多少个 GPU。head 和 worker 节点部署资源中的 GPU 类型计数会自动更新。确保 workerSpec.tensorParallelSize 的值至少为 1
    • workerSpec.pipelineParallelSize: 确定使用多少个节点来平衡部署中的模型。此变量代表节点总数,包括头和 worker 节点。确保 workerSpec.pipelineParallelSize 的值至少为 2。不要在生产环境中修改这个值。

      注意

      根据环境和模型大小,您可能需要指定其他参数。

  6. 通过应用 InferenceService 配置来部署模型:

    oc apply -f <inference-service-file.yaml>
    Copy to Clipboard Toggle word wrap

验证

要确认您已将环境设置为在多个 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
      Copy to Clipboard Toggle word wrap

      响应示例

      +-----------------------------------------------------------------------------------------+
      | 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 |
      +-----------------------------------------+------------------------+----------------------+
      Copy to Clipboard Toggle word wrap

      通过检查 <1> 和 <2> 的值来确认模型是否已正确加载。如果模型没有加载,则这些字段的值为 0MiB

  • 使用以下命令验证 InferenceService 的状态: 注意:在技术预览中,您只能使用端口转发来推断。

    oc wait --for=condition=ready pod/${podName} -n $DEMO_NAMESPACE --timeout=300s
    export MODEL_NAME=granite-8b-code-base-pvc
    Copy to Clipboard Toggle word wrap

    响应示例

       NAME                 URL                                                   READY   PREV   LATEST   PREVROLLEDOUTREVISION   LATESTREADYREVISION                          AGE
       granite-8b-code-base-pvc   http://granite-8b-code-base-pvc.default.example.com
    Copy to Clipboard Toggle word wrap

  • 向模型发送请求,以确认模型可用于推测:

    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
            }"
    Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat