透過 Triton 和 TensorRT-LLM,在 GKE 上使用 GPU 提供 Gemma 開放模型


本教學課程示範如何使用 NVIDIA TritonTensorRT-LLM 服務堆疊,透過 Google Kubernetes Engine (GKE) 上的 GPU 部署及提供 Gemma 大型語言模型 (LLM)。這項服務可做為基礎,協助您瞭解及探索如何在代管 Kubernetes 環境中,實際部署 LLM 以進行推論。您會將預先建構的容器連同 Triton 和 TensorRT-LLM 部署至 GKE。您也會設定 GKE,載入 Gemma 2B 和 7B 的權重。

本教學課程的適用對象為機器學習 (ML) 工程師、平台管理員和操作員,以及有興趣使用 Kubernetes 容器自動化調度管理功能,在 H100、A100 和 L4 GPU 硬體上提供 LLM 服務的資料和 AI 專家。如要進一步瞭解內容中提及的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。 Google Cloud

如果您需要整合式代管 AI 平台,以便快速建構及提供機器學習模型,同時兼顧成本效益,建議您試用 Vertex AI 部署解決方案。

閱讀本頁面之前,請先熟悉下列概念:

背景

本節說明本指南中使用的重要技術。

Gemma

Gemma 是一組以開放授權發布的輕量級生成式人工智慧 (AI) 模型,您可以在應用程式、硬體、行動裝置或代管服務中執行這些 AI 模型。您可以使用 Gemma 模型生成文字,也可以調整這些模型,用於執行特定工作。

詳情請參閱 Gemma 說明文件

GPU

GPU 可加速處理節點上執行的特定工作負載,例如機器學習和資料處理。GKE 提供各種機器類型選項,可供節點設定使用,包括搭載 NVIDIA H100、L4 和 A100 GPU 的機器類型。

TensorRT-LLM

NVIDIA TensorRT-LLM (TRT-LLM) 是一套工具包,內含 Python API,可組裝最佳化解決方案,定義 LLM 並建構 TensorRT 引擎,在 NVIDIA GPU 上有效率地執行推論。TensorRT-LLM 包含以下功能:

  • 最佳化 Transformer 實作方式,包括層融合、啟用快取、記憶體緩衝區重複使用和 PagedAttention
  • 進行中或持續批次處理,以提升整體服務輸送量
  • 張量平行處理和管道平行處理,可在多個 GPU 上提供分散式服務
  • 量化 (FP16、FP8、INT8)

詳情請參閱 TensorRT-LLM 說明文件

Triton

NVIDIA Triton Inference Server 是適用於 AI/ML 應用程式的開放原始碼推論伺服器。Triton 支援在 NVIDIA GPU 和 CPU 上執行高效能推論作業,並提供最佳化後端,包括 TensorRT 和 TensorRT-LLM。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. 在「New principals」(新增主體) 欄位中,輸入您的使用者 ID。 這通常是 Google 帳戶的電子郵件地址。

    5. 在「Select a role」(選取角色) 清單中,選取角色。
    6. 如要授予其他角色,請按一下 「新增其他角色」,然後新增每個其他角色。
    7. 按一下 [Save]
  • 如果沒有 Kaggle 帳戶,請先建立一個。
  • 請確認專案有足夠的 L4 GPU 配額。詳情請參閱「關於 GPU」和「分配配額」。

準備環境

在本教學課程中,您將使用 Cloud Shell 管理託管於Google Cloud的資源。Cloud Shell 已預先安裝本教學課程所需的軟體,包括 kubectl gcloud CLI

如要使用 Cloud Shell 設定環境,請按照下列步驟操作:

  1. 在 Google Cloud 控制台中,按一下Cloud Shell 啟用圖示Google Cloud 控制台中的「啟用 Cloud Shell」,啟動 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」部分下方,按一下「Create New Token」

系統會下載名為「kaggle.json」的檔案。

將存取權杖上傳至 Cloud Shell

在 Cloud Shell 中,將 Kaggle API 權杖上傳至專案: Google Cloud

  1. 在 Cloud Shell 中,依序點選「更多」>「上傳」
  2. 選取「檔案」,然後按一下「選擇檔案」
  3. 開啟 kaggle.json 檔案。
  4. 按一下「上傳」。

建立及設定 Google Cloud 資源

請按照下列操作說明建立必要資源。

建立 GKE 叢集和節點集區

您可以在 GKE Autopilot 或 Standard 叢集的 GPU 上提供 Gemma 服務。建議您使用 Autopilot 叢集,享受全代管 Kubernetes 體驗。如要為工作負載選擇最合適的 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 叢集。

標準

  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 會建立包含一個 L4 GPU 節點的單一節點集區。

為 Kaggle 憑證建立 Kubernetes Secret

在本教學課程中,您會使用 Kubernetes Secret 儲存 Kaggle 憑證。

在 Cloud Shell 中執行下列操作:

  1. 設定 kubectl 與叢集通訊:

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

    替換下列值:

    • REGION:支援您要使用的加速器類型,例如 L4 GPU 的 us-central1
    • CLUSTER_NAME:叢集名稱。
  2. 建立 Secret 來儲存 Kaggle 憑證:

    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 控制器會建立一或多個 Pod,並確保這些 Pod 成功執行特定工作。

以下程序可能需要幾分鐘才能完成。

Gemma 2B-it

TensorRT-LLM 引擎是使用 bfloat16 啟動、輸入序列長度=2048,以及輸出序列長度=1024,以 Gemma 的 Gemma 2B-it (指令調整) PyTorch 檢查點為目標,在 L4 GPU 上建構而成。您可以在單一 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. 查看工作的記錄:

    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. 等待工作完成:

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

    輸出結果會與下列內容相似:

    job.batch/data-loader-gemma-2b condition met
    
  5. 確認工作已順利完成 (這可能需要幾分鐘):

    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 啟動、輸入序列長度=1024,以及輸出序列長度=512,以 Gemma 7B-it (指令調整) PyTorch 檢查點為目標 L4 GPU 建構而成。您可以在單一 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. 查看工作的記錄:

    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. 等待工作完成:

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

    輸出結果會與下列內容相似:

    job.batch/data-loader-gemma-7b condition met
    
  5. 確認工作已順利完成 (這可能需要幾分鐘):

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

    輸出結果會與下列內容相似:

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

請先確認工作已順利完成,再繼續前往下一節。

部署 Triton

在本節中,您會部署使用 Triton 的容器,並透過 TensorRT-LLM 後端提供要使用的 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. 等待部署作業完成:

    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 訊息,表示容器可能尚未完成下載模型資料。再次檢查 Pod 的記錄,確認是否有 Connected 訊息,表示模型已準備好提供服務。
  • 如果看到 Connection refused,請確認連接埠轉送已啟用

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。

刪除已部署的資源

如要避免系統向您的 Google Cloud 帳戶收取本指南所建立資源的費用,請執行下列指令:

gcloud container clusters delete CLUSTER_NAME \
    --region=REGION

替換下列值:

  • REGION:支援您要使用的加速器類型,例如 L4 GPU 的 us-central1
  • CLUSTER_NAME:叢集名稱。

後續步驟