ノート:
- このチュートリアルでは、Oracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントに例の値を使用します。演習を終える際は、これらの値をクラウド環境に固有の値に置き換えてください。
OCI Object Storageに格納されたモデル・リポジトリとの推論のためにOKEにNVIDIA NIMをデプロイ
イントロダクション
このチュートリアルでは、NVIDIA TensorRT-LLMバックエンドおよびNVIDIA Triton推論サーバーを使用してOracle Cloud Infrastructure Container Engine for Kubernetes (OKE)にNVIDIA NIMをデプロイし、Kubernetesアーキテクチャで大規模言語モデル(LLM)を提供する方法を示します。使用されるモデルは、GPU A10のLlama2-7B-chat
です。スケーラビリティのために、OCI Object Storageのバケットでモデル・リポジトリをホストしています。
ノート:このチュートリアルのすべてのテストは、
nemollm-inference-ms:24.02.rc4
を使用したLLMのNVIDIA NIMの早期アクセス・バージョンでリリースされています。
目的
- LLM推論サーバーのスケーラブルな配備を実現します。
前提条件
-
Oracle Cloud Infrastructure (OCI)テナントへのアクセス。
-
A10 GPU (
VM.GPU.A10.1
など)などのNVIDIA GPUを使用したシェイプへのアクセス。制限を引き上げるリクエストの詳細は、サービス制限を参照してください。 -
インスタンスがインスタンス・プリンシパルを介して認証する機能。詳細は、インスタンスからのサービスのコールを参照してください。
-
NVIDIA NIMコンテナをプルするためのNVIDIA AI Enterpriseへのアクセス。詳細については、NVIDIA AI Enterpriseを参照してください。
-
llama2-7B-chat
をダウンロードするように構成されたアクセス・トークンを持つHuggingFaceアカウント。 -
KubernetesとHelmの基本的な用語の知識。
タスク1: OCI ComputeでのGPUインスタンスの作成
-
OCIコンソールにログインし、「OCIメニュー」、「コンピュート」、「インスタンス」の順に移動し、「インスタンスの作成」をクリックします。
-
Oracle Cloud MarketplaceイメージのNVIDIA GPU Cloudマシン・イメージおよびブート・ボリュームが250GBの
VM.GPU.A10.1
を選択します。詳細は、Oracle Cloud InfrastructureでのNVIDIA GPU Cloudの使用を参照してください。 -
マシンが起動したら、秘密キーとマシン・パブリックIPを使用してマシンに接続します。
ssh -i <private_key> ubuntu@<public_ip>
-
ブート・ボリュームの領域が増加していることを確認します。
df -h # check the initial space on disk sudo growpart /dev/sda 1 sudo resize2fs /dev/sda1 df -h # check the space after the commands execution
タスク2: NVIDIAドライバの更新(オプション)
ドライバとCUDAバージョン間の互換性マトリックスを使用して、NVIDIAが提供するガイダンスに基づいて、ドライバを最新バージョンに更新することをお薦めします。詳細は、CUDA CompatibilityおよびCUDA Toolkit 12.4 Update 1 Downloadsを参照してください。
sudo apt purge nvidia* libnvidia*
sudo apt-get install -y cuda-drivers-545
sudo apt-get install -y nvidia-kernel-open-545
sudo apt-get -y install cuda-toolkit-12-3
sudo reboot
nvidia-container-toolkit
があることを確認します。
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
新しいバージョンを確認するには、次のコマンドを実行します。
nvidia-smi
/usr/local/cuda/bin/nvcc --version
タスク3: モデル・レジストリの準備
事前構築済モデルを使用できます。ただし、A10 GPUでLlama2-7B-chat
を実行することを選択します。記述時には、この選択肢を使用できないため、モデル・リポジトリを自分で構築する必要があります。
-
OCIオブジェクト・ストレージに
NIM
という名前のバケットを作成します。詳細は、オブジェクト・ストレージ・バケットの作成を参照してください。 -
ターミナル・ウィンドウに移動し、ユーザー名とパスワードを使用してNVIDIAコンテナ・レジストリにログインし、コンテナをプルします。次のコマンドを実行します
docker login nvcr.io docker pull nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4
-
HuggingFaceモデルをクローニングします。
# Install git-lfs curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs # clone the model from HF git clone https://huggingface.co/meta-llama/Llama-2-7b-chat-hf
-
モデル構成を作成します。
model_config.yaml
ファイルをコピーし、モデルストアをホストするディレクトリを作成します。ここでは、モデル・リポジトリ・ジェネレータ・コマンドが出力を格納します。mkdir model-store chmod -R 777 model-store
-
モデル・リポジトリ・ジェネレータ・コマンドを実行します。
docker run --rm -it --gpus all -v $(pwd)/model-store:/model-store -v $(pwd)/model_config.yaml:/model_config.yaml -v $(pwd)/Llama-2-7b-chat-hf:/engine_dir nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4 bash -c "model_repo_generator llm --verbose --yaml_config_file=/model_config.yaml"
-
モデル・リポジトリをOCIオブジェクト・ストレージ・バケットにエクスポートします。
モデル・リポジトリは、ディレクトリ
model-store
にあります。Oracle Cloud Infrastructureコマンドライン・インタフェース(OCI CLI)を使用して、リージョン内のいずれかのバケットへの一括アップロードを実行できます。このチュートリアルでは、バケットはNIM
で、モデル・ストアをNIM/llama2-7b-hf
にアップロードします(異なるモデル構成を同じバケットにアップロードする場合)。cd model-store oci os object bulk-upload -bn NIM --src-dir . --prefix llama2-7b-hf/ --auth instance_principal
タスク4: 仮想マシンへのリクエストの送信(IaaS実行)
これで、モデル・リポジトリが1つのOCI Object Storageバケットにアップロードされました。
ノート:オプション・パラメータ
--model-repository
は現在コンテナでハードコードされており、起動時にバケットを指すことはできません。1つのオプションは、コンテナ内のPythonスクリプトを適応させることですが、sudo権限が必要です。もう1つは、バケットをファイル・システムとしてマシンに直接マウントすることです。このチュートリアルでは、rcloneで2番目の方法を選択します。fuse3
およびjq
がマシンにインストールされていることを確認します。Ubuntuでは、sudo apt install fuse3 jq
を実行できます。
-
OCIコンソールからフェッチするか、コンピュート・インスタンスから次のコマンドを実行して、ネームスペース、コンパートメントOCIDおよびリージョンを取得します。
#NAMESPACE: echo namespace is : `oci os ns get --auth instance_principal | jq .data` #COMPARTMENT_OCID: echo compartment ocid is: `curl -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/instance/ | jq .compartmentId` #REGION: echo region is: `curl -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/instance/ | jq .region`
-
rcloneをダウンロードしてインストールします。
curl https://rclone.org/install.sh | sudo bash
-
rclone構成ファイルを準備します。必ず、
##NAMESPACE##
##COMPARTMENT_OCID##
##REGION##
を値で更新してください。mkdir -p ~/rclone mkdir -p ~/test_directory/model_bucket_oci cat << EOF > ~/rclone/rclone.conf [model_bucket_oci] type = oracleobjectstorage provider = instance_principal_auth namespace = ##NAMESPACE## compartment = ##COMPARTMENT_OCID## region = ##REGION## EOF
-
rcloneを使用してバケットをマウントします。
sudo /usr/bin/rclone mount --config=$HOME/rclone/rclone.conf --tpslimit 50 --vfs-cache-mode writes --allow-non-empty --transfers 10 --allow-other model_bucket_oci:NIM/llama2-7b-hf $HOME/test_directory/model_bucket_oci
-
別のターミナル・ウィンドウで、
ls $HOME/test_directory/model_bucket_oci
がバケットの内容を返すことを確認できます。 -
別のターミナル・ウィンドウで、
model-store
へのパスを引数として渡すコンテナを起動します。docker run --gpus all -p9999:9999 -p9998:9998 -v $HOME/test_directory/model_bucket_oci:/model-store nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4 nemollm_inference_ms --model llama2-7b-chat --openai_port="9999" --nemo_port="9998" --num_gpus 1
-
3分後、推論サーバーは動作する準備ができているはずです。別の端末ウィンドウで、次のリクエストを実行できます。
ノート:ローカル・マシンから実行する場合は、パブリックIPを使用し、マシン・レベルとサブネット・レベルの両方でポート
9999
を開く必要があります。curl -X "POST" 'http://localhost:9999/v1/completions' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "model": "llama2-7b-chat", "prompt": "Can you briefly describe Oracle Cloud?", "max_tokens": 100, "temperature": 0.7, "n": 1, "stream": false, "stop": "string", "frequency_penalty": 0.0 }' | jq ".choices[0].text"
タスク5: cloud-init
スクリプトの更新
ノート:理想的には、Kubernetesでrcloneを使用するより簡単な方法は、推論サーバーを起動する前にrclone containerをサイドカーとして使用することです。これはDockerを使用してローカルで正常に動作しますが、
FUSE
を使用するには--device
オプションが必要なため、この機能のサポートが不足しているため、Kubernetesでの使用が複雑になります(2024年3月現在、2015年からの機能リクエストであるFUSEボリューム)。このチュートリアルでは、ホストにrcloneをサービスとして設定し、起動時にバケットをマウントします。
cloud-initスクリプトで、##NAMESPACE##
、##COMPARTMENT_OCID##
および##REGION##
行17、18および19の値を、タスク4.1で取得した値に置き換えます。57行目でバケットの値を更新することもできます。デフォルトでは、NIM
と呼ばれ、llama2-7b-hf
というディレクトリがあります。
このcloud-init
スクリプトは、OKEクラスタのGPUノードにアップロードされます。1つ目の部分は、ブート・ボリュームを値セットに増やすことです。次に、rcloneをダウンロードし、正しいディレクトリを作成し、GPU VMで実行したのと同じ方法で構成ファイルを作成します。最後に、rcloneをサービスとして起動し、バケットを/opt/mnt/model_bucket_oci
にマウントします。
タスク6: OKEへのデプロイ
デプロイメントの最後にあるターゲット・アーキテクチャは、次の図のようになります。
全てをOKEにまとめます。
わずかな適応でOKEクラスタを作成します。詳細は、コンソールを使用した、クイック作成ワークフローでのデフォルト設定でのクラスタの作成を参照してください。
-
まず、デフォルト・イメージで1ノードのみ(つまり、5 OCPUおよび80GB RAMの
VM.Standard.E4.Flex
)での監視に使用されるmonitoring
という1ノード・プールを作成します。 -
クラスタが起動したら、GPUドライバ(
Oracle-Linux-8.X-Gen2-GPU-XXXX.XX.XX
など)でデフォルトのイメージを使用して、NIM
という1つのGPUノード(VM.GPU.A10.1
)を持つ別のノード・プールを作成します。ノート:ブート・ボリューム(350GB)を増やし、以前に変更したcloud-initスクリプトを「拡張オプションの表示」および「初期化スクリプト」に追加してください。
タスク7: OCI Cloud ShellでのHelmを使用したデプロイ
OCIクラウド・シェルにアクセスするには、コンソールを使用してクラウド・シェルにアクセスするにはを参照してください。
-
Helm構成は、
values.yaml
を更新する必要があるアーカイブoke.zip
にあります。アーカイブをOCI Cloud Shellにアップロードし、解凍します。詳細は、メニューを使用したクラウド・シェルへのファイルのアップロードを参照してください。unzip oke.zip cd oke
-
values.yaml
でイメージをプルするシークレットの資格証明を確認します。詳細は、「イメージ・プル・シークレットの作成」を参照してください。registry: nvcr.io username: $oauthtoken password: <YOUR_KEY_FROM_NVIDIA> email: someone@host.com
タスク8: モニタリングのデプロイ
監視は、GrafanaとPrometheusポッドで構成されます。構成は、kube-prometheus-stackから取得されます。
ここでは、インターネットからGrafanaダッシュボードにアクセスするためのパブリック・ロード・バランサを追加します。username=admin
およびpassword=xxxxxxxxx
を使用してログインします。Prometheusがデプロイされたサンプル・リリースで推論サーバー・メトリックを検索できるようにするには、serviceMonitorSelectorNilUsesHelmValues
フラグが必要です。
-
モニタリング・ポッドをデプロイします。
helm install example-metrics --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set grafana.service.type=LoadBalancer prometheus-community/kube-prometheus-stack --debug
ノート:固定シェイプおよび帯域幅100Mbpsで作成されたデフォルトのロード・バランサ。帯域幅がボトルネックになっている場合は、柔軟なシェイプに切り替え、OCIの制限に従って帯域幅を適応させることができます。詳細は、タイプLoadBalancerのKubernetesサービスのOCIロード・バランサのプロビジョニングを参照してください。
-
Grafanaダッシュボードの例は、
oke.zip
にあるdashboard-review.json
にあります。Grafanaのインポート機能を使用して、このダッシュボードをインポートおよび表示します。 -
次のコマンドを実行すると、GrafanaダッシュボードのパブリックIPを確認できます。
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 2m33s example-metrics-grafana LoadBalancer 10.96.82.33 141.145.220.114 80:31005/TCP 2m38s
タスク9: 推論サーバーのデプロイ
-
次のコマンドを実行して、デフォルト構成を使用して推論サーバーをデプロイします。
cd <directory containing Chart.yaml> helm install example . -f values.yaml --debug
-
kubectl
を使用してステータスを確認し、推論サーバー・ポッドが実行されるまで待機します。最初のプルには数分かかる場合があります。コンテナが作成されると、モデルのロードにも数分かかります。次のコマンドを使用して、ポッドを監視できます。kubectl describe pods <POD_NAME> kubectl logs <POD_NAME>
-
設定が完了したら、コンテナが実行されている必要があります。
$ kubectl get pods NAME READY STATUS RESTARTS AGE example-triton-inference-server-5f74b55885-n6lt7 1/1 Running 0 2m21s
タスク10: NVIDIA NIMコンテナでのTriton Inference Serverの使用
推論サーバーが実行中です。推論を実行するために、HTTPまたはGoogleリモート・プロシージャ・コール(gRPC)リクエストを送信できます。デフォルトでは、推論サービスはLoadBalancerサービス・タイプで公開されます。推論サーバーの外部IPを検索するには、次を使用します。このチュートリアルでは、34.83.9.133
です。
-
推論サーバーのパブリックIPを取得するサービスを取得します。
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ... example-triton-inference-server LoadBalancer 10.18.13.28 34.83.9.133 8000:30249/TCP,8001:30068/TCP,8002:32723/TCP 47m
-
推論サーバーは、ポート
8000
のHTTPエンドポイント、ポート8001
のgRPCエンドポイント、およびポート8002
のPrometheusメトリック・エンドポイントを公開します。curlを使用して、HTTPエンドポイントから推論サーバーのメタデータを取得できます。$ curl 34.83.9.133:8000/v2
-
クライアント・マシンから、ポート
9999
のパブリックIPにリクエストを送信できます。curl -X "POST" 'http://34.83.9.133:9999/v1/completions' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "model": "llama2-7b-chat", "prompt": "Can you briefly describe Oracle Cloud?", "max_tokens": 100, "temperature": 0.7, "n": 1, "stream": false, "stop": "string", "frequency_penalty": 0.0 }' | jq ".choices[0].text"
出力は次のようになります:
"\n\nOracle Cloud is a comprehensive cloud computing platform offered by Oracle Corporation. It provides a wide range of cloud services, including Infrastructure as a Service (IaaS), Platform as a Service (PaaS), and Software as a Service (SaaS). Oracle Cloud offers a variety of benefits, including:\n\n1. Scalability: Oracle Cloud allows customers to scale their resources up or down as needed, providing the flexibility to handle changes in business demand."
タスク11: デプロイメントのクリーン・アップ
-
推論サーバーの使用が終了したら、helmを使用してデプロイメントを削除する必要があります。
$ helm list NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE example 1 Wed Feb 27 22:16:55 2019 DEPLOYED triton-inference-server-1.0.0 1.0 default example-metrics 1 Tue Jan 21 12:24:07 2020 DEPLOYED prometheus-operator-6.18.0 0.32.0 default $ helm uninstall example --debug $ helm uninstall example-metrics
-
PrometheusおよびGrafanaサービスの場合、CRDを明示的に削除する必要があります。詳細は、「Helmチャートのアンインストール」を参照してください。
$ kubectl delete crd alertmanagerconfigs.monitoring.coreos.com alertmanagers.monitoring.coreos.com podmonitors.monitoring.coreos.com probes.monitoring.coreos.com prometheuses.monitoring.coreos.com prometheusrules.monitoring.coreos.com servicemonitors.monitoring.coreos.com thanosrulers.monitoring.coreos.com
-
モデル・リポジトリを保持するために作成されたOCIオブジェクト・ストレージ・バケットを削除することもできます。
$ oci os bucket delete --bucket-name NIM --empty
関連リンク
承認
- 著者 - Bruno Garbaccio(AIインフラ/GPUスペシャリスト、EMEA)
その他の学習リソース
docs.oracle.com/learnの他のラボをご覧いただくか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスして、Oracle Learning Explorerになります。
製品ドキュメントは、Oracle Help Centerを参照してください。
Deploy NVIDIA NIM on OKE for Inference with the Model Repository Stored on OCI Object Storage
F96575-01
April 2024