En esta guía se explica cómo simplificar y acelerar la carga de pesos de modelos de IA y aprendizaje automático en Google Kubernetes Engine (GKE) con Hyperdisk ML. El controlador de CSI para Persistent Disk en Compute Engine es la forma principal de acceder al almacenamiento de Hyperdisk ML con clústeres de GKE.
Información general
Hyperdisk ML es una solución de almacenamiento de alto rendimiento que se puede usar para escalar tus aplicaciones. Proporciona un alto rendimiento agregado a muchas máquinas virtuales simultáneamente, por lo que es ideal si quieres ejecutar cargas de trabajo de IA o aprendizaje automático que necesiten acceder a grandes cantidades de datos.
Si se habilita en el modo de solo lectura múltiple, puedes usar Hyperdisk ML para acelerar la carga de los pesos del modelo hasta 11,9 veces en comparación con la carga directa desde un registro de modelos. Esta aceleración es posible gracias a la arquitectura de Hyperdisk de Google Cloud, que permite escalar a 2500 nodos simultáneos a 1,2 TiB/s. Esto te permite mejorar los tiempos de carga y reducir el aprovisionamiento excesivo de pods en tus cargas de trabajo de inferencia de IA o aprendizaje automático.
Estos son los pasos generales para crear y usar Hyperdisk ML:
- Pre-caché o hidratación de datos en una imagen de disco de disco persistente: 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 servir. El Persistent Disk de la imagen de disco debe ser compatible con Google Cloud Hyperdisk.
- 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 ML cargado con datos. También puedes crear clases de almacenamiento multizona para asegurarte de que tus datos estén disponibles en todas las zonas en las que se ejecuten tus pods.
- Crea un Deployment de Kubernetes para consumir el volumen de Hyperdisk ML: haz referencia al volumen de Hyperdisk ML con carga de datos acelerada para que tus aplicaciones lo consuman.
Volúmenes de Hyperdisk ML multizona
Los discos Hyperdisk ML solo están disponibles en una zona. También puedes usar la función multizona de Hyperdisk ML para vincular dinámicamente varios discos zonales que contengan el mismo contenido en un único PersistentVolumeClaim y PersistentVolume lógicos. 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 estar ubicados en la misma región (por ejemplo, us-central1-a
y us-central1-b
).
Un caso de uso habitual de la inferencia de IA o aprendizaje automático es ejecutar pods en diferentes zonas para mejorar la disponibilidad de los aceleradores y la rentabilidad con máquinas virtuales de acceso puntual. Como Hyperdisk ML es zonal, si tu servidor de inferencia ejecuta muchos pods en varias zonas, GKE clonará automáticamente los discos en las zonas para asegurarse de que tus datos sigan a tu aplicación.
Los volúmenes Hyperdisk ML multizona tienen las siguientes limitaciones:
- No se admiten las operaciones de cambio de tamaño ni las de creación de copias de volumen.
- Los volúmenes Hyperdisk ML multizona solo se admiten en modo de solo lectura.
- Cuando se usan discos preexistentes con un volumen de Hyperdisk ML multizona, GKE no realiza comprobaciones para validar que el contenido del disco en las zonas sea el mismo. Si alguno de los discos contiene contenido diferente, asegúrate de que tu aplicación tenga en cuenta las posibles incoherencias entre las zonas.
Para obtener más información, consulta Crear un volumen de Hyperdisk ML ReadOnlyMany multizona a partir de un VolumeSnapshot.
Antes de empezar
Antes de empezar, asegúrate de que has realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando
gcloud components update
.
- Defina su región y zona predeterminadas con uno de los valores admitidos.
- Comprueba que tu Trusted Cloud proyecto tiene suficiente cuota para crear los nodos necesarios en esta guía. El código de ejemplo para la creación de clústeres de GKE y recursos de Kubernetes requiere la siguiente cuota mínima en la región que elijas: 88 CPUs C3 y 8 GPUs NVIDIA L4.
Requisitos
Para usar volúmenes de Hyperdisk ML en GKE, tus clústeres deben cumplir los siguientes requisitos:
- Usa clústeres Linux con la versión 1.30.2-gke.1394000 de GKE o una posterior. Si usas un canal de lanzamiento, asegúrate de que tenga la versión mínima de GKE o una posterior que se requiera para este controlador.
- Asegúrate de que el controlador de CSI para Persistent Disk en Compute Engine esté habilitado. El controlador de Persistent Disk de Compute Engine está habilitado de forma predeterminada en los clústeres Autopilot y Standard nuevos, y no se puede inhabilitar ni editar cuando se usa Autopilot. Si necesitas habilitar el controlador de CSI para Persistent Disk en Compute Engine desde tu clúster, consulta el artículo Habilitar el controlador de CSI para Persistent Disk en Compute Engine en un clúster ya creado.
- Si quieres ajustar el valor de lectura anticipada, usa la versión 1.29.2-gke.1217000 de GKE o una posterior.
- Si quieres usar la función de aprovisionamiento dinámico multizona, utiliza la versión 1.30.2-gke.1394000 de GKE o una posterior.
- Hyperdisk ML solo se admite en determinados tipos de nodos y zonas. Para obtener más información, consulta el artículo Acerca de Hyperdisk ML en la documentación de Compute Engine.
Acceder al modelo
Para acceder a los modelos de Gemma e implementarlos en GKE, primero debes firmar el acuerdo de consentimiento de licencia y, a continuación, generar un token de acceso de Hugging Face.
Firmar el contrato de consentimiento de licencia
Debes firmar el acuerdo de consentimiento para usar Gemma. Te las indicamos a continuación:
- Accede a la página de consentimiento del modelo en Kaggle.com.
- Verifica el consentimiento con tu cuenta de Hugging Face.
- Acepta los términos del modelo.
Generar 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 si aún no tienes uno:
- Haz clic en Tu perfil > Configuración > Tokens de acceso.
- Selecciona New Token (Nuevo token).
- Especifica el nombre que quieras y un rol de al menos
Read
. - Selecciona Generar un token.
- Copia el token generado en el portapapeles.
Crear un clúster de GKE
Puedes servir LLMs en GPUs en un clúster Autopilot o Standard de GKE. Te recomendamos que uses un clúster de Autopilot para disfrutar de una experiencia de Kubernetes totalmente gestionada. Para elegir el modo de funcionamiento de GKE que mejor se adapte a tus cargas de trabajo, consulta Elegir un modo de funcionamiento de GKE.
Autopilot
En Cloud Shell, ejecuta el siguiente comando:
gcloud container clusters create-auto hdml-gpu-l4 \ --project=PROJECT \ --location=CONTROL_PLANE_LOCATION \ --release-channel=rapid \ --cluster-version=1.30.2-gke.1394000
Sustituye los siguientes valores:
- PROJECT: el ID del proyecto. Trusted Cloud by S3NS
- CONTROL_PLANE_LOCATION: la región de Compute Engine del plano de control de tu clúster. Proporciona una región que admita el tipo de acelerador que quieras 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 soliciten las cargas de trabajo desplegadas.
Configura
kubectl
para que se comunique con tu clúster:gcloud container clusters get-credentials hdml-gpu-l4 \ --location=CONTROL_PLANE_LOCATION
Estándar
En Cloud Shell, ejecuta el siguiente comando para crear un clúster Standard y grupos de nodos:
gcloud container clusters create hdml-gpu-l4 \ --location=CONTROL_PLANE_LOCATION \ --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=CONTROL_PLANE_LOCATION \ --project=PROJECT \ --node-locations=ZONES \ --cluster=hdml-gpu-l4 \ --machine-type=g2-standard-24 \ --num-nodes=2
Sustituye los siguientes valores:
- CLUSTER_VERSION: la versión de tu clúster de GKE (por ejemplo, 1.30.2-gke.1394000).
- CONTROL_PLANE_LOCATION: la ubicación de Compute Engine del plano de control de tu clúster. En el caso de los clústeres regionales, proporciona una región con una zona que admita el acelerador que quieras usar. En el caso de los clústeres zonales, proporciona una zona que admita el acelerador que quieras usar. Para comprobar dónde están disponibles los aceleradores específicos, consulta la disponibilidad de las GPUs por regiones y zonas.
- ZONES: las zonas en las que se crean los nodos.
Puedes especificar tantas zonas como necesites para tu clúster. Todas las zonas deben estar en la misma región que el plano de control del clúster, especificada por la marca
--location
. En el caso de los clústeres zonales,--node-locations
debe contener la zona principal del clúster. - PROJECT: el ID del proyecto. Trusted Cloud by S3NS
La creación del clúster puede tardar varios minutos.
Configura
kubectl
para que se comunique con tu clúster:gcloud container clusters get-credentials hdml-gpu-l4
Pre-almacenar en caché datos en una imagen de disco de Persistent Disk
Para usar Hyperdisk ML, debes prealmacenar en caché los datos en una imagen de disco y crear un volumen de Hyperdisk ML para que tu carga de trabajo en GKE pueda acceder a él para leer. Este enfoque (también llamado hidratación de datos) asegura que tus datos estén disponibles cuando tu carga de trabajo los necesite.
En los siguientes pasos se describe cómo copiar manualmente datos de una fuente, como un repositorio de Hugging Face, directamente en un volumen de Hyperdisk ML mediante un trabajo de Kubernetes.
Si tus datos ya están en un segmento de Cloud Storage, puedes usar Hyperdisk ML para automatizar la transferencia de datos de Cloud Storage a Hyperdisk ML. De esta forma, no tendrás que seguir los pasos para crear manualmente un trabajo que se describen en las siguientes secciones.
Crear un StorageClass que admita Hyperdisk ML
Guarda el siguiente manifiesto de StorageClass en un archivo llamado
hyperdisk-ml.yaml
.apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hyperdisk-ml parameters: type: hyperdisk-ml provisioned-throughput-on-create: "2400Mi" provisioner: pd.csi.storage.gke.io allowVolumeExpansion: false reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer mountOptions: - read_ahead_kb=4096
Crea el objeto StorageClass ejecutando este comando:
kubectl create -f hyperdisk-ml.yaml
Crear un PersistentVolumeClaim ReadWriteOnce (RWO)
Guarda el siguiente manifiesto de PersistentVolumeClaim en un archivo llamado
producer-pvc.yaml
. Usarás el StorageClass que has creado antes. Este PVC usa el modo de accesoReadWriteOnce
porque lo utiliza un trabajo de Kubernetes para descargar datos del modelo en el disco persistente, lo que requiere acceso de escritura. Google Cloud Hyperdisk no admite el modo de accesoReadWriteMany
. 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
Para crear el PersistentVolumeClaim, ejecuta este comando:
kubectl create -f producer-pvc.yaml
Crear un trabajo de Kubernetes para rellenar el volumen de HyperDisk de Google Cloud montado
En esta sección se muestra un ejemplo de cómo crear un trabajo de Kubernetes que aprovisione un disco y descargue el modelo ajustado de instrucciones de Gemma 7B de Hugging Face en el volumen de Google Cloud Hyperdisk montado.
Para acceder al LLM de Gemma que usan los ejemplos de esta guía, crea un secreto 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 -
Sustituye HF_TOKEN por el token de Hugging Face que has generado anteriormente.
Guarda el siguiente manifiesto de ejemplo como
producer-job.yaml
:apiVersion: batch/v1 kind: Job metadata: name: producer-job spec: template: spec: affinity: # Node affinity ensures that Pods are scheduled on the nodes that support Hyperdisk ML. nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: # Specifies the Performance compute class. For more information, # see https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-compute-classes#when-to-use. - key: cloud.google.com/compute-class operator: In values: - "Performance" - matchExpressions: - key: cloud.google.com/machine-family operator: In values: - "c3" - matchExpressions: # Restricts Pod scheduling to a specific zone because Hyperdisk ML disks # are a zonal resource. - key: topology.kubernetes.io/zone operator: In values: - "ZONE" containers: - name: copy resources: requests: cpu: "32" limits: cpu: "32" # The image used to download models from Hugging Face. image: huggingface/downloader:0.17.3 command: [ "huggingface-cli" ] args: - download # The Hugging Face model to download. - google/gemma-1.1-7b-it # Destination directory within the container. - --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: # Mount path for the PersistentVolume. - mountPath: "/data" name: volume # Prevents Pod restarts on scheduling failures. The Job will create new Pods # for retries, up to the specified "backoffLimit". restartPolicy: Never volumes: - name: volume persistentVolumeClaim: # References the Hyperdisk ML PVC created earlier. claimName: producer-pvc # Runs only one Pod at any given time. parallelism: 1 # After the Pod runs successfully, the Job is complete. completions: 1 # Max retries on Pod failure. backoffLimit: 4
Sustituye ZONE por la zona de cálculo en la que quieras crear el hiperdisco. Si lo usas con el ejemplo de implementación, asegúrate de que sea una zona que tenga capacidad de máquinas G2.
Para crear el trabajo, ejecuta este comando:
kubectl apply -f producer-job.yaml
El trabajo puede tardar unos minutos en terminar de copiar los datos en el volumen del disco persistente. Cuando la tarea completa el aprovisionamiento, su estado se marca como "Completada".
Para comprobar el progreso del estado de tu trabajo, ejecuta el siguiente comando:
kubectl get job producer-job
Una vez que se haya completado el trabajo, puedes limpiarlo ejecutando este comando:
kubectl delete job producer-job
Crear un volumen de Hyperdisk ML ReadOnlyMany a partir de un Hyperdisk de Google Cloud preexistente
En esta sección se describen los pasos para crear un par de PersistentVolume y PersistentVolumeClaim ReadOnlyMany (ROM) a partir de un volumen de Hyperdisk de Google Cloud preexistente. Para obtener más información, consulta Usar discos persistentes preexistentes como volúmenes persistentes.
En la versión 1.30.2-gke.1394000 de GKE y posteriores, GKE convierte automáticamente el modo de acceso de un volumen de
READ_WRITE_SINGLE
Google Cloud Hyperdisk aREAD_ONLY_MANY
.Si estás usando un volumen de Hyperdisk de Google Cloud en una versión anterior de GKE, debes modificar el modo de acceso manualmente ejecutando el siguiente comando:
gcloud compute disks update HDML_DISK_NAME \ --zone=ZONE \ --access-mode=READ_ONLY_MANY
Sustituye los siguientes valores:
- HDML_DISK_NAME: el nombre de tu volumen de Hyperdisk ML.
- ZONE: la zona de cálculo en la que se crea el volumen de Hyperdisk de Google Cloud.
Crea un par PersistentVolume y PersistentVolumeClaim que haga referencia al disco que has rellenado anteriormente.
Guarda el siguiente archivo de manifiesto como
hdml-static-pv.yaml
:apiVersion: v1 kind: PersistentVolume metadata: name: hdml-static-pv spec: storageClassName: "hyperdisk-ml" capacity: storage: 300Gi # The "ReadOnlyMany" access mode allows the volume to be mounted by multiple # nodes for read-only access. accessModes: - ReadOnlyMany # ClaimRef links this PersistentVolume to a PersistentVolumeClaim. claimRef: namespace: default name: hdml-static-pvc csi: driver: pd.csi.storage.gke.io # The unique identifier of the Compute Engine disk resource backing # this volume. volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME fsType: ext4 readOnly: true # Node affinity ensures that Pod is scheduled in a zone where the volume # is replicated. 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
Sustituye los siguientes valores:
- PROJECT: el proyecto en el que se crea el 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 que ya existe.
Crea los recursos PersistentVolume y PersistentVolumeClaim ejecutando este comando:
kubectl apply -f hdml-static-pv.yaml
Crear un volumen de Hyperdisk ML ReadOnlyMany multizona a partir de un VolumeSnapshot
En esta sección se describen los pasos para crear un volumen de Hyperdisk ML multizona en el modo de acceso ReadOnlyMany. Usas un VolumeSnapshot para una imagen de disco de Persistent Disk preexistente. Para obtener más información, consulta el artículo sobre cómo crear copias de seguridad del almacenamiento de discos persistentes mediante capturas de volumen.
Para crear el volumen de Hyperdisk ML multizona, sigue estos pasos:
Crea un VolumeSnapshot de tu disco
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 # The snapshot will be deleted when the "VolumeSnapshot" object is deleted. deletionPolicy: Delete parameters: snapshot-type: images
Para crear el recurso VolumeSnapshotClass, ejecuta el siguiente comando:
kubectl apply -f disk-image-vsc.yaml
Guarda el siguiente manifiesto como un archivo llamado
my-snapshot.yaml
. Hacer referencia al PersistentVolumeClaim que has creado anteriormente en Crear un PersistentVolumeClaim ReadWriteOnce (RWO).apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: my-snapshot spec: volumeSnapshotClassName: disk-image-vsc source: # The name of the PersistentVolumeClaim to snapshot. persistentVolumeClaimName: producer-pvc
Para crear el recurso VolumeSnapshot, ejecuta el siguiente comando:
kubectl apply -f my-snapshot.yaml
Cuando el VolumeSnapshot esté marcado como "Ready", ejecuta el siguiente comando para crear el volumen de Hyperdisk ML:
kubectl wait --for=jsonpath='{.status.readyToUse}'=true \ --timeout=300s volumesnapshot my-snapshot
Crear un StorageClass multizona
Si quieres que se pueda acceder a copias de tus datos en más de una zona, especifica el parámetro enable-multi-zone-provisioning
en tu StorageClass, que crea discos en las zonas que hayas especificado en el campo allowedTopologies
.
Para crear el StorageClass, sigue estos pasos:
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: "4800Mi" 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 mountOptions: - read_ahead_kb=8192
Sustituye ZONE_1, ZONE_2, ..., ZONE_N por las zonas en las que se puede acceder a tu almacenamiento.
En este ejemplo, se define el valor
Immediate
en volumeBindingMode, lo que permite a GKE aprovisionar el PersistentVolumeClaim antes de que cualquier consumidor haga referencia a él.Para crear el recurso StorageClass, ejecuta el siguiente comando:
kubectl apply -f hyperdisk-ml-multi-zone.yaml
Crea un PersistentVolumeClaim que use el StorageClass multizona
El siguiente paso es crear un PersistentVolumeClaim que haga referencia a 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 tu snapshot.
Para crear el PersistentVolumeClaim, sigue estos pasos:
Guarda el siguiente manifiesto como un archivo llamado
hdml-consumer-pvc.yaml
.kind: PersistentVolumeClaim apiVersion: v1 metadata: name: hdml-consumer-pvc spec: # Specifies that the new PersistentVolumeClaim should be provisioned from the # contents of the volume snapshot named "my-snapshot". dataSource: name: my-snapshot kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io accessModes: - ReadOnlyMany storageClassName: hyperdisk-ml-multi-zone resources: requests: storage: 300Gi
Para crear el PersistentVolumeClaim, ejecuta el siguiente comando:
kubectl apply -f hdml-consumer-pvc.yaml
Crear un Deployment para consumir el volumen de Hyperdisk ML
Cuando utilices pods con PersistentVolumes, te recomendamos que uses un controlador de carga de trabajo (como un Deployment o un StatefulSet).
Si quieres usar un objeto PersistentVolume preexistente en modo ReadOnlyMany con un objeto Deployment, consulta Usar discos persistentes con varios lectores.
Para crear y probar tu implementación, sigue estos pasos:
Guarda el siguiente manifiesto de ejemplo como
vllm-gemma-deployment
.apiVersion: apps/v1 kind: Deployment metadata: name: vllm-gemma-deployment spec: replicas: 2 selector: # Labels used to select the Pods managed by this Deployment. matchLabels: app: gemma-server template: metadata: labels: app: gemma-server # Labels for AI/GKE integration. ai.gke.io/model: gemma-7b ai.gke.io/inference-server: vllm spec: affinity: # Node affinity ensures Pods run on nodes with L4 GPUs. nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/gke-accelerator operator: In values: - nvidia-l4 # Pod anti-affinity prefers scheduling Pods in different zones for # higher availability. podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - gemma-server topologyKey: topology.kubernetes.io/zone containers: - name: inference-server # The container image for the vLLM 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 to run the vLLM API server. command: ["python3", "-m", "vllm.entrypoints.api_server"] args: # Specifies the model to load, using an environment variable. - --model=$(MODEL_ID) - --tensor-parallel-size=2 env: # Environment variable to define the model path. - name: MODEL_ID value: /models/gemma-7b volumeMounts: - mountPath: /dev/shm name: dshm # Mount point for the Hyperdisk ML volume containing the model. - mountPath: /models name: gemma-7b volumes: - name: dshm emptyDir: medium: Memory - name: gemma-7b # References the PersistentVolumeClaim for the Hyperdisk ML volume. persistentVolumeClaim: claimName: CLAIM_NAME --- apiVersion: v1 kind: Service metadata: name: llm-service spec: # Selects Pods with the label "app: gemma-server". selector: app: gemma-server # The "ClusterIP" field makes the Service reachable only within the cluster. type: ClusterIP ports: - protocol: TCP port: 8000 targetPort: 8000
Sustituye CLAIM_NAME por uno de estos valores:
hdml-static-pvc
: si usas un volumen de Hyperdisk ML de un Hyperdisk de Google Cloud.hdml-consumer-pvc
: si usas un volumen de Hyperdisk ML a partir de una imagen de disco de VolumeSnapshot.
Ejecuta el siguiente comando para esperar a que el servidor de inferencia esté disponible:
kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
Para comprobar que tu servidor vLLM está en funcionamiento, sigue estos pasos:
Ejecuta el siguiente comando para configurar el reenvío de puertos al modelo:
kubectl port-forward service/llm-service 8000:8000
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
En el siguiente resultado se 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:**"]}
Ajustar el valor de lectura anticipada
Si tienes cargas de trabajo que realizan operaciones de E/S secuenciales, puede que te convenga ajustar el valor de lectura anticipada. Esto suele aplicarse a cargas de trabajo de inferencia o entrenamiento que necesitan cargar pesos de modelos de IA o aprendizaje automático en la memoria. La mayoría de las cargas de trabajo con E/S secuencial suelen experimentar una mejora del rendimiento con un valor de lectura anticipada de 1024 KB o superior.
Ajustar el valor de lectura anticipada de los nuevos volúmenes
Para especificar esta opción, añade read_ahead_kb
al campo mountOptions
de tu StorageClass. En el siguiente ejemplo se muestra cómo puedes ajustar el valor de lectura anticipada a 4096 KB. Esto se aplicará a los volúmenes persistentes aprovisionados dinámicamente que se creen con la clase de almacenamiento hyperdisk-ml
.
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
mountOptions:
- read_ahead_kb=4096
Ajustar el valor de lectura anticipada de los volúmenes
En el caso de los volúmenes aprovisionados de forma estática o los PersistentVolumes preexistentes, puedes especificar esta opción añadiendo read_ahead_kb
al campo spec.mountOptions
.
En el siguiente ejemplo se muestra cómo ajustar el valor de lectura anticipada a 4096 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
# The unique identifier of the Compute Engine disk resource backing this volume.
volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
# Node affinity ensures that Pods are scheduled in the zone where the volume exists.
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.gke.io/zone
operator: In
values:
- ZONE
storageClassName: hyperdisk-ml
mountOptions:
- read_ahead_kb=4096
Sustituye los siguientes valores:
- DISK_NAME: el nombre del volumen de Google Cloud Hyperdisk que ya existe.
- ZONE: la zona en la que se crea el volumen de Google Cloud Hyperdisk preexistente.
Probar y comparar el rendimiento de tu volumen de Hyperdisk ML
En esta sección se muestra cómo puede usar Flexible I/O Tester (FIO) para comparar el rendimiento de sus volúmenes de Hyperdisk ML al leer datos preexistentes . Puede usar estas métricas para evaluar el rendimiento de su volumen en cargas de trabajo y configuraciones específicas.
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 # Specifies the files to use for the benchmark. Multiple files can be separated by colons. - --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 # Use non-buffered I/O. - --direct=1 # Set the I/O pattern to read. - --rw=read # Open files in read-only mode. - --readonly # Block size for I/O operations. - --bs=4096k # I/O engine to use. - --ioengine=libaio # Number of I/O units to keep in flight against each file. - --iodepth=8 # Duration of the test in seconds. - --runtime=60 # Number of jobs to run. - --numjobs=1 # Name of the job. - --name=read_benchmark volumeMounts: - mountPath: "/models" name: volume restartPolicy: Never volumes: - name: volume persistentVolumeClaim: claimName: hdml-static-pvc parallelism: 1 completions: 1 backoffLimit: 1
Sustituye CLAIM_NAME por el nombre de tu PersistentVolumeClaim (por ejemplo,
hdml-static-pvc
).Para crear el trabajo, ejecuta el siguiente comando:
kubectl apply -f benchmark-job.yaml.
Usa los
kubectl
registros para ver el resultado de la herramientafio
: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%
Monitorizar el rendimiento o las IOPS de un volumen de Hyperdisk ML
Para monitorizar el rendimiento aprovisionado de tu volumen de Hyperdisk ML, consulta el artículo Analizar las IOPS y el rendimiento aprovisionados de la documentación de Compute Engine.
Para actualizar el rendimiento o las IOPS aprovisionadas de un volumen de Hyperdisk ML, o para obtener información sobre los parámetros adicionales de Hyperdisk de Google Cloud que puede especificar en su StorageClass, consulte Escalar el rendimiento del almacenamiento con Hyperdisk de Google Cloud.
Solución de problemas
En esta sección se proporcionan directrices 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 se produce cuando un volumen de aprendizaje automático de Hyperdisk ya está en uso y conectado por un nodo 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 automáticamente el valor de accessMode del volumen de Hyperdisk ML de READ_WRITE_SINGLE
a READ_ONLY_MANY
cuando lo utiliza un PersistentVolume con el modo de acceso ReadOnlyMany. Esta actualización se realiza cuando el disco se conecta a un nuevo nodo.
Para solucionar este problema, elimina todos los pods que hagan referencia al disco mediante un PersistentVolume en modo ReadWriteOnce. Espera a que se desmonte el disco y, a continuación, vuelve a crear la carga de trabajo que consume el objeto PersistentVolume en modo ReadOnlyMany.
El disco no se puede adjuntar en el modo READ_WRITE
El siguiente error indica que GKE ha intentado adjuntar un volumen de Hyperdisk ML en modo de acceso READ_ONLY_MANY
a un nodo de GKE mediante 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 automáticamente el valor de accessMode del volumen de Hyperdisk ML de READ_WRITE_SINGLE
a READ_ONLY_MANY
cuando lo utiliza un PersistentVolume con el modo de acceso ReadOnlyMany. Sin embargo, GKE no actualizará automáticamente el modo de acceso de READ_ONLY_MANY
a READ_WRITE_SINGLE
.
Se trata de un mecanismo de seguridad para asegurarse de que no se escriba en los discos multizona por error, ya que esto podría provocar que el contenido de los discos multizona sea diferente.
Para solucionar este problema, te recomendamos que sigas el flujo de trabajo Pre-cache data to a Persistent Disk disk image (Pre-almacenar en caché datos en una imagen de disco de Persistent Disk) si necesitas contenido actualizado. Si necesitas más control sobre el modo de acceso y otros ajustes del volumen de Hyperdisk ML, consulta Modificar los ajustes de un volumen de Hyperdisk Trusted Cloud by S3NS .
Se ha superado la cuota: cuota de rendimiento insuficiente
El siguiente error indica que no había suficiente cuota de cantidad de datos provisionados 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 solucionar este problema, consulte Cuotas de disco para obtener más información sobre la cuota de Hyperdisk y cómo aumentarla en su proyecto.
Para obtener más información sobre cómo solucionar problemas, consulta el artículo Escalar el rendimiento del almacenamiento con Hyperdisk de Google Cloud.
Siguientes pasos
- Consulta cómo automatizar la transferencia de datos de Cloud Storage a un volumen de HyperDisk con GKE Volume Populator.
- Consulta cómo migrar volúmenes de Persistent Disk a Hyperdisk.
- Consulta más información sobre el controlador de CSI para Persistent Disk en GitHub.