2.12. 여러 GPU 노드를 사용하여 모델 배포


대용량 언어 모델(LLM)과 같은 대규모 모델을 처리하기 위해 여러 GPU 노드에 모델을 배포합니다.

vLLM 서비스 프레임워크를 사용하여 여러 GPU 노드에서 Red Hat OpenShift AI 모델을 제공할 수 있습니다. 멀티 노드 유추는 KServe 런타임에 vLLM NVIDIA GPU ServingRuntime과 동일한 이미지를 사용하는 v llm-multinode-runtime 사용자 지정 런타임을 사용하며 다중 GPU 유추에 필요한 정보도 포함합니다.

PVC(영구 볼륨 클레임) 또는 OCI(Open Container Initiative) 컨테이너 이미지에서 모델을 배포할 수 있습니다.

중요

여러 GPU 노드를 사용하여 모델을 배포하는 것은 현재 Red Hat OpenShift AI에서 기술 프리뷰 기능으로만 사용할 수 있습니다. 기술 프리뷰 기능은 Red Hat 프로덕션 서비스 수준 계약(SLA)에서 지원되지 않으며 기능적으로 완전하지 않을 수 있습니다. Red Hat은 프로덕션 환경에서 사용하는 것을 권장하지 않습니다. 이러한 기능을 사용하면 향후 제품 기능을 조기에 이용할 수 있어 개발 과정에서 고객이 기능을 테스트하고 피드백을 제공할 수 있습니다.

Red Hat 기술 프리뷰 기능의 지원 범위에 대한 자세한 내용은 기술 프리뷰 기능 지원범위를 참조하십시오.

사전 요구 사항

  • OpenShift 클러스터에 대한 클러스터 관리자 권한이 있습니다.
  • OpenShift CLI(명령줄 인터페이스)를 다운로드하여 설치했습니다. 자세한 내용은 OpenShift CLI 설치(Red Hat OpenShift Dedicated) 또는 OpenShift CLI 설치 (AWS에 Red Hat OpenShift Service)를 참조하십시오.
  • Node Feature Discovery Operator, NVIDIA GPU Operator와 같은 GPU 유형에 대해 Operator를 활성화했습니다. 가속기 활성화에 대한 자세한 내용은 가속기 활성화를 참조하십시오.

    • NVIDIA GPU (nvidia.com/gpu)를 사용하고 있습니다.
    • ServingRuntime 또는 InferenceService 를 통해 GPU 유형을 지정했습니다. ServingRuntime 에 지정된 GPU 유형이 InferenceService 에 설정된 것과 다른 경우 두 GPU 유형이 모두 리소스에 할당되어 오류가 발생할 수 있습니다.
  • 클러스터에서 KServe를 활성화했습니다.
  • 설정에 하나의 헤드 Pod만 있습니다. InferenceServicemin_replicas 또는 max_replicas 설정을 사용하여 복제본 수를 조정하지 마십시오. 추가 헤드 Pod를 생성하면 Cryostat 클러스터에서 제외될 수 있습니다.
  • PVC에서 배포하려면: RWX(ReadWriteMany) 액세스 모드로 설정 및 구성된 PVC(영구 볼륨 클레임)가 있어야 합니다.
  • OCI 컨테이너 이미지에서 배포하려면 다음을 수행합니다.

    • OCI 컨테이너 이미지에 모델을 저장했습니다.
    • 모델이 개인 OCI 리포지토리에 저장된 경우 이미지 가져오기 보안을 구성했습니다.

프로세스

  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
      chmod 작업은 Pod가 root로 실행되는 경우에만 허용됩니다. Pod를 root로 실행하지 않는 경우 인수에서 'chmod -R 777'을 제거합니다.
      2 7
      모델의 경로를 지정합니다.
      3
      InferenceService 에 있는 containers.image 의 값입니다. 이 값에 액세스하려면 oc get configmap inferenceservice-config -n redhat-ods-operator -oyaml | grep kserve-storage-initializer명령을 실행합니다.
      4
      S3 버킷에 대한 액세스 키 ID입니다.
      5
      S3 버킷에 대한 시크릿 액세스 키입니다.
      6
      S3 버킷의 이름입니다.
      8
      S3 버킷의 끝점입니다.
      9
      AWS S3 버킷을 사용하는 경우 S3 버킷의 리전입니다. ODF 또는 Minio와 같은 다른 S3 호환 스토리지를 사용하는 경우 AWS_DEFAULT_REGION 환경 변수를 제거할 수 있습니다.
      10
      SSL 오류가 발생하면 S3_VERIFY_SSLfalse 로 변경합니다.
  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
    배포 방법에 따라 모델의 경로를 지정합니다.
    • For PVC: pvc://<pvc_name>/<model_path>
    • OCI 컨테이너 이미지의 경우:oci://<registry_host>/<org_or_username>/<repository_name><tag_or_digest>
    2
    다음 구성을 InferenceService 에 추가할 수 있습니다.
    • workerSpec.tensorParallelSize: 노드당 사용되는 GPU 수를 결정합니다. 헤드 및 작업자 노드 배포 리소스의 GPU 유형 수가 자동으로 업데이트됩니다. workerSpec.tensorParallelSize 의 값이 1 이상이어야 합니다.
    • workerSpec.pipelineParallelSize: 배포의 모델의 균형을 조정하는 데 사용되는 노드 수를 결정합니다. 이 변수는 헤드 및 작업자 노드를 모두 포함하여 총 노드 수를 나타냅니다. workerSpec.pipelineParallelSize 의 값이 2 이상이어야 합니다. 프로덕션 환경에서는 이 값을 변경하지 마십시오.

      참고

      환경 및 모델 크기에 따라 추가 인수를 지정해야 할 수도 있습니다.

  6. InferenceService 구성을 적용하여 모델을 배포합니다.

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

검증

여러 GPU 노드에 모델을 배포하도록 환경을 설정하려면 GPU 리소스 상태, InferenceService 상태, Cryostat 클러스터 상태를 확인하고 모델에 요청을 보냅니다.

  • GPU 리소스 상태를 확인합니다.

    • 헤드 및 작업자 노드의 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

  • 모델을 유추할 수 있는지 확인하려면 요청을 보냅니다.Send a request to the model to confirm that the model is available for inference:

    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

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다. 최신 업데이트를 확인하세요.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

Theme

© 2025 Red Hat