通过 Triton 和 TensorRT-LLM 使用 GKE 中的 GPU 应用 Gemma 开放模型


本教程介绍如何通过 NVIDIA TritonTensorRT-LLM 服务堆栈,使用 Google Kubernetes Engine (GKE) 中的图形处理器 (GPU) 来应用 Gemma 大语言模型 (LLM)。在本教程中,您将下载 2B 和 7B 参数指令调优 Gemma 模型,并使用运行 Triton 和 TensorRT-LLM 的容器将它们部署到 GKE AutopilotStandard 集群。

如果您在部署和应用 AI/机器学习工作负载时需要利用代管式 Kubernetes 的精细控制、可伸缩性、弹性、可移植性和成本效益,那么本指南是一个很好的起点。如果您需要统一的代管式 AI 平台来经济高效地快速构建和应用机器学习模型,我们建议您试用我们的 Vertex AI 部署解决方案。

背景

您可以通过 Triton 和 TensorRT-LLM 使用 GKE 中的 GPU 应用 Gemma,从而实现一个可直接用于生产环境的强大推理服务解决方案,具备代管式 Kubernetes 的所有优势,包括高效的可伸缩性和更高的可用性。本部分介绍本指南中使用的关键技术。

Gemma

Gemma 是一组公开提供的轻量级生成式人工智能 (AI) 模型(根据开放许可发布)。这些 AI 模型可以在应用、硬件、移动设备或托管服务中运行。您可以使用 Gemma 模型生成文本,但也可以针对专门任务对这些模型进行调优。

如需了解详情,请参阅 Gemma 文档

GPU

利用 GPU,您可以加速在节点上运行的特定工作负载(例如机器学习和数据处理)。GKE 提供了一系列机器类型选项以用于节点配置,包括配备 NVIDIA H100、L4 和 A100 GPU 的机器类型。

使用 GKE 中的 GPU 之前,我们建议您完成以下学习路线:

  1. 了解当前 GPU 版本可用性
  2. 了解 GKE 中的 GPU

TensorRT-LLM

NVIDIA TensorRT-LLM (TRT-LLM) 是一种具有 Python API 的工具包,可汇编经过优化的解决方案,以定义 LLM 并构建可在 NVIDIA GPU 上高效执行推理的 TensorRT 引擎。TensorRT-LLM 包含以下功能:

  • 具有层融合、激活缓存、内存缓冲区重复使用和 PagedAttention 且经过优化的 Transformer(转换器)实现
  • 运行中批处理或连续批处理,可提高整体服务吞吐量
  • 张量并行处理和流水线并行处理,用于在多个 GPU 上实现分布式服务
  • 量化(FP16、FP8、INT8)

如需了解详情,请参阅 TensorRT-LLM 文档

海卫一

NVIDIA Triton 推理服务器是适用于 AI/机器学习应用的开源推理服务器。Triton 通过经过优化的后端(包括 TensorRT 和 TensorRT-LLM),支持在 NVIDIA GPU 和 CPU 上进行高性能推理。Triton 包含以下功能:

  • 多 GPU、多节点推理
  • 多模型并发执行
  • 模型集成学习或链式
  • 预测请求的静态、动态和连续或运行中批处理

如需了解详情,请参阅 Triton 文档

目标

本指南适用于使用 PyTorch 的生成式 AI 客户、GKE 的新用户或现有用户、机器学习工程师、MLOps (DevOps) 工程师或是对使用 Kubernetes 容器编排功能在 H100、A100 和 L4 GPU 硬件上应用 LLM 感兴趣的平台管理员。

阅读完本指南后,您应该能够执行以下步骤:

  1. 使用处于 Autopilot 模式的 GKE 集群准备环境。
  2. 将使用 Triton 和 TritonRT-LLM 的容器部署到您的集群。
  3. 通过 curl,使用 Triton 和 TensorRT-LLM 应用 Gemma 2B 或 7B 模型。

准备工作

  • 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  • 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  • 确保您的 Google Cloud 项目已启用结算功能

  • 启用所需的 API。

    启用 API

  • 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  • 确保您的 Google Cloud 项目已启用结算功能

  • 启用所需的 API。

    启用 API

  • 确保您拥有项目的以下一个或多个角色: roles/container.admin, roles/iam.serviceAccountAdmin

    检查角色

    1. 在 Google Cloud 控制台中,前往 IAM 页面。

      转到 IAM
    2. 选择项目。
    3. 主账号列中,找到您的电子邮件地址所在的行。

      如果您的电子邮件地址不在此列,则表示您没有任何角色。

    4. 在您的电子邮件地址所在的行对应的角色列中,检查角色列表是否包含所需的角色。

    授予角色

    1. 在 Google Cloud 控制台中,前往 IAM 页面。

      转到 IAM
    2. 选择项目。
    3. 点击 授予访问权限
    4. 新的主账号字段中,输入您的电子邮件地址。
    5. 选择角色列表中,选择一个角色。
    6. 如需授予其他角色,请点击 添加其他角色,然后添加其他各个角色。
    7. 点击 Save(保存)。
  • 如果您还没有 Kaggle 账号,请创建一个。
  • 确保您的项目具有足够的 GPU 配额。如需了解详情,请参阅 GPU 简介分配配额

准备环境

在本教程中,您将使用 Cloud Shell 来管理 Google Cloud 上托管的资源。Cloud Shell 预安装有本教程所需的软件,包括 kubectlgcloud CLI

如需使用 Cloud Shell 设置您的环境,请按照以下步骤操作:

  1. 在 Google Cloud 控制台中,点击 Google Cloud 控制台中的 Cloud Shell 激活图标 激活 Cloud Shell 以启动 Cloud Shell 会话。此操作会在 Google Cloud 控制台的底部窗格中启动会话。

  2. 设置默认环境变量:

    gcloud config set project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export REGION=REGION
    export CLUSTER_NAME=triton
    

    替换以下值:

    • PROJECT_ID:您的 Google Cloud 项目 ID
    • REGION:支持要使用的加速器类型的区域,例如适用于 L4 GPU 的 us-central1

获取对模型的访问权限

如需获取对 Gemma 模型的访问权限,您必须登录 Kaggle 平台并获取 Kaggle API 令牌。

您必须签署同意协议才能使用 Gemma。请按照以下说明操作:

  1. 访问 Kaggle.com 上的模型同意页面
  2. 如果您尚未登录 Kaggle,请进行登录。
  3. 点击申请访问权限
  4. Choose Account for Consent(选择进行同意的账号)部分中,选择 Verify via Kaggle Account(通过 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

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
    

    集群创建可能需要几分钟的时间。

  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}
    
  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 引擎文件

在本部分中,您将运行一个作业以下载 TensorRT-LLM 引擎文件并将文件存储在您之前创建的 PersistentVolume 中。该作业还会准备好配置文件,以便在下一步中将模型部署在 Triton 服务器上。此过程可能需要几分钟的时间。

Gemma 2B-it

该 TensorRT-LLM 引擎基于 Gemma 的 Gemma 2B-it(指令调优)PyTorch 检查点而构建,使用了 bfloat16 激活,输入序列长度=2048,输出序列长度=1024,以 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 引擎基于 Gemma 的 Gemma 7B-it(指令调优)PyTorch 检查点而构建,使用了 bfloat16 激活,输入序列长度=1024,输出序列长度=512,以 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}

后续步骤