Este guia mostra como disponibilizar modelos de linguagem grandes (LLMs) usando o Ray e o complemento Ray Operator com o Google Kubernetes Engine (GKE). O framework do Ray fornece uma plataforma completa de IA/ML para treinamento, treinamento detalhado e inferência de cargas de trabalho de ML. O Ray Serve é uma estrutura no Ray que pode ser usada para disponibilizar LLMs conhecidos do Hugging Face.
Antes de ler este guia, confira se você conhece o modelo que quer disponibilizar neste tutorial. É possível veicular qualquer um dos seguintes modelos:
Esta página é destinada a engenheiros de machine learning (ML) e administradores e operadores de plataforma que facilitam cargas de trabalho de ML. Para saber mais sobre papéis comuns e tarefas de exemplo referenciados no conteúdo do Google Cloud , consulte Tarefas e funções de usuário comuns do GKE.
Abordamos as etapas a seguir:
- Crie um cluster do GKE Autopilot ou do Standard com o complemento do operador do Ray ativado.
- Implante um recurso do RayService que baixa e disponibiliza um modelo de linguagem grande (LLM) do Hugging Face.
- Implante uma interface de chat e converse com LLMs.
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 CLI do Google Cloud para essa tarefa,
    instale e inicialize a
    gcloud CLI. Se você instalou a CLI gcloud anteriormente, instale a versão
    mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.
- Crie uma conta do Hugging Face caso ainda não tenha uma.
- Verifique se você tem um token do Hugging Face.
- Verifique se você tem acesso ao modelo do Hugging Face que quer usar. Isso geralmente é concedido com a assinatura de um contrato e a solicitação de acesso ao proprietário do modelo na página do modelo do Hugging Face.
- Verifique se você tem uma cota de GPU na região us-central1. Para saber mais, consulte Cota de GPU.
Preparar o ambiente
- No Google Cloud console, inicie uma instância do Cloud Shell: 
 Abrir o Cloud Shell
- Clone o repositório de amostra: - git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/llm export TUTORIAL_HOME=`pwd`
- Defina as variáveis de ambiente padrão: - gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export COMPUTE_REGION=us-central1 export CLUSTER_VERSION=CLUSTER_VERSION export HF_TOKEN=HUGGING_FACE_TOKEN- Substitua: - PROJECT_ID: o Google Cloud ID do projeto.
- CLUSTER_VERSION: a versão do GKE a ser usada. Precisa ser- 1.30.1ou mais recente.
- HUGGING_FACE_TOKEN: seu token de acesso do Hugging Face.
 
Criar um cluster com um pool de nós de GPU
É possível disponibilizar um LLM em GPUs L4 com Ray em um cluster do GKE Autopilot ou Standard usando o complemento do Operador do Ray. Recomendamos que você use um cluster do Autopilot para ter uma experiência totalmente gerenciada do Kubernetes. Escolha um cluster Standard se o caso de uso exigir alta escalonabilidade ou se você quiser mais controle sobre a configuração do cluster. 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.
Use o Cloud Shell para criar um cluster Autopilot ou Standard:
Autopilot
Crie um cluster Autopilot com o complemento do operador do Ray ativado:
gcloud container clusters create-auto rayserve-cluster \
    --enable-ray-operator \
    --cluster-version=${CLUSTER_VERSION} \
    --location=${COMPUTE_REGION}
Standard
Crie um cluster Standard com o complemento do Operador do Ray ativado:
gcloud container clusters create rayserve-cluster \
    --addons=RayOperator \
    --cluster-version=${CLUSTER_VERSION} \
    --machine-type=g2-standard-24 \
    --location=${COMPUTE_ZONE} \
    --num-nodes=2 \
    --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest
Criar um Secret do Kubernetes para as credenciais do Hugging Face
No Cloud Shell, crie um Secret do Kubernetes assim:
- Configure - kubectlpara se comunicar com o cluster:- gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${COMPUTE_REGION}
- 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 -
Implantar o modelo LLM
O repositório do GitHub clonado tem um diretório para cada modelo que inclui uma configuração do RayService. A configuração de cada modelo inclui os seguintes componentes:
- Implantação do Ray Serve: a implantação do Ray Serve, que inclui configuração de recursos e dependências de ambiente de execução.
- Modelo: o ID do modelo do Hugging Face.
- Cluster do Ray: o cluster do Ray e os recursos necessários para cada componente, incluindo pods principais e de worker. 
Gemma 2B IT
- Implante o modelo: - kubectl apply -f gemma-2b-it/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice gemma-2b-it -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço para o aplicativo Ray Serve: - kubectl get service gemma-2b-it-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gemma-2b-it-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Gemma 7B IT
- Implante o modelo: - kubectl apply -f gemma-7b-it/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice gemma-7b-it -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço para o aplicativo Ray Serve: - kubectl get service gemma-7b-it-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gemma-7b-it-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Llama 2 7B
- Implante o modelo: - kubectl apply -f llama-2-7b/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice llama-2-7b -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço para o aplicativo Ray Serve: - kubectl get service llama-2-7b-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE llama-2-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Llama 3 8B
- Implante o modelo: - kubectl apply -f llama-3-8b/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice llama-3-8b -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço para o aplicativo Ray Serve: - kubectl get service llama-3-8b-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE llama-3-8b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Mistral 7B
- Implante o modelo: - kubectl apply -f mistral-7b/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice mistral-7b -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço para o aplicativo Ray Serve: - kubectl get service mistral-7b-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mistral-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Disponibilizar o modelo
Os modelos Llama2 7B e Llama3 8B usam a especificação de chat da API OpenAI. Os outros modelos oferecem suporte apenas à geração de texto, que é uma técnica que gera texto com base em comandos.
Configurar o encaminhamento de portas
Configure o encaminhamento de portas para o servidor de inferência:
Gemma 2B IT
kubectl port-forward svc/gemma-2b-it-serve-svc 8000:8000
Gemma 7B IT
kubectl port-forward svc/gemma-7b-it-serve-svc 8000:8000
Llama2 7B
kubectl port-forward svc/llama-7b-serve-svc 8000:8000
Llama 3 8B
kubectl port-forward svc/llama-3-8b-serve-svc 8000:8000
Mistral 7B
kubectl port-forward svc/mistral-7b-serve-svc 8000:8000
Interagir com o modelo usando curl
Use o curl para conversar com o modelo:
Gemma 2B IT
Em uma nova sessão do terminal:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Gemma 7B IT
Em uma nova sessão do terminal:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Llama2 7B
Em uma nova sessão do terminal:
curl http://localhost:8000/v1/chat/completions     -H "Content-Type: application/json"     -d '{
      "model": "meta-llama/Llama-2-7b-chat-hf",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
      ],
      "temperature": 0.7
    }'
Llama 3 8B
Em uma nova sessão do terminal:
curl http://localhost:8000/v1/chat/completions     -H "Content-Type: application/json"     -d '{
      "model": "meta-llama/Meta-Llama-3-8B-Instruct",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
      ],
      "temperature": 0.7
    }'
Mistral 7B
Em uma nova sessão do terminal:
curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Como os modelos que você disponibilizou não retêm nenhum histórico, cada mensagem e resposta precisa ser enviada de volta ao modelo para criar uma experiência de conversa interativa. O exemplo a seguir mostra como criar uma conversa interativa usando o modelo Llama 3 8B:
Crie um diálogo com o modelo usando curl:
curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
      "model": "meta-llama/Meta-Llama-3-8B-Instruct",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."},
        {"role": "assistant", "content": " \n1. Java\n2. Python\n3. C++\n4. C#\n5. JavaScript"},
        {"role": "user", "content": "Can you give me a brief description?"}
      ],
      "temperature": 0.7
}'
O resultado será assim:
{
  "id": "cmpl-3cb18c16406644d291e93fff65d16e41",
  "object": "chat.completion",
  "created": 1719035491,
  "model": "meta-llama/Meta-Llama-3-8B-Instruct",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Here's a brief description of each:\n\n1. **Java**: A versatile language for building enterprise-level applications, Android apps, and web applications.\n2. **Python**: A popular language for data science, machine learning, web development, and scripting, known for its simplicity and ease of use.\n3. **C++**: A high-performance language for building operating systems, games, and other high-performance applications, with a focus on efficiency and control.\n4. **C#**: A modern, object-oriented language for building Windows desktop and mobile applications, as well as web applications using .NET.\n5. **JavaScript**: A versatile language for client-side scripting on the web, commonly used for creating interactive web pages, web applications, and mobile apps.\n\nNote: These descriptions are brief and don't do justice to the full capabilities and uses of each language."
      },
      "logprobs": null,
      "finish_reason": "stop",
      "stop_reason": null
    }
  ],
  "usage": {
    "prompt_tokens": 73,
    "total_tokens": 245,
    "completion_tokens": 172
  }
}
(Opcional) Conectar-se à interface de chat
É possível usar o Gradio para criar aplicativos da Web que permitam interagir com seu
modelo. O Gradio é uma biblioteca Python que tem um wrapper ChatInterface que
cria interfaces de usuário para chatbots. Para Llama 2 7B e Llama 3 7B, você
instalou o Gradio ao implantar o modelo de LLM.
- Configure o encaminhamento de portas para o Serviço - gradio:- kubectl port-forward service/gradio 8080:8080 &
- Abra http://localhost:8080 no navegador para conversar com o modelo. 
Disponibilizar vários modelos com a multiplexação de modelos
A multiplexação de modelos é uma técnica usada para disponibilizar vários modelos no mesmo cluster do Ray. É possível rotear o tráfego para modelos específicos usando cabeçalhos de solicitação ou balanceamento de carga.
Neste exemplo, você cria um aplicativo multiplexado do Ray Serve com dois modelos: Gemma 7B IT e Llama 3 8B.
- Implante o recurso do RayService: - kubectl apply -f model-multiplexing/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice model-multiplexing -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T14:00:41Z" serveDeploymentStatuses: MutliModelDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment_1: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço do Kubernetes para o aplicativo do Ray Serve: - kubectl get service model-multiplexing-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-multiplexing-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
- Configure o encaminhamento de portas para o aplicativo do Ray Serve: - kubectl port-forward svc/model-multiplexing-serve-svc 8000:8000
- Envie uma solicitação ao modelo de TI do Gemma 7B: - curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: google/gemma-7b-it" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'- O resultado será assim: - {"text": ["What are the top 5 most popular programming languages? Please be brief.\n\n1. JavaScript\n2. Java\n3. C++\n4. Python\n5. C#"]}
- Envie uma solicitação para o modelo Llama 3 8B: - curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: meta-llama/Meta-Llama-3-8B-Instruct" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'- O resultado será assim: - {"text": ["What are the top 5 most popular programming languages? Please be brief. Here are your top 5 most popular programming languages, based on the TIOBE Index, a widely used measure of the popularity of programming languages.\r\n\r\n1. **Java**: Used in Android app development, web development, and enterprise software development.\r\n2. **Python**: A versatile language used in data science, machine learning, web development, and automation.\r\n3. **C++**: A high-performance language used in game development, system programming, and high-performance computing.\r\n4. **C#**: Used in Windows and web application development, game development, and enterprise software development.\r\n5. **JavaScript**: Used in web development, mobile app development, and server-side programming with technologies like Node.js.\r\n\r\nSource: TIOBE Index (2022).\r\n\r\nThese rankings can vary depending on the source and methodology used, but this gives you a general idea of the most popular programming languages."]}
- Envie uma solicitação para um modelo aleatório excluindo o cabeçalho - serve_multiplexed_model_id:- curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'- A saída é uma das saídas das etapas anteriores. 
Criar vários modelos com a composição de modelos
A composição de modelos é uma técnica usada para combinar vários modelos em um único aplicativo. A composição de modelos permite encadear entradas e saídas em vários LLMs e dimensionar seus modelos como um único aplicativo.
Neste exemplo, você vai compor dois modelos, Gemma 7B IT e Llama 3 8B, em um único aplicativo. O primeiro modelo é o assistente que responde às perguntas fornecidas no comando. O segundo modelo é o de resumo. A saída do modelo de assistente é encadeada na entrada do modelo de resumo. O resultado final é a versão resumida da resposta do modelo de assistente.
- Implante o recurso do RayService: - kubectl apply -f model-composition/
- Aguarde até que o recurso do RayService esteja pronto: - kubectl get rayservice model-composition -o yaml- O resultado será assim: - status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T14:00:41Z" serveDeploymentStatuses: MutliModelDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY VLLMDeployment_1: healthLastUpdateTime: "2024-06-22T14:00:41Z" status: HEALTHY status: RUNNING- Nesta saída, - status: RUNNINGindica que o recurso do RayService está pronto.
- Confirme se o GKE criou o Serviço para o aplicativo do Ray Serve: - kubectl get service model-composition-serve-svc- O resultado será assim: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-composition-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
- Envie uma solicitação para o modelo: - curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What is the most popular programming language for machine learning and why?", "max_tokens": 1000}'
- O resultado será assim: - {"text": ["\n\n**Sure, here is a summary in a single sentence:**\n\nThe most popular programming language for machine learning is Python due to its ease of use, extensive libraries, and growing community."]}
Excluir o projeto
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Excluir recursos individuais
Se você usou um projeto existente e não quer excluí-lo, exclua os recursos individuais.
- Exclua o cluster: - gcloud container clusters delete rayserve-cluster
A seguir
- Descubra como executar cargas de trabalho de IA/ML otimizadas com os recursos de orquestração da plataforma GKE.
- Treinar um modelo com GPUs no modo Standard do GKE
- Saiba como usar o RayServe no GKE conferindo o exemplo de código no GitHub (em inglês).