Disponibilizar LLMs no GKE com uma estratégia de provisionamento de GPU de alta disponibilidade e custo otimizado

Este guia mostra como otimizar os custos de cargas de trabalho de veiculação de LLM no GKE. Este tutorial usa uma combinação de VMs de início flexível, VMs spot e ComputeClasses para inferência econômica.

Este guia usa Mixtral 8x7b como um exemplo de LLM que pode ser implantado.

Este guia é destinado a engenheiros de machine learning (ML), administradores e operadores de plataforma e especialistas em dados e IA interessados em usar os recursos de orquestração de contêineres do Kubernetes para veiculação de LLMs. Para mais informações sobre papéis comuns e exemplos de tarefas referenciados no Google Cloud content, consulte Funções e tarefas comuns do usuário do GKE.

Preços de início flexível

O início flexível é recomendado se a carga de trabalho exigir recursos provisionados dinamicamente conforme necessário, por até sete dias com reservas de curto prazo, sem gerenciamento complexo de cotas e acesso econômico. O início flexível é desenvolvido pelo Programador dinâmico de cargas de trabalho e é faturado usando os preços do Programador dinâmico de cargas de trabalho:

  • Descontos (até 53%) para vCPUs, GPUs e TPUs.
  • Você paga conforme a utilização.

Contexto

Esta seção descreve as técnicas disponíveis que podem ser usadas para receber recursos de computação, incluindo aceleradores de GPU, com base nos requisitos das cargas de trabalho de IA/ML. Essas técnicas são chamadas de estratégias de disponibilidade de aceleradores no GKE.

GPUs

As unidades de processamento gráfico (GPUs) permitem acelerar cargas de trabalho específicas, como machine learning e processamento de dados. O GKE oferece nós equipados com essas GPUs poderosas para otimizar o desempenho de tarefas de machine learning e processamento de dados. O GKE oferece uma gama de opções de tipo de máquina para configuração de nós, incluindo tipos de máquinas com GPUs NVIDIA H100, A100 e L4.

Para mais informações, consulte Sobre GPUs no GKE.

Início flexível

O início flexível, com tecnologia do Programador dinâmico de cargas de trabalho, é uma opção de consumo de GPU em que o GKE mantém sua solicitação de GPU e provisiona automaticamente VMs de início flexível quando a capacidade fica disponível. Considere usar o início flexível para cargas de trabalho que precisam de capacidade de GPU por um tempo limitado, até sete dias, e não têm uma data de início fixa. Para mais informações, consulte Início flexível.

VMs spot

Também é possível usar GPUs com VMs spot quando as cargas de trabalho conseguirem tolerar interrupções frequentes de nós. O uso de VMs spot ou de início flexível reduz o preço da execução das GPUs. O uso de VMs spot combinadas com o início flexível oferece uma opção de failover quando a capacidade de VMs spot não está disponível.

Para mais informações, consulte Como usar VMs spot com pools de nós de GPU.

ComputeClasses

É possível solicitar GPUs usando ComputeClasses. As ComputeClasses permitem definir uma hierarquia de configurações de nós para o GKE priorizar durante as decisões de escalonamento de nós, para que as cargas de trabalho sejam executadas no hardware selecionado. Para mais informações, consulte Sobre ComputeClasses personalizadas.

Antes de começar

  • Faça login na sua Google Cloud conta do. Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho dos nossos produtos em situações reais. Clientes novos também recebem US $300 em créditos para executar, testar e implantar cargas de trabalho.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  • Verify that billing is enabled for your Google Cloud project.

Receber acesso ao modelo

Gere um novo token do Hugging Face, se você ainda não tiver um:

  1. Clique em Seu perfil > Configurações > Tokens de acesso.
  2. Selecione Novo token.
  3. Dê o nome que você quiser e atribua um papel com, no mínimo, privilégios de leitura Read.
  4. Selecione Gerar um token.

Criar uma ComputeClass

Nesta seção, você cria uma ComputeClass personalizada. As ComputeClasses definem os tipos e as relações entre vários recursos de computação usados pela carga de trabalho.

  1. No Google Cloud console, inicie uma sessão do Cloud Shell clicando em Ícone de ativação do Cloud Shell Ativar o Cloud Shell no Google Cloud console. Uma sessão será aberta no painel inferior do Google Cloud console.
  2. Crie um arquivo de manifesto dws-flex-start.yaml:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: dws-model-inference-class
    spec:
      priorities:
        - machineType: g2-standard-24
          spot: true
        - machineType: g2-standard-24
          flexStart:
            enabled: true
            nodeRecycling:
              leadTimeSeconds: 3600
      nodePoolAutoCreation:
        enabled: true
    
  3. Aplique o manifesto dws-flex-start.yaml:

    kubectl apply -f dws-flex-start.yaml
    

O GKE implanta máquinas g2-standard-24 com aceleradores L4. O GKE usa ComputeClasses para priorizar VMs spot primeiro e VMs de início flexível em segundo.

Implantar a carga de trabalho do LLM

  1. Crie um secret do Kubernetes que contenha o token do Hugging Face usando o comando a seguir:

    kubectl create secret generic model-inference-secret \
        --from-literal=HUGGING_FACE_TOKEN=HUGGING_FACE_TOKEN \
        --dry-run=client -o yaml | kubectl apply -f -
    

    Substitua HUGGING_FACE_TOKEN pelo seu token de acesso do Hugging Face.

  2. Crie um arquivo chamado mixtral-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: inference-mixtral-ccc
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: llm
      template:
        metadata:
          labels:
            app: llm
        spec:
          nodeSelector:
            cloud.google.com/compute-class: dws-model-inference-class
          containers:
          - name: llm
            image: us-docker.pkg.dev/deeplearning-platform-release/gcr.io/huggingface-text-generation-inference-cu124.2-3.ubuntu2204.py311
            resources:
              requests:
                cpu: "5"
                memory: "40Gi"
                nvidia.com/gpu: "2"
              limits:
                cpu: "5"
                memory: "40Gi"
                nvidia.com/gpu: "2"
            env:
            - name: MODEL_ID
              value: mistralai/Mixtral-8x7B-Instruct-v0.1
            - name: NUM_SHARD
              value: "2"
            - name: PORT
              value: "8080"
            - name: QUANTIZE
              value: bitsandbytes-nf4
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: model-inference-secret
                  key: HUGGING_FACE_TOKEN
            volumeMounts:
              - mountPath: /dev/shm
                name: dshm
              - mountPath: /tmp
                name: ephemeral-volume
          volumes:
            - name: dshm
              emptyDir:
                  medium: Memory
            - name: ephemeral-volume
              ephemeral:
                volumeClaimTemplate:
                  metadata:
                    labels:
                      type: ephemeral
                  spec:
                    accessModes: ["ReadWriteOnce"]
                    storageClassName: "premium-rwo"
                    resources:
                      requests:
                        storage: 100Gi
    

    Nesse manifesto, o campo mountPath está definido como /tmp, porque é o caminho em que a variável de ambiente HF_HOME no contêiner de machine learning (DLC, na sigla em inglês) para inferência de geração de texto (TGI, na sigla em inglês) está definida, em vez do caminho /data padrão definido na imagem padrão do TGI. O modelo transferido por download será armazenado nesse diretório.

  3. Implante o modelo:

    kubectl apply -f  mixtral-deployment.yaml
    

    O GKE programa um novo pod para implantação, o que aciona o escalonador automático do pool de nós para adicionar um segundo nó antes de implantar a segunda réplica do modelo.

  4. Verifique o status do modelo:

    watch kubectl get deploy inference-mixtral-ccc
    

    Se o modelo foi implantado com sucesso, a saída será semelhante a esta:

    NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
    inference-mixtral-ccc  1/1     1            1           10m
    

    Para sair da exibição, pressione CTRL + C.

  5. Aguarde o contêiner fazer o download e começar a veicular o modelo:

    watch "kubectl logs $(kubectl get pods -l app=llm -o custom-columns=:metadata.name --no-headers) | tail"
    

    Para sair da exibição, pressione CTRL + C.

  6. Confira os pools de nós provisionados pelo GKE:

    kubectl get nodes -L cloud.google.com/gke-nodepool
    

    O resultado será assim:

      NAME                                                  STATUS   ROLES    AGE   VERSION               GKE-NODEPOOL
      gke-flex-na-nap-g2-standard--0723b782-fg7v   Ready    <none>   10m   v1.32.3-gke.1152000   nap-g2-standard-24-spot-gpu2-1gbdlbxz
      gke-flex-nap-zo-default-pool-09f6fe53-fzm8   Ready    <none>   32m   v1.32.3-gke.1152000   default-pool
      gke-flex-nap-zo-default-pool-09f6fe53-lv2v   Ready    <none>   32m   v1.32.3-gke.1152000   default-pool
      gke-flex-nap-zo-default-pool-09f6fe53-pq6m   Ready    <none>   32m   v1.32.3-gke.1152000   default-pool
    

    O nome do pool de nós criado indica o tipo de máquina. Nesse caso, o GKE provisionou VMs spot.

  7. Exponha o modelo:

    kubectl expose deployment/inference-mixtral-ccc --port 8080 --name=llm-service
    

Interagir com o modelo usando curl

Esta seção mostra como realizar um teste de inferência básico para verificar o modelo implantado.

  1. Configure o encaminhamento de portas para o modelo:

    kubectl port-forward service/llm-service 8080:8080
    

    O resultado será assim:

    Forwarding from 127.0.0.1:8080 -> 8080
    
  2. Em uma nova sessão do terminal, converse com seu modelo usando curl:

    curl http://localhost:8080/v1/completions \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{
        "model": "mixtral-8x7b-instruct-gptq",
        "prompt": "<s>[INST]Who was the first president of the United States?[/INST]",
        "max_tokens": 40}'
    

    A saída será assim:

    George Washington was a Founding Father and the first president of the United States, serving from 1789 to 1797.
    

Limpar

Para evitar cobranças na sua Google Cloud conta pelos recursos usados nesta página, exclua o projeto que contém os recursos ou mantenha o projeto e exclua os recursos individuais.

Excluir o projeto

  1. No Google Cloud console, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
  3. Na caixa de diálogo, digite o ID do projeto e clique em Desligar para excluir o projeto.

Excluir o recurso individual

  1. Exclua os recursos do Kubernetes que você criou neste guia:

    kubectl delete deployment inference-mixtral-ccc
    kubectl delete service llm-service
    kubectl delete computeclass dws-model-inference-class
    kubectl delete secret model-inference-secret
    
  2. Exclua o cluster:

    gcloud container clusters delete CLUSTER_NAME
    

A seguir