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

流程

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

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

    oc new-project kserve-demo
  3. 从您要部署模型的命名空间中,为模型存储创建一个 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>
  4. 要将模型下载到 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
  5. 创建 vllm-multinode-runtime 自定义运行时:

    oc process vllm-multinode-runtime-template -n redhat-ods-applications|oc apply -n kserve-demo -f -
  6. 使用以下 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
            }"
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

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

让开源更具包容性

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

關於紅帽

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

© 2024 Red Hat, Inc.