Neste tutorial, mostramos como disponibilizar um modelo de linguagem grande (LLM) com GPUs no Google Kubernetes Engine (GKE) usando várias GPUs para inferência eficiente e escalonável. Além disso, você vai criar um cluster do GKE que usa várias GPUs L4 e preparar a infraestrutura do GKE para disponibilizar qualquer um dos seguintes modelos:
O número de GPUs varia de acordo com o formato de dados do modelo. Neste tutorial, cada modelo usa duas GPUs L4. Para saber mais, consulte Como calcular a quantidade de GPUs.
Antes de concluir este tutorial no GKE, recomendamos que você leia Sobre as GPUs no GKE.
Objetivos
Este tutorial é destinado a engenheiros de MLOps ou DevOps ou administradores de plataforma que querem usar os recursos de orquestração do GKE para exibir LLMs.
Este tutorial inclui as etapas a seguir:
- Crie um cluster e pools de nós.
- Prepare a carga de trabalho.
- Implante a carga de trabalho.
- Interaja com a interface do LLM.
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
.
Alguns modelos têm requisitos adicionais. Verifique se você cumpre estes requisitos:
- Para acessar modelos do Hugging Face, use um token HuggingFace.
- Para o modelo Mixtral 8x7b: aceite as condições do modelo Mistral Mixtral.
- Para o modelo Llama 3 70b: verifique se você tem uma licença ativa para os modelos do Meta Llama.
prepare o ambiente
No console do Google Cloud, inicie uma instância do Cloud Shell:
Abrir o Cloud ShellDefina as variáveis de ambiente padrão:
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export REGION=us-central1
Substitua PROJECT_ID pelo ID do projeto do Google Cloud.
Criar um cluster do GKE e um pool de nós
É 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 l4-demo \ --project=${PROJECT_ID} \ --region=${REGION} \ --release-channel=rapid
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 l4-demo --region=${REGION}
Padrão
No Cloud Shell, execute o seguinte comando para criar um cluster padrão que use a federação de identidade da carga de trabalho para o GKE:
gcloud container clusters create l4-demo --location ${REGION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=$REGION-a \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type n2d-standard-4 \ --num-nodes 1 --min-nodes 1 --max-nodes 5 \ --release-channel=rapid
A criação do cluster pode levar vários minutos.
Execute o seguinte comando para criar um pool de nós para o cluster:
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --machine-type g2-standard-24 \ --enable-autoscaling --enable-image-streaming \ --num-nodes=0 --min-nodes=0 --max-nodes=3 \ --node-locations $REGION-a,$REGION-c --region $REGION --spot
O GKE cria os seguintes recursos para o LLM:
- Um cluster público da edição Standard do Google Kubernetes Engine (GKE).
- Um pool de nós com o tipo de máquina
g2-standard-24
escalonado para zero nós. Nenhuma GPU será cobrada até que você inicie pods que solicitam GPUs. Este pool de nós provisiona VMs spot, que têm um preço menor do que as VMs Standard padrão do Compute Engine e não oferecem garantia de disponibilidade. É possível remover a flag--spot
desse comando e o seletor de nóscloud.google.com/gke-spot
na configuraçãotext-generation-inference.yaml
para usar VMs sob demanda.
Configure
kubectl
para se comunicar com o cluster:gcloud container clusters get-credentials l4-demo --region=${REGION}
Preparar sua carga de trabalho
Na seção a seguir, mostramos como configurar sua carga de trabalho, dependendo do modelo que você quer usar:
Llama 3 70b
Defina as variáveis de ambiente padrão:
export HF_TOKEN=HUGGING_FACE_TOKEN
Substitua
HUGGING_FACE_TOKEN
pelo token HuggingFace.Crie um secret do Kubernetes para o token HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Crie o seguinte manifesto
text-generation-inference.yaml
:Nesse manifesto:
NUM_SHARD
precisa ser2
porque o modelo requer duas GPUs NVIDIA L4.QUANTIZE
está definido comobitsandbytes-nf4
, o que significa que o modelo é carregado em 4 bits em vez de em 32 bits. Isso permite que o GKE reduza a quantidade de memória de GPU necessária e melhore a velocidade de inferência. No entanto, a acurácia do modelo pode diminuir. Para saber como calcular as GPUs a serem solicitadas, consulte Como calcular a quantidade de GPUs.
Aplique o manifesto:
kubectl apply -f text-generation-inference.yaml
O resultado será assim:
deployment.apps/llm created
Verifique o status do modelo:
kubectl get deploy
O resultado será assim:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m
Confira os registros da implantação em execução:
kubectl logs -l app=llm
O resultado será assim:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Mixtral 8x7b
Defina as variáveis de ambiente padrão:
export HF_TOKEN=HUGGING_FACE_TOKEN
Substitua
HUGGING_FACE_TOKEN
pelo token HuggingFace.Crie um secret do Kubernetes para o token HuggingFace:
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Crie o seguinte manifesto
text-generation-inference.yaml
:Nesse manifesto:
NUM_SHARD
precisa ser2
porque o modelo requer duas GPUs NVIDIA L4.QUANTIZE
está definido comobitsandbytes-nf4
, o que significa que o modelo é carregado em 4 bits em vez de em 32 bits. Isso permite que o GKE reduza a quantidade de memória de GPU necessária e melhore a velocidade de inferência. No entanto, isso pode reduzir a acurácia do modelo. Para saber como calcular as GPUs a serem solicitadas, consulte Como calcular a quantidade de GPUs.
Aplique o manifesto:
kubectl apply -f text-generation-inference.yaml
O resultado será assim:
deployment.apps/llm created
Verifique o status do modelo:
watch kubectl get deploy
A saída será semelhante ao exemplo abaixo quando a implantação estiver pronta. Para sair da exibição, digite
CTRL + C
:NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Confira os registros da implantação em execução:
kubectl logs -l app=llm
O resultado será assim:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Falcon 40b
Crie o seguinte manifesto
text-generation-inference.yaml
:Nesse manifesto:
NUM_SHARD
precisa ser2
porque o modelo requer duas GPUs NVIDIA L4.QUANTIZE
está definido comobitsandbytes-nf4
, o que significa que o modelo é carregado em 4 bits em vez de em 32 bits. Isso permite que o GKE reduza a quantidade de memória de GPU necessária e melhore a velocidade de inferência. No entanto, a acurácia do modelo pode diminuir. Para saber como calcular as GPUs a serem solicitadas, consulte Como calcular a quantidade de GPUs.
Aplique o manifesto:
kubectl apply -f text-generation-inference.yaml
O resultado será assim:
deployment.apps/llm created
Verifique o status do modelo:
watch kubectl get deploy
A saída será semelhante ao exemplo abaixo quando a implantação estiver pronta. Para sair da exibição, digite
CTRL + C
:NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Confira os registros da implantação em execução:
kubectl logs -l app=llm
O resultado será assim:
{"timestamp":"2024-03-09T05:08:14.751646Z","level":"INFO","message":"Warming up model","target":"text_generation_router","filename":"router/src/main.rs","line_number":291} {"timestamp":"2024-03-09T05:08:19.961136Z","level":"INFO","message":"Setting max batch total tokens to 133696","target":"text_generation_router","filename":"router/src/main.rs","line_number":328} {"timestamp":"2024-03-09T05:08:19.961164Z","level":"INFO","message":"Connected","target":"text_generation_router","filename":"router/src/main.rs","line_number":329} {"timestamp":"2024-03-09T05:08:19.961171Z","level":"WARN","message":"Invalid hostname, defaulting to 0.0.0.0","target":"text_generation_router","filename":"router/src/main.rs","line_number":343}
Criar um serviço do tipo ClusterIP
Crie o seguinte manifesto
llm-service.yaml
:apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080
Aplique o manifesto:
kubectl apply -f llm-service.yaml
Implantar uma interface de chat
Use o Gradio para criar um aplicativo da Web que permita a interação com o modelo. O Gradio é uma biblioteca Python que tem um wrapper ChatInterface que cria interfaces de usuário para chatbots.
Llama 3 70b
Crie um arquivo chamado
gradio.yaml
:Aplique o manifesto:
kubectl apply -f gradio.yaml
Encontre o endereço IP externo do serviço:
kubectl get svc
O resultado será assim:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copie o endereço IP externo da coluna
EXTERNAL-IP
.Confira a interface do modelo no navegador da Web usando o endereço IP externo com a porta exposta:
http://EXTERNAL_IP
Mixtral 8x7b
Crie um arquivo chamado
gradio.yaml
:Aplique o manifesto:
kubectl apply -f gradio.yaml
Encontre o endereço IP externo do serviço:
kubectl get svc
O resultado será assim:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copie o endereço IP externo da coluna
EXTERNAL-IP
.Confira a interface do modelo no navegador da Web usando o endereço IP externo com a porta exposta:
http://EXTERNAL_IP
Falcon 40b
Crie um arquivo chamado
gradio.yaml
:Aplique o manifesto:
kubectl apply -f gradio.yaml
Encontre o endereço IP externo do serviço:
kubectl get svc
O resultado será assim:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copie o endereço IP externo da coluna
EXTERNAL-IP
.Confira a interface do modelo no navegador da Web usando o endereço IP externo com a porta exposta:
http://EXTERNAL_IP
Como calcular a quantidade de GPUs
A quantidade de GPUs depende do valor da flag QUANTIZE
. Neste
tutorial, QUANTIZE
está definido como bitsandbytes-nf4
, o que significa que o modelo é
carregado em 4 bits.
Um modelo de 70 bilhões de parâmetros exigiria no mínimo 40 GB de memória de GPU, o que equivale a 70 bilhões vezes 4 bits (70 bilhões x 4 bits = 35 GB) e considera 5 GB de sobrecarga. Nesse caso, uma única GPU L4 não teria memória suficiente. Portanto, os exemplos neste tutorial usam duas GPUs L4 de memória (2 x 24 = 48 GB). Essa configuração é suficiente para executar o Falcon 40b ou o Llama 3 70b em GPUs L4.
Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.
Exclua o cluster
Para evitar cobranças na sua conta do Google Cloud pelos recursos criados neste guia, exclua o cluster do GKE:
gcloud container clusters delete l4-demo --region ${REGION}