Este guia aborda como simplificar e acelerar o carregamento de ponderações de modelos de IA/AA no Google Kubernetes Engine (GKE) através do Hyperdisk ML. O controlador CSI do Persistent Disk do Compute Engine é a principal forma de aceder ao armazenamento de ML do Hyperdisk com clusters do GKE.
Vista geral
O Hyperdisk ML é uma solução de armazenamento de alto desempenho que pode ser usada para escalar horizontalmente as suas aplicações. Oferece um elevado débito agregado a muitas máquinas virtuais em simultâneo, o que o torna ideal se quiser executar cargas de trabalho de IA/AA que precisam de acesso a grandes quantidades de dados.
Quando ativado no modo de leitura para muitos, pode usar o Hyperdisk ML para acelerar o carregamento dos pesos dos modelos até 11,9 vezes em relação ao carregamento diretamente a partir de um registo de modelos. Esta aceleração é possível graças à arquitetura do Google Cloud Hyperdisk que permite escalar para 2500 nós simultâneos a 1,2 TiB/s. Isto permite-lhe gerar melhores tempos de carregamento e reduzir o aprovisionamento excessivo de pods para as suas cargas de trabalho de inferência de IA/ML.
Os passos de nível elevado para criar e usar o Hyperdisk ML são os seguintes:
- Pré-armazenar em cache ou preencher dados numa imagem de disco de disco persistente: carregue volumes do Hyperdisk ML com dados de uma origem de dados externa (por exemplo, ponderações do Gemma carregadas a partir do Cloud Storage) que podem ser usados para publicação. O Persistent Disk para a imagem do disco tem de ser compatível com o Google Cloud Hyperdisk.
- Crie um volume de ML do Hyperdisk usando um Google Cloud Hyperdisk pré-existente: crie um volume do Kubernetes que faça referência ao volume de ML do Hyperdisk carregado com dados. Opcionalmente, pode criar classes de armazenamento multizona para garantir que os seus dados estão disponíveis em todas as zonas em que os seus pods vão ser executados.
- Crie uma implementaçã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 as suas aplicações consumirem.
Volumes de ML de Hyperdisk multizona
Os discos de ML Hyperdisk só estão disponíveis numa única zona. Opcionalmente, pode usar a funcionalidade multizona do Hyperdisk ML para associar dinamicamente vários discos zonais que contêm o mesmo conteúdo num único PersistentVolumeClaim e PersistentVolume lógico. Os discos zonais referenciados pela funcionalidade de várias zonas têm de estar localizados na mesma região. Por exemplo, se o cluster regional for criado em us-central1
, os discos multizona têm de estar localizados na mesma região (por exemplo, us-central1-a
e us-central1-b
).
Um exemplo de utilização comum para a inferência de IA/AM é executar pods em várias zonas para melhorar a disponibilidade dos aceleradores e a rentabilidade com VMs Spot. Uma vez que o Hyperdisk ML é zonal, se o seu servidor de inferência executar muitos pods em várias zonas, o GKE clona automaticamente os discos em várias zonas para garantir que os seus dados seguem a sua aplicação.
Os volumes de ML Hyperdisk multizona têm as seguintes limitações:
- As operações de redimensionamento e instantâneos de volume não são suportadas.
- Os volumes de ML Hyperdisk multizona só são suportados no modo de leitura.
- Quando usa discos pré-existentes com um volume de ML do Hyperdisk de 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 contiver conteúdo divergente, certifique-se de que a sua aplicação tem em conta a potencial inconsistência entre zonas.
Para saber mais, consulte o artigo Crie um volume ML Hyperdisk ReadOnlyMany de várias zonas a partir de um VolumeSnapshot.
Antes de começar
Antes de começar, certifique-se de que realizou as seguintes tarefas:
- Ative a API Google Kubernetes Engine. Ative a API Google Kubernetes Engine
- Se quiser usar a CLI gcloud para esta tarefa,
instale-a e, em seguida,
inicialize-a. Se instalou anteriormente a CLI gcloud, execute
gcloud components update
para obter a versão mais recente.
- Defina a região e a zona predefinidas para um dos valores suportados.
- Certifique-se de que o seu Trusted Cloud projeto tem quota suficiente para criar os nós necessários neste guia. O código de exemplo para a criação de recursos do cluster do GKE e do Kubernetes requer a seguinte quota mínima na região à sua escolha: 88 CPUs C3 e 8 GPUs NVIDIA L4.
Requisitos
Para usar volumes de ML do Hyperdisk no GKE, os seus clusters têm de cumprir os seguintes requisitos:
- Use clusters Linux com a versão 1.30.2-gke.1394000 ou posterior do GKE. Se usar um canal de lançamento, certifique-se de que o canal tem a versão mínima do GKE ou posterior que é necessária para este controlador.
- Certifique-se de que o controlador CSI do Persistent Disk do Compute Engine está ativado. O controlador de disco persistente do Compute Engine está ativado por predefinição em novos clusters do Autopilot e Standard, e não pode ser desativado nem editado quando usa o Autopilot. Se precisar de ativar o controlador CSI do Persistent Disk do Compute Engine a partir do cluster, consulte o artigo Ativar o controlador CSI do Persistent Disk do Compute Engine num cluster existente.
- Se quiser ajustar o valor de leitura antecipada, use a versão 1.29.2-gke.1217000 ou posterior do GKE.
- Se quiser usar a funcionalidade de aprovisionamento dinâmico de várias zonas, use a versão 1.30.2-gke.1394000 ou posterior do GKE.
- O Hyperdisk ML só é suportado em determinados tipos de nós e zonas. Para saber mais, consulte o artigo Acerca do Hyperdisk ML na documentação do Compute Engine.
Aceda ao modelo
Para aceder aos modelos Gemma para implementação no GKE, primeiro tem de assinar o contrato de consentimento de licença e, em seguida, gerar um token de acesso do Hugging Face.
Assine o contrato de consentimento de licença
Tem de assinar o contrato de consentimento para usar o Gemma. Siga estas instruções:
- Aceda à página de consentimento do modelo em Kaggle.com.
- Valide o consentimento através da sua conta do Hugging Face.
- Aceite os termos do modelo.
Gere um token de acesso
Para aceder ao modelo através do Hugging Face, precisa de um token do Hugging Face.
Siga estes passos para gerar um novo token se ainda não tiver um:
- Clique em O seu perfil > Definições > Tokens de acesso.
- Selecione Novo token.
- Especifique um nome à sua escolha e uma função de, pelo menos,
Read
. - Selecione Gerar um token.
- Copie o token gerado para a área de transferência.
Crie um cluster do GKE
Pode publicar MDIs em GPUs num cluster padrão ou do GKE Autopilot. Recomendamos que use um cluster do Autopilot para uma experiência do Kubernetes totalmente gerida. Para escolher o modo de funcionamento do GKE mais adequado às suas cargas de trabalho, consulte o artigo Escolha um modo de funcionamento do GKE.
Piloto automático
No Cloud Shell, execute o seguinte 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 Trusted Cloud by S3NS ID do projeto.
- CONTROL_PLANE_LOCATION: a região do Compute Engine do plano de controlo do seu cluster. Indique uma região que suporte o tipo de acelerador que quer usar, por exemplo,
us-east4
para a GPU L4.
O GKE cria um cluster do Autopilot com nós de CPU e GPU, conforme solicitado pelas cargas de trabalho implementadas.
Configure
kubectl
para comunicar com o cluster:gcloud container clusters get-credentials hdml-gpu-l4 \ --location=CONTROL_PLANE_LOCATION
Standard
No Cloud Shell, execute o seguinte comando para criar um cluster padrão e node pools:
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 seu cluster do GKE (por exemplo, 1.30.2-gke.1394000).
- CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Para clusters regionais, indique uma região com uma zona que suporte o acelerador que quer usar. Para clusters zonais, indique uma zona que suporte o acelerador que quer usar. Para verificar onde estão disponíveis aceleradores específicos, consulte o artigo Disponibilidade de GPUs por regiões e zonas.
- ZONES: as zonas nas quais os nós são criados.
Pode especificar quantas zonas forem necessárias para o seu cluster. Todas as zonas têm de estar na mesma região que o plano de controlo do cluster, especificado pela flag
--location
. Para clusters zonais,--node-locations
tem de conter a zona principal do cluster. - PROJECT: o Trusted Cloud by S3NS ID do projeto.
A criação do cluster pode demorar vários minutos.
Configure
kubectl
para comunicar com o cluster:gcloud container clusters get-credentials hdml-gpu-l4
Pré-cache dados numa imagem de disco do Persistent Disk
Para usar o Hyperdisk ML, pré-armazena dados em cache numa imagem de disco e cria um volume do Hyperdisk ML para acesso de leitura pela sua carga de trabalho no GKE. Esta abordagem (também denominada preenchimento de dados) garante que os seus dados estão disponíveis quando a sua carga de trabalho precisar deles.
Os passos seguintes descrevem como copiar manualmente dados de uma origem, como o repositório do Hugging Face, diretamente para um volume de ML do Hyperdisk através de um trabalho do Kubernetes.
Se os seus dados já estiverem num contentor do Cloud Storage, pode usar o Hyperdisk ML para automatizar a transferência de dados do Cloud Storage para o Hyperdisk ML. Isto elimina a necessidade dos passos de criação manual de tarefas descritos nas secções seguintes.
Crie uma StorageClass que suporte o Hyperdisk ML
Guarde o seguinte manifesto StorageClass num ficheiro com o nome
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
Execute este comando para criar a StorageClass:
kubectl create -f hyperdisk-ml.yaml
Crie um PersistentVolumeClaim (PVC) ReadWriteOnce (RWO)
Guarde o seguinte manifesto PersistentVolumeClaim num ficheiro com o nome
producer-pvc.yaml
. Vai usar a StorageClass que criou anteriormente. Este PVC usa o modo de acessoReadWriteOnce
porque é usado por um trabalho do Kubernetes para transferir dados do modelo para o disco persistente, o que requer acesso de escrita. O modo de acessoReadWriteMany
não é suportado pelo Google Cloud Hyperdisk. Certifique-se de que o disco tem capacidade suficiente para armazenar os 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 trabalho do Kubernetes para preencher o volume do Google Cloud Hyperdisk montado
Esta secção mostra um exemplo de criação de uma tarefa do Kubernetes que aprovisiona um disco e transfere o modelo ajustado de instruções Gemma 7B do Hugging Face para o volume do Google Cloud Hyperdisk montado.
Para aceder ao MDG do Gemma usado nos exemplos deste guia, crie um segredo 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 gerou anteriormente.
Guarde 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 de computação onde quer criar o Hyperdisk. Se o estiver a usar com o exemplo de implementação, certifique-se de que é uma zona com capacidade de máquinas G2.
Execute este comando para criar a tarefa:
kubectl apply -f producer-job.yaml
A tarefa pode demorar alguns minutos a concluir a cópia dos dados para o volume do disco persistente. Quando a tarefa conclui o aprovisionamento, o respetivo estado é marcado como "Concluído".
Para verificar o progresso do estado da tarefa, execute o seguinte comando:
kubectl get job producer-job
Quando a tarefa estiver concluída, pode limpar a tarefa executando este comando:
kubectl delete job producer-job
Crie um volume de ML Hyperdisk ReadOnlyMany a partir de um Hyperdisk do Google Cloud pré-existente
Esta secção aborda os passos para criar um par ReadOnlyMany (ROM) PersistentVolume e PersistentVolumeClaim a partir de um volume do Google Cloud Hyperdisk pré-existente. Para saber mais, consulte o artigo Usar discos persistentes pré-existentes como PersistentVolumes.
Na versão 1.30.2-gke.1394000 e posteriores do GKE, o GKE converte automaticamente o modo de acesso de um volume do Google Cloud Hyperdisk para
READ_ONLY_MANY
.READ_WRITE_SINGLE
Se estiver a usar um volume do Google Cloud Hyperdisk pré-existente numa versão anterior do GKE, tem de modificar 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 seu volume do Hyperdisk ML.
- ZONE: a zona de computação onde o volume do Hyperdisk do Google Cloud pré-existente é criado.
Crie um par PersistentVolume e PersistentVolumeClaim, referenciando o disco que preencheu anteriormente.
Guarde 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 onde o cluster do GKE é criado.
- ZONE: a zona onde o volume do Hyperdisk do Google Cloud preexistente é criado.
- DISK_NAME: o nome do volume do Hyperdisk do Google Cloud pré-existente.
Execute este comando para criar os recursos PersistentVolume e PersistentVolumeClaim:
kubectl apply -f hdml-static-pv.yaml
Crie um volume de ML Hyperdisk ReadOnlyMany de várias zonas a partir de um VolumeSnapshot
Esta secção aborda os passos para criar um volume de ML do Hyperdisk no modo de acesso ReadOnlyMany. Usa um VolumeSnapshot para uma imagem de disco do Persistent Disk pré-existente. Para saber mais, consulte o artigo Crie uma cópia de segurança do armazenamento do disco persistente com instantâneos de volumes.
Para criar o volume de ML do Hyperdisk multizonal, siga estes passos:
Crie um VolumeSnapshot do seu disco
Guarde o seguinte manifesto como um ficheiro denominado
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
Guarde o seguinte manifesto como um ficheiro denominado
my-snapshot.yaml
. Vai fazer referência ao PersistentVolumeClaim que criou anteriormente em Crie um PersistentVolumeClaim (RWO) ReadWriteOnce.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 seguinte comando para criar o volume de ML do Hyperdisk:
kubectl wait --for=jsonpath='{.status.readyToUse}'=true \ --timeout=300s volumesnapshot my-snapshot
Crie uma StorageClass multizona
Se quiser que as cópias dos seus dados estejam acessíveis em mais do que uma zona, especifique o parâmetro enable-multi-zone-provisioning
na StorageClass, que cria discos nas zonas especificadas no campo allowedTopologies
.
Para criar a StorageClass, siga estes passos:
Guarde o seguinte manifesto como um ficheiro denominado
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 onde o seu armazenamento pode ser acedido.
Este exemplo define o volumeBindingMode como
Immediate
, o que permite ao GKE aprovisionar o PersistentVolumeClaim antes de qualquer consumidor fazer referência ao mesmo.Execute o seguinte comando para criar a StorageClass:
kubectl apply -f hyperdisk-ml-multi-zone.yaml
Crie um PersistentVolumeClaim que use a StorageClass multizona
O passo seguinte é criar um PersistentVolumeClaim que faça referência à StorageClass.
O GKE usa o conteúdo da imagem do disco especificada para aprovisionar automaticamente um volume do Hyperdisk ML em cada zona especificada na sua captura de ecrã.
Para criar o PersistentVolumeClaim, siga estes passos:
Guarde o seguinte manifesto como um ficheiro denominado
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
Crie uma implementação para consumir o volume de ML do Hyperdisk
Quando usar pods com volumes persistentes, recomendamos que use um controlador de carga de trabalho (como uma implementação ou um StatefulSet).
Se quiser usar um PersistentVolume pré-existente no modo ReadOnlyMany com uma implementação, consulte o artigo Use discos persistentes com vários leitores.
Para criar e testar a implementação, siga estes passos:
Guarde 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 estiver a usar um volume de ML do Hyperdisk a partir de um Hyperdisk do Google Cloud existente.hdml-consumer-pvc
: se estiver a usar um volume de ML do Hyperdisk a partir de uma imagem de disco VolumeSnapshot.
Execute o seguinte comando para aguardar que o servidor de inferência fique disponível:
kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
Para testar se o servidor vLLM está em funcionamento, siga estes passos:
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 um pedido 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 seguinte 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:**"]}
Ajuste o valor de leitura antecipada
Se tiver cargas de trabalho que executam E/S sequenciais, podem beneficiar da otimização do valor de leitura antecipada. Isto aplica-se normalmente a cargas de trabalho de inferência ou preparação que precisam de carregar pesos de modelos de IA/ML na memória. A maioria das cargas de trabalho com E/S sequencial normalmente observa uma melhoria no desempenho com um valor de leitura antecipada de 1024 KB ou superior.
Ajuste o valor de leitura antecipada para novos volumes
Pode especificar esta opção adicionando read_ahead_kb
ao campo mountOptions
na sua StorageClass. O exemplo seguinte
mostra como pode ajustar o valor de leitura antecipada para 4096 KB. Isto aplica-se
a novos volumes persistentes aprovisionados dinamicamente criados com a
hyperdisk-ml
StorageClass.
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
Ajuste o valor de leitura antecipada para volumes existentes
Para volumes aprovisionados estaticamente ou PersistentVolumes pré-existentes, pode especificar esta opção adicionando read_ahead_kb
ao campo spec.mountOptions
.
O exemplo seguinte mostra como pode ajustar o valor de leitura antecipada para 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
Substitua os seguintes valores:
- DISK_NAME: o nome do volume do Hyperdisk do Google Cloud pré-existente.
- ZONE: a zona onde o volume do Hyperdisk do Google Cloud preexistente é criado.
Teste e compare o desempenho do volume de ML do Hyperdisk
Esta secção mostra como pode usar o Flexible I/O Tester (FIO) para testar o desempenho dos seus volumes de ML do Hyperdisk para ler dados pré-existentes . Pode usar estas métricas para avaliar o desempenho do volume para cargas de trabalho e configurações específicas.
Guarde 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 seu PersistentVolumeClaim (por exemplo,
hdml-static-pvc
).Crie a tarefa executando o seguinte comando:
kubectl apply -f benchmark-job.yaml.
Use os registos
kubectl
para ver o resultado da ferramentafio
:kubectl logs benchmark-job-nrk88 -f
O resultado tem um aspeto semelhante ao seguinte:
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%
Monitorize a taxa de transferência ou as IOPS num volume do Hyperdisk ML
Para monitorizar o desempenho aprovisionado do seu volume de ML Hyperdisk, consulte o artigo Analise os IOPS e a taxa de transferência aprovisionados na documentação do Compute Engine.
Para atualizar o débito aprovisionado ou os IOPS de um volume do Hyperdisk ML existente, ou para saber mais acerca dos parâmetros adicionais do Google Cloud Hyperdisk que pode especificar na sua StorageClass, consulte o artigo Aumente o desempenho do armazenamento com o Google Cloud Hyperdisk.
Resolução de problemas
Esta secção fornece orientações de resolução de problemas para resolver problemas com volumes de ML do Hyperdisk no GKE.
Não é possível atualizar o modo de acesso ao disco
O seguinte erro ocorre quando um volume de ML do Hyperdisk já está a ser 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 do Hyperdisk ML de READ_WRITE_SINGLE
para READ_ONLY_MANY
quando é usado por um PersistentVolume no modo de acesso ReadOnlyMany. Esta atualização é feita quando o disco é anexado a um novo nó.
Para resolver este problema, elimine todos os pods que referenciam o disco através de um PersistentVolume no modo ReadWriteOnce. Aguarde até que o disco seja separado e, em seguida, recrie a carga de trabalho que consome o PersistentVolume no modo ReadOnlyMany.
Não é possível anexar o disco com o modo READ_WRITE
O seguinte erro indica que o GKE tentou anexar um volume do Hyperdisk ML no modo de acesso READ_ONLY_MANY
a um nó 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 do Hyperdisk ML de READ_WRITE_SINGLE
para READ_ONLY_MANY
quando é usado por um PersistentVolume no modo de acesso ReadOnlyMany. No entanto, o GKE não atualiza automaticamente o modo de acesso de READ_ONLY_MANY
para READ_WRITE_SINGLE
.
Este é um mecanismo de segurança para garantir que os discos de várias zonas não são escritos por engano, uma vez que isto pode resultar em conteúdo divergente entre os discos de várias zonas.
Para resolver este problema, recomendamos que siga o fluxo de trabalho de pré-armazenamento em cache de dados numa imagem de disco do disco persistente se precisar de conteúdo atualizado. Se precisar de mais controlo sobre o modo de acesso e outras definições do volume de ML do Hyperdisk, consulte o artigo Modifique as definições de um volume do Trusted Cloud by S3NS Hyperdisk.
Quota excedida: quota de débito insuficiente
O seguinte erro indica que não existia quota de débito de ML do Hyperdisk suficiente no momento do aprovisionamento do disco.
failed to provision volume with StorageClass ... failed (QUOTA_EXCEEDED): Quota 'HDML_TOTAL_THROUGHPUT' exceeded
Para resolver este problema, consulte o artigo Quotas de disco para saber mais acerca da quota do Hyperdisk e como aumentar a quota de disco no seu projeto.
Para ver orientações de resolução de problemas adicionais, consulte o artigo Aumente o desempenho do armazenamento com o Google Cloud Hyperdisk.
O que se segue?
- Saiba como automatizar a transferência de dados do Cloud Storage para um volume do Hyperdisk através do GKE Volume Populator.
- Saiba como migrar volumes de discos persistentes para o Hyperdisk.
- Leia mais sobre o controlador CSI de disco persistente no GitHub.