Triton と TensorRT-LLM を備えた GKE で GPU を使用して Gemma オープンモデルを提供する


このチュートリアルでは、NVIDIA の TritonTensorRT-LLM のサービス スタックを備えた Google Kubernetes Engine(GKE)で GPU を使用して Gemma 大規模言語モデル(LLM)をデプロイしてサービングする方法について説明します。これにより、マネージド Kubernetes 環境における推論用 LLM の実用的なデプロイに関する基礎を学ぶことができます。Triton と TensorRT-LLM を含むビルド済みコンテナを GKE にデプロイします。また、Gemma 2B と 7B の重みを読み込むように GKE を構成します。

このチュートリアルは、ML エンジニア、プラットフォームの管理者とオペレーターのほか、Kubernetes のコンテナ オーケストレーション機能を使用して H100、A100、L4 GPU ハードウェアで LLM をサービングすることに関心があるデータと AI のスペシャリストを対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

ML モデルを費用対効果の高い方法で迅速に構築して提供するために、統合されたマネージド AI プラットフォームが必要な場合は、Vertex AI デプロイ ソリューションをお試しになることをおすすめします。

このページを読む前に、次のことをよく理解しておいてください。

背景

このセクションでは、このガイドで使用されている重要なテクノロジーについて説明します。

Gemma

Gemma は、オープン ライセンスでリリースされ一般公開されている、軽量の生成 AI モデルのセットです。これらの AI モデルは、アプリケーション、ハードウェア、モバイル デバイス、ホスト型サービスで実行できます。Gemma モデルはテキスト生成に使用できますが、特殊なタスク用にチューニングすることもできます。

詳しくは、Gemma のドキュメントをご覧ください。

GPU

GPU を使用すると、ノードで実行される特定のワークロード(ML やデータ処理など)を高速化できます。GKE には、NVIDIA H100、L4、A100 GPU を搭載したマシンタイプをはじめとして、ノード構成用のさまざまなマシンタイプ オプションが用意されています。

TensorRT-LLM

NVIDIA TensorRT-LLM(TRT-LLM)は、最適化されたソリューションを集約して LLM を定義し、NVIDIA GPU で推論を効率的に実行する TensorRT エンジンを構築するための Python API を備えたツールキットです。TensorRT-LLM には次のような機能があります。

  • レイヤの融合、アクティベーション キャッシュ、メモリバッファの再利用、PagedAttention により最適化された Transformer の実装
  • サービング スループット全体を向上させる実行中または継続的なバッチ処理
  • 複数の GPU での分散サービングのためのテンソル並列処理とパイプライン並列処理
  • 量子化(FP16、FP8、INT8)

詳細については、TensorRT-LLM のドキュメントをご覧ください。

Triton

NVIDIA Triton 推論サーバーは、AI / ML アプリケーション用のオープンソース推論サーバーです。Triton は、TensorRT や TensorRT-LLM などの最適化されたバックエンドを備えた NVIDIA GPU と CPU の両方で高パフォーマンスの推論をサポートします。Triton には次のような機能があります。

  • マルチ GPU、マルチノードの推論
  • 複数モデルの同時実行
  • モデルのアンサンブルまたはチェーン
  • 予測リクエストの静的、動的、継続的または実行中のバッチ処理

詳しくは、Triton のドキュメントをご覧ください。

目標

  1. Autopilot モードの GKE クラスタで環境を準備する。
  2. Triton と TritonRT-LLM を含むコンテナをクラスタにデプロイする。
  3. Triton と TensorRT-LLM を使用して、curl を介して Gemma 2B または 7B モデルを提供する。

始める前に

  • 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.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  • Enable the required API.

    Enable the API

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

    Go to project selector

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

  • Enable the required API.

    Enable the API

  • Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      IAM に移動
    2. プロジェクトを選択します。
    3. [ アクセスを許可] をクリックします。
    4. [新しいプリンシパル] フィールドに、ユーザー ID を入力します。 これは通常、Google アカウントのメールアドレスです。

    5. [ロールを選択] リストでロールを選択します。
    6. 追加のロールを付与するには、 [別のロールを追加] をクリックして各ロールを追加します。
    7. [保存] をクリックします。
      • Kaggle アカウントを作成します(まだアカウントを保有されていない場合)。
      • L4 GPU 用にプロジェクトに十分な割り当てがあることを確認します。詳細については、GPU について数量に基づく割り当てをご覧ください。

      環境を準備する

      このチュートリアルでは、Cloud Shell を使用してGoogle Cloudでホストされているリソースを管理します。Cloud Shell には、このチュートリアルに必要な kubectlgcloud CLI などのソフトウェアがプリインストールされています。

      Cloud Shell を使用して環境を設定するには、次の操作を行います。

      1. Google Cloud コンソールで Cloud Shell 有効化アイコンCloud Shell をアクティブにする)をクリックして、Google Cloud コンソールで Cloud Shell セッションを起動します。これにより、 Google Cloud コンソールの下部ペインでセッションが起動します。

      2. デフォルトの環境変数を設定します。

        gcloud config set project PROJECT_ID
        gcloud config set billing/quota_project PROJECT_ID
        export PROJECT_ID=$(gcloud config get project)
        export REGION=REGION
        export CLUSTER_NAME=CLUSTER_NAME
        

        次の値を置き換えます。

        • PROJECT_ID: Google Cloudプロジェクト ID
        • REGION: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、L4 GPU の場合は us-central1)。
        • CLUSTER_NAME: クラスタの名前。

      モデルへのアクセス権を取得する

      Gemma モデルにアクセスするには、Kaggle プラットフォームにログインして Kaggle API トークンを取得する必要があります。

      Gemma を使用するには同意契約に署名する必要があります。手順は次のとおりです。

      1. Kaggle.com のモデルの同意ページにアクセスします。
      2. Kaggle にログインしていない場合はログインします。
      3. [アクセス権限をリクエスト] をクリックします。
      4. [同意に使用するアカウントを選択] セクションで、[Kaggle アカウントを使用して確認] を選択して、同意に Kaggle アカウントを使用します。
      5. モデルの利用規約に同意します。

      アクセス トークンを生成する

      Kaggle からモデルにアクセスするには、Kaggle API トークンが必要です。トークンをまだ生成していない場合は、次の手順に沿って生成します。

      1. ブラウザで [Kaggle の設定] に移動します。
      2. [API] セクションで、[新しいトークンを作成] をクリックします。

      kaggle.json という名前のファイルがダウンロードされます。

      アクセス トークンを Cloud Shell にアップロードする

      Cloud Shell で、Kaggle API トークンを Google Cloudプロジェクトにアップロードします。

      1. Cloud Shell で、 [その他] > [アップロード] をクリックします。
      2. [ファイル] を選択し、[ファイルを選択] をクリックします。
      3. kaggle.json ファイルを開きます。
      4. [アップロード] をクリックします。

      Google Cloud リソースを作成して構成する

      次の手順で、必要なリソースを作成します。

      GKE クラスタとノードプールを作成する

      GKE Autopilot クラスタまたは GKE Standard クラスタの GPU で Gemma を提供できます。フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。

      Autopilot

      Cloud Shell で、次のコマンドを実行します。

      gcloud container clusters create-auto CLUSTER_NAME \
        --project=PROJECT_ID \
        --region=REGION \
        --release-channel=rapid \
        --cluster-version=1.28
      

      次の値を置き換えます。

      • PROJECT_ID: Google Cloudプロジェクト ID
      • REGION: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、L4 GPU の場合は us-central1)。
      • CLUSTER_NAME: クラスタの名前。

      GKE は、デプロイされたワークロードからのリクエストに応じた CPU ノードと GPU ノードを持つ Autopilot クラスタを作成します。

      Standard

      1. Cloud Shell で、次のコマンドを実行して Standard クラスタを作成します。

        gcloud container clusters create CLUSTER_NAME \
            --project=PROJECT_ID \
            --location=REGION-a \
            --workload-pool=PROJECT_ID.svc.id.goog \
            --release-channel=rapid \
            --machine-type=e2-standard-4 \
            --num-nodes=1
        

        次の値を置き換えます。

        • PROJECT_ID: Google Cloudプロジェクト ID
        • REGION: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、L4 GPU の場合は us-central1)。
        • CLUSTER_NAME: クラスタの名前。

        クラスタの作成には数分かかることもあります。

      2. 次のコマンドを実行して、クラスタのノードプールを作成します。

        gcloud container node-pools create gpupool \
            --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
            --project=PROJECT_ID \
            --location=REGION-a \
            --cluster=CLUSTER_NAME \
            --machine-type=g2-standard-12 \
            --num-nodes=1
        

        GKE は、1 つの L4 GPU ノードを含む単一のノードプールを作成します。

      Kaggle 認証情報用の Kubernetes Secret を作成する

      このチュートリアルでは、Kaggle 認証情報に Kubernetes Secret を使用します。

      Cloud Shell で、次の操作を行います。

      1. クラスタと通信を行うように kubectl を構成します。

        gcloud container clusters get-credentials CLUSTER_NAME \
            --location=REGION
        

        次の値を置き換えます。

        • REGION: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、L4 GPU の場合は us-central1)。
        • CLUSTER_NAME: クラスタの名前。
      2. Kaggle 認証情報を保存する Secret を作成します。

        kubectl create secret generic kaggle-secret \
            --from-file=kaggle.json \
            --dry-run=client -o yaml | kubectl apply -f -
        

      チェックポイントを保存する PersistentVolume リソースを作成する

      このセクションでは、永続ディスクを基盤とする PersistentVolume を作成して、モデルのチェックポイントを保存します。

      1. 次の trtllm_checkpoint_pv.yaml マニフェストを作成します。

        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: model-data
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 100G
      2. 次のようにマニフェストを適用します。

        kubectl apply -f trtllm_checkpoint_pv.yaml
        

      Gemma の TensorRT-LLM エンジン ファイルをダウンロードする

      このセクションでは、Kubernetes Job を実行して次のタスクを行います。

      • TensorRT-LLM エンジン ファイルをダウンロードし、先ほど作成した PersistentVolume にファイルを保存します。
      • Triton サーバーにモデルをデプロイするための構成ファイルを準備します。

      Kubernetes の Job コントローラは、1 つ以上の Pod を作成し、特定のタスクが正常に実行されるようにします。

      このプロセスには数分かかる場合があります。

      Gemma 2B-it

      TensorRT-LLM エンジンは、bfloat16 アクティベーション、入力シーケンス長 2,048、出力シーケンス長 1,024 のターゲット L4 GPU を使用して、Gemma の Gemma 2B-it(指示調整済み)PyTorch チェックポイントからビルドされています。単一の L4 GPU にモデルをデプロイできます。

      1. 次の job-download-gemma-2b.yaml マニフェストを作成します。

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: fetch-model-scripts
        data:
          fetch_model.sh: |-
            #!/usr/bin/bash -x
            pip install kaggle --break-system-packages && \
        
            MODEL_NAME=$(echo ${MODEL_PATH} | awk -F'/' '{print $2}') && \
            VARIATION_NAME=$(echo ${MODEL_PATH} | awk -F'/' '{print $4}') && \
            ACTIVATION_DTYPE=bfloat16 && \
        
            TOKENIZER_DIR=/data/trt_engine/${MODEL_NAME}/${VARIATION_NAME}/${ACTIVATION_DTYPE}/${WORLD_SIZE}-gpu/tokenizer.model && \
            ENGINE_PATH=/data/trt_engine/${MODEL_NAME}/${VARIATION_NAME}/${ACTIVATION_DTYPE}/${WORLD_SIZE}-gpu/ && \
            TRITON_MODEL_REPO=/data/triton/model_repository && \
        
            mkdir -p /data/${MODEL_NAME}_${VARIATION_NAME} && \
            mkdir -p ${ENGINE_PATH} && \
            mkdir -p ${TRITON_MODEL_REPO} && \
        
            kaggle models instances versions download ${MODEL_PATH} --untar -p /data/${MODEL_NAME}_${VARIATION_NAME} && \
            rm -f /data/${MODEL_NAME}_${VARIATION_NAME}/*.tar.gz && \
            find /data/${MODEL_NAME}_${VARIATION_NAME} -type f && \
            find /data/${MODEL_NAME}_${VARIATION_NAME} -type f | xargs -I '{}' mv '{}' ${ENGINE_PATH} && \
        
            # copying configuration files
            echo -e "\nCreating configuration files" && \
            cp -r /tensorrtllm_backend/all_models/inflight_batcher_llm/* ${TRITON_MODEL_REPO} && \
        
            # updating configuration files
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/preprocessing/config.pbtxt tokenizer_dir:${TOKENIZER_DIR},tokenizer_type:sp,triton_max_batch_size:64,preprocessing_instance_count:1 && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/postprocessing/config.pbtxt tokenizer_dir:${TOKENIZER_DIR},tokenizer_type:sp,triton_max_batch_size:64,postprocessing_instance_count:1 && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/tensorrt_llm_bls/config.pbtxt triton_max_batch_size:64,decoupled_mode:False,bls_instance_count:1,accumulate_tokens:False && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/ensemble/config.pbtxt triton_max_batch_size:64 && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/tensorrt_llm/config.pbtxt triton_max_batch_size:64,decoupled_mode:False,max_beam_width:1,engine_dir:${ENGINE_PATH},max_tokens_in_paged_kv_cache:2560,max_attention_window_size:2560,kv_cache_free_gpu_mem_fraction:0.5,exclude_input_in_output:True,enable_kv_cache_reuse:False,batching_strategy:inflight_batching,max_queue_delay_microseconds:600,batch_scheduler_policy:guaranteed_no_evict,enable_trt_overlap:False && \
        
            echo -e "\nCompleted extraction to ${ENGINE_PATH}"
        ---
        apiVersion: batch/v1
        kind: Job
        metadata:
          name: data-loader-gemma-2b
          labels:
            app: data-loader-gemma-2b
        spec:
          ttlSecondsAfterFinished: 120
          template:
            metadata:
              labels:
                app: data-loader-gemma-2b
            spec:
              restartPolicy: OnFailure
              containers:
              - name: gcloud
                image: us-docker.pkg.dev/google-samples/containers/gke/tritonserver:2.42.0
                command:
                - /scripts/fetch_model.sh
                env:
                - name: KAGGLE_CONFIG_DIR
                  value: /kaggle
                - name: MODEL_PATH
                  value: "google/gemma/tensorrtllm/2b-it/2"
                - name: WORLD_SIZE
                  value: "1"
                volumeMounts:
                - mountPath: "/kaggle/"
                  name: kaggle-credentials
                  readOnly: true
                - mountPath: "/scripts/"
                  name: scripts-volume
                  readOnly: true
                - mountPath: "/data"
                  name: data
              volumes:
              - name: kaggle-credentials
                secret:
                  defaultMode: 0400
                  secretName: kaggle-secret
              - name: scripts-volume
                configMap:
                  defaultMode: 0700
                  name: fetch-model-scripts
              - name: data
                persistentVolumeClaim:
                  claimName: model-data
              tolerations:
              - key: "key"
                operator: "Exists"
                effect: "NoSchedule"
      2. 次のようにマニフェストを適用します。

        kubectl apply -f job-download-gemma-2b.yaml
        
      3. Job のログを表示します。

        kubectl logs -f job/data-loader-gemma-2b
        

        ログの出力は次のようになります。

        ...
        Creating configuration files
        + echo -e '\n02-16-2024 04:07:45 Completed building TensortRT-LLM engine at /data/trt_engine/gemma/2b/bfloat16/1-gpu/'
        + echo -e '\nCreating configuration files'
        ...
        
      4. Job が完了するまで待ちます。

        kubectl wait --for=condition=complete --timeout=900s job/data-loader-gemma-2b
        

        出力は次のようになります。

        job.batch/data-loader-gemma-2b condition met
        
      5. Job が正常に完了したことを確認します(数分かかることがあります)。

        kubectl get job/data-loader-gemma-2b
        

        出力は次のようになります。

        NAME             COMPLETIONS   DURATION   AGE
        data-loader-gemma-2b   1/1           ##s        #m##s
        

      Gemma 7B-it

      TensorRT-LLM エンジンは、bfloat16 アクティベーション、入力シーケンス長 1,024、出力シーケンス長 512 のターゲット L4 GPU を使用して、Gemma の Gemma 7B-it(指示調整済み)PyTorch チェックポイントからビルドされています。単一の L4 GPU にモデルをデプロイできます。

      1. 次の job-download-gemma-7b.yaml マニフェストを作成します。

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: fetch-model-scripts
        data:
          fetch_model.sh: |-
            #!/usr/bin/bash -x
            pip install kaggle --break-system-packages && \
        
            MODEL_NAME=$(echo ${MODEL_PATH} | awk -F'/' '{print $2}') && \
            VARIATION_NAME=$(echo ${MODEL_PATH} | awk -F'/' '{print $4}') && \
            ACTIVATION_DTYPE=bfloat16 && \
        
            TOKENIZER_DIR=/data/trt_engine/${MODEL_NAME}/${VARIATION_NAME}/${ACTIVATION_DTYPE}/${WORLD_SIZE}-gpu/tokenizer.model && \
            ENGINE_PATH=/data/trt_engine/${MODEL_NAME}/${VARIATION_NAME}/${ACTIVATION_DTYPE}/${WORLD_SIZE}-gpu/ && \
            TRITON_MODEL_REPO=/data/triton/model_repository && \
        
            mkdir -p ${ENGINE_PATH} && \
            mkdir -p ${TRITON_MODEL_REPO} && \
        
            kaggle models instances versions download ${MODEL_PATH} --untar -p /data/${MODEL_NAME}_${VARIATION_NAME} && \
            rm -f /data/${MODEL_NAME}_${VARIATION_NAME}/*.tar.gz && \
            find /data/${MODEL_NAME}_${VARIATION_NAME} -type f && \
            find /data/${MODEL_NAME}_${VARIATION_NAME} -type f | xargs -I '{}' mv '{}' ${ENGINE_PATH} && \
        
            # copying configuration files
            echo -e "\nCreating configuration files" && \
            cp -r /tensorrtllm_backend/all_models/inflight_batcher_llm/* ${TRITON_MODEL_REPO} && \
        
            # updating configuration files
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/preprocessing/config.pbtxt tokenizer_dir:${TOKENIZER_DIR},tokenizer_type:sp,triton_max_batch_size:64,preprocessing_instance_count:1 && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/postprocessing/config.pbtxt tokenizer_dir:${TOKENIZER_DIR},tokenizer_type:sp,triton_max_batch_size:64,postprocessing_instance_count:1 && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/tensorrt_llm_bls/config.pbtxt triton_max_batch_size:64,decoupled_mode:False,bls_instance_count:1,accumulate_tokens:False && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/ensemble/config.pbtxt triton_max_batch_size:64 && \
            python3 /tensorrtllm_backend/tools/fill_template.py -i ${TRITON_MODEL_REPO}/tensorrt_llm/config.pbtxt triton_max_batch_size:64,decoupled_mode:False,max_beam_width:1,engine_dir:${ENGINE_PATH},max_tokens_in_paged_kv_cache:2560,max_attention_window_size:2560,kv_cache_free_gpu_mem_fraction:0.5,exclude_input_in_output:True,enable_kv_cache_reuse:False,batching_strategy:inflight_batching,max_queue_delay_microseconds:600,batch_scheduler_policy:guaranteed_no_evict,enable_trt_overlap:False && \
        
            echo -e "\nCompleted extraction to ${ENGINE_PATH}"
        ---
        apiVersion: batch/v1
        kind: Job
        metadata:
          name: data-loader-gemma-7b
          labels:
            app: data-loader-gemma-7b
        spec:
          ttlSecondsAfterFinished: 120
          template:
            metadata:
              labels:
                app: data-loader-gemma-7b
            spec:
              restartPolicy: OnFailure
              containers:
              - name: gcloud
                image: us-docker.pkg.dev/google-samples/containers/gke/tritonserver:2.42.0
                command:
                - /scripts/fetch_model.sh
                env:
                - name: KAGGLE_CONFIG_DIR
                  value: /kaggle
                - name: MODEL_PATH
                  value: "google/gemma/tensorrtllm/7b-it/2"
                - name: WORLD_SIZE
                  value: "1"
                volumeMounts:
                - mountPath: "/kaggle/"
                  name: kaggle-credentials
                  readOnly: true
                - mountPath: "/scripts/"
                  name: scripts-volume
                  readOnly: true
                - mountPath: "/data"
                  name: data
              volumes:
              - name: kaggle-credentials
                secret:
                  defaultMode: 0400
                  secretName: kaggle-secret
              - name: scripts-volume
                configMap:
                  defaultMode: 0700
                  name: fetch-model-scripts
              - name: data
                persistentVolumeClaim:
                  claimName: model-data
              tolerations:
              - key: "key"
                operator: "Exists"
                effect: "NoSchedule"
      2. 次のようにマニフェストを適用します。

        kubectl apply -f job-download-gemma-7b.yaml
        
      3. Job のログを表示します。

        kubectl logs -f job/data-loader-gemma-7b
        

        ログの出力は次のようになります。

        ...
        Creating configuration files
        + echo -e '\n02-16-2024 04:07:45 Completed building TensortRT-LLM engine at /data/trt_engine/gemma/7b/bfloat16/1-gpu/'
        + echo -e '\nCreating configuration files'
        ...
        
      4. Job が完了するまで待ちます。

        kubectl wait --for=condition=complete --timeout=900s job/data-loader-gemma-7b
        

        出力は次のようになります。

        job.batch/data-loader-gemma-7b condition met
        
      5. Job が正常に完了したことを確認します(数分かかることがあります)。

        kubectl get job/data-loader-gemma-7b
        

        出力は次のようになります。

        NAME             COMPLETIONS   DURATION   AGE
        data-loader-gemma-7b   1/1           ##s        #m##s
        

      次のセクションに進む前に、Job が正常に完了したことを確認してください。

      Triton をデプロイする

      このセクションでは、TensorRT-LLM バックエンドを使用して Triton を使用するコンテナをデプロイし、使用する Gemma モデルを提供します。

      1. 次の deploy-triton-server.yaml マニフェストを作成します。

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: launch-tritonserver
        data:
          entrypoint.sh: |-
            #!/usr/bin/bash -x
            # Launch Triton Inference server
        
            WORLD_SIZE=1
            TRITON_MODEL_REPO=/data/triton/model_repository
        
            python3 /tensorrtllm_backend/scripts/launch_triton_server.py \
              --world_size ${WORLD_SIZE} \
              --model_repo ${TRITON_MODEL_REPO}
        
            tail -f /dev/null
        ---
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: triton-gemma-deployment
          labels:
            app: gemma-server
            version: v1 
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: gemma-server 
              version: v1
          template:
            metadata:
              labels:
                app: gemma-server
                ai.gke.io/model: gemma
                ai.gke.io/inference-server: triton
                examples.ai.gke.io/source: user-guide
                version: v1
            spec:
              containers:
              - name: inference-server 
                image: us-docker.pkg.dev/google-samples/containers/gke/tritonserver:2.42.0
                imagePullPolicy: IfNotPresent
                resources:
                  requests:
                    ephemeral-storage: "40Gi"
                    memory: "40Gi"
                    nvidia.com/gpu: 1
                  limits:
                    ephemeral-storage: "40Gi"
                    memory: "40Gi"
                    nvidia.com/gpu: 1
                command:
                - /scripts/entrypoint.sh
                volumeMounts:
                - mountPath: "/scripts/"
                  name: scripts-volume
                  readOnly: true
                - mountPath: "/data"
                  name: data
                ports:
                  - containerPort: 8000
                    name: http
                  - containerPort: 8001
                    name: grpc
                  - containerPort: 8002
                    name: metrics
                livenessProbe:
                  failureThreshold: 60
                  initialDelaySeconds: 600
                  periodSeconds: 5
                  httpGet:
                    path: /v2/health/live
                    port: http
                readinessProbe:
                  failureThreshold: 60
                  initialDelaySeconds: 600
                  periodSeconds: 5
                  httpGet:
                    path: /v2/health/ready
                    port: http
              securityContext:
                runAsUser: 1000
                fsGroup: 1000
              volumes:
              - name: scripts-volume
                configMap:
                  defaultMode: 0700
                  name: launch-tritonserver
              - name: data
                persistentVolumeClaim:
                  claimName: model-data
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-l4
              tolerations:
              - key: "key"
                operator: "Exists"
                effect: "NoSchedule"
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: triton-server
          labels:
            app: gemma-server 
        spec:
          type: ClusterIP
          ports:
            - port: 8000
              targetPort: http
              name: http-inference-server
            - port: 8001
              targetPort: grpc
              name: grpc-inference-server
            - port: 8002
              targetPort: metrics
              name: http-metrics
          selector:
            app: gemma-server
      2. 次のようにマニフェストを適用します。

        kubectl apply -f deploy-triton-server.yaml
        
      3. Deployment が利用可能になるまで待ちます。

        kubectl wait --for=condition=Available --timeout=900s deployment/triton-gemma-deployment
        
      4. マニフェストのログを表示します。

        kubectl logs -f -l app=gemma-server
        

        デプロイ リソースが Triton サーバーを起動し、モデルデータを読み込みます。この処理には数分かかることがあります(最大 20 分以上)。出力は次のようになります。

        I0216 03:24:57.387420 29 server.cc:676]
        +------------------+---------+--------+
        | Model            | Version | Status |
        +------------------+---------+--------+
        | ensemble         | 1       | READY  |
        | postprocessing   | 1       | READY  |
        | preprocessing    | 1       | READY  |
        | tensorrt_llm     | 1       | READY  |
        | tensorrt_llm_bls | 1       | READY  |
        +------------------+---------+--------+
        
        ....
        ....
        ....
        
        I0216 03:24:57.425104 29 grpc_server.cc:2519] Started GRPCInferenceService at 0.0.0.0:8001
        I0216 03:24:57.425418 29 http_server.cc:4623] Started HTTPService at 0.0.0.0:8000
        I0216 03:24:57.466646 29 http_server.cc:315] Started Metrics Service at 0.0.0.0:8002
        

      モデルを提供する

      このセクションでは、モデルを操作します。

      ポート転送をセットアップする

      次のコマンドを実行して、モデルへのポート転送を設定します。

      kubectl port-forward service/triton-server 8000:8000
      

      出力は次のようになります。

      Forwarding from 127.0.0.1:8000 -> 8000
      Forwarding from [::1]:8000 -> 8000
      Handling connection for 8000
      

      curl を使用してモデルを操作する

      このセクションでは、基本的なスモークテストを実行して、デプロイされた指示調整済みモデルを確認する方法について説明します。わかりやすくするため、このセクションでは 2B 指示チューニング済みモデルのみを使用したテスト方法について説明します。

      新しいターミナル セッションで、curl を使用してモデルとチャットします。

      USER_PROMPT="I'm new to coding. If you could only recommend one programming language to start with, what would it be and why?"
      
      curl -X POST localhost:8000/v2/models/ensemble/generate \
        -H "Content-Type: application/json" \
        -d @- <<EOF
      {
          "text_input": "<start_of_turn>user\n${USER_PROMPT}<end_of_turn>\n",
          "temperature": 0.9,
          "max_tokens": 128
      }
      EOF
      

      次の出力には、モデルのレスポンスの例が表示されています。

      {
        "context_logits": 0,
        "cum_log_probs": 0,
        "generation_logits": 0,
        "model_name": "ensemble",
        "model_version": "1",
        "output_log_probs": [0.0,0.0,...],
        "sequence_end": false,
        "sequence_id": 0,
        "sequence_start": false,
        "text_output":"Python.\n\nPython is an excellent choice for beginners due to its simplicity, readability, and extensive documentation. Its syntax is close to natural language, making it easier for beginners to understand and write code. Python also has a vast collection of libraries and tools that make it versatile for various projects. Additionally, Python's dynamic nature allows for easier learning and experimentation, making it a perfect choice for newcomers to get started.Here are some specific reasons why Python is a good choice for beginners:\n\n- Simple and Easy to Read: Python's syntax is designed to be close to natural language, making it easier for"
      }
      

      問題のトラブルシューティング

      • Empty reply from server というメッセージが表示された場合は、コンテナがモデルデータのダウンロードを完了していない可能性があります。モデルがサービス提供の準備ができていることを示す Connected というメッセージがないか、再度 Pod のログを確認します。
      • Connection refused が表示された場合は、ポート転送が有効であることを確認します。

      クリーンアップ

      このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

      デプロイされたリソースを削除する

      このガイドで作成したリソースについて Google Cloud アカウントに課金されないようにするには、次のコマンドを実行します。

      gcloud container clusters delete CLUSTER_NAME \
          --region=REGION
      

      次の値を置き換えます。

      • REGION: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、L4 GPU の場合は us-central1)。
      • CLUSTER_NAME: クラスタの名前。

      次のステップ