このガイドでは、Google Kubernetes Engine(GKE)で Ray と Ray Operator アドオンを使用して大規模言語モデル(LLM)を提供する方法について説明します。
このガイドでは、次のモデルを提供できます。
このガイドでは、Ray Serve フレームワークでサポートされているモデルの多重化やモデルの構成などのモデル サービング手法についても説明します。
背景
Ray フレームワークは、ML ワークロードのトレーニング、微調整、推論を行うエンドツーエンドの AI / ML プラットフォームを提供します。Ray Serve は、Hugging Face の一般的な LLM を提供するために使用できる Ray のフレームワークです。
GPU の数はモデルのデータ形式によって異なります。このガイドでは、モデルで 1 つまたは 2 つの L4 GPU を使用できます。
このガイドでは、次の手順を説明します。
- Ray Operator アドオンを有効にして、Autopilot または Standard GKE クラスタを作成します。
- Hugging Face から大規模言語モデル(LLM)をダウンロードして提供する RayService リソースをデプロイします。
- LLM でチャット インターフェースとダイアログをデプロイします。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
- Hugging Face アカウントを作成します(まだ作成していない場合)。
- Hugging Face トークンがあることを確認します。
- 使用する Hugging Face モデルにアクセスできることを確認します。通常、これは契約に署名し、Hugging Face モデルページでモデル所有者にアクセスをリクエストすることで付与されます。
us-central1
リージョンに GPU 割り当てがあることを確認します。詳細については、GPU 割り当てをご覧ください。
環境を準備する
Google Cloud コンソールで、Cloud Shell インスタンスを起動します。
Cloud Shell を開くサンプル リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/llm export TUTORIAL_HOME=`pwd`
デフォルトの環境変数を設定します。
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export COMPUTE_REGION=us-central1 export CLUSTER_VERSION=CLUSTER_VERSION export HF_TOKEN=HUGGING_FACE_TOKEN
次のように置き換えます。
PROJECT_ID
: Google Cloud プロジェクト ID。CLUSTER_VERSION
: 使用する GKE のバージョン。1.30.1
以降にする必要があります。HUGGING_FACE_TOKEN
: Hugging Face アクセス トークン。
クラスタと GPU ノードプールを作成する
Ray Operator アドオンを使用して、GKE Autopilot クラスタまたは Standard クラスタで Ray を使用して L4 GPU で LLM を提供できます。一般的に、フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。高い拡張性を必要とするユースケースや、クラスタ構成をより詳細に制御する必要がある場合は、Standard クラスタを選択します。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。
Cloud Shell を使用して、Autopilot クラスタまたは Standard クラスタを作成します。
Autopilot
Ray Operator アドオンを有効にして Autopilot クラスタを作成します。
gcloud container clusters create-auto rayserve-cluster \
--enable-ray-operator \
--cluster-version=${CLUSTER_VERSION} \
--location=${COMPUTE_REGION}
Standard
Ray Operator アドオンを有効にして Standard クラスタを作成します。
gcloud container clusters create rayserve-cluster \
--addons=RayOperator \
--cluster-version=${CLUSTER_VERSION} \
--machine-type=g2-standard-24 \
--location=${COMPUTE_ZONE} \
--num-nodes=2 \
--accelerator type=nvidia-l4,count=2,gpu-driver-version=latest
Hugging Face の認証情報用の Kubernetes Secret を作成する
Cloud Shell で、次の手順で Kubernetes Secret を作成します。
クラスタと通信を行うように
kubectl
を構成します。gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${COMPUTE_REGION}
Hugging Face トークンを含む Kubernetes Secret を作成します。
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
LLM モデルをデプロイする
クローンを作成した GitHub リポジトリには、RayService 構成を含むモデルごとにディレクトリがあります。各モデルの構成には、次のコンポーネントが含まれます。
- Ray Serve デプロイ: リソース構成とランタイム依存関係を含む Ray Serve デプロイ。
- モデル: Hugging Face モデル ID。
Ray クラスタ: 基盤となる Ray クラスタと、各コンポーネントに必要なリソース(ヘッド Pod とワーカー Pod を含む)。
Gemma 2B IT
モデルをデプロイします。
kubectl apply -f gemma-2b-it/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice gemma-2b-it -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Service を作成したことを確認します。
kubectl get service gemma-2b-it-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gemma-2b-it-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Gemma 7B IT
モデルをデプロイします。
kubectl apply -f gemma-7b-it/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice gemma-7b-it -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Service を作成したことを確認します。
kubectl get service gemma-7b-it-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gemma-7b-it-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Llama 2 7B
モデルをデプロイします。
kubectl apply -f llama-2-7b/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice llama-2-7b -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Service を作成したことを確認します。
kubectl get service llama-2-7b-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE llama-2-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Llama 3 8B
モデルをデプロイします。
kubectl apply -f llama-3-8b/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice llama-3-8b -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Service を作成したことを確認します。
kubectl get service llama-3-8b-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE llama-3-8b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Mistral 7B
モデルをデプロイします。
kubectl apply -f mistral-7b/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice mistral-7b -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Service を作成したことを確認します。
kubectl get service mistral-7b-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mistral-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
モデルをサービングする
Llama2 7B モデルと Llama3 8B モデルは OpenAI API チャット仕様を使用します。他のモデルは、プロンプトに基づいてテキストを生成する手法であるテキスト生成のみをサポートします。
ポート転送を設定する
推論サーバーへのポート転送を設定します。
Gemma 2B IT
kubectl port-forward svc/gemma-2b-it-serve-svc 8000:8000
Gemma 7B IT
kubectl port-forward svc/gemma-7b-it-serve-svc 8000:8000
Llama2 7B
kubectl port-forward svc/llama-7b-serve-svc 8000:8000
Llama 3 8B
kubectl port-forward svc/llama-3-8b-serve-svc 8000:8000
Mistral 7B
kubectl port-forward svc/mistral-7b-serve-svc 8000:8000
curl を使用してモデルを操作する
curl を使用してモデルとチャットします。
Gemma 2B IT
新しいターミナル セッションで、次の操作を行います。
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Gemma 7B IT
新しいターミナル セッションで、次の操作を行います。
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Llama2 7B
新しいターミナル セッションで、次の操作を行います。
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "meta-llama/Llama-2-7b-chat-hf",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
],
"temperature": 0.7
}'
Llama 3 8B
新しいターミナル セッションで、次の操作を行います。
curl http://localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
],
"temperature": 0.7
}'
Mistral 7B
新しいターミナル セッションで、次の操作を行います。
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
提供したモデルは履歴を保持しません。インタラクティブな会話エクスペリエンスを作成するには、メッセージと返信をモデルに送り返す必要があります。次の例は、Llama 3 8B モデルを使用してインタラクティブなダイアログを作成する方法を示しています。
curl
を使用して、モデルとのダイアログを作成します。
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."},
{"role": "assistant", "content": " \n1. Java\n2. Python\n3. C++\n4. C#\n5. JavaScript"},
{"role": "user", "content": "Can you give me a brief description?"}
],
"temperature": 0.7
}'
出力は次のようになります。
{
"id": "cmpl-3cb18c16406644d291e93fff65d16e41",
"object": "chat.completion",
"created": 1719035491,
"model": "meta-llama/Meta-Llama-3-8B-Instruct",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Here's a brief description of each:\n\n1. **Java**: A versatile language for building enterprise-level applications, Android apps, and web applications.\n2. **Python**: A popular language for data science, machine learning, web development, and scripting, known for its simplicity and ease of use.\n3. **C++**: A high-performance language for building operating systems, games, and other high-performance applications, with a focus on efficiency and control.\n4. **C#**: A modern, object-oriented language for building Windows desktop and mobile applications, as well as web applications using .NET.\n5. **JavaScript**: A versatile language for client-side scripting on the web, commonly used for creating interactive web pages, web applications, and mobile apps.\n\nNote: These descriptions are brief and don't do justice to the full capabilities and uses of each language."
},
"logprobs": null,
"finish_reason": "stop",
"stop_reason": null
}
],
"usage": {
"prompt_tokens": 73,
"total_tokens": 245,
"completion_tokens": 172
}
}
(省略可)チャット インターフェースに接続する
Gradio を使用して、モデルを操作できるウェブ アプリケーションを作成できます。Gradio は、chatbot のユーザー インターフェースを作成する ChatInterface
ラッパーを含む Python ライブラリです。Llama 2 7B と Llama 3 7B の場合、LLM モデルをデプロイするときに Gradio をインストールしました。
gradio
Service へのポート転送を設定します。kubectl port-forward service/gradio 8080:8080 &
ブラウザで http://localhost:8080 を開き、モデルとチャットします。
モデルの多重化を使用して複数のモデルを提供する
モデルの多重化は、同じ Ray クラスタ内で複数のモデルを提供する手法です。リクエスト ヘッダーを使用するか、ロード バランシングを使用して、トラフィックを特定のモデルに転送できます。
この例では、Gemma 7B IT モデルと Llama 3 8B モデルの 2 つのモデルで構成される多重化された Ray Serve アプリケーションを作成します。
RayService リソースをデプロイします。
kubectl apply -f model-multiplexing/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice model-multiplexing -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T14:00:41Z" serveDeploymentStatuses: MutliModelDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment_1: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Kubernetes Service を作成したことを確認します。
kubectl get service model-multiplexing-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-multiplexing-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Ray Serve アプリケーションへのポート転送を設定します。
kubectl port-forward svc/model-multiplexing-serve-svc 8000:8000
Gemma 7B IT モデルにリクエストを送信します。
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: google/gemma-7b-it" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'
出力は次のようになります。
{"text": ["What are the top 5 most popular programming languages? Please be brief.\n\n1. JavaScript\n2. Java\n3. C++\n4. Python\n5. C#"]}
Llama 3 8B モデルにリクエストを送信します。
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: meta-llama/Meta-Llama-3-8B-Instruct" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'
出力は次のようになります。
{"text": ["What are the top 5 most popular programming languages? Please be brief. Here are your top 5 most popular programming languages, based on the TIOBE Index, a widely used measure of the popularity of programming languages.\r\n\r\n1. **Java**: Used in Android app development, web development, and enterprise software development.\r\n2. **Python**: A versatile language used in data science, machine learning, web development, and automation.\r\n3. **C++**: A high-performance language used in game development, system programming, and high-performance computing.\r\n4. **C#**: Used in Windows and web application development, game development, and enterprise software development.\r\n5. **JavaScript**: Used in web development, mobile app development, and server-side programming with technologies like Node.js.\r\n\r\nSource: TIOBE Index (2022).\r\n\r\nThese rankings can vary depending on the source and methodology used, but this gives you a general idea of the most popular programming languages."]}
ヘッダー
serve_multiplexed_model_id
を除外して、ランダムなモデルにリクエストを送信します。curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'
出力は、前のステップの出力の 1 つです。
モデル構成で複数のモデルを作成する
モデル構成は、複数のモデルを 1 つのアプリケーションに作成するために使用される手法です。モデル構成を使用すると、複数の LLM の入力と出力を連結し、モデルを単一のアプリケーションとしてスケーリングできます。
この例では、Gemma 7B IT モデルと Llama 3 8B モデルを 1 つのアプリケーションに作成します。最初のモデルは、プロンプトで提供された質問に回答するアシスタント モデルです。2 番目のモデルは、要約モデルです。アシスタント モデルの出力は、要約モデルの入力に連結されます。最終的な結果は、アシスタント モデルからのレスポンスの要約版です。
RayService リソースをデプロイします。
kubectl apply -f model-composition/
RayService リソースの準備が整うまで待ちます。
kubectl get rayservice model-composition -o yaml
出力は次のようになります。
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T14:00:41Z" serveDeploymentStatuses: MutliModelDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment_1: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY status: RUNNING
この出力では、
status: RUNNING
は RayService リソースの準備ができていることを示します。GKE が Ray Serve アプリケーションの Service を作成したことを確認します。
kubectl get service model-composition-serve-svc
出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-composition-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
モデルにリクエストを送信します。
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What is the most popular programming language for machine learning and why?", "max_tokens": 1000}'
出力は次のようになります。
{"text": ["\n\n**Sure, here is a summary in a single sentence:**\n\nThe most popular programming language for machine learning is Python due to its ease of use, extensive libraries, and growing community."]}
プロジェクトを削除する
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
個々のリソースを削除する
使用している既存のプロジェクトを削除しない場合は、リソースを個別に削除できます。
クラスタを削除します。
gcloud container clusters delete rayserve-cluster
次のステップ
- GKE プラットフォームのオーケストレーション機能を使用して、最適化された AI / ML ワークロードを実行する方法を確認する。
- GKE Standard モードで GPU を使用してモデルをトレーニングする
- GKE で RayServe を使用する方法については、GitHub のサンプルコードをご覧ください。