Acelera la carga de datos de IA/AA con Hyperdisk ML


En esta guía, se explica cómo simplificar y acelerar la carga de pesos de modelos de IA/ML en Google Kubernetes Engine (GKE) con Hyperdisk ML. El controlador de CSI de Persistent Disk para Compute Engine es la forma principal en la que puedes acceder al almacenamiento de Hyperdisk ML con clústeres de GKE.

Descripción general

Hyperdisk ML es una solución de almacenamiento de alto rendimiento que se puede usar para escalar horizontalmente tus aplicaciones. Proporciona una alta capacidad de procesamiento agregada a muchas máquinas virtuales de forma simultánea, por lo que es ideal si deseas ejecutar cargas de trabajo de IA/AA que necesitan acceso a grandes cantidades de datos.

Cuando se habilita en el modo de solo lectura para varios, puedes usar Hyperdisk ML para acelerar la carga de pesos del modelo hasta en 11.9 veces en comparación con la carga directamente desde un registro de modelos. Esta aceleración es posible gracias a la arquitectura de Google Cloud Hyperdisk, que permite escalar hasta 2,500 nodos simultáneos a 1.2 TB/s. Esto te permite impulsar mejores tiempos de carga y reducir el aprovisionamiento excesivo de Pods para tus cargas de trabajo de inferencia de IA/AA.

Los pasos de alto nivel para crear y usar Hyperdisk ML son los siguientes:

  1. Almacena en caché previamente o hidrata los datos en una imagen de disco de Persistent Disk: carga volúmenes de Hyperdisk ML con datos de una fuente de datos externa (por ejemplo, pesos de Gemma cargados desde Cloud Storage) que se pueden usar para la publicación. El Persistent Disk para la imagen de disco debe ser compatible con Google Cloud Hyperdisk.
  2. Crea un volumen de Hyperdisk ML con un Hyperdisk de Google Cloud preexistente: Crea un volumen de Kubernetes que haga referencia al volumen de Hyperdisk de AA cargado con datos. De manera opcional, puedes crear clases de almacenamiento multizona para garantizar que tus datos estén disponibles en todas las zonas en las que se ejecutarán tus Pods.
  3. Crea una implementación de Kubernetes para consumir el volumen de Hyperdisk ML: Haz referencia al volumen de Hyperdisk ML con carga de datos acelerada para que lo consuman tus aplicaciones.

Volúmenes de Hyperdisk ML multizona

Los discos de Hyperdisk ML solo están disponibles en una zona. De manera opcional, puedes usar la función multizona de Hyperdisk ML para vincular de forma dinámica varios discos zonales que tengan el mismo contenido en un solo recurso lógico PersistentVolumeClaim y PersistentVolume. Los discos zonales a los que hace referencia la función multizona deben estar ubicados en la misma región. Por ejemplo, si tu clúster regional se crea en us-central1, los discos multizona deben ubicarse en la misma región (por ejemplo, us-central1-a, us-central1-b).

Un caso de uso común para la inferencia de IA/AA es ejecutar Pods en varias zonas para mejorar la disponibilidad del acelerador y la eficiencia de costos con VMs Spot. Dado que Hyperdisk ML es zonal, si tu servidor de inferencia ejecuta muchos Pods en varias zonas, GKE clona automáticamente los discos en todas las zonas para garantizar que tus datos sigan a tu aplicación.

Hidratación de Hyperdisk ML de fuentes de datos externas y creación de PV multizona para acceder a los datos entre zonas.

Los volúmenes de Hyperdisk ML multizona tienen las siguientes limitaciones:

  • No se admiten las operaciones de cambio de tamaño de volumen ni de instantáneas de volumen.
  • Los volúmenes de Hyperdisk ML multizona solo son compatibles en modo de solo lectura.
  • Cuando se usan discos preexistentes con un volumen de Hyperdisk ML multizona, GKE no realiza verificaciones para validar que el contenido del disco en todas las zonas sea el mismo. Si alguno de los discos tiene contenido divergente, asegúrate de que tu aplicación tenga en cuenta las posibles inconsistencias entre las zonas.

Para obtener más información, consulta Crea un volumen de Hyperdisk ML de ReadOnlyMany multizonal desde una VolumeSnapshot.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.
  • Establece tu región y zona predeterminadas en uno de los valores admitidos.
  • Asegúrate de que tu proyecto de Google Cloud tenga cuota suficiente para crear los nodos necesarios en esta guía. El código de ejemplo para el clúster de GKE y la creación de recursos de Kubernetes requieren la siguiente cuota mínima en la región que elijas: 88 CPU C3, 8 GPUs NVIDIA L4.

Requisitos

Para usar los volúmenes de Hyperdisk ML en GKE, tus clústeres deben cumplir los siguientes requisitos:

  • Usa clústeres de Linux que ejecuten la versión 1.30.2-gke.1394000 de GKE o una posterior. Si usas un canal de versiones, asegúrate de que el canal tenga la versión mínima de GKE o una posterior para este controlador.
  • Asegúrate de que el controlador de CSI de Persistent Disk para Compute Engine esté habilitado. El controlador de Persistent Disk para Compute Engine está habilitado de forma predeterminada en los clústeres nuevos de Autopilot y Standard y no se puede inhabilitar ni editar cuando se usa Autopilot. Si necesitas habilitar el controlador de CSI de Persistent Disk de Compute Engine desde tu clúster, consulta Habilita el controlador de CSI de disco persistente de Compute Engine en un clúster existente.
  • Si deseas ajustar el valor de lectura anticipada, usa la versión de GKE 1.29.2-gke.1217000 o una posterior.
  • Si deseas usar la función de aprovisionamiento dinámico multizona, usa la versión 1.30.2-gke.1394000 de GKE o una posterior.
  • Hyperdisk ML solo se admite en ciertos tipos de nodos y zonas. Para obtener más información, consulta Acerca de Google Cloud Hyperdisk en la documentación de Compute Engine.

Obtén acceso al modelo

Para obtener acceso a los modelos de Gemma para la implementación en GKE, primero debes firmar el contrato de consentimiento de licencia y, luego, generar un token de acceso de Hugging Face.

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

  1. Accede a la página de consentimiento del modelo en Kaggle.com.
  2. Verifica el consentimiento con tu cuenta de Hugging Face.
  3. Acepta los términos del modelo.

Genera un token de acceso

Para acceder al modelo a través de Hugging Face, necesitarás un token de Hugging Face.

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

  1. Haz clic en Tu perfil > Configuración > Tokens de acceso.
  2. Selecciona Token nuevo.
  3. Especifica el nombre que desees y un rol de al menos Read.
  4. Selecciona Genera un token.
  5. Copia el token generado al portapapeles.

Cree un clúster de GKE

Puedes entregar LLM en GPU en un clúster de GKE Autopilot o Standard. Te recomendamos que uses un clúster de 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

  1. En Cloud Shell, ejecute el siguiente comando:

    gcloud container clusters create-auto hdml-gpu-l4 \
      --project=PROJECT \
      --region=REGION \
      --release-channel=rapid \
      --cluster-version=1.30.2-gke.1394000
    

    Reemplaza los siguientes valores:

    • PROJECT: el ID del proyecto de Google Cloud.
    • REGION: una región que admita el tipo de acelerador que deseas usar, por ejemplo, us-east4 para la GPU L4.

    GKE crea un clúster de Autopilot con nodos de CPU y GPU según lo solicitan las cargas de trabajo implementadas.

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

    gcloud container clusters get-credentials hdml-gpu-l4 \
      --region=REGION
    

Estándar

  1. En Cloud Shell, ejecuta el siguiente comando para crear un clúster de Standard y grupos de nodos:

    gcloud container clusters create hdml-gpu-l4 \
        --location=REGION \
        --num-nodes=1 \
        --machine-type=c3-standard-44 \
        --release-channel=rapid \
        --cluster-version=CLUSTER_VERSION \
        --node-locations=ZONES \
        --project=PROJECT
    
    gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \
        --location=REGION \
        --project=PROJECT \
        --node-locations=ZONES \
        --cluster=hdml-gpu-l4 \
        --machine-type=g2-standard-24 \
        --num-nodes=2
    

    Reemplaza los siguientes valores:

    • CLUSTER_VERSION: La versión de tu clúster de GKE (por ejemplo, 1.30.2-gke.1394000).
    • REGION: La región de procesamiento del plano de control del clúster. La región debe admitir el acelerador que deseas usar, por ejemplo, us-east4, para la GPU L4. Verifica en qué regiones están disponibles las GPUs L4.
    • ZONES: son las zonas en las que se crean los nodos. Puedes especificar tantas zonas como sea necesario para tu clúster. Todas las zonas deben estar en la misma región que el plano de control del clúster, especificado por la marca --zone. En el caso de los clústeres zonales, --node-locations debe contener la zona principal del clúster.
    • PROJECT: el ID del proyecto de Google Cloud.

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

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

    gcloud container clusters get-credentials hdml-gpu-l4
    

Cómo almacenar datos en caché previamente en una imagen de disco de Persistent Disk

Para usar Hyperdisk ML, almacenas en caché los datos en una imagen de disco y creas un volumen de Hyperdisk ML para que tu carga de trabajo en GKE tenga acceso de lectura. Este enfoque (también llamado hidratación de datos) garantiza que tus datos estén disponibles cuando tu carga de trabajo lo necesite.

Para copiar los datos de Cloud Storage y almacenar en caché previamente una imagen de disco de disco persistente, sigue estos pasos:

Crea una StorageClass que admita Hyperdisk ML

  1. Guarda el siguiente manifiesto StorageClass como un archivo llamado hyperdisk-ml.yaml:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
        name: hyperdisk-ml
    parameters:
        type: hyperdisk-ml
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    
  2. Para crear una StorageClass, ejecuta este comando:

    kubectl create -f hyperdisk-ml.yaml
    

Crea un PersistentVolumeClaim ReadWriteOnce (RWO)

  1. Guarda el siguiente manifiesto de PersistentVolumeClaim en un archivo llamado producer-pvc.yaml. Usarás el StorageClass que creaste anteriormente. Asegúrate de que tu disco tenga capacidad suficiente para almacenar tus datos.

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: producer-pvc
    spec:
      storageClassName: hyperdisk-ml
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 300Gi
    
  2. Ejecuta el siguiente comando para crear la PersistentVolumeClaim:

    kubectl create -f producer-pvc.yaml
    

Crea un trabajo de Kubernetes para propagar el volumen de Google Cloud Hyperdisk activado

En esta sección, se muestra un ejemplo de cómo crear un trabajo de Kubernetes que aprovisiona un disco y descarga el modelo ajustado de instrucciones Gemma 7B de Hugging Face en el volumen Google Cloud Hyperdisk activado.

  1. Para acceder al LLM de Gemma que usan los ejemplos de esta guía, crea un Secret de Kubernetes que contenga el token de Hugging Face:

    kubectl create secret generic hf-secret \
        --from-literal=hf_api_token=HF_TOKEN\
        --dry-run=client -o yaml | kubectl apply -f -
    

    Reemplaza HF_TOKEN por el token de Hugging Face que generaste antes.

  2. Guarda el siguiente manifiesto de ejemplo como producer-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: producer-job
    spec:
      template:  # Template for the Pods the Job will create
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: cloud.google.com/compute-class
                    operator: In
                    values:
                    - "Performance"
                - matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                    - "c3"
                - matchExpressions:
                  - key: topology.kubernetes.io/zone
                    operator: In
                    values:
                    - "ZONE"
          containers:
          - name: copy
            resources:
              requests:
                cpu: "32"
              limits:
                cpu: "32"
            image: huggingface/downloader:0.17.3
            command: [ "huggingface-cli" ]
            args:
            - download
            - google/gemma-1.1-7b-it
            - --local-dir=/data/gemma-7b
            - --local-dir-use-symlinks=False
            env:
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
              - mountPath: "/data"
                name: volume
          restartPolicy: Never
          volumes:
            - name: volume
              persistentVolumeClaim:
                claimName: producer-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 4        # Max retries on failure
    

    Reemplaza ZONE por la zona de procesamiento en la que deseas que se cree el Hyperdisk. Si lo usas con el ejemplo de Deployment, asegúrate de que sea una zona que tenga capacidad de máquina G2.

  3. Ejecuta este comando para crear el trabajo:

    kubectl apply -f producer-job.yaml
    

    Es posible que la tarea tarde unos minutos en terminar de copiar los datos en el volumen de Persistent Disk. Cuando el trabajo completa el aprovisionamiento, su estado se marca como “Completo”.

  4. Para verificar el progreso del estado de tu trabajo, ejecuta el siguiente comando:

    kubectl get job producer-job
    
  5. Una vez que se complete el trabajo, puedes ejecutar este comando para limpiarlo:

    kubectl delete job producer-job
    

Crea un volumen de Hyperdisk ML ReadOnlyMany a partir de un Google Cloud Hyperdisk preexistente

En esta sección, se abordan los pasos para crear un par de PersistentVolume ReadOnlyMany (ROM) y PersistentVolumeClaim a partir de un volumen de Google Cloud Hyperdisk preexistente. Para obtener más información, consulta Usa discos persistentes preexistentes como PersistentVolumes.

  1. En la versión 1.30.2-gke.1394000 y posteriores de GKE, GKE convierte de forma automática el modo de acceso de un volumen READ_WRITE_SINGLE de Google Cloud Hyperdisk a READ_ONLY_MANY.

    Si usas un volumen de Google Cloud Hyperdisk preexistente en una versión anterior de GKE, debes modificar el modo de acceso de forma manual mediante la ejecución del siguiente comando:

    gcloud compute disks update HDML_DISK_NAME \
        --zone=ZONE \
        --access-mode=READ_ONLY_MANY
    

    Reemplaza los siguientes valores:

    • HDML_DISK_NAME: el nombre de tu volumen de Hyperdisk ML.
    • ZONE: la zona de procesamiento en la que se crea el volumen de Google Cloud Hyperdisk preexistente.
  2. Crea un par de PersistentVolume y PersistentVolumeClaim, con referencia al disco que propagaste antes.

    1. Guarda el siguiente manifiesto como hdml-static-pv.yaml:

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: hdml-static-pv
      spec:
        storageClassName: "hyperdisk-ml"
        capacity:
          storage: 300Gi
        accessModes:
          - ReadOnlyMany
        claimRef:
          namespace: default
          name: hdml-static-pvc
        csi:
          driver: pd.csi.storage.gke.io
          volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
          fsType: ext4
          readOnly: true
        nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.gke.io/zone
                operator: In
                values:
                - ZONE
      ---
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        namespace: default
        name: hdml-static-pvc
      spec:
        storageClassName: "hyperdisk-ml"
        volumeName: hdml-static-pv
        accessModes:
        - ReadOnlyMany
        resources:
          requests:
            storage: 300Gi
      

      Reemplaza los siguientes valores:

      • PROJECT: es el proyecto en el que se crea tu clúster de GKE.
      • ZONE: la zona en la que se crea el volumen de Google Cloud Hyperdisk preexistente.
      • DISK_NAME: el nombre del volumen de Google Cloud Hyperdisk preexistente.
    2. Ejecuta este comando para crear los recursos de PersistentVolume y PersistentVolumeClaim:

      kubectl apply -f hdml-static-pv.yaml
      

Crea un volumen de Hyperdisk ML ReadOnlyMany de varias zonas a partir de un VolumeSnapshot

En esta sección, se abordan los pasos para crear un volumen de Hyperdisk ML multizona en modo de acceso ReadOnlyMany. Usa una VolumeSnapshot para una imagen de disco de Persistent Disk preexistente. Para obtener más información, consulta Crea una copia de seguridad del almacenamiento de Persistent Disk con instantáneas de volumen.

Para crear el volumen de Hyperdisk ML multizona, sigue estos pasos:

Crea una VolumeSnapshot de tu disco

  1. Guarda el siguiente manifiesto como un archivo llamado disk-image-vsc.yaml:

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshotClass
    metadata:
      name: disk-image-vsc
    driver: pd.csi.storage.gke.io
    deletionPolicy: Delete
    parameters:
      snapshot-type: images
    
  2. Crea una VolumeSnapshotClass mediante la ejecución del siguiente comando:

    kubectl apply -f disk-image-vsc.yaml
    
  3. Guarda el siguiente manifiesto como un archivo llamado my-snapshot.yaml: Harás referencia a la PersistentVolumeClaim que creaste antes en Crea una PersistentVolumeClaim ReadWriteOnce (RWO).

    apiVersion: snapshot.storage.k8s.io/v1
    kind: VolumeSnapshot
    metadata:
      name: my-snapshot
    spec:
      volumeSnapshotClassName: disk-image-vsc
      source:
        persistentVolumeClaimName: producer-pvc
    
  4. Para crear la VolumeSnapshot, ejecuta el siguiente comando:

    kubectl apply -f my-snapshot.yaml
    
  5. Cuando la VolumeSnapshot esté marcada como "Lista", ejecuta el siguiente comando para crear el volumen de Hyperdisk ML:

    kubectl wait --for=jsonpath='{.status.readyToUse}'=true \
        --timeout=300s volumesnapshot my-snapshot
    

Crea una StorageClass multizona

Si deseas que las copias de tus datos sean accesibles en más de una zona, especifica el parámetro enable-multi-zone-provisioning en tu StorageClass, que crea discos en las zonas que especificaste en el campo allowedTopologies.

Para crear el proveedor, sigue estos pasos:

  1. Guarda el siguiente manifiesto como un archivo llamado hyperdisk-ml-multi-zone.yaml:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: hyperdisk-ml-multi-zone
    parameters:
      type: hyperdisk-ml
      provisioned-throughput-on-create: "2400Mi"
      enable-multi-zone-provisioning: "true"
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowedTopologies:
    - matchLabelExpressions:
      - key: topology.gke.io/zone
        values:
        - ZONE_1
        - ZONE_2
    

    Reemplaza ZONE_1, ZONE_2, ..., ZONE_N por las zonas en las que se puede acceder a tu almacenamiento.

    En este ejemplo, se establece el volumeBindingMode en Immediate, lo que permite que GKE aprovisione la PersistentVolumeClaim antes de que cualquier consumidor haga referencia a ella.

  2. Ejecuta el siguiente comando para crear la StorageClass:

    kubectl apply -f hyperdisk-ml-multi-zone.yaml
    

Crea una PersistentVolumeClaim que use la StorageClass multizona

El siguiente paso es crear una PersistentVolumeClaim que haga referencia a la StorageClass.

GKE usa el contenido de la imagen de disco especificada para aprovisionar automáticamente un volumen de Hyperdisk ML en cada zona especificada en la instantánea.

Para crear la PersistentVolumeClaim, sigue estos pasos:

  1. Guarda el siguiente manifiesto como un archivo llamado hdml-consumer-pvc.yaml:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: hdml-consumer-pvc
    spec:
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      accessModes:
      - ReadOnlyMany
      storageClassName: hyperdisk-ml-multi-zone
      resources:
        requests:
          storage: 300Gi
    
  2. Crea la PersistentVolumeClaim mediante la ejecución del siguiente comando:

    kubectl apply -f hdml-consumer-pvc.yaml
    

Crea un Deployment para consumir el volumen de Hyperdisk ML

Cuando uses Pods con PersistentVolumes, te recomendamos usar un controlador de carga de trabajo (como Deployment o StatefulSet).

Si quieres usar un PersistentVolume preexistente en el modo ReadOnlyMany con un Deployment, consulta Usa discos persistentes con varios lectores.

Para crear y probar tu implementación, sigue estos pasos:

  1. Guarda el siguiente manifiesto de ejemplo como vllm-gemma-deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gemma-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            ai.gke.io/model: gemma-7b
            ai.gke.io/inference-server: vllm
        spec:
          affinity:
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 100
                podAffinityTerm:
                  labelSelector:
                    matchExpressions:
                    - key: security
                      operator: In
                      values:
                      - S2
                  topologyKey: topology.kubernetes.io/zone
          containers:
          - name: inference-server
            image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:latest
            resources:
              requests:
                cpu: "2"
                memory: "25Gi"
                ephemeral-storage: "25Gi"
                nvidia.com/gpu: 2
              limits:
                cpu: "2"
                memory: "25Gi"
                ephemeral-storage: "25Gi"
                nvidia.com/gpu: 2
            command: ["python3", "-m", "vllm.entrypoints.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=2
            env:
            - name: MODEL_ID
              value: /models/gemma-7b
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
            - mountPath: /models
              name: gemma-7b
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          - name: gemma-7b
            persistentVolumeClaim:
              claimName: CLAIM_NAME
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: gemma-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
    

    Reemplaza CLAIM_NAME por uno de estos valores:

    • hdml-static-pvc: si usas un volumen de Hyperdisk ML desde un Google Cloud Hyperdisk existente.
    • hdml-consumer-pvc: si usas un volumen de Hyperdisk ML desde una imagen de disco de VolumeSnapshot.
  2. Ejecuta el siguiente comando para esperar que el servidor de inferencia esté disponible:

    kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
    
  3. Para probar que tu servidor de vLLM esté en funcionamiento, sigue estos pasos:

    1. Ejecuta el siguiente comando para configurar la redirección de puertos al modelo:

      kubectl port-forward service/llm-service 8000:8000
      
    2. Ejecuta un comando curl para enviar una solicitud al modelo:

      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 http://localhost:8000/generate \
      -H "Content-Type: application/json" \
      -d @- <<EOF
      {
          "prompt": "<start_of_turn>user\n${USER_PROMPT}<end_of_turn>\n",
          "temperature": 0.90,
          "top_p": 1.0,
          "max_tokens": 128
      }
      EOF
      

    El resultado muestra un ejemplo de la respuesta del modelo.

    {"predictions":["Prompt:\n<start_of_turn>user\nI'm new to coding. If you could only recommend one programming language to start with, what would it be and why?<end_of_turn>\nOutput:\nPython is often recommended for beginners due to its clear, readable syntax, simple data types, and extensive libraries.\n\n**Reasons why Python is a great language for beginners:**\n\n* **Easy to read:** Python's syntax is straightforward and uses natural language conventions, making it easier for beginners to understand the code.\n* **Simple data types:** Python has basic data types like integers, strings, and lists that are easy to grasp and manipulate.\n* **Extensive libraries:** Python has a vast collection of well-documented libraries covering various tasks, allowing beginners to build projects without reinventing the wheel.\n* **Large supportive community:**"]}
    

Ajusta el valor de lectura anticipada

Si tienes cargas de trabajo que realizan E/S secuenciales, es posible que se beneficien de la configuración del valor de lectura anticipada. Por lo general, esto se aplica a las cargas de trabajo de inferencia o entrenamiento que necesitan cargar las cargas del modelo de IA/AA en la memoria. La mayoría de las cargas de trabajo con E/S secuencial suelen experimentar una mejora en el rendimiento con un valor de lectura anticipada de 1,024 KB o más.

Puedes especificar esta opción a través de la opción de activación read_ahead_kb cuando aprovisiones de forma estática un PersistentVolume nuevo o cuando modifiques un PersistentVolume aprovisionado de forma dinámica.

En el siguiente ejemplo, se muestra cómo ajustar el valor de lectura anticipada a 4,096 KB.

apiVersion: v1
kind: PersistentVolume
  name: DISK_NAME
spec:
  accessModes:
  - ReadOnlyMany
  capacity:
    storage: 300Gi
  csi:
    driver: pd.csi.storage.gke.io
    fsType: ext4
    readOnly: true
    volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.gke.io/zone
          operator: In
          values:
          - ZONE
  storageClassName: hyperdisk-ml
  mountOptions:
  - read_ahead_kb=4096

Reemplaza los siguientes valores:

  • DISK_NAME: el nombre del volumen de Google Cloud Hyperdisk preexistente.
  • ZONE: la zona en la que se crea el volumen de Google Cloud Hyperdisk preexistente.

Prueba y compara el rendimiento del volumen de Hyperdisk ML

En esta sección, se muestra cómo puedes usar el verificador de E/S flexible (FIO) para comparar el rendimiento de los volúmenes de Hyperdisk ML a fin de leer datos preexistentes. Puedes usar estas métricas a fin de evaluar el rendimiento del volumen para cargas de trabajo y configuraciones específicas.

  1. Guarda el siguiente manifiesto de ejemplo como benchmark-job.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: benchmark-job
    spec:
      template:  # Template for the Pods the Job will create
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: cloud.google.com/compute-class
                    operator: In
                    values:
                    - "Performance"
                - matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                    - "c3"
    
          containers:
          - name: fio
            resources:
              requests:
                cpu: "32"
            image: litmuschaos/fio
            args:
            - fio
            - --filename
            - /models/gemma-7b/model-00001-of-00004.safetensors:/models/gemma-7b/model-00002-of-00004.safetensors:/models/gemma-7b/model-00003-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors
            - --direct=1
            - --rw=read
            - --readonly
            - --bs=4096k
            - --ioengine=libaio
            - --iodepth=8
            - --runtime=60
            - --numjobs=1
            - --name=read_benchmark
            volumeMounts:
            - mountPath: "/models"
              name: volume
          restartPolicy: Never
          volumes:
          - name: volume
            persistentVolumeClaim:
              claimName: hdml-static-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 1        # Max retries on failure
    

    Reemplaza CLAIM_NAME por el nombre de la PersistentVolumeClaim (por ejemplo, hdml-static-pvc).

  2. Actualiza el trabajo a través de la ejecución del siguiente comando:

    kubectl apply -f benchmark-job.yaml.
    
  3. Usa los registros de kubectl para ver el resultado de la herramienta fio:

    kubectl logs benchmark-job-nrk88 -f
    

    El resultado es similar al siguiente:

    read_benchmark: (g=0): rw=read, bs=4M-4M/4M-4M/4M-4M, ioengine=libaio, iodepth=8
    fio-2.2.10
    Starting 1 process
    
    read_benchmark: (groupid=0, jobs=1): err= 0: pid=32: Fri Jul 12 21:29:32 2024
    read : io=18300MB, bw=2407.3MB/s, iops=601, runt=  7602msec
        slat (usec): min=86, max=1614, avg=111.17, stdev=64.46
        clat (msec): min=2, max=33, avg=13.17, stdev= 1.08
        lat (msec): min=2, max=33, avg=13.28, stdev= 1.06
        clat percentiles (usec):
        |  1.00th=[11072],  5.00th=[12352], 10.00th=[12608], 20.00th=[12736],
        | 30.00th=[12992], 40.00th=[13120], 50.00th=[13248], 60.00th=[13376],
        | 70.00th=[13504], 80.00th=[13632], 90.00th=[13888], 95.00th=[14016],
        | 99.00th=[14400], 99.50th=[15296], 99.90th=[22144], 99.95th=[25728],
        | 99.99th=[33024]
        bw (MB  /s): min= 2395, max= 2514, per=100.00%, avg=2409.79, stdev=29.34
        lat (msec) : 4=0.39%, 10=0.31%, 20=99.15%, 50=0.15%
    cpu          : usr=0.28%, sys=8.08%, ctx=4555, majf=0, minf=8203
    IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=99.8%, 16=0.0%, 32=0.0%, >=64=0.0%
        submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
        complete  : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
        issued    : total=r=4575/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
        latency   : target=0, window=0, percentile=100.00%, depth=8
    
    Run status group 0 (all jobs):
    READ: io=18300MB, aggrb=2407.3MB/s, minb=2407.3MB/s, maxb=2407.3MB/s, mint=7602msec, maxt=7602msec
    
    Disk stats (read/write):
    nvme0n2: ios=71239/0, merge=0/0, ticks=868737/0, in_queue=868737, util=98.72%
    

Supervisa la capacidad de procesamiento o las IOPS en un volumen de Hyperdisk ML

Para supervisar el rendimiento aprovisionado del volumen de Hyperdisk ML, consulta Analiza las IOPS aprovisionadas y la capacidad de procesamiento en la documentación de Compute Engine.

Para actualizar la capacidad de procesamiento o los IOPS aprovisionados de un volumen de Hyperdisk ML existente, o para obtener información sobre los parámetros adicionales de Google Cloud Hyperdisk que puedes especificar en tu StorageClass, consulta Escala el rendimiento del almacenamiento con Google Cloud Hyperdisk.

Soluciona problemas

En esta sección, se proporciona orientación para solucionar problemas con los volúmenes de Hyperdisk ML en GKE.

No se puede actualizar el modo de acceso al disco

El siguiente error ocurre cuando un nodo ya está usando y conectando un volumen de Hyperdisk ML en modo de acceso ReadWriteOnce.

AttachVolume.Attach failed for volume ... Failed to update access mode:
failed to set access mode for zonal volume ...
'Access mode cannot be updated when the disk is attached to instance(s).'., invalidResourceUsage

GKE actualiza de forma automática el accessMode del volumen de Hyperdisk ML de READ_WRITE_SINGLE a READ_ONLY_MANY cuando lo usa un PersistentVolume con modo de acceso ReadOnlyMany. Esta actualización se realiza cuando el disco se adjunta a un nodo nuevo.

Para resolver este problema, borra todos los Pods que hacen referencia al disco con un PersistentVolume en modo ReadWriteOnce. Espera a que se desconecte el disco y, luego, vuelve a crear la carga de trabajo que consume el PersistentVolume en modo ReadOnlyMany.

El disco no se puede conectar con el modo READ_WRITE

El siguiente error indica que GKE intentó conectar un volumen de Hyperdisk de ML en modo de acceso READ_ONLY_MANY a un nodo de GKE con el modo de acceso ReadWriteOnce.

AttachVolume.Attach failed for volume ...
Failed to Attach: failed cloud service attach disk call ...
The disk cannot be attached with READ_WRITE mode., badRequest

GKE actualiza de forma automática el accessMode del volumen de Hyperdisk ML de READ_WRITE_SINGLE a READ_ONLY_MANY cuando lo usa un PersistentVolume con modo de acceso ReadOnlyMany. Sin embargo, GKE no actualizará automáticamente el modo de acceso de READ_ONLY_MANY a READ_WRITE_SINGLE. Este es un mecanismo de seguridad para garantizar que no se escriba en los discos multizona por accidente, ya que esto podría generar contenido divergente entre los discos multizona.

Para resolver este problema, te recomendamos que sigas el flujo de trabajo Datos almacenados en caché previo a una imagen de disco de Persistent Disk si necesitas contenido actualizado. Si necesitas más control sobre el modo de acceso del volumen de Hyperdisk ML y otros parámetros de configuración, consulta Modifica la configuración de un volumen de Google Cloud Hyperdisk.

Se superó la cuota: Cuota de capacidad de procesamiento insuficiente

El siguiente error indica que no había suficiente cuota de capacidad de procesamiento de Hyperdisk ML en el momento del aprovisionamiento del disco.

failed to provision volume with StorageClass ... failed (QUOTA_EXCEEDED): Quota 'HDML_TOTAL_THROUGHPUT' exceeded

Para resolver este problema, consulta Cuotas de disco a fin de obtener más información sobre la cuota de Hyperdisk y cómo aumentar la cuota de disco en tu proyecto.

Para obtener más orientación sobre la solución de problemas, consulta Escala el rendimiento del almacenamiento con Google Cloud Hyperdisk.

¿Qué sigue?