Ce guide explique comment diffuser des modèles de langage volumineux (LLM) à l'aide de Ray et du module complémentaire Ray Operator avec Google Kubernetes Engine (GKE).
Dans ce guide, vous pouvez diffuser l'un des modèles suivants :
Ce guide aborde également les techniques de diffusion de modèles telles que le multiplexage et la composition de modèles, qui sont compatibles avec le framework Ray Serve.
Contexte
Le framework Ray fournit une plate-forme AI/ML de bout en bout pour l'entraînement, l'optimisation et l'inférence de charges de travail de machine learning. Ray Serve est un framework de Ray que vous pouvez utiliser pour diffuser des LLM populaires à partir de Hugging Face.
Selon le format de données du modèle, le nombre de GPU varie. Dans ce guide, votre modèle peut utiliser un ou deux GPU L4.
Ce guide couvre les étapes suivantes :
- Créez un cluster GKE Autopilot ou Standard avec le module complémentaire Ray Operator activé.
- Déployez une ressource RayService qui télécharge et diffuse un grand modèle de langage (LLM) depuis Hugging Face.
- Déployez une interface de chat et interagissez avec des LLM.
Avant de commencer
Avant de commencer, effectuez les tâches suivantes :
- Activez l'API Google Kubernetes Engine. Activer l'API Google Kubernetes Engine
- Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande
gcloud components update
.
- Créez un compte Hugging Face si vous n'en possédez pas.
- Assurez-vous de disposer d'un jeton Hugging Face.
- Assurez-vous d'avoir accès au modèle Hugging Face que vous souhaitez utiliser. Pour cela, vous devez généralement signer un accord et demander l'accès au propriétaire du modèle sur la page du modèle Hugging Face.
- Assurez-vous de disposer d'un quota de GPU dans la région
us-central1
. Pour en savoir plus, consultez la page Quota de GPU.
Préparer votre environnement
Dans la console Google Cloud, démarrez une instance Cloud Shell :
Ouvrir Cloud ShellClonez l'exemple de dépôt :
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/llm export TUTORIAL_HOME=`pwd`
Définissez les variables d'environnement par défaut :
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
Remplacez les éléments suivants :
PROJECT_ID
: ID de votre projet Google Cloud.CLUSTER_VERSION
: version de GKE à utiliser. Doit être1.30.1
ou une version ultérieure.HUGGING_FACE_TOKEN
: jeton d'accès Hugging Face.
Créer un cluster GKE avec un pool de nœuds GPU.
Vous pouvez diffuser un LLM sur des GPU L4 avec Ray dans un cluster GKE Autopilot ou Standard à l'aide du module complémentaire Ray Operator. Nous vous recommandons généralement d'utiliser un cluster Autopilot pour une expérience Kubernetes entièrement gérée. Choisissez plutôt un cluster Standard si votre cas d'utilisation nécessite une grande évolutivité ou si vous souhaitez davantage de contrôle sur la configuration du cluster. Pour choisir le mode de fonctionnement GKE le mieux adapté à vos charges de travail, consultez la section Choisir un mode de fonctionnement GKE.
Utilisez Cloud Shell pour créer un cluster Autopilot ou Standard :
Autopilot
Créez un cluster Autopilot avec le module complémentaire Ray Operator activé :
gcloud container clusters create-auto rayserve-cluster \
--enable-ray-operator \
--cluster-version=${CLUSTER_VERSION} \
--location=${COMPUTE_REGION}
Standard
Créez un cluster Standard avec le module complémentaire Ray Operator activé :
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
Créer un secret Kubernetes pour les identifiants Hugging Face
Dans Cloud Shell, créez un Secret Kubernetes en procédant comme suit :
Configurez
kubectl
de manière à communiquer avec votre cluster :gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${COMPUTE_REGION}
Créez un secret Kubernetes contenant le jeton Hugging Face:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Déployer le modèle LLM
Le dépôt GitHub que vous avez cloné comporte un répertoire pour chaque modèle qui inclut une configuration RayService. La configuration de chaque modèle comprend les composants suivants :
- Déploiement de Ray Serve : déploiement de Ray Serve, qui inclut la configuration des ressources et les dépendances d'exécution.
- Modèle : ID du modèle Hugging Face.
Cluster Ray : le cluster Ray sous-jacent et les ressources requises pour chaque composant, y compris les pods principaux et de calcul.
Gemma 2B IT
Déployez le modèle :
kubectl apply -f gemma-2b-it/
Attendez que la ressource RayService soit prête :
kubectl get rayservice gemma-2b-it -o yaml
Le résultat ressemble à ce qui suit :
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le Service pour l'application Ray Serve :
kubectl get service gemma-2b-it-serve-svc
Le résultat ressemble à ce qui suit :
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
Déployez le modèle :
kubectl apply -f gemma-7b-it/
Attendez que la ressource RayService soit prête :
kubectl get rayservice gemma-7b-it -o yaml
Le résultat ressemble à ce qui suit :
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le service pour l'application Ray Serve :
kubectl get service gemma-7b-it-serve-svc
Le résultat ressemble à ce qui suit :
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
Déployez le modèle :
kubectl apply -f llama-2-7b/
Attendez que la ressource RayService soit prête :
kubectl get rayservice llama-2-7b -o yaml
Le résultat ressemble à ce qui suit :
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le Service pour l'application Ray Serve :
kubectl get service llama-2-7b-serve-svc
Le résultat ressemble à ce qui suit :
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
Déployez le modèle :
kubectl apply -f llama-3-8b/
Attendez que la ressource RayService soit prête :
kubectl get rayservice llama-3-8b -o yaml
Le résultat ressemble à ce qui suit :
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le Service pour l'application Ray Serve :
kubectl get service llama-3-8b-serve-svc
Le résultat ressemble à ce qui suit :
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
Déployez le modèle :
kubectl apply -f mistral-7b/
Attendez que la ressource RayService soit prête :
kubectl get rayservice mistral-7b -o yaml
Le résultat ressemble à ce qui suit :
status: activeServiceStatus: applicationStatuses: llm: healthLastUpdateTime: "2024-06-22T02:51:52Z" serveDeploymentStatuses: VLLMDeployment: healthLastUpdateTime: "2024-06-22T02:51:52Z" status: HEALTHY status: RUNNING
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le Service pour l'application Ray Serve :
kubectl get service mistral-7b-serve-svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mistral-7b-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Diffuser le modèle
Les modèles Llama2 7B et Llama3 8B utilisent la spécification de chat de l'API OpenAI. Les autres modèles ne sont compatibles qu'avec la génération de texte, une technique qui génère du texte en fonction d'une requête.
Configurer le transfert de port
Configurez un transfert de port vers le serveur d'inférence :
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
Llama 2 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 avec le modèle à l'aide de curl
Utilisez curl pour discuter avec votre modèle :
Gemma 2B IT
Dans une nouvelle session de 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
Dans une nouvelle session de 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}'
Llama 2 7B
Dans une nouvelle session de 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
Dans une nouvelle session de 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
Dans une nouvelle session de 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}'
Étant donné que les modèles que vous avez diffusés ne conservent aucun historique, chaque message et chaque réponse doivent être renvoyés au modèle pour créer une expérience de dialogue interactive. L'exemple suivant montre comment créer un dialogue interactif à l'aide du modèle Llama 3 8B :
Créez un dialogue avec le modèle à l'aide 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
}'
Le résultat ressemble à ce qui suit :
{
"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
}
}
(Facultatif) Se connecter à l'interface de chat
Vous pouvez utiliser Gradio pour créer des applications Web qui vous permettent d'interagir avec votre modèle. Gradio est une bibliothèque Python dotée d'un wrapper ChatInterface
qui crée des interfaces utilisateur pour les chatbots. Pour Llama 2 7B et Llama 3 7B, vous avez installé Gradio lorsque vous avez déployé le modèle LLM.
Configurez le transfert de port vers le Service
gradio
:kubectl port-forward service/gradio 8080:8080 &
Ouvrez http://localhost:8080 dans votre navigateur pour discuter avec le modèle.
Diffuser plusieurs modèles avec le multiplexage de modèles
Le multiplexage de modèles est une technique utilisée pour diffuser plusieurs modèles au sein du même cluster Ray. Vous pouvez acheminer le trafic vers des modèles spécifiques à l'aide d'en-têtes de requête ou en équilibrant la charge.
Dans cet exemple, vous allez créer une application Ray Serve multiplexée composée de deux modèles : Gemma 7B IT et Llama 3 8B.
Déployez la ressource RayService :
kubectl apply -f model-multiplexing/
Attendez que la ressource RayService soit prête :
kubectl get rayservice model-multiplexing -o yaml
Le résultat ressemble à ce qui suit :
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
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le service Kubernetes pour l'application Ray Serve :
kubectl get service model-multiplexing-serve-svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-multiplexing-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Configurez le transfert de port vers l'application Ray Serve :
kubectl port-forward svc/model-multiplexing-serve-svc 8000:8000
Envoyez une requête au modèle 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}'
Le résultat ressemble à ce qui suit :
{"text": ["What are the top 5 most popular programming languages? Please be brief.\n\n1. JavaScript\n2. Java\n3. C++\n4. Python\n5. C#"]}
Envoyez une requête au modèle 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}'
Le résultat ressemble à ce qui suit :
{"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."]}
Envoyez une requête à un modèle aléatoire en excluant l'en-tête
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}'
La sortie est l'une des sorties des étapes précédentes.
Composez plusieurs modèles avec la composition de modèles
La composition de modèles est une technique qui permet de composer plusieurs modèles dans une seule application. La composition de modèles vous permet d'enchaîner des entrées et des sorties sur plusieurs LLM et d'adapter vos modèles en une seule application.
Dans cet exemple, vous allez composer deux modèles, Gemma 7B IT et Llama 3 8B, dans une seule application. Le premier modèle est le modèle d'assistant qui répond aux questions fournies dans l'invite. Le deuxième modèle est le modèle de résumé. La sortie du modèle d'assistant est associée à l'entrée du modèle de résumé. Le résultat final est la version résumée de la réponse du modèle d'assistant.
Déployez la ressource RayService :
kubectl apply -f model-composition/
Attendez que la ressource RayService soit prête :
kubectl get rayservice model-composition -o yaml
Le résultat ressemble à ce qui suit :
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
Dans ce résultat,
status: RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le service pour l'application Ray Serve :
kubectl get service model-composition-serve-svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE model-composition-serve-svc ClusterIP 34.118.226.104 <none> 8000/TCP 45m
Envoyez une requête au modèle :
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}'
Le résultat ressemble à ce qui suit :
{"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."]}
Supprimer le projet
- 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.
Supprimer les ressources individuelles
Si vous avez utilisé un projet existant et que vous ne souhaitez pas le supprimer, vous pouvez supprimer les ressources individuelles.
Supprimez le cluster à l'aide de la commande suivante :
gcloud container clusters delete rayserve-cluster
Étape suivante
- Découvrez comment exécuter des charges de travail d'IA/ML optimisées avec les fonctionnalités d'orchestration de plate-forme GKE.
- Entraîner les modèles avec des GPU en mode GKE Standard
- Découvrez comment utiliser RayServe sur GKE en consultant l'exemple de code sur GitHub.