Este tutorial demonstra como implementar e publicar um modelo de linguagem (conteúdo extenso) (MDI/CE) usando várias GPUs no GKE para uma inferência eficiente e escalável. Cria um cluster do GKE que usa várias GPUs L4 e prepara a infraestrutura para publicar qualquer um dos seguintes modelos:
Consoante o formato de dados do modelo, o número necessário de GPUs varia. Neste tutorial, cada modelo usa duas GPUs L4. Para saber mais, consulte o artigo Calcular a quantidade de GPUs.
Este tutorial destina-se a engenheiros de aprendizagem automática (AA), administradores e operadores de plataformas, bem como a especialistas em dados e IA interessados em usar capacidades de orquestração de contentores do Kubernetes para publicar MDIs/CEs. Para saber mais sobre as funções comuns e as tarefas de exemplo referenciadas no Google Cloud conteúdo, consulte Funções e tarefas comuns do utilizador do GKE.
Antes de ler esta página, certifique-se de que conhece o seguinte:
Objetivos
Neste tutorial:
- Crie um cluster e node pools.
- Prepare a sua carga de trabalho.
- Implemente a sua carga de trabalho.
- Interaja com a interface do GML.
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.
Alguns modelos têm requisitos adicionais. Certifique-se de que cumpre estes requisitos:
- Para aceder a modelos da Hugging Face, use um token da Hugging Face.
- Para o modelo Mixtral 8x7b, aceite as condições do modelo Mistral Mixtral.
- Para o modelo Llama 3 70b, certifique-se de que tem uma licença ativa para os modelos Meta Llama.
Prepare o seu ambiente
Na Google Cloud consola, inicie uma instância do Cloud Shell:
Abrir Cloud ShellDefina as variáveis de ambiente predefinidas:
gcloud config set project PROJECT_ID gcloud config set billing/quota_project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export CONTROL_PLANE_LOCATION=us-central1
Substitua PROJECT_ID pelo seu Google Cloud ID do projeto.
Crie um cluster e um node pool do GKE
Pode publicar MDIs em GPUs num cluster do GKE Autopilot ou Standard. 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 l4-demo \ --project=${PROJECT_ID} \ --location=${CONTROL_PLANE_LOCATION} \ --release-channel=rapid
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 l4-demo --location=${CONTROL_PLANE_LOCATION}
Standard
No Cloud Shell, execute o seguinte comando para criar um cluster Standard que use a Workload Identity Federation para o GKE:
gcloud container clusters create l4-demo \ --location ${CONTROL_PLANE_LOCATION} \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --enable-image-streaming \ --node-locations=${CONTROL_PLANE_LOCATION}-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 demorar vários minutos.
Execute o seguinte comando para criar um node pool para o cluster:
gcloud container node-pools create g2-standard-24 --cluster l4-demo \ --location ${CONTROL_PLANE_LOCATION} \ --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 ${CONTROL_PLANE_LOCATION}-a,${CONTROL_PLANE_LOCATION}-c \ --spot
O GKE cria os seguintes recursos para o GML:
- Um cluster da edição Standard do Google Kubernetes Engine (GKE) público.
- Um node pool com o tipo de máquina
g2-standard-24
reduzido para 0 nós. Não lhe é cobrado nenhum valor pelas GPUs até iniciar pods que solicitem GPUs. Este conjunto de nós aprovisiona VMs do Spot, que têm um preço inferior ao das VMs padrão do Compute Engine predefinidas e não oferecem garantia de disponibilidade. Pode remover a flag--spot
deste comando e o seletor de nóscloud.google.com/gke-spot
na configuraçãotext-generation-inference.yaml
para usar VMs a pedido.
Configure
kubectl
para comunicar com o cluster:gcloud container clusters get-credentials l4-demo --location=${CONTROL_PLANE_LOCATION}
Prepare a sua carga de trabalho
Esta secção mostra como configurar a sua carga de trabalho consoante o modelo que quer usar. Este tutorial usa implementações do Kubernetes para implementar o modelo. Uma implementação é um objeto da API Kubernetes que lhe permite executar várias réplicas de pods distribuídas entre os nós num cluster.
Llama 3 70b
Defina as variáveis de ambiente predefinidas:
export HF_TOKEN=HUGGING_FACE_TOKEN
Substitua
HUGGING_FACE_TOKEN
pelo seu token do HuggingFace.Crie um segredo do Kubernetes para o token da 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
text-generation-inference.yaml
manifesto de implementação:Neste manifesto:
NUM_SHARD
tem de 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 32 bits. Isto permite ao GKE reduzir a quantidade de memória da GPU necessária e melhora a velocidade de inferência. No entanto, a precisão do modelo pode diminuir. Para saber como calcular as GPUs a pedir, consulte o artigo Calcular a quantidade de GPUs.
Aplique o manifesto:
kubectl apply -f text-generation-inference.yaml
O resultado é semelhante ao seguinte:
deployment.apps/llm created
Valide o estado do modelo:
kubectl get deploy
O resultado é semelhante ao seguinte:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m
Veja os registos da implementação em execução:
kubectl logs -l app=llm
O resultado é semelhante ao seguinte:
{"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 predefinidas:
export HF_TOKEN=HUGGING_FACE_TOKEN
Substitua
HUGGING_FACE_TOKEN
pelo seu token do HuggingFace.Crie um segredo do Kubernetes para o token da 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
text-generation-inference.yaml
manifesto de implementação:Neste manifesto:
NUM_SHARD
tem de 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 32 bits. Isto permite ao GKE reduzir a quantidade de memória da GPU necessária e melhora a velocidade de inferência. No entanto, isto pode reduzir a precisão do modelo. Para saber como calcular o número de GPUs a pedir, consulte o artigo Calcular a quantidade de GPUs.
Aplique o manifesto:
kubectl apply -f text-generation-inference.yaml
O resultado é semelhante ao seguinte:
deployment.apps/llm created
Valide o estado do modelo:
watch kubectl get deploy
Quando a implementação estiver pronta, o resultado é semelhante ao seguinte:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Para sair do relógio, escreva
CTRL + C
.Veja os registos da implementação em execução:
kubectl logs -l app=llm
O resultado é semelhante ao seguinte:
{"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
text-generation-inference.yaml
manifesto de implementação:Neste manifesto:
NUM_SHARD
tem de 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 32 bits. Isto permite ao GKE reduzir a quantidade de memória da GPU necessária e melhora a velocidade de inferência. No entanto, a precisão do modelo pode diminuir. Para saber como calcular o número de GPUs a pedir, consulte o artigo Calcular a quantidade de GPUs.
Aplique o manifesto:
kubectl apply -f text-generation-inference.yaml
O resultado é semelhante ao seguinte:
deployment.apps/llm created
Valide o estado do modelo:
watch kubectl get deploy
Quando a implementação estiver pronta, o resultado é semelhante ao seguinte:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Para sair do relógio, escreva
CTRL + C
.Veja os registos da implementação em execução:
kubectl logs -l app=llm
O resultado é semelhante ao seguinte:
{"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}
Crie um serviço do tipo ClusterIP
Exponha os seus pods internamente no cluster para que possam ser descobertos e acedidos por outras aplicações.
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
Implemente uma interface de chat
Use o Gradio para criar uma aplicação Web que lhe permita interagir com o seu modelo. O Gradio é uma biblioteca Python que tem um wrapper ChatInterface que cria interfaces de utilizador para chatbots.
Llama 3 70b
Crie um ficheiro com o nome
gradio.yaml
:Aplique o manifesto:
kubectl apply -f gradio.yaml
Encontre o endereço IP externo do serviço:
kubectl get svc
O resultado é semelhante ao seguinte:
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
.Veja a interface do modelo a partir do navegador de Internet através do endereço IP externo com a porta exposta:
http://EXTERNAL_IP
Mixtral 8x7b
Crie um ficheiro com o nome
gradio.yaml
:Aplique o manifesto:
kubectl apply -f gradio.yaml
Encontre o endereço IP externo do serviço:
kubectl get svc
O resultado é semelhante ao seguinte:
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
.Veja a interface do modelo a partir do navegador de Internet através do endereço IP externo com a porta exposta:
http://EXTERNAL_IP
Falcon 40b
Crie um ficheiro com o nome
gradio.yaml
:Aplique o manifesto:
kubectl apply -f gradio.yaml
Encontre o endereço IP externo do serviço:
kubectl get svc
O resultado é semelhante ao seguinte:
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
.Veja a interface do modelo a partir do navegador de Internet através do endereço IP externo com a porta exposta:
http://EXTERNAL_IP
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 mil milhões de parâmetros requer um mínimo de 40 GB de memória da GPU, o que equivale a 70 mil milhões de vezes 4 bits (70 mil milhões x 4 bits= 35 GB) e considera uma sobrecarga de 5 GB. Neste caso, uma única GPU L4 não teria memória suficiente. Por conseguinte, os exemplos neste tutorial usam duas GPUs L4 de memória (2 x 24 = 48 GB). Esta configuração é suficiente para executar o Falcon 40b ou o Llama 3 70b em GPUs L4.
Limpar
Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.
Elimine o cluster
Para evitar incorrer em custos na sua Google Cloud conta pelos recursos que criou neste guia, elimine o cluster do GKE:
gcloud container clusters delete l4-demo --location ${CONTROL_PLANE_LOCATION}