3.12. 複数の GPU ノードを使用したモデルのデプロイ
大規模言語モデル (LLM) などの大規模モデルを処理するために、複数の GPU ノードにわたってモデルをデプロイします。
この手順では、vLLM サービングフレームワークを使用して、複数の GPU ノードにわたって Red Hat OpenShift AI 上でモデルを提供する方法を説明します。マルチノード推論では、vllm-multinode-runtime
カスタムランタイムを使用します。vllm-multinode-runtime
ランタイムは、VLLM ServingRuntime for KServe と同じイメージを使用し、マルチ 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 が 1 つだけある。
InferenceService
のmin_replicas
またはmax_replicas
設定を使用してレプリカ数を調整しないでください。追加のヘッド Pod を作成すると、それらが Ray クラスターから除外される可能性があります。 - 永続ボリューム要求 (PVC) が設定済みで、ReadWriteMany (RWX) アクセスモード用に設定されている。
手順
ターミナルウィンドウで、クラスター管理者として OpenShift クラスターにまだログインしていない場合は、次の例に示すように OpenShift CLI にログインします。
$ oc login <openshift_cluster_url> -u <admin_username> -p <password>
モデルをデプロイするための namespace を選択または作成します。たとえば、次のコマンドを実行して、
kserve-demo
namespace を作成できます。oc new-project kserve-demo
ターゲット namespace で、モデルストレージ用の 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
モデルが推論に使用できることを確認するために、モデルにリクエストを送信します。
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 }"