Este guia aborda como simplificar e acelerar o carregamento de pesos de modelos de IA/ML no Google Kubernetes Engine (GKE) usando o Hyperdisk ML. O driver CSI de disco permanente do Compute Engine é a principal maneira de acessar o armazenamento de hiperdisco ML com clusters do GKE.
Visão geral
O Hyperdisk ML é uma solução de armazenamento de alto desempenho usada para escalonar horizontalmente os aplicativos. Ele oferece um alto throughput agregado para muitas máquinas virtuais simultaneamente, o que o torna ideal se você quiser executar cargas de trabalho de IA/ML que precisam de acesso a grandes quantidades de dados.
Quando ativado no modo somente leitura, é possível usar o ML do Hyperdisk para acelerar o carregamento de pesos de modelo em até 11,9 vezes em relação ao carregamento diretamente de um registro de modelo. Essa aceleração é possível graças à arquitetura do Hyperdisk do Google Cloud, que permite o escalonamento para 2.500 nós simultâneos a 1,2 TiB/s. Assim, você gera tempos de carregamento melhores e reduzir o provisionamento excessivo de pods para suas cargas de trabalho de inferência de IA/ML.
As etapas avançadas para criar e usar o ML do Hyperdisk são as seguintes:
- Pré-armazenar em cache ou hidratar dados em uma imagem de disco do Persistent Disk: Carregue volumes de ML do Hyperdisk com dados de uma fonte de dados externa (por exemplo, pesos Gemma carregados do Cloud Storage) que podem ser para veiculação. O disco permanente da imagem de disco precisa ser compatível com o hiperdisco do Google Cloud.
- Criar um volume de ML do Hyperdisk usando um Hyperdisk do Google Cloud preexistente: crie um volume do Kubernetes que faz referência ao volume de ML do Hyperdisk carregado com dados. Também é possível criar classes de armazenamento em várias zonas para garantir que seus dados estejam disponíveis em todos zonas em que os pods vão executar.
- Crie uma implantação do Kubernetes para consumir o volume de ML do Hyperdisk: faça referência ao volume de ML do Hyperdisk com o carregamento de dados acelerado para que seus aplicativos o consumam.
Volumes do Hyperdisk ML de várias zonas
Os discos do Hyperdisk ML só estão disponíveis em uma única zona. Também é possível
usar o recurso de várias zonas do Hyperdisk ML para vincular de forma dinâmica
vários discos zonais que contêm o mesmo conteúdo em um único PersistentVolumeClaim
e PersistentVolume lógico. Discos zonais referenciados pelo
o atributo de várias zonas precisa estar localizado na mesma região. Por exemplo, se o
cluster regional for criado em us-central1
, os discos de várias zonas precisarão estar localizados
na mesma região (por exemplo, us-central1-a
, us-central1-b
).
Um caso de uso comum para inferência de IA/ML é executar pods em zonas para melhoria disponibilidade do acelerador e eficiência de custos com VMs spot. Como o Hyperdisk ML é zonal, se o servidor de inferência executar muitos pods em zonas, o GKE clonar automaticamente os discos nas zonas para garantir que os dados sigam suas para o aplicativo.
Os volumes de ML do Hyperdisk em várias zonas têm as seguintes limitações:
- As operações de redimensionamento e snapshots de volume não são compatíveis.
- Os volumes de ML do Hyperdisk de várias zonas só têm suporte no modo somente leitura.
- Ao usar discos preexistentes com um volume de ML do Hyperdisk em várias zonas, o GKE não realiza verificações para validar se o conteúdo do disco em todas as zonas é o mesmo. Se algum dos discos tiver conteúdo divergente, garantir que seu aplicativo leve em consideração possíveis inconsistências entre as zonas.
Para saber mais, consulte Criar um volume de ML do Hyperdisk ReadOnlyMany com várias zonas a partir de um VolumeSnapshot.
Antes de começar
Antes de começar, verifique se você realizou as tarefas a seguir:
- Ativar a API Google Kubernetes Engine. Ativar a API Google Kubernetes Engine
- Se você quiser usar a CLI do Google Cloud para essa tarefa,
instale e inicialize a
gcloud CLI. Se você instalou a CLI gcloud anteriormente, instale a versão
mais recente executando o comando
gcloud components update
. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.
- Defina a região e a zona padrão como um dos valores compatíveis.
- Verifique se o projeto do Google Cloud tem cota suficiente para criar os nós necessários neste guia. O exemplo de código para a criação de recursos do cluster do GKE e do Kubernetes exige a cota mínima a seguir na região escolhida: 88 CPUs C3 e 8 GPUs NVIDIA L4.
Requisitos
Para usar volumes do Hyperdisk ML no GKE, os clusters precisam atender aos seguintes requisitos:
- Use clusters do Linux com o GKE versão 1.30.2-gke.1394000 ou posterior. Se você usar um canal de lançamento, verifique se ele tem a versão mínima do GKE necessária para o driver.
- Verifique se o driver CSI do disco permanente do Compute Engine está ativado. O driver de disco permanente do Compute Engine é ativado por padrão em novos clusters do Autopilot e Standard e não pode ser desativado ou editado ao usar o Autopilot. Se você precisar ativar o driver CSI do disco permanente do Compute Engine no cluster, consulte Como ativar o driver CSI do disco permanente do Compute Engine em um cluster atual.
- Se você quiser ajustar o valor de readahead, use a versão do GKE 1.29.2-gke.1217000 ou mais recente.
- Se você quiser usar o recurso provisionado dinamicamente em várias zonas, use a versão 1.30.2-gke.1394000 ou mais recente do GKE.
- O Hyperdisk ML só é compatível com determinados tipos de nós e zonas. Para saber mais, consulte Sobre o Hyperdisk ML na documentação do Compute Engine.
Receber acesso ao modelo
Para ter acesso aos modelos Gemma para implantação no GKE, primeiro assine o contrato de consentimento de licença e gere um token de acesso do Hugging Face.
Assinar o contrato de consentimento de licença
É necessário assinar o contrato de consentimento para usar o Gemma. Siga estas instruções:
- Acesse a página de consentimento do modelo em Kaggle.com.
- Confirme seu consentimento usando sua conta do Hugging Face.
- Aceite os termos do modelo.
Gerar um token de acesso
Para acessar o modelo usando Hugging Face, você vai precisar de um token do Hugging Face.
Siga as etapas abaixo para gerar um novo token, caso ainda não tenha um:
- Clique em Seu perfil > Configurações > Tokens de acesso.
- Selecione Novo token.
- Especifique um Nome de sua escolha e um Papel de pelo menos
Read
. - Selecione Gerar um token.
- Copie o token gerado para a área de transferência.
Crie um cluster do GKE
É possível disponibilizar os LLMs no GPUs em um cluster do GKE Autopilot ou Standard. Recomendamos que você use um cluster do Autopilot para ter uma experiência totalmente gerenciada do Kubernetes. Para escolher o modo de operação do GKE mais adequado para suas cargas de trabalho, consulte Escolher um modo de operação do GKE.
Piloto automático
No Cloud Shell, execute este 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
Substitua os seguintes valores:
- PROJECT: o ID do projeto Google Cloud .
- CONTROL_PLANE_LOCATION: a região do Compute Engine do plano de controle do cluster. Informe uma região compatível com o tipo de acelerador que você quer usar, por exemplo,
us-east4
para GPU L4.
O GKE cria um cluster do Autopilot com nós de CPU e GPU conforme solicitado pelas cargas de trabalho implantadas.
Configure
kubectl
para se comunicar com o cluster:gcloud container clusters get-credentials hdml-gpu-l4 \ --location=CONTROL_PLANE_LOCATION
Padrão
No Cloud Shell, execute o seguinte comando para criar um cluster padrão e pools de nós:
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
Substitua os seguintes valores:
- CLUSTER_VERSION: a versão do cluster do GKE (por exemplo, 1.30.2-gke.1394000).
- CONTROL_PLANE_LOCATION: o local do Compute Engine do plano de controle do cluster. Para clusters regionais, forneça uma região com uma zona que ofereça suporte ao acelerador que você quer usar. Para clusters zonais, forneça uma zona que ofereça suporte ao acelerador que você quer usar. Para verificar onde aceleradores específicos estão disponíveis, consulte Disponibilidade de GPU por regiões e zonas.
- ZONES: as
zonas em que os nós são criados.
Especifique quantas zonas forem
necessárias para o cluster. Todas as zonas precisam estar na mesma região que o
plano de controle do cluster, especificado pela sinalização
--location
. Para clusters zonais,--node-locations
precisa conter a zona principal do cluster. - PROJECT: o ID do projeto Google Cloud .
A criação do cluster pode levar vários minutos.
Configure
kubectl
para se comunicar com o cluster:gcloud container clusters get-credentials hdml-gpu-l4
Pré-armazenar dados em cache para uma imagem de disco do disco permanente
Para usar o Hyperdisk ML, você pré-armazena os dados em cache em uma imagem de disco e cria um Volume de ML do Hyperdisk para acesso de leitura pela carga de trabalho no GKE. Essa abordagem (também chamada de hidratação de dados) garante que seus a disponibilidade dos dados quando a carga de trabalho precisar.
As etapas a seguir descrevem como copiar manualmente dados de uma origem, como o repositório do Hugging Face, diretamente para um volume de ML do Hyperdisk usando um job do Kubernetes.
Se os dados já estiverem em um bucket do Cloud Storage, use o Hyperdisk ML para automatizar a transferência de dados do Cloud Storage para o Hyperdisk ML. Isso elimina a necessidade das etapas manuais de criação de jobs descritas nas seções a seguir.
Criar um StorageClass compatível com o ML do Hyperdisk
Salve o manifesto StorageClass em um arquivo chamado
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
Crie o StorageClass executando este comando:
kubectl create -f hyperdisk-ml.yaml
Criar um PersistentVolumeClaim ReadWriteOnce (RWO)
Salve o seguinte manifesto PersistentVolumeClaim em um arquivo chamado
producer-pvc.yaml
. Você vai usar o StorageClass criado anteriormente. Esse PVC usa o modo de acessoReadWriteOnce
porque é usado por um Job do Kubernetes para fazer o download de dados do modelo no disco permanente, o que exige acesso de gravação. O modo de acessoReadWriteMany
não é compatível com o Google Cloud Hyperdisk. Confira se o disco tem capacidade suficiente para armazenar seus dados.kind: PersistentVolumeClaim apiVersion: v1 metadata: name: producer-pvc spec: storageClassName: hyperdisk-ml accessModes: - ReadWriteOnce resources: requests: storage: 300Gi
Execute este comando para criar o PersistentVolumeClaim:
kubectl create -f producer-pvc.yaml
Crie um job do Kubernetes para preencher o volume do Hyperdisk do Google Cloud montado.
Esta seção mostra um exemplo de criação de um job do Kubernetes que provisiona um disco e faz o download do modelo ajustado de instruções Gemma 7B do Hugging Face para o volume do Hyperdisk do Google Cloud montado.
Para acessar o LLM do Gemma usado nos exemplos deste guia, crie um secret do Kubernetes que contenha o token do Hugging Face:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=HF_TOKEN\ --dry-run=client -o yaml | kubectl apply -f -
Substitua HF_TOKEN pelo token do Hugging Face que você gerou anteriormente.
Salve o seguinte manifesto de exemplo 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
Substitua ZONE pela zona do Compute em que você quer o hiperdisco que será criado. Se você estiver usando o exemplo de implantação, verifique se é uma zona com capacidade de máquina G2.
Execute este comando para criar o job:
kubectl apply -f producer-job.yaml
Pode levar alguns minutos para que o job termine de copiar os dados para o volume do Persistent Disk. Quando o job conclui o provisionamento, o status dele é marcado como "Concluído".
Para verificar o progresso do status do job, execute o seguinte comando:
kubectl get job producer-job
Depois que o job for concluído, será possível limpá-lo executando este comando:
kubectl delete job producer-job
Criar um volume de ML do hiperdisco ReadOnly Many com base em um hiperdisco pré-existente do Google Cloud
Esta seção aborda as etapas para criar um par de PersistentVolume e PersistentVolumeClaim ReadOnlyMany (ROM) em um volume do Hyperdisk do Google Cloud preexistente. Para saber mais, consulte Como usar discos permanentes pré-existentes como PersistentVolumes.
Na versão 1.30.2-gke.1394000 e posterior do GKE, converte automaticamente o modo de acesso de uma
READ_WRITE_SINGLE
Volume do hiperdisco do Google Cloud paraREAD_ONLY_MANY
.Se você estiver usando um volume do Google Cloud Hyperdisk pré-existente em um do GKE, modifique o modo de acesso manualmente executando o seguinte comando:
gcloud compute disks update HDML_DISK_NAME \ --zone=ZONE \ --access-mode=READ_ONLY_MANY
Substitua os seguintes valores:
- HDML_DISK_NAME: o nome do volume do Hyperdisk ML.
- ZONE: a zona do Compute em que o volume preexistente do Google Cloud Hyperdisk é criado.
Crie um par de PersistentVolume e PersistentVolumeClaim, referenciando o que você preencheu anteriormente.
Salve o seguinte manifesto 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
Substitua os seguintes valores:
- PROJECT: o projeto em que o cluster do GKE foi criado.
- ZONE: a zona em que o volume preexistente do Google Cloud Hyperdisk é criado.
- DISK_NAME: o nome do volume do Google Cloud Hyperdisk preexistente.
Crie os recursos PersistentVolume e PersistentVolumeClaim executando este comando:
kubectl apply -f hdml-static-pv.yaml
Criar um volume de ML Hyperdisk ReadOnlyMany de várias zonas a partir de um VolumeSnapshot
Esta seção aborda as etapas para criar um volume de ML do Hyperdisk com várias zonas no modo de acesso ReadOnlyMany. Você usa um VolumeSnapshot para uma imagem de disco do Persistent Disk já existente. Para saber mais, consulte Fazer backup do armazenamento do Persistent Disk usando snapshots de volume.
Para criar o volume de ML do Hyperdisk de várias zonas, siga estas etapas:
Criar um VolumeSnapshot do disco
Salve o seguinte manifesto como um arquivo chamado
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
Crie o VolumeSnapshotClass executando o seguinte comando:
kubectl apply -f disk-image-vsc.yaml
Salve o seguinte manifesto como um arquivo chamado
my-snapshot.yaml
. Você vai fazer referência ao PersistentVolumeClaim criado anteriormente em Criar um 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
Crie o VolumeSnapshot executando o seguinte comando:
kubectl apply -f my-snapshot.yaml
Quando o VolumeSnapshot estiver marcado como "Pronto", execute o comando a seguir para criar o volume de ML do Hyperdisk:
kubectl wait --for=jsonpath='{.status.readyToUse}'=true \ --timeout=300s volumesnapshot my-snapshot
Criar um StorageClass de várias zonas
Se quiser disponibilizar cópias dos dados em mais de uma zona, especifique
o parâmetro enable-multi-zone-provisioning
no StorageClass, que
Cria discos nas zonas especificadas no campo allowedTopologies
.
Para criar o StorageClass, siga estas etapas:
Salve o seguinte manifesto como um arquivo chamado
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
Substitua ZONE_1, ZONE_2, ..., ZONE_N pelas zonas em que o armazenamento pode ser acessado.
Este exemplo define o volumeBindingMode como
Immediate
, permitindo que o GKE provisione o PersistentVolumeClaim antes de qualquer consumidor que o referenciar.Crie o StorageClass executando o seguinte comando:
kubectl apply -f hyperdisk-ml-multi-zone.yaml
Criar um PersistentVolumeClaim que usa o StorageClass de várias zonas
A próxima etapa é criar um PersistentVolumeClaim que referencia o esse StorageClass padrão.
O GKE usa o conteúdo da imagem de disco especificada para provisionar um volume de ML do Hyperdisk em cada zona especificada no snapshot.
Para criar o PersistentVolumeClaim, siga estas etapas:
Salve o seguinte manifesto como um arquivo chamado
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
Crie o PersistentVolumeClaim executando o seguinte comando:
kubectl apply -f hdml-consumer-pvc.yaml
Criar uma implantação para consumir o volume do hiperdisco ML
Ao usar pods com PersistentVolumes, recomendamos usar um controlador de carga de trabalho (como uma implantação ou StatefulSet).
Se você quiser usar um PersistentVolume preexistente no modo ReadOnlyMany com uma implantação, consulte Usar discos permanentes com vários leitores.
Para criar e testar a implantação, siga estas etapas:
Salve o seguinte manifesto de exemplo 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
Substitua CLAIM_NAME por um destes valores:
hdml-static-pvc
: se você estão usando um volume de ML do Hyperdisk de um hiperdisco atual do Google Cloud.hdml-consumer-pvc
: se você estão usando um volume de ML do Hyperdisk com base em uma imagem de disco do VolumeSnapshot.
Execute o comando a seguir para aguardar a disponibilidade do servidor de inferência:
kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
Para testar se o servidor vLLM está em execução, siga estas etapas:
Execute o seguinte comando para configurar o encaminhamento de portas para o modelo:
kubectl port-forward service/llm-service 8000:8000
Execute um comando
curl
para enviar uma solicitação ao 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
A saída a seguir mostra um exemplo da resposta do 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 o valor de readahead
Se você tiver cargas de trabalho que executam E/S sequencial, elas poderão se beneficiar do ajuste do valor de leitura antecipada. Isso geralmente se aplica a cargas de trabalho de inferência ou treinamento que precisam ser carregadas pesos do modelo de IA/ML na memória. A maioria das cargas de trabalho com E/S sequencial normalmente tem uma melhoria de desempenho com um valor de leitura antecipada de 1.024 KB ou mais.
Ajustar o valor de readahead para novos volumes
Para especificar essa opção, adicione read_ahead_kb
ao campo mountOptions
na StorageClass. O exemplo a seguir mostra como ajustar o valor de readahead para 4.096 KB. Isso será aplicado
a novos PersistentVolumes provisionados dinamicamente criados usando o
StorageClass 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 o valor de readahead para volumes atuais
Para volumes provisionados estaticamente ou PersistentVolumes preexistentes, adicione read_ahead_kb
ao campo spec.mountOptions
para especificar essa opção.
O exemplo a seguir mostra como ajustar o valor de readahead para
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
# 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
Substitua os seguintes valores:
- DISK_NAME: o nome do volume do Google Cloud Hyperdisk preexistente.
- ZONE: a zona em que o volume preexistente do Google Cloud Hyperdisk é criado.
Testar e comparar o desempenho do volume de ML do Hyperdisk
Esta seção mostra como usar o testador flexível de E/S (FIO) para comparar o desempenho dos seus volumes de ML do Hyperdisk para ler dados preexistentes. É possível usar essas métricas para avaliar o desempenho do volume em cargas de trabalho e configurações específicas.
Salve o seguinte manifesto de exemplo 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
Substitua CLAIM_NAME pelo nome do PersistentVolumeClaim (por exemplo,
hdml-static-pvc
).Crie o job novamente executando o seguinte comando:
kubectl apply -f benchmark-job.yaml.
Use os registros
kubectl
para conferir a saída da ferramentafio
:kubectl logs benchmark-job-nrk88 -f
A saída será assim:
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%
Monitorar a capacidade ou IOPS em um volume do Hyperdisk ML
Para monitorar o desempenho provisionado do volume do Hyperdisk ML, consulte Analisar IOPS e capacidade provisionadas na documentação do Compute Engine.
Para atualizar a capacidade provisionada ou os IOPS de um volume de ML do Hyperdisk ou para saber mais sobre outros parâmetros do Hyperdisk do Google Cloud que podem ser especificados em StorageClass, consulte Dimensionar o desempenho do armazenamento usando o Hyperdisk do Google Cloud.
Solução de problemas
Nesta seção, fornecemos orientações para resolver problemas com volumes do Hyperdisk ML no GKE.
Não é possível atualizar o modo de acesso ao disco
O erro a seguir ocorre quando um volume de ML do Hyperdisk já está sendo usado e anexado por um nó no modo de acesso 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
O GKE atualiza automaticamente o accessMode do volume de ML do Hyperdisk
de READ_WRITE_SINGLE
a READ_ONLY_MANY
, quando usado por um
PersistentVolume. Essa atualização é feita quando o disco é
anexado a um novo nó.
Para resolver esse problema, exclua todos os pods que estão referenciando o disco usando um PersistentVolume no modo ReadWriteOnce. Aguarde o disco ser removido e e recrie a carga de trabalho que consome o PersistentVolume no modo ReadOnlyMany.
O disco não pode ser anexado no modo READ_WRITE
O erro a seguir indica que o GKE tentou anexar um
Volume de ML do Hyperdisk no modo de acesso READ_ONLY_MANY
a um cluster do GKE
usando o modo de acesso 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
O GKE atualiza automaticamente o accessMode do volume de ML do Hyperdisk
de READ_WRITE_SINGLE
a READ_ONLY_MANY
, quando usado por um
PersistentVolume. No entanto, o GKE não vai
atualizar automaticamente o modo de acesso de READ_ONLY_MANY
para READ_WRITE_SINGLE
.
Este é um mecanismo de segurança para garantir que discos multizonais sejam
não gravados acidentalmente, o que poderia resultar em conteúdo divergente entre
e discos de várias zonas.
Para resolver esse problema, recomendamos que você siga as Fluxo de trabalho Pré-armazenar dados em cache para uma imagem de disco permanente se você precisa de conteúdo atualizado. Se você precisar de mais controle sobre o modo de acesso do volume de ML do Hyperdisk e outras configurações, consulte Modificar as configurações de um volume do Google Cloud Hyperdisk.
Cota excedida: cota de throughput insuficiente
O erro a seguir indica que o ML do Hyperdisk é insuficiente. a cota de capacidade de processamento no momento do provisionamento de disco.
failed to provision volume with StorageClass ... failed (QUOTA_EXCEEDED): Quota 'HDML_TOTAL_THROUGHPUT' exceeded
Para resolver esse problema, consulte Cotas de disco para saber mais sobre a cota do Hyperdisk e como aumentar a cota de disco no seu projeto.
Para mais orientações sobre solução de problemas, consulte Dimensionar o desempenho do armazenamento com o Hyperdisk do Google Cloud.
A seguir
- Aprenda a automatizar a transferência de dados do Cloud Storage para um volume do Hyperdisk usando o GKE Volume Populator.
- Saiba como migrar volumes do Persistent Disk para o Hyperdisk.
- Leia mais sobre o driver CSI do Persistent Disk no GitHub.