Cloud Run GPU で Ollama を使用して LLM 推論を実行する


このチュートリアルでは、Google のオープン大規模言語モデル(LLM)である Gemma 2 を GPU 対応の Cloud Run サービス(高速推論)にデプロイする方法について説明します。

また、オープンモデル用の LLM 推論サーバーである Ollama を使用します。このチュートリアルを完了したら、Ollama でサポートされている他のオープンモデル(Llama 3.1(8B)Mistral(7B)Qwen2(7B) など)もぜひご確認ください。

目標

  • GPU 対応の Cloud Run サービスに OllamaGemma 2 モデルをデプロイします。
  • プライベート エンドポイントの Ollama サービスにプロンプトを送信します。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Artifact Registry, Cloud Build, Cloud Run, and Cloud Storage APIs.

    Enable the APIs

  7. gcloud CLI をインストールして初期化します
  8. このチュートリアルを完了するには、Cloud Run Admin API の [割り当てとシステムの上限] ページで Total Nvidia L4 GPU allocation, per project per region 割り当てをリクエストします。

必要なロール

チュートリアルを完了するために必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。

ロールの付与については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

gcloud を設定する

Cloud Run サービス用に Google Cloud CLI を構成するには:

  1. デフォルト プロジェクトを設定します。

    gcloud config set project PROJECT_ID

    アイコンをクリックして、変数 PROJECT_ID をこのチュートリアル用に作成したプロジェクトの名前に置き換えます。これにより、このページで PROJECT_ID を参照するすべてのリストに正しい値が設定されます。

  2. Cloud Run コマンドでリージョン us-central1 が使用されるように Google Cloud CLI を構成します。

    gcloud config set run/region us-central1

Artifact Registry Docker リポジトリを作成する

このチュートリアルのコンテナ イメージを保存する Docker リポジトリを作成します。

gcloud artifacts repositories create REPOSITORY \
  --repository-format=docker \
  --location=us-central1

REPOSITORY は、リポジトリの名前に置き換えます。例: repo

Docker を使用して Ollama と Gemma を含むコンテナ イメージを作成する

  1. Ollama サービス用のディレクトリを作成し、そのディレクトリを作業ディレクトリに変更します。

    mkdir ollama-backend
    cd ollama-backend
  2. Dockerfile ファイルを作成します。

    FROM ollama/ollama:0.3.6
    
    # Listen on all interfaces, port 8080
    ENV OLLAMA_HOST 0.0.0.0:8080
    
    # Store model weight files in /models
    ENV OLLAMA_MODELS /models
    
    # Reduce logging verbosity
    ENV OLLAMA_DEBUG false
    
    # Never unload model weights from the GPU
    ENV OLLAMA_KEEP_ALIVE -1 
    
    # Store the model weights in the container image
    ENV MODEL gemma2:9b
    RUN ollama serve & sleep 5 && ollama pull $MODEL 
    
    # Start Ollama
    ENTRYPOINT ["ollama", "serve"]

インスタンスの起動を高速化するためにモデルの重みをコンテナ イメージに保存する

Gemma 2(9B)や同等サイズのモデルの重みをコンテナ イメージに直接保存することをおすすめします。

モデルの重みは、LLM の動作を定義する数値パラメータです。Ollama は、推論リクエストの処理を開始する前に、コンテナ インスタンスの起動時にこれらのファイルを完全に読み取り、重みを GPU メモリ(VRAM)に読み込む必要があります。

Cloud Run では、リクエストのレイテンシを最小限に抑えるため、コンテナ インスタンスの高速起動が重要です。コンテナ インスタンスの起動に時間がかかると、サービスが 0 から 1 インスタンスにスケーリングする時間もかかります。また、トラフィックの急増時のスケールアウトにもさらに時間がかかります。

起動を高速化するには、モデルファイルをコンテナ イメージ自体に保存します。これは、起動時にリモートからファイルをダウンロードする場合よりも高速で、信頼性が高い方法です。Cloud Run の内部コンテナ イメージ ストレージは、トラフィックの急増に対応するように最適化されています。インスタンスの起動時にコンテナのファイル システムをすばやくセットアップできます。

Gemma 2(9B)のモデルの重みは 5.4 GB のストレージを占有します。モデルが大きいほど、モデルの重みのファイルが大きくなり、コンテナ イメージへの保存が現実的でない場合があります。トレードオフの概要については、ベスト プラクティス: GPU を使用した Cloud Run での AI 推論をご覧ください。

Cloud Build を使用してコンテナ イメージをビルドする

Cloud Build でコンテナ イメージをビルドし、Artifact Registry リポジトリに push するには:

gcloud builds submit \
   --tag us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/ollama-gemma \
   --machine-type e2-highcpu-32

以下の点に注意してください。

  • ビルドを高速化するため、このコマンドは CPU とネットワーク帯域幅が大きい強力なマシンタイプを選択します。
  • ビルドには 7 分ほどかかります。
  • 別の方法として、Docker を使用してローカルでイメージをビルドし、Artifact Registry に push することもできます。ネットワーク帯域幅によっては、Cloud Build で実行するよりも時間がかかる場合があります。

Cloud Run サービスとして Ollama をデプロイする

コンテナ イメージが Artifact Registry リポジトリに保存されたので、Ollama を Cloud Run サービスとしてデプロイする準備が整いました。

専用のサービス アカウントを作成する

Ollama サービスがサービス ID として使用する専用のサービス アカウントを作成します。

gcloud iam service-accounts create OLLAMA_IDENTITY \
  --display-name="Service Account for Ollama Cloud Run service"

OLLAMA_IDENTITY は、作成するサービス アカウントの名前に置き換えます(例: ollama)。

必要最小限の権限セットですべての Cloud Run サービスに専用のサービス アカウントを作成する方法がベスト プラクティスです。Ollama サービスは Google Cloud APIs を呼び出す必要がないため、サービス アカウントに権限を付与する必要はありません。

サービスをデプロイする

サービスを Cloud Run にデプロイする

gcloud beta run deploy ollama-gemma \
  --image us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/ollama-gemma \
  --concurrency 4 \
  --cpu 8 \
  --set-env-vars OLLAMA_NUM_PARALLEL=4 \
  --gpu 1 \
  --gpu-type nvidia-l4 \
  --max-instances 7 \
  --memory 32Gi \
  --no-allow-unauthenticated \
  --no-cpu-throttling \
  --service-account OLLAMA_IDENTITY@PROJECT_ID.iam.gserviceaccount.com \
  --timeout=600

このコマンドの次のフラグに注意してください。

  • --concurrency 4 は、環境変数 OLLAMA_NUM_PARALLEL の値と一致するように設定されています。
  • --gpu-type nvidia-l4--gpu 1 は、サービスのすべての Cloud Run インスタンスに 1 つの NVIDIA L4 GPU を割り当てます。
  • --no-allow-authenticated は、サービスへの未認証アクセスを制限します。サービスを非公開にすることで、サービス間通信に Cloud Run の組み込み Identity and Access Management(IAM)認証を使用できます。IAM を使用したアクセスの管理をご覧ください。
  • GPU を利用するには --no-cpu-throttling が必要です。
  • --service-account には、サービスのサービス ID を設定します。

最適なパフォーマンスを実現するための同時実行の設定

このセクションでは、推奨される同時実行設定のコンテキストについて説明します。リクエストのレイテンシを最適化するには、--concurrency の設定が Ollama の OLLAMA_NUM_PARALLEL 環境変数と同じであることを確認します。

  • OLLAMA_NUM_PARALLEL には、各モデルで推論リクエストを同時に処理するために使用できるリクエスト スロットの数を設定します。
  • --concurrency には、Cloud Run が Ollama インスタンスに同時に送信するリクエストの数を設定します。

--concurrencyOLLAMA_NUM_PARALLEL を超えている場合、Cloud Run は、使用可能なリクエスト スロットよりも多くのリクエストを Ollama のモデルに送信できます。これにより、Ollama 内でリクエストがキューに追加され、キューに追加されたリクエストのレイテンシが増加します。また、キューに追加されたリクエストが Cloud Run をトリガーしてスケールアウトし、新しいインスタンスを起動しないため、自動スケーリングの応答性が低下します。

Ollama は、1 つの GPU から複数のモデルをサービングする機能も備えています。Ollama インスタンスでリクエストのキューイングを完全に回避するには、OLLAMA_NUM_PARALLEL と一致するように --concurrency を設定する必要があります。

OLLAMA_NUM_PARALLEL を増やすと、並列リクエストにかかる時間も長くなることに注意してください。

使用率の最適化

GPU 使用率を最適化するには、--concurrency を増やします。ただし、OLLAMA_NUM_PARALLEL の 2 倍の範囲内にします。これにより、Ollama でリクエストがキューイングされますが、使用率の向上に役立ちます。Ollama インスタンスは、キュー内のリクエストをすぐに処理できるため、キューはトラフィックの急増への対応に役立ちます。

デプロイされた Ollama サービスを curl でテストする

Ollama サービスがデプロイされたので、そのサービスにリクエストを送信できます。ただし、リクエストを直接送信すると、Cloud Run は HTTP 401 Unauthorized で応答します。これは、LLM 推論 API が他のサービス(フロントエンド アプリケーションなど)によって呼び出されることを前提としているためです。Cloud Run のサービス間認証の詳細については、サービス間の認証をご覧ください。

Ollama サービスにリクエストを送信するには、Cloud Run デベロッパー プロキシなどを使用して、有効な OIDC トークンを含むヘッダーをリクエストに追加します。

  1. プロキシを起動し、cloud-run-proxy コンポーネントのインストールを求めるメッセージが表示されたら、「Y」を選択します。

    gcloud run services proxy ollama-gemma --port=9090
  2. プロキシを実行したまま、別のターミナルタブでリクエストを送信します。プロキシは localhost:9090 で実行されます。

    curl http://localhost:9090/api/generate -d '{
      "model": "gemma2:9b",
      "prompt": "Why is the sky blue?"
    }'

    このコマンドは、次のようなストリーミング出力を生成します。

    {"model":"gemma2:9b","created_at":"2024-07-15T23:21:39.288463414Z","response":"The","done":false}
    {"model":"gemma2:9b","created_at":"2024-07-15T23:21:39.320937525Z","response":" sky","done":false}
    {"model":"gemma2:9b","created_at":"2024-07-15T23:21:39.353173544Z","response":" appears","done":false}
    {"model":"gemma2:9b","created_at":"2024-07-15T23:21:39.385284976Z","response":" blue","done":false}
    ...
    

クリーンアップ

  1. このチュートリアルで作成した他の Google Cloud リソースを削除します。

次のステップ