En esta guía, se muestra cómo entregar modelos de lenguaje grande (LLM) con Ray y el complemento Ray Operator con Google Kubernetes Engine (GKE).
En esta guía, puedes entregar cualquiera de los siguientes modelos:
En esta guía, también se abordan técnicas de entrega de modelos, como la multiplexación y la composición de modelos, que son compatibles con el framework de Ray Serve.
Información general
El framework de Ray proporciona una plataforma de IA/AA de extremo a extremo para el entrenamiento, el entrenamiento detallado y la inferencia de cargas de trabajo de aprendizaje automático. Ray Serve es un framework en Ray que puedes usar para entregar LLM populares de Hugging Face.
Según el formato de datos del modelo, la cantidad de GPU varía. En esta guía, tu modelo puede usar una o dos GPUs L4.
En esta guía se abarcan los siguientes pasos:
- Crea un clúster de GKE Autopilot o Standard con el complemento Ray Operator habilitado.
- Implementa un recurso de RayService que descargue y entregue un modelo de lenguaje grande (LLM) de Hugging Face.
- Implementa una interfaz de chat y dialoga con los LLM.
Antes de comenzar
Antes de comenzar, asegúrate de haber realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta
gcloud components update
para obtener la versión más reciente.
- Crea una cuenta de Hugging Face, si todavía no la tienes.
- Asegúrate de tener un token de Hugging Face.
- Asegúrate de tener acceso al modelo de Hugging Face que deseas usar. Por lo general, se otorga mediante la firma de un acuerdo y la solicitud de acceso al propietario del modelo en la página del modelo de Hugging Face.
- Asegúrate de tener cuota de GPU en la región
us-central1
. Para obtener más información, consulta Cuota de GPU.
Prepara el entorno
En la consola de Google Cloud, inicia una instancia de Cloud Shell:
Abrir Cloud ShellClona el repositorio de ejemplo:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/llm export TUTORIAL_HOME=`pwd`
Configura las variables de entorno predeterminadas:
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
Reemplaza lo siguiente:
PROJECT_ID
: El ID del proyecto de Google Cloud.CLUSTER_VERSION
: la versión de GKE que se usará. Debe ser1.30.1
o una versión posterior.HUGGING_FACE_TOKEN
: Tu token de acceso de Hugging Face.
Crea un clúster con un grupo de nodos de GPU
Puedes entregar un LLM en GPU L4 con Ray en un clúster de GKE Autopilot o Standard con el complemento Ray Operator. Por lo general, recomendamos que uses un clúster de Autopilot para una experiencia de Kubernetes completamente administrada. En su lugar, elige un clúster estándar si tu caso de uso requiere alta escalabilidad o si deseas más control sobre la configuración del clúster. Para elegir el modo de operación de GKE que se adapte mejor a tus cargas de trabajo, consulta Elige un modo de operación de GKE.
Usa Cloud Shell para crear un clúster de Autopilot o Standard:
Autopilot
Crea un clúster de Autopilot con el complemento Ray Operator habilitado:
gcloud container clusters create-auto rayserve-cluster \
--enable-ray-operator \
--cluster-version=${CLUSTER_VERSION} \
--location=${COMPUTE_REGION}
Estándar
Crea un clúster estándar con el complemento Ray Operator habilitado:
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
Crea un secreto de Kubernetes para las credenciales de Hugging Face
En Cloud Shell, crea un Secret de Kubernetes de la siguiente manera:
Configura
kubectl
para comunicarse con tu clúster:gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${COMPUTE_REGION}
Crea un Secret de Kubernetes que contenga el token de Hugging Face:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Implementa el modelo de LLM
El repositorio de GitHub que clonaste tiene un directorio para cada modelo que incluye una configuración de RayService. La configuración de cada modelo incluye los siguientes componentes:
- Implementación de Ray Serve: La implementación de Ray Serve, que incluye la configuración de recursos y las dependencias del entorno de ejecución
- Model: El ID del modelo de Hugging Face.
Clúster de Ray: El clúster subyacente de Ray y los recursos necesarios para cada componente, incluidos los pods principales y de trabajo.
Gemma 2B IT
Implementa el modelo:
kubectl apply -f gemma-2b-it/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice gemma-2b-it -o yaml
El resultado es similar a este:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE haya creado el Service para la aplicación Ray Serve:
kubectl get service gemma-2b-it-serve-svc
El resultado es similar a este:
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
Implementa el modelo:
kubectl apply -f gemma-7b-it/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice gemma-7b-it -o yaml
El resultado es similar a este:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE haya creado el Service para la aplicación Ray Serve:
kubectl get service gemma-7b-it-serve-svc
El resultado es similar a este:
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
Implementa el modelo:
kubectl apply -f llama-2-7b/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice llama-2-7b -o yaml
El resultado es similar a este:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE haya creado el Service para la aplicación Ray Serve:
kubectl get service llama-2-7b-serve-svc
El resultado es similar a este:
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
Implementa el modelo:
kubectl apply -f llama-3-8b/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice llama-3-8b -o yaml
El resultado es similar a este:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE haya creado el Service para la aplicación Ray Serve:
kubectl get service llama-3-8b-serve-svc
El resultado es similar a este:
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
Implementa el modelo:
kubectl apply -f mistral-7b/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice mistral-7b -o yaml
El resultado es similar a este:
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE haya creado el Service para la aplicación Ray Serve:
kubectl get service mistral-7b-serve-svc
El resultado es similar a este:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mistral-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Entrega el modelo
Los modelos Llama2 7B y Llama3 8B usan la especificación de chat de la API de OpenAI. Los otros modelos solo admiten la generación de texto, que es una técnica que genera texto en función de una instrucción.
Configura la redirección de puertos.
Configura la redirección de puertos al servidor de inferencia:
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
Interactúa con el modelo con curl
Usa curl para chatear con tu modelo:
Gemma 2B IT
En una sesión de terminal nueva, haz lo siguiente:
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
En una sesión de terminal nueva, haz lo siguiente:
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
En una sesión de terminal nueva, haz lo siguiente:
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
En una sesión de terminal nueva, haz lo siguiente:
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
En una sesión de terminal nueva, haz lo siguiente:
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}'
Debido a que los modelos que entregaste no conservan ningún historial, cada mensaje y respuesta se debe enviar de vuelta al modelo para crear una experiencia de diálogo interactivo. En el siguiente ejemplo, se muestra cómo puedes crear un diálogo interactivo con el modelo Llama 3 8B:
Crea un diálogo con el modelo a través de 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
}'
El resultado es similar a este:
{
"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
}
}
Conéctate a la interfaz de chat (opcional)
Puedes usar Gradio para compilar aplicaciones web que te permitan interactuar con tu
modelo. Gradio es una biblioteca de Python que tiene un
wrapper ChatInterface
que crea interfaces de usuario para chatbots. En el caso de Llama 2 7B y Llama 3 7B,
instalaste Gradio cuando implementaste el modelo de LLM.
Configura la redirección de puertos al Service
gradio
:kubectl port-forward service/gradio 8080:8080 &
Abre http://localhost:8080 en tu navegador para chatear con el modelo.
Cómo entregar varios modelos con multiplexación de modelos
La multiplexación de modelos es una técnica que se usa para entregar varios modelos dentro del mismo clúster de Ray. Puedes enrutar el tráfico a modelos específicos con encabezados de solicitud o con el balanceamiento de cargas.
En este ejemplo, crearás una aplicación multiplexada de Ray Serve que consta de dos modelos: Gemma 7B IT y Llama 3 8B.
Implementa el recurso RayService:
kubectl apply -f model-multiplexing/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice model-multiplexing -o yaml
El resultado es similar a este:
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
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE haya creado el Service de Kubernetes para la aplicación Ray Serve:
kubectl get service model-multiplexing-serve-svc
El resultado es similar a este:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-multiplexing-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Configura la redirección de puertos a la aplicación de Ray Serve:
kubectl port-forward svc/model-multiplexing-serve-svc 8000:8000
Envía una solicitud al modelo Gemma 7B IT:
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}'
El resultado es similar a este:
{"text": ["What are the top 5 most popular programming languages? Please be brief.\n\n1. JavaScript\n2. Java\n3. C++\n4. Python\n5. C#"]}
Envía una solicitud al 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}'
El resultado es similar a este:
{"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."]}
Para enviar una solicitud a un modelo aleatorio, excluye el encabezado
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}'
El resultado es uno de los resultados de los pasos anteriores.
Cómo crear varios modelos con la composición de modelos
La composición de modelos es una técnica que se usa para componer varios modelos en una sola aplicación. La composición de modelos te permite encadenar entradas y salidas en varios LLM y escalar tus modelos como una sola aplicación.
En este ejemplo, compilas dos modelos, Gemma 7B IT y Llama 3 8B, en una sola aplicación. El primer modelo es el modelo de asistente que responde las preguntas proporcionadas en la instrucción. El segundo modelo es el de resumen. El resultado del modelo de asistente se encadena a la entrada del modelo de resumen. El resultado final es la versión resumida de la respuesta del modelo del asistente.
Implementa el recurso RayService:
kubectl apply -f model-composition/
Espera a que el recurso de RayService esté listo:
kubectl get rayservice model-composition -o yaml
El resultado es similar a este:
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
En este resultado,
status: RUNNING
indica que el recurso de RayService está listo.Confirma que GKE creó el Service para la aplicación Ray Serve:
kubectl get service model-composition-serve-svc
El resultado es similar a este:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-composition-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Envía una solicitud al 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}'
El resultado es similar a este:
{"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."]}
Borra el proyecto
- 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.
Borra los recursos individuales
Si usaste un proyecto existente y no quieres borrarlo, puedes borrar los recursos individuales.
Borra el clúster:
gcloud container clusters delete rayserve-cluster
¿Qué sigue?
- Descubre cómo ejecutar cargas de trabajo de IA/AA optimizadas con las capacidades de organización de la plataforma de GKE.
- Entrena un modelo con GPU en el modo GKE Standard
- Consulta el código de muestra en GitHub para aprender a usar RayServe en GKE.