このチュートリアルでは、効率的でスケーラブルな推論を行うために、GKE で複数の GPU を使用して大規模言語モデル(LLM)をデプロイしてサービングする方法について説明します。複数の L4 GPU を使用する GKE クラスタを作成し、次のいずれかのモデルを処理するインフラストラクチャを準備します。
必要な GPU の数はモデルのデータ形式によって異なります。このチュートリアルでは、各モデルで 2 つの L4 GPU を使用します。詳細については、GPU の量の計算をご覧ください。
このチュートリアルは、LLM の提供に Kubernetes コンテナ オーケストレーション機能を使用する ML エンジニア、プラットフォーム管理者、オペレーター、データおよび AI スペシャリストを対象としています。 Google Cloudのコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。
このページを読む前に、次のことをよく理解しておいてください。
目標
このチュートリアルの内容は次のとおりです。
- クラスタとノードプールを作成する。
- ワークロードを準備する。
- ワークロードをデプロイする。
- LLM インターフェースを操作する。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
モデルによっては追加の要件があります。次の要件を満たしていることを確認してください。
- Hugging Face からモデルにアクセスするには、HuggingFace トークンを使用します。
- Mixtral 8x7b モデルの場合 - Mistral Mixtral モデルの条件に同意します。
- Llama 3 70b モデルの場合 - Meta Llama モデルの有効なライセンスがあることを確認します。
環境を準備する
Google Cloud コンソールで、Cloud Shell インスタンスを起動します。
Cloud Shell を開くデフォルトの環境変数を設定します。
gcloud config set project PROJECT_ID gcloud config set billing/quota_project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export CONTROL_PLANE_LOCATION=us-central1PROJECT_ID は、実際の Google Cloudプロジェクト ID に置き換えます。
GKE クラスタとノードプールを作成する
GKE Autopilot クラスタまたは GKE Standard クラスタの GPU で LLM を提供できます。フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。
Autopilot
Cloud Shell で、次のコマンドを実行します。
gcloud container clusters create-auto l4-demo \ --project=${PROJECT_ID} \ --location=${CONTROL_PLANE_LOCATION} \ --release-channel=rapidGKE は、デプロイされたワークロードからのリクエストに応じた CPU ノードと GPU ノードを持つ Autopilot クラスタを作成します。
クラスタと通信を行うように
kubectlを構成します。gcloud container clusters get-credentials l4-demo --location=${CONTROL_PLANE_LOCATION}
Standard
Cloud Shell で次のコマンドを実行して、GKE 用 Workload Identity 連携を使用する Standard クラスタを作成します。
gcloud container clusters create l4-demo \ --location ${CONTROL_PLANE_LOCATION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=${CONTROL_PLANE_LOCATION}-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type n2d-standard-4 \ --num-nodes 1 --min-nodes 1 --max-nodes 5 \ --release-channel=rapidクラスタの作成には数分かかることもあります。
次のコマンドを実行して、クラスタのノードプールを作成します。
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --location ${CONTROL_PLANE_LOCATION} \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --machine-type g2-standard-24 \ --enable-autoscaling --enable-image-streaming \ --num-nodes=0 --min-nodes=0 --max-nodes=3 \ --node-locations ${CONTROL_PLANE_LOCATION}-a,${CONTROL_PLANE_LOCATION}-c \ --spotGKE は、LLM 用に次のリソースを作成します。
- パブリック Standard クラスタ。
- 0 ノードにスケールダウンされた
g2-standard-24マシンタイプのノードプール。GPU をリクエストする Pod を起動するまで、GPU の料金は発生しません。このノードプールは Spot VM をプロビジョニングします。Spot VM はデフォルトの標準の Compute Engine VM よりも低価格ですが、可用性は保証されません。オンデマンド VM を使用するには、このコマンドから--spotフラグとtext-generation-inference.yaml構成のcloud.google.com/gke-spotノードセレクタを削除します。
クラスタと通信を行うように
kubectlを構成します。gcloud container clusters get-credentials l4-demo --location=${CONTROL_PLANE_LOCATION}
ワークロードを準備する
このセクションでは、使用するモデルに応じてワークロードを設定する方法について説明します。このチュートリアルでは、Kubernetes Deployment を使用してモデルをデプロイします。Deployment は、クラスタ内のノードに分散された Pod の複数のレプリカを実行できる Kubernetes API オブジェクトです。
Llama 3 70b
デフォルトの環境変数を設定します。
export HF_TOKEN=HUGGING_FACE_TOKENHUGGING_FACE_TOKENは、HuggingFace トークンに置き換えます。HuggingFace トークンの Kubernetes Secret を作成します。
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -次の
text-generation-inference.yamlDeployment マニフェストを作成します。このマニフェストの内容:
- このモデルには 2 つの NVIDIA L4 GPU が必要なため、
NUM_SHARDは2にする必要があります。 QUANTIZEがbitsandbytes-nf4に設定されているため、モデルは 32 ビットではなく 4 ビットで読み込まれます。これにより、GKE は必要な GPU メモリの量を減らし、推論速度を向上させることができます。ただし、モデルの精度は低下する可能性があります。リクエストする GPU を計算する方法については、GPU の量の計算をご覧ください。
- このモデルには 2 つの NVIDIA L4 GPU が必要なため、
次のようにマニフェストを適用します。
kubectl apply -f text-generation-inference.yaml出力は次のようになります。
deployment.apps/llm createdモデルのステータスを確認します。
kubectl get deploy出力は次のようになります。
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m実行中のデプロイのログを表示します。
kubectl logs -l app=llm出力は次のようになります。
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Mixtral 8x7b
デフォルトの環境変数を設定します。
export HF_TOKEN=HUGGING_FACE_TOKENHUGGING_FACE_TOKENは、HuggingFace トークンに置き換えます。HuggingFace トークンの Kubernetes Secret を作成します。
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -次の
text-generation-inference.yamlDeployment マニフェストを作成します。このマニフェストの内容:
- このモデルには 2 つの NVIDIA L4 GPU が必要なため、
NUM_SHARDは2にする必要があります。 QUANTIZEがbitsandbytes-nf4に設定されているため、モデルは 32 ビットではなく 4 ビットで読み込まれます。これにより、GKE は必要な GPU メモリの量を減らし、推論速度を向上させることができます。ただし、これによりモデルの精度が低下する可能性があります。リクエストする GPU を計算する方法については、GPU の量の計算をご覧ください。
- このモデルには 2 つの NVIDIA L4 GPU が必要なため、
次のようにマニフェストを適用します。
kubectl apply -f text-generation-inference.yaml出力は次のようになります。
deployment.apps/llm createdモデルのステータスを確認します。
watch kubectl get deployデプロイの準備ができている場合、出力は次のようになります。
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m監視を終了するには、「
CTRL + C」と入力します。実行中のデプロイのログを表示します。
kubectl logs -l app=llm出力は次のようになります。
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Falcon 40b
次の
text-generation-inference.yamlDeployment マニフェストを作成します。このマニフェストの内容:
- このモデルには 2 つの NVIDIA L4 GPU が必要なため、
NUM_SHARDは2にする必要があります。 QUANTIZEがbitsandbytes-nf4に設定されているため、モデルは 32 ビットではなく 4 ビットで読み込まれます。これにより、GKE は必要な GPU メモリの量を減らし、推論速度を向上させることができます。ただし、モデルの精度は低下する可能性があります。リクエストする GPU を計算する方法については、GPU の量の計算をご覧ください。
- このモデルには 2 つの NVIDIA L4 GPU が必要なため、
次のようにマニフェストを適用します。
kubectl apply -f text-generation-inference.yaml出力は次のようになります。
deployment.apps/llm createdモデルのステータスを確認します。
watch kubectl get deployデプロイの準備ができている場合、出力は次のようになります。
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m監視を終了するには、「
CTRL + C」と入力します。実行中のデプロイのログを表示します。
kubectl logs -l app=llm出力は次のようになります。
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
ClusterIP タイプの Service を作成する
Pod をクラスタ内で公開し、他のアプリケーションから検出およびアクセスできるようにします。
次の
llm-service.yamlマニフェストを作成します。apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080次のようにマニフェストを適用します。
kubectl apply -f llm-service.yaml
チャット インターフェースをデプロイする
Gradio を使用して、モデルを操作できるウェブ アプリケーションを作成します。Gradio は、chatbot のユーザー インターフェースを作成する ChatInterface ラッパーを含む Python ライブラリです。
Llama 3 70b
gradio.yamlという名前のファイルを作成します。次のようにマニフェストを適用します。
kubectl apply -f gradio.yamlService の外部 IP アドレスを探します。
kubectl get svc出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125mEXTERNAL-IP列の外部 IP アドレスをコピーします。外部 IP アドレスと公開ポートを指定して、ウェブブラウザでモデル インターフェースを表示します。
http://EXTERNAL_IP
Mixtral 8x7b
gradio.yamlという名前のファイルを作成します。次のようにマニフェストを適用します。
kubectl apply -f gradio.yamlService の外部 IP アドレスを探します。
kubectl get svc出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125mEXTERNAL-IP列の外部 IP アドレスをコピーします。外部 IP アドレスと公開ポートを指定して、ウェブブラウザでモデル インターフェースを表示します。
http://EXTERNAL_IP
Falcon 40b
gradio.yamlという名前のファイルを作成します。次のようにマニフェストを適用します。
kubectl apply -f gradio.yamlService の外部 IP アドレスを探します。
kubectl get svc出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125mEXTERNAL-IP列の外部 IP アドレスをコピーします。外部 IP アドレスと公開ポートを指定して、ウェブブラウザでモデル インターフェースを表示します。
http://EXTERNAL_IP
GPU の量を計算する
GPU の数は、QUANTIZE フラグの値によって異なります。このチュートリアルでは、QUANTIZE は bitsandbytes-nf4 に設定されています。これは、モデルが 4 ビットで読み込まれることを意味します。
700 億のパラメータ モデルでは、最低 40 GB の GPU メモリが必要です。これは 700 億 × 4 ビット(700 億 x 4 ビット = 35 GB)に相当し、5 GB のオーバーヘッドを考慮します。この場合、1 つの L4 GPU ではメモリが不足します。したがって、このチュートリアルの例では、2 つの L4 GPU メモリ(2 × 24 = 48 GB)を使用します。この構成は、L4 GPU で Falcon 40b または Llama 3 70b を実行するのに十分です。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
クラスタの削除
このガイドで作成したリソースが Google Cloud アカウントに課金されないようにするために、GKE クラスタを削除します。
gcloud container clusters delete l4-demo --location ${CONTROL_PLANE_LOCATION}