Entrega Gemma con TPU en GKE con JetStream

En este instructivo, se muestra cómo entregar un modelo de lenguaje grande (LLM) Gemma con unidades de procesamiento tensorial (TPU) en Google Kubernetes Engine (GKE). Implementas un contenedor prediseñado con JetStream y MaxText en GKE. También configurarás GKE para que cargue las ponderaciones de Gemma 7B desde Cloud Storage en el tiempo de ejecución.

Este instructivo está dirigido a ingenieros de aprendizaje automático (AA), administradores y operadores de plataformas, y especialistas en datos y en IA que estén interesados en usar las capacidades de organización de contenedores de Kubernetes para entregar LLM. Para obtener más información sobre los roles comunes y las tareas de ejemplo a las que hacemos referencia en el contenido deGoogle Cloud , consulta Roles de usuario y tareas comunes de GKE.

Antes de leer esta página, asegúrate de estar familiarizado con lo siguiente:

Fondo

En esta sección, se describen las tecnologías clave que se usan en este instructivo.

Gemma

Gemma es un conjunto de modelos de Inteligencia Artificial (IA) básicos y de disponibilidad general que se lanzan con una licencia abierta. Estos modelos de IA están disponibles para ejecutarse en tus aplicaciones, hardware, dispositivos móviles o servicios alojados. Puedes usar los modelos de Gemma para la generación de texto, pero también puedes ajustar estos modelos en el caso de tareas especializadas.

Para obtener más información, consulta la documentación de Gemma.

TPU

Las TPU son circuitos integrados personalizados específicos de aplicaciones (ASIC) de Google que se usan para acelerar el aprendizaje automático y los modelos de IA compilados con frameworks como el siguiente:TensorFlow, PyTorch yJAX.

En este instructivo se aborda la entrega del modelo Gemma 7B. GKE implementa el modelo en los nodos TPUv5e de host único con topologías de TPU configuradas según los requisitos del modelo para entregar mensajes con baja latencia.

JetStream

JetStream es un framework de entrega de inferencia de código abierto que desarrolla Google. JetStream permite la inferencia de alto rendimiento, alta capacidad de procesamiento y con optimización de memoria en TPU y GPU. Proporciona optimizaciones de rendimiento avanzadas, incluidas técnicas de procesamiento por lotes y de cuantización continuas, para facilitar la implementación de LLM. JetStream permite que PyTorch/XLA y JAX TPU entregue un rendimiento óptimo.

Para obtener más información sobre estas optimizaciones, consulta los repositorios de proyectos de JetStream PyTorch y JetStream MaxText.

MaxText

MaxText es una implementación de LLM JAX escalable y adaptable, compilada en bibliotecas JAX de código abierto como Flax, Orbax y Optax. La implementación de LLM solo de decodificador de MaxText se escribe en Python. Aprovecha en gran medida el compilador XLA para lograr un alto rendimiento sin necesidad de compilar kernels personalizados.

Para obtener más información sobre los modelos y tamaños de parámetros más recientes que admite MaxText, consulta el repositorio del proyecto de MaxtText.

Objetivos

  1. Prepara un clúster de GKE en modo Autopilot o Estándar con la topología de TPU recomendada según las características del modelo.
  2. Implementa componentes de JetStream en GKE.
  3. Obtén y publica el modelo ajustado por instrucciones de Gemma 7B.
  4. Entrega el modelo publicado y, luego, interactúa con él.

Arquitectura

En esta sección, se describe la arquitectura de GKE que se usa en este instructivo. La arquitectura consta de un clúster de GKE en modo Autopilot o Estándar que aprovisiona TPU y aloja componentes de JetStream para implementar y entregar los modelos.

En el siguiente diagrama, se muestran los componentes de esta arquitectura:

Arquitectura del clúster de GKE con grupos de nodos TPU de host único que contienen los componentes HTTP de Maxengine y Max.

Esta arquitectura incluye los siguientes componentes:

  • Un clúster regional de GKE en modo Autopilot o Estándar.
  • Dos grupos de nodos de porción de TPU de host único que alojan la implementación de JetStream.
  • El componente de Service distribuye el tráfico entrante a todas las réplicas de JetStream HTTP.
  • JetStream HTTP es un servidor HTTP que acepta solicitudes como wrapper del formato requerido de JetStream y las envía al cliente GRPC de JetStream.
  • Maxengine es un servidor de JetStream que ejecuta inferencias con procesamiento por lotes continuo.

Antes de comenzar

  • 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.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

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

    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.

      Ir a IAM
    2. Selecciona el proyecto.
    3. Haz clic en Otorgar acceso.
    4. En el campo Principales nuevas, ingresa tu identificador de usuario. Esta suele ser la dirección de correo electrónico de una Cuenta de Google.

    5. En la lista Seleccionar un rol, elige uno.
    6. Para otorgar roles adicionales, haz clic en Agregar otro rol y agrega uno más.
    7. Haz clic en Guardar.
      • Asegúrate de tener suficiente cuota para ocho chips TPU v5e PodSlice Lite. En este instructivo, usarás instancias bajo demanda.
      • Crea una cuenta de Kaggle, si todavía no tienes una.

      Obtén acceso al modelo

      A fin de obtener acceso al modelo de Gemma para la implementación en GKE, primero debes firmar el acuerdo de consentimiento de licencia.

      Debes firmar el acuerdo de consentimiento para usar Gemma. Sigue estas instrucciones:

      1. Accede a la página de consentimiento del modelo de Gemma en Kaggle.com.
      2. Accede a Kaggle si aún no lo hiciste.
      3. Haz clic en Solicitar acceso.
      4. En la sección Elegir cuenta para el consentimiento, selecciona Verificar mediante la cuenta de Kaggle para usar tu cuenta de Kaggle para obtener el consentimiento.
      5. Acepta los Términos y Condiciones del modelo.

      Genera un token de acceso

      Para acceder al modelo a través de Kaggle, necesitas un token de la API de Kaggle.

      Sigue estos pasos para generar un token nuevo si aún no tienes uno:

      1. En el navegador, ve a la configuración de Kaggle.
      2. En la sección API, haz clic en Crear token nuevo.

      Se descargará un archivo con el nombre kaggle.json.

      Prepare el entorno

      En este instructivo, usarás Cloud Shell para administrar recursos alojados enGoogle Cloud. Cloud Shell tiene preinstalado el software que necesitarás para este instructivo, incluidos kubectl y la CLI de gcloud.

      Para configurar tu entorno con Cloud Shell, sigue estos pasos:

      1. En la Google Cloud consola, haz clic en Ícono de activación de Cloud Shell Activar Cloud Shell en la Google Cloud consola para iniciar una sesión de Cloud Shell. Esto inicia una sesión en el panel inferior de la consola de Google Cloud .

      2. Configura las variables de entorno predeterminadas:

        gcloud config set project PROJECT_ID
        gcloud config set billing/quota_project PROJECT_ID
        export PROJECT_ID=$(gcloud config get project)
        export CLUSTER_NAME=CLUSTER_NAME
        export BUCKET_NAME=BUCKET_NAME
        export CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATION
        export NODE_LOCATION=NODE_LOCATION
        export CLUSTER_VERSION=CLUSTER_VERSION
        

        Reemplaza los siguientes valores:

        • PROJECT_ID: Es el Google Cloud ID de tu proyecto.
        • CLUSTER_NAME: Es el nombre del clúster de GKE.
        • BUCKET_NAME: Es el nombre de tu bucket de Cloud Storage. No es necesario especificar el prefijo gs://.
        • CONTROL_PLANE_LOCATION: La región de Compute Engine del plano de control de tu clúster. Esta región debe contener zonas en las que los tipos de máquinas de TPU v5e estén disponibles (por ejemplo, us-west1, us-west4, us-central1, us-east1, us-east5 o europe-west4). Para los clústeres de Autopilot, asegúrate de tener suficientes recursos zonales de TPU v5e para la región que elijas.
        • (Solo clúster estándar) NODE_LOCATION: Es la zona en la que los recursos de TPU están disponibles (por ejemplo, us-west4-a). Para los clústeres de Autopilot, no necesitas especificar este valor.
        • CLUSTER_VERSION: la versión de GKE, que debe ser compatible con el tipo de máquina que deseas usar. Ten en cuenta que es posible que la versión predeterminada de GKE no tenga disponibilidad para la TPU de destino. Para obtener una lista de las versiones mínimas de GKE disponibles por tipo de máquina de TPU, consulta disponibilidad de TPU en GKE.

      Crea y configura recursos de Google Cloud

      Sigue estas instrucciones para crear los recursos necesarios.

      Crea un clúster de GKE

      Puedes entregar Gemma en TPU en un clúster de GKE Autopilot o Estándar. Te recomendamos que uses un clúster en modo Autopilot para una experiencia de Kubernetes completamente administrada. Para elegir el modo de operación de GKE que se adapte mejor a tus cargas de trabajo, consulta Elige un modo de operación de GKE.

      Autopilot

      En Cloud Shell, ejecuta el siguiente comando:

      gcloud container clusters create-auto ${CLUSTER_NAME} \
        --project=${PROJECT_ID} \
        --location=${CONTROL_PLANE_LOCATION} \
        --cluster-version=${CLUSTER_VERSION}
      

      Estándar

      1. Crea un clúster de GKE Estándar regional que use la federación de identidades para cargas de trabajo en GKE.

        gcloud container clusters create ${CLUSTER_NAME} \
            --enable-ip-alias \
            --machine-type=e2-standard-4 \
            --num-nodes=2 \
            --cluster-version=${CLUSTER_VERSION} \
            --workload-pool=${PROJECT_ID}.svc.id.goog \
            --location=${CONTROL_PLANE_LOCATION}
        

        La creación del clúster puede tomar varios minutos.

      2. Ejecuta el siguiente comando a la hora de crear un grupo de nodos para el clúster:

        gcloud container node-pools create gemma-7b-tpu-nodepool \
          --cluster=${CLUSTER_NAME} \
          --machine-type=ct5lp-hightpu-8t \
          --project=${PROJECT_ID} \
          --num-nodes=2 \
          --location=${CONTROL_PLANE_LOCATION} \
          --node-locations=${NODE_LOCATION}
        

        GKE crea un grupo de nodos TPU v5e con una topología 2x4 y dos nodos.

      Crea un bucket de Cloud Storage

      En Cloud Shell, ejecuta el siguiente comando:

      gcloud storage buckets create gs://${BUCKET_NAME} --location=${CONTROL_PLANE_LOCATION}
      

      Esto crea un bucket de Cloud Storage para almacenar los archivos del modelo que descargas de Kaggle.

      Sube el token de acceso a Cloud Shell

      En Cloud Shell, puedes subir el token de la API de Kaggle a tu proyecto Google Cloud:

      1. En Cloud Shell, haz clic en Más > Subir.
      2. Elige Archivo y haz clic en Elegir archivos.
      3. Abre el archivo kaggle.json.
      4. Haz clic en Subir.

      Crea un secreto de Kubernetes para las credenciales de Docker

      En Cloud Shell, haz lo siguiente:

      1. Configura kubectl para comunicarse con tu clúster:

        gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${CONTROL_PLANE_LOCATION}
        
      2. Crea un secreto para almacenar las credenciales de Kaggle:

        kubectl create secret generic kaggle-secret \
            --from-file=kaggle.json
        

      Configura el acceso a tus cargas de trabajo con la federación de identidades para cargas de trabajo en GKE

      Asigna una Cuenta de servicio de Kubernetes a la aplicación y configúrala para que actúe como una cuenta de servicio de IAM.

      1. Crea una cuenta de servicio de IAM para tu aplicación:

        gcloud iam service-accounts create wi-jetstream
        
      2. Agrega una vinculación de política de IAM para que tu cuenta de servicio de IAM administre Cloud Storage:

        gcloud projects add-iam-policy-binding ${PROJECT_ID} \
            --member "serviceAccount:wi-jetstream@${PROJECT_ID}.iam.gserviceaccount.com" \
            --role roles/storage.objectUser
        
        gcloud projects add-iam-policy-binding ${PROJECT_ID} \
            --member "serviceAccount:wi-jetstream@${PROJECT_ID}.iam.gserviceaccount.com" \
            --role roles/storage.insightsCollectorService
        
      3. Para permitir que la cuenta de servicio de Kubernetes actúe en nombre de la cuenta de servicio de IAM, agrega una vinculación de política de IAM entre las dos. Esta vinculación permite que la cuenta de servicio de Kubernetes actúe como la cuenta de servicio de IAM.

        gcloud iam service-accounts add-iam-policy-binding wi-jetstream@${PROJECT_ID}.iam.gserviceaccount.com \
            --role roles/iam.workloadIdentityUser \
            --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/default]"
        
      4. Anota la cuenta de servicio de Kubernetes con la dirección de correo electrónico de la cuenta de servicio de IAM.

        kubectl annotate serviceaccount default \
            iam.gke.io/gcp-service-account=wi-jetstream@${PROJECT_ID}.iam.gserviceaccount.com
        

      Convierte los puntos de control del modelo

      En esta sección, crearás un trabajo para llevar a cabo la siguiente acción:

      1. Descarga el punto de control base de Orbax desde Kaggle.
      2. Sube el punto de control a un bucket de Cloud Storage.
      3. Convierte el punto de control en un punto de control compatible con MaxText.
      4. Anula el análisis del punto de control que se usará para la entrega.

      Implementa el trabajo de conversión de punto de control del modelo

      Sigue estas instrucciones para descargar y convertir los archivos de punto de control del modelo Gemma 7B. En este instructivo, se usa un trabajo de Kubernetes. Un controlador de Job en Kubernetes crea uno o más Pods y garantiza que ejecuten correctamente una tarea específica.

      1. Crea el siguiente manifiesto como job-7b.yaml.

        apiVersion: batch/v1
        kind: Job
        metadata:
          name: data-loader-7b
        spec:
          ttlSecondsAfterFinished: 30
          template:
            spec:
              restartPolicy: Never
              containers:
              - name: inference-checkpoint
                image: us-docker.pkg.dev/cloud-tpu-images/inference/inference-checkpoint:v0.2.4
                args:
                - -b=BUCKET_NAME
                - -m=google/gemma/maxtext/7b-it/2
                volumeMounts:
                - mountPath: "/kaggle/"
                  name: kaggle-credentials
                  readOnly: true
                resources:
                  requests:
                    google.com/tpu: 8
                  limits:
                    google.com/tpu: 8
              nodeSelector:
                cloud.google.com/gke-tpu-topology: 2x4
                cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
              volumes:
              - name: kaggle-credentials
                secret:
                  defaultMode: 0400
                  secretName: kaggle-secret
        
      2. Aplica el manifiesto

        kubectl apply -f job-7b.yaml
        
      3. Espera a que el Pod que programa el trabajo comience a ejecutarse:

        kubectl get pod -w
        

        El resultado será similar al siguiente, y puede tardar unos minutos:

        NAME                  READY   STATUS              RESTARTS   AGE
        data-loader-7b-abcd   0/1     ContainerCreating   0          28s
        data-loader-7b-abcd   1/1     Running             0          51s
        

        En el caso de los clústeres Autopilot, puede tardar unos minutos en aprovisionar los recursos TPU necesarios.

      4. Visualiza los registros del trabajo:

        kubectl logs -f jobs/data-loader-7b
        

        Cuando se completa el trabajo, el resultado es similar al siguiente:

        Successfully generated decode checkpoint at: gs://BUCKET_NAME/final/unscanned/gemma_7b-it/0/checkpoints/0/items
        + echo -e '\nCompleted unscanning checkpoint to gs://BUCKET_NAME/final/unscanned/gemma_7b-it/0/checkpoints/0/items'
        
        Completed unscanning checkpoint to gs://BUCKET_NAME/final/unscanned/gemma_7b-it/0/checkpoints/0/items
        

      Implementa JetStream

      En esta sección, implementarás el contenedor de JetStream para entregar el modelo de Gemma.

      Sigue estas instrucciones para implementar el modelo ajustado por instrucciones de Gemma 7B. En este instructivo, se usa una implementación de Kubernetes. Un Deployment es un objeto de la API de Kubernetes que te permite ejecutar varias réplicas de Pods que se distribuyen entre los nodos de un clúster.

      1. Guarda el siguiente manifiesto de Deployment como jetstream-gemma-deployment.yaml:

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: maxengine-server
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: maxengine-server
          template:
            metadata:
              labels:
                app: maxengine-server
            spec:
              nodeSelector:
                cloud.google.com/gke-tpu-topology: 2x4
                cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
              containers:
              - name: maxengine-server
                image: us-docker.pkg.dev/cloud-tpu-images/inference/maxengine-server:v0.2.2
                args:
                - model_name=gemma-7b
                - tokenizer_path=assets/tokenizer.gemma
                - per_device_batch_size=4
                - max_prefill_predict_length=1024
                - max_target_length=2048
                - async_checkpointing=false
                - ici_fsdp_parallelism=1
                - ici_autoregressive_parallelism=-1
                - ici_tensor_parallelism=1
                - scan_layers=false
                - weight_dtype=bfloat16
                - load_parameters_path=gs://BUCKET_NAME/final/unscanned/gemma_7b-it/0/checkpoints/0/items
                - prometheus_port=PROMETHEUS_PORT
                ports:
                - containerPort: 9000
                resources:
                  requests:
                    google.com/tpu: 8
                  limits:
                    google.com/tpu: 8
              - name: jetstream-http
                image: us-docker.pkg.dev/cloud-tpu-images/inference/jetstream-http:v0.2.2
                ports:
                - containerPort: 8000
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: jetstream-svc
        spec:
          selector:
            app: maxengine-server
          ports:
          - protocol: TCP
            name: jetstream-http
            port: 8000
            targetPort: 8000
          - protocol: TCP
            name: jetstream-grpc
            port: 9000
            targetPort: 9000
        

        El manifiesto establece las siguientes propiedades clave:

        • tokenizer_path: La ruta de acceso al tokenizador de tu modelo.
        • load_parameters_path: La ruta de acceso en el bucket de Cloud Storage en el que se almacenan tus puntos de control.
        • per_device_batch_size: Es el tamaño del lote de decodificación por dispositivo, en el que un chip TPU equivale a un dispositivo.
        • max_prefill_predict_length: La longitud máxima del relleno previo cuando se realiza la regresión automática.
        • max_target_length: La longitud máxima de la secuencia.
        • model_name: Es el nombre del modelo (gemma-7b).
        • ici_fsdp_parallelism: La cantidad de fragmentos para el paralelismo de datos fragmentados por completo (FSDP).
        • ici_tensor_parallelism: La cantidad de fragmentos para el paralelismo de tensor.
        • ici_autoregressive_parallelism: La cantidad de fragmentos para el paralelismo autorregresivo.
        • prometheus_port: Es el puerto para exponer las métricas de Prometheus. Quita este argumento si no se necesitan métricas.
        • scan_layers: capas de análisis de marca booleana (booleana).
        • weight_dtype: El tipo de datos del peso (bfloat16).
      2. Aplica el manifiesto

        kubectl apply -f jetstream-gemma-deployment.yaml
        
      3. Verifica la implementación:

        kubectl get deployment
        

        El resultado es similar a este:

        NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
        maxengine-server                  2/2     2            2           ##s
        

        En el caso de los clústeres Autopilot, puede tardar unos minutos en aprovisionar los recursos TPU necesarios.

      4. Consulta los registros del servidor HTTP para comprobar que el modelo se cargó y compiló. Es posible que el servidor tarde unos minutos en completar esta operación.

        kubectl logs deploy/maxengine-server -f -c jetstream-http
        

        El resultado es similar al siguiente:

        kubectl logs deploy/maxengine-server -f -c jetstream-http
        
        INFO:     Started server process [1]
        INFO:     Waiting for application startup.
        INFO:     Application startup complete.
        INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
        
      5. Visualiza los registros de MaxEngine y comprueba que se haya completado la compilación.

        kubectl logs deploy/maxengine-server -f -c maxengine-server
        

        El resultado es similar al siguiente:

        2024-03-29 17:09:08,047 - jax._src.dispatch - DEBUG - Finished XLA compilation of jit(initialize) in 0.26236414909362793 sec
        2024-03-29 17:09:08,150 - root - INFO - ---------Generate params 0 loaded.---------
        

      Entrega el modelo

      En esta sección, interactuarás con el modelo.

      Configura la redirección de puertos

      Puedes acceder a la implementación de JetStream a través del Service de ClusterIP que creaste en el paso anterior. Solo se puede acceder a los servicios de ClusterIP desde el clúster. Por lo tanto, para acceder al servicio desde fuera del clúster, completa los siguientes pasos:

      Para establecer una sesión de redirección de puertos, ejecuta el siguiente comando:

      kubectl port-forward svc/jetstream-svc 8000:8000
      

      Interactúa con el modelo con curl

      1. Para comprobar que puedes acceder al servidor HTTP de JetStream, abre una terminal nueva y ejecuta el siguiente comando:

        curl --request POST \
        --header "Content-type: application/json" \
        -s \
        localhost:8000/generate \
        --data \
        '{
            "prompt": "What are the top 5 programming languages",
            "max_tokens": 200
        }'
        

        La solicitud inicial puede tardar varios segundos en completarse debido a la preparación del modelo. El resultado es similar al siguiente:

        {
            "response": "\nfor data science in 2023?\n\n**1. Python:**\n- Widely used for data science due to its simplicity, readability, and extensive libraries for data wrangling, analysis, visualization, and machine learning.\n- Popular libraries include pandas, scikit-learn, and matplotlib.\n\n**2. R:**\n- Statistical programming language widely used for data analysis, visualization, and modeling.\n- Popular libraries include ggplot2, dplyr, and caret.\n\n**3. Java:**\n- Enterprise-grade language with strong performance and scalability.\n- Popular libraries include Spark, TensorFlow, and Weka.\n\n**4. C++:**\n- High-performance language often used for data analytics and machine learning models.\n- Popular libraries include TensorFlow, PyTorch, and OpenCV.\n\n**5. SQL:**\n- Relational database language essential for data wrangling and querying large datasets.\n- Popular tools"
        }
        

      Interactúa con el modelo a través de una interfaz de chat de Gradio (opcional)

      En esta sección, compilarás una aplicación de chat web que te permita interactuar con el modelo ajustado a instrucciones.

      Gradio es una biblioteca de Python que tiene un wrapper ChatInterface de ChatInterface que crea interfaces de usuario para chatbots.

      Implementa la interfaz de chat

      1. En Cloud Shell, guarda el siguiente manifiesto YAML como gradio.yaml:

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: gradio
          labels:
            app: gradio
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: gradio
          template:
            metadata:
              labels:
                app: gradio
            spec:
              containers:
              - name: gradio
                image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.3
                resources:
                  requests:
                    cpu: "512m"
                    memory: "512Mi"
                  limits:
                    cpu: "1"
                    memory: "512Mi"
                env:
                - name: CONTEXT_PATH
                  value: "/generate"
                - name: HOST
                  value: "http://jetstream-svc:8000"
                - name: LLM_ENGINE
                  value: "max"
                - name: MODEL_ID
                  value: "gemma"
                - name: USER_PROMPT
                  value: "<start_of_turn>user\nprompt<end_of_turn>\n"
                - name: SYSTEM_PROMPT
                  value: "<start_of_turn>model\nprompt<end_of_turn>\n"
                ports:
                - containerPort: 7860
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: gradio
        spec:
          selector:
            app: gradio
          ports:
            - protocol: TCP
              port: 8080
              targetPort: 7860
          type: ClusterIP
        
      2. Aplica el manifiesto

        kubectl apply -f gradio.yaml
        
      3. Espera a que la implementación esté disponible:

        kubectl wait --for=condition=Available --timeout=300s deployment/gradio
        

      Usa la interfaz de chat

      1. En Cloud Shell, ejecuta el siguiente comando:

        kubectl port-forward service/gradio 8080:8080
        

        Esto crea una redirección de puertos desde Cloud Shell al servicio de Gradio.

      2. Haz clic en el botón Ícono de vista previa en la Web Vista previa en la Web, que se encuentra en la parte superior derecha de la barra de tareas de Cloud Shell. Haga clic en Vista previa en el puerto 8080. Se abrirá una pestaña nueva en el navegador.

      3. Interactúa con Gemma con la interfaz de chat de Gradio. Agrega un mensaje y haz clic en Enviar.

      Soluciona problemas

      • Si recibes el mensaje Empty reply from server, es posible que el contenedor no haya terminado de descargar los datos del modelo. Vuelve a verificar los registros del Pod en busca del mensaje Connected, que indica que el modelo está listo para entregar.
      • Si ves Connection refused, verifica que tu redirección de puertos esté activa.

      Realiza una limpieza

      Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

      Borra los recursos implementados

      Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que creaste en esta guía, ejecuta los siguientes comandos y sigue las indicaciones:

      gcloud container clusters delete ${CLUSTER_NAME} --location=${CONTROL_PLANE_LOCATION}
      
      gcloud iam service-accounts delete wi-jetstream@PROJECT_ID.iam.gserviceaccount.com
      
      gcloud storage rm --recursive gs://BUCKET_NAME
      

      ¿Qué sigue?