Acelerar o carregamento de dados de IA/ML com o Hyperdisk ML


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 ao Hyperdisk do Google Cloud Arquitetura que permite o escalonamento para 2.500 nós simultâneos a 1,2 TB/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:

  1. 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.
  2. 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.
  3. 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.

Hidratação do ML do Hyperdisk de fontes de dados externas e criação de PV de várias zonas para acessar os dados em todas as zonas.

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 Google Cloud CLI para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando gcloud components update.
  • 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 Para saber mais, acesse Sobre o Google Cloud Hyperdisk 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.

É necessário assinar o contrato de consentimento para usar o Gemma. Siga estas instruções:

  1. Acesse a página de consentimento do modelo em Kaggle.com.
  2. Confirme seu consentimento usando sua conta do Hugging Face.
  3. 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:

  1. Clique em Seu perfil > Configurações > Tokens de acesso.
  2. Selecione Novo token.
  3. Especifique um Nome de sua escolha e um Papel de pelo menos Read.
  4. Selecione Gerar um token.
  5. 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

  1. No Cloud Shell, execute este comando:

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

    Substitua os seguintes valores:

    • PROJECT: o ID do projeto do Google Cloud.
    • REGION: 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.

  2. Configure kubectl para se comunicar com o cluster:

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

Padrão

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

    Substitua os seguintes valores:

    • CLUSTER_VERSION: a versão do cluster do GKE (por exemplo, 1.30.2-gke.1394000).
    • REGION: a região de computação do plano de controle do cluster. A região precisa oferecer suporte ao acelerador que você quiser usar, por exemplo, us-east4, para GPU L4. Verifique em quais regiões as GPUs L4 estão disponíveis.
    • 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 --zone. Para clusters zonais, --node-locations precisa conter a zona principal do cluster.
    • PROJECT: o ID do projeto do Google Cloud.

    A criação do cluster pode levar vários minutos.

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

Para copiar os dados do Cloud Storage e pré-cachear uma imagem de disco do Persistent Disk, siga estas etapas:

Criar um StorageClass compatível com o ML do Hyperdisk

  1. 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
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: WaitForFirstConsumer
    
  2. Crie o StorageClass executando este comando:

    kubectl create -f hyperdisk-ml.yaml
    

Criar um PersistentVolumeClaim ReadWriteOnce (RWO)

  1. Salve o seguinte manifesto PersistentVolumeClaim em um arquivo chamado producer-pvc.yaml. Você vai usar o StorageClass criado anteriormente. 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
    
  2. 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.

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

  2. Salve o seguinte manifesto de exemplo como producer-job.yaml:

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

    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.

  3. 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".

  4. Para verificar o progresso do status do job, execute o seguinte comando:

    kubectl get job producer-job
    
  5. 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.

  1. 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 para READ_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.
  2. Crie um par de PersistentVolume e PersistentVolumeClaim, referenciando o que você preencheu anteriormente.

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

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

  1. 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
    deletionPolicy: Delete
    parameters:
      snapshot-type: images
    
  2. Crie o VolumeSnapshotClass executando o seguinte comando:

    kubectl apply -f disk-image-vsc.yaml
    
  3. 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:
        persistentVolumeClaimName: producer-pvc
    
  4. Crie o VolumeSnapshot executando o seguinte comando:

    kubectl apply -f my-snapshot.yaml
    
  5. 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:

  1. 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: "2400Mi"
      enable-multi-zone-provisioning: "true"
    provisioner: pd.csi.storage.gke.io
    allowVolumeExpansion: false
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowedTopologies:
    - matchLabelExpressions:
      - key: topology.gke.io/zone
        values:
        - ZONE_1
        - ZONE_2
    

    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.

  2. 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:

  1. Salve o seguinte manifesto como um arquivo chamado hdml-consumer-pvc.yaml.

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: hdml-consumer-pvc
    spec:
      dataSource:
        name: my-snapshot
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io
      accessModes:
      - ReadOnlyMany
      storageClassName: hyperdisk-ml-multi-zone
      resources:
        requests:
          storage: 300Gi
    
  2. 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:

  1. Salve o seguinte manifesto de exemplo como vllm-gemma-deployment.

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

    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.
  2. 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
    
  3. Para testar se o servidor vLLM está em execução, siga estas etapas:

    1. Execute o seguinte comando para configurar o encaminhamento de portas para o modelo:

      kubectl port-forward service/llm-service 8000:8000
      
    2. 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.

É possível especificar essa opção pela opção de montagem read_ahead_kb ao provisionar estaticamente um novo PersistentVolume ou ao modificar um um PersistentVolume provisionado dinamicamente.

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
    volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.gke.io/zone
          operator: In
          values:
          - ZONE
  storageClassName: hyperdisk-ml
  mountOptions:
  - read_ahead_kb=4096

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.

  1. 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
            - --filename
            - /models/gemma-7b/model-00001-of-00004.safetensors:/models/gemma-7b/model-00002-of-00004.safetensors:/models/gemma-7b/model-00003-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors
            - --direct=1
            - --rw=read
            - --readonly
            - --bs=4096k
            - --ioengine=libaio
            - --iodepth=8
            - --runtime=60
            - --numjobs=1
            - --name=read_benchmark
            volumeMounts:
            - mountPath: "/models"
              name: volume
          restartPolicy: Never
          volumes:
          - name: volume
            persistentVolumeClaim:
              claimName: hdml-static-pvc
      parallelism: 1         # Run 1 Pods concurrently
      completions: 1         # Once 1 Pods complete successfully, the Job is done
      backoffLimit: 1        # Max retries on failure
    

    Substitua CLAIM_NAME pelo nome do PersistentVolumeClaim (por exemplo, hdml-static-pvc).

  2. Crie o job novamente executando o seguinte comando:

    kubectl apply -f benchmark-job.yaml.
    
  3. Use os registros kubectl para conferir a saída da ferramenta fio:

    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