3.13. 여러 GPU 노드를 사용하여 모델 배포
대용량 언어 모델(LLM)과 같은 대규모 모델을 처리하기 위해 여러 GPU 노드에 모델을 배포합니다.
다음 절차에서는 vLLM 서비스 프레임워크를 사용하여 여러 GPU 노드에서 Red Hat OpenShift AI 모델을 제공하는 방법을 보여줍니다. 다중 노드 유추는 vllm-multinode-runtime
사용자 지정 런타임을 사용합니다. vllm-multinode-runtime
런타임에서는 KServe 런타임의 VLLM ServingRuntime과 동일한 이미지를 사용하며 다중 GPU 유추에 필요한 정보도 포함합니다.
여러 GPU 노드를 사용하여 모델을 배포하는 것은 현재 Red Hat OpenShift AI에서 기술 프리뷰 기능으로만 사용할 수 있습니다. 기술 프리뷰 기능은 Red Hat 프로덕션 서비스 수준 계약(SLA)에서 지원되지 않으며 기능적으로 완전하지 않을 수 있습니다. Red Hat은 프로덕션 환경에서 사용하는 것을 권장하지 않습니다. 이러한 기능을 사용하면 향후 제품 기능을 조기에 이용할 수 있어 개발 과정에서 고객이 기능을 테스트하고 피드백을 제공할 수 있습니다.
Red Hat 기술 프리뷰 기능의 지원 범위에 대한 자세한 내용은 기술 프리뷰 기능 지원범위를 참조하십시오.
사전 요구 사항
- OpenShift 클러스터에 대한 클러스터 관리자 권한이 있습니다.
- OpenShift CLI(명령줄 인터페이스)를 다운로드하여 설치했습니다. OpenShift CLI 설치를 참조하십시오.
Node Feature Discovery Operator, NVIDIA GPU Operator와 같은 GPU 유형에 대해 Operator를 활성화했습니다. 가속기 활성화에 대한 자세한 내용은 가속기 활성화를 참조하십시오.
-
NVIDIA GPU (
nvidia.com/gpu
)를 사용하고 있습니다. -
ServingRuntime
또는InferenceService
를 통해 GPU 유형을 지정했습니다.ServingRuntime
에 지정된 GPU 유형이InferenceService
에 설정된 것과 다른 경우 두 GPU 유형이 모두 리소스에 할당되어 오류가 발생할 수 있습니다.
-
NVIDIA GPU (
- 클러스터에서 KServe를 활성화했습니다.
-
설정에 하나의 헤드 Pod만 있습니다.
InferenceService
의min_replicas
또는max_replicas
설정을 사용하여 복제본 수를 조정하지 마십시오. 추가 헤드 Pod를 생성하면 Cryostat 클러스터에서 제외될 수 있습니다. - RWX(ReadWriteMany) 액세스 모드로 설정 및 구성된 PVC(영구 볼륨 클레임)가 있습니다.
프로세스
터미널 창에서 클러스터 관리자로 OpenShift 클러스터에 로그인하지 않은 경우 다음 예와 같이 OpenShift CLI에 로그인합니다.
$ oc login <openshift_cluster_url> -u <admin_username> -p <password>
모델 배포를 위한 네임스페이스를 선택하거나 만듭니다. 예를 들어 다음 명령을 실행하여
kserve-demo
네임스페이스를 생성할 수 있습니다.oc new-project kserve-demo
대상 네임스페이스에서 모델 스토리지를 위한 PVC를 생성하고 스토리지 클래스의 이름을 지정합니다. 스토리지 클래스는 파일 스토리지여야 합니다.
참고PVC를 이미 구성한 경우 이 단계를 건너뛸 수 있습니다.
kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: granite-8b-code-base-pvc spec: accessModes: - ReadWriteMany volumeMode: Filesystem resources: requests: storage: 50Gi storageClassName: __<fileStorageClassName>__
모델을 PVC에 다운로드합니다. 예를 들면 다음과 같습니다.
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:xxxxx command: ["sh"] args: ["-c", "mkdir -p /mnt/models/granite-8b-code-base && chmod -R 777 /mnt/models"] volumeMounts: - mountPath: "/mnt/models/" name: model-volume containers: - resources: requests: memory: 40Gi name: download-model imagePullPolicy: IfNotPresent image: quay.io/modh/kserve-storage-initializer@sha256:xxxxx args: - 's3://$<bucket_name>/granite-8b-code-base/' - /mnt/models/granite-8b-code-base env: - name: AWS_ACCESS_KEY_ID value: <id> - name: AWS_SECRET_ACCESS_KEY value: <secret> - name: BUCKET_NAME value: <bucket_name> - name: S3_USE_HTTPS value: "1" - name: AWS_ENDPOINT_URL value: <AWS endpoint> - name: awsAnonymousCredential value: 'false' - name: AWS_DEFAULT_REGION value: <region> volumeMounts: - mountPath: "/mnt/models/" name: model-volume
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: granite-8b-code-base-pvc spec: predictor: model: modelFormat: name: vLLM runtime: vllm-multinode-runtime storageUri: pvc://granite-8b-code-base-pvc/granite-8b-code-base workerSpec: {}
다음 구성을
InferenceService
에 추가할 수 있습니다.-
workerSpec.tensorParallelSize
: 노드당 사용되는 GPU 수를 결정합니다. 헤드 및 작업자 노드 배포 리소스의 GPU 유형 수가 자동으로 업데이트됩니다.workerSpec.tensorParallelSize
의 값이1
이상이어야 합니다. -
workerSpec.pipelineParallelSize
: 배포에 관련된 노드 수를 결정합니다. 이 변수는 헤드 및 작업자 노드를 모두 포함하여 총 노드 수를 나타냅니다.workerSpec.pipelineParallelSize
의 값이2
이상이어야 합니다.
-
검증
여러 GPU 노드에 모델을 배포하도록 환경을 설정하려면 GPU 리소스 상태, InferenceService
상태, ray 클러스터 상태를 확인하고 모델에 요청을 보냅니다.
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
샘플 응답
+-----------------------------------------------------------------------------------------+ | 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
모델을 유추할 수 있는지 확인하려면 요청을 보냅니다.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 }"