Ce tutoriel explique comment déployer et diffuser un grand modèle de langage (LLM) à l'aide de plusieurs GPU sur GKE pour une inférence efficace et évolutive. Vous créez un cluster GKE qui utilise plusieurs GPU L4 et vous préparez l'infrastructure pour diffuser l'un des modèles suivants:
Selon le format de données du modèle, le nombre de GPU requis varie. Dans ce tutoriel, chaque modèle utilise deux GPU L4. Pour en savoir plus, consultez la section Calculer la quantité de GPU.
Ce tutoriel est destiné aux ingénieurs en machine learning (ML), aux administrateurs et opérateurs de plate-forme, ainsi qu'aux spécialistes des données et de l'IA qui souhaitent utiliser les fonctionnalités d'orchestration de conteneurs Kubernetes pour diffuser des LLM. Pour en savoir plus sur les rôles courants et les exemples de tâches référencés dans le contenu Google Cloud, consultez la section Rôles utilisateur et tâches courantes de l'utilisateur dans GKE Enterprise.
Avant de lire cette page, assurez-vous de connaître les éléments suivants:
Objectifs
Dans ce tutoriel, vous allez :
- Créer un cluster et des pools de nœuds
- Préparer votre charge de travail.
- Déployer votre charge de travail.
- Interagir avec l'interface du 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
.
Des conditions supplémentaires s'appliquent à certains modèles. Assurez-vous de remplir les conditions suivantes:
- Pour accéder aux modèles depuis Hugging Face, utilisez un jeton HuggingFace.
- Pour le modèle Mixtral 8x7b, acceptez les conditions du modèle Mixtral Mistral.
- Pour le modèle Llama 3 70b, assurez-vous de disposer d'une licence active pour les modèles Meta Llama.
Préparer votre environnement
Dans la console Google Cloud, démarrez une instance Cloud Shell :
Ouvrir Cloud ShellDéfinissez les variables d'environnement par défaut :
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export REGION=us-central1
Remplacez PROJECT_ID par votre Google Cloud ID de projet.
Créer un cluster GKE et un pool de nœuds
Vous pouvez diffuser les LLM sur des GPU dans un cluster GKE Autopilot ou GKE Standard. Nous vous recommandons d'utiliser un cluster GKE Autopilot pour une expérience Kubernetes entièrement gérée. Pour choisir le mode de fonctionnement GKE le mieux adapté à vos charges de travail, consultez la section Choisir un mode de fonctionnement GKE.
Autopilot
Dans Cloud Shell, exécutez la commande suivante :
gcloud container clusters create-auto l4-demo \ --project=${PROJECT_ID} \ --region=${REGION} \ --release-channel=rapid
GKE crée un cluster Autopilot avec des nœuds de processeur et de GPU, à la demande des charges de travail déployées.
Configurez
kubectl
de manière à communiquer avec votre cluster :gcloud container clusters get-credentials l4-demo --region=${REGION}
Standard
Dans Cloud Shell, exécutez la commande suivante pour créer un cluster standard qui utilise la fédération d'identité de charge de travail pour 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
La création du cluster peut prendre plusieurs minutes.
Exécutez la commande suivante pour créer un pool de nœuds pour votre 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
GKE crée les ressources suivantes pour le LLM :
- Un cluster Google Kubernetes Engine (GKE) standard public.
- Un pool de nœuds avec le type de machine
g2-standard-24
réduit à 0 nœud. Vous ne payez aucun GPU tant que vous n'avez pas lancé de pods qui en demandent. Ce pool de nœuds provisionne des VM Spot, dont la tarification est inférieure à celle des VM Compute Engine standard par défaut mais qui n'offrent aucune garantie de disponibilité. Vous pouvez supprimer l'option--spot
de cette commande et le sélecteur de nœudcloud.google.com/gke-spot
dans la configurationtext-generation-inference.yaml
pour utiliser des VM à la demande.
Configurez
kubectl
de manière à communiquer avec votre cluster :gcloud container clusters get-credentials l4-demo --region=${REGION}
Préparer votre charge de travail
Cette section explique comment configurer votre charge de travail en fonction du modèle que vous souhaitez utiliser. Ce tutoriel utilise des déploiements Kubernetes pour déployer le modèle. Un déploiement est un objet d'API Kubernetes qui vous permet d'exécuter plusieurs réplicas de pods répartis entre les nœuds d'un cluster.
Llama 3 70b
Définissez les variables d'environnement par défaut :
export HF_TOKEN=HUGGING_FACE_TOKEN
Remplacez
HUGGING_FACE_TOKEN
par votre jeton HuggingFace.Créez un secret Kubernetes pour le jeton HuggingFace :
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Créez le fichier manifeste de déploiement
text-generation-inference.yaml
suivant:Dans le fichier manifeste :
NUM_SHARD
doit être défini sur2
, car le modèle nécessite deux GPU NVIDIA L4.QUANTIZE
est défini surbitsandbytes-nf4
, ce qui signifie que le modèle est chargé en 4 bits au lieu de 32 bits. Cela permet à GKE de réduire la quantité de mémoire GPU nécessaire et d'améliorer la vitesse d'inférence. Cependant, la justesse du modèle peut diminuer. Pour savoir comment calculer le nombre de GPU à demander, consultez la section Calculer le nombre de GPU.
Appliquez le fichier manifeste :
kubectl apply -f text-generation-inference.yaml
Le résultat ressemble à ce qui suit :
deployment.apps/llm created
Vérifiez l'état du modèle :
kubectl get deploy
Le résultat ressemble à ce qui suit :
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 20m
Affichez les journaux du déploiement en cours d'exécution :
kubectl logs -l app=llm
Le résultat ressemble à ce qui suit :
{"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
Définissez les variables d'environnement par défaut :
export HF_TOKEN=HUGGING_FACE_TOKEN
Remplacez
HUGGING_FACE_TOKEN
par votre jeton HuggingFace.Créez un secret Kubernetes pour le jeton HuggingFace :
kubectl create secret generic l4-demo \ --from-literal=HUGGING_FACE_TOKEN=${HF_TOKEN} \ --dry-run=client -o yaml | kubectl apply -f -
Créez le fichier manifeste de déploiement
text-generation-inference.yaml
suivant:Dans le fichier manifeste :
NUM_SHARD
doit être défini sur2
, car le modèle nécessite deux GPU NVIDIA L4.QUANTIZE
est défini surbitsandbytes-nf4
, ce qui signifie que le modèle est chargé en 4 bits au lieu de 32 bits. Cela permet à GKE de réduire la quantité de mémoire GPU nécessaire et d'améliorer la vitesse d'inférence. Toutefois, cela peut réduire la justesse du modèle. Pour savoir comment calculer le nombre de GPU à demander, consultez la section Calculer la quantité de GPU.
Appliquez le fichier manifeste :
kubectl apply -f text-generation-inference.yaml
Le résultat ressemble à ce qui suit :
deployment.apps/llm created
Vérifiez l'état du modèle :
watch kubectl get deploy
Une fois le déploiement prêt, le résultat ressemble à ce qui suit:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Pour quitter la lecture, appuyez sur
CTRL + C
.Affichez les journaux du déploiement en cours d'exécution :
kubectl logs -l app=llm
Le résultat ressemble à ce qui suit :
{"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
Créez le fichier manifeste de déploiement
text-generation-inference.yaml
suivant:Dans le fichier manifeste :
NUM_SHARD
doit être défini sur2
, car le modèle nécessite deux GPU NVIDIA L4.QUANTIZE
est défini surbitsandbytes-nf4
, ce qui signifie que le modèle est chargé en 4 bits au lieu de 32 bits. Cela permet à GKE de réduire la quantité de mémoire GPU nécessaire et d'améliorer la vitesse d'inférence. Cependant, la justesse du modèle peut diminuer. Pour savoir comment calculer le nombre de GPU à demander, consultez la section Calculer la quantité de GPU.
Appliquez le fichier manifeste :
kubectl apply -f text-generation-inference.yaml
Le résultat ressemble à ce qui suit :
deployment.apps/llm created
Vérifiez l'état du modèle :
watch kubectl get deploy
Une fois le déploiement prêt, le résultat ressemble à ce qui suit:
NAME READY UP-TO-DATE AVAILABLE AGE llm 1/1 1 1 10m
Pour quitter la lecture, appuyez sur
CTRL + C
.Affichez les journaux du déploiement en cours d'exécution :
kubectl logs -l app=llm
Le résultat ressemble à ce qui suit :
{"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}
Créer un service de type ClusterIP
Exposez vos pods en interne dans le cluster afin qu'ils puissent être découverts et consultés par d'autres applications.
Créez le fichier manifeste
llm-service.yaml
suivant :apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: llm type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 8080
Appliquez le fichier manifeste :
kubectl apply -f llm-service.yaml
Déployer une interface de chat
Utilisez Gradio pour créer une application Web qui vous permet 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.
Llama 3 70b
Créez un fichier nommé
gradio.yaml
:Appliquez le fichier manifeste :
kubectl apply -f gradio.yaml
Recherchez l'adresse IP externe du service :
kubectl get svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copiez l'adresse IP externe présente dans la colonne
EXTERNAL-IP
.Consultez l'interface du modèle depuis votre navigateur Web en utilisant l'adresse IP externe avec le port exposé :
http://EXTERNAL_IP
Mixtral 8x7b
Créez un fichier nommé
gradio.yaml
:Appliquez le fichier manifeste :
kubectl apply -f gradio.yaml
Recherchez l'adresse IP externe du service :
kubectl get svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copiez l'adresse IP externe présente dans la colonne
EXTERNAL-IP
.Consultez l'interface du modèle depuis votre navigateur Web en utilisant l'adresse IP externe avec le port exposé :
http://EXTERNAL_IP
Falcon 40b
Créez un fichier nommé
gradio.yaml
:Appliquez le fichier manifeste :
kubectl apply -f gradio.yaml
Recherchez l'adresse IP externe du service :
kubectl get svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gradio-service LoadBalancer 10.24.29.197 34.172.115.35 80:30952/TCP 125m
Copiez l'adresse IP externe présente dans la colonne
EXTERNAL-IP
.Consultez l'interface du modèle depuis votre navigateur Web en utilisant l'adresse IP externe avec le port exposé :
http://EXTERNAL_IP
Calculer le nombre de GPU
Le nombre de GPU dépend de la valeur de l'option QUANTIZE
. Dans ce tutoriel, QUANTIZE
est défini sur bitsandbytes-nf4
, ce qui signifie que le modèle est chargé en 4 bits.
Un modèle avec 70 milliards de paramètres nécessiterait au moins 40 Go de mémoire GPU, à raison de 70 milliards fois 4 bits (70 milliards x 4 bits= 35 Go) en prenant en compte une surcharge de 5 Go. Dans ce cas, un GPU L4 ne disposerait pas de suffisamment de mémoire. Par conséquent, les exemples de ce tutoriel utilisent la mémoire de deux GPU L4 de mémoire (2 x 24 = 48 Go). Cette configuration est suffisante pour exécuter Falcon 40b ou Llama 3 70b sur les GPU L4.
Effectuer un nettoyage
Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.
Supprimer le cluster
Pour éviter que les ressources que vous avez créées dans ce guide ne soient facturées sur votre compte Google Cloud , supprimez le cluster GKE:
gcloud container clusters delete l4-demo --region ${REGION}