Ce tutoriel explique comment diffuser un grand modèle de langage (LLM) à l'aide de TPU (Tensor Processing Units) sur Google Kubernetes Engine (GKE) avec le Module complémentaire Ray Operator et le framework de diffusion vLLM.
Dans ce tutoriel, vous pouvez diffuser des modèles LLM sur TPU v5e ou TPU Trillium (v6e) comme suit:
- Instruction Llama 3 8B sur un TPU v5e à hôte unique.
- Instruction Mistral 7B v0.3 sur un TPU v5e à hôte unique.
- Llava 1.5 13b hf sur un TPU v5e à hôte unique.
- Llama 3.1 70 B sur un TPU Trillium (v6e) à hôte unique.
Ce guide s'adresse aux clients d'IA générative, aux utilisateurs GKE nouveaux et existants, aux ingénieurs en ML, aux ingénieurs MLOps (DevOps) ou aux administrateurs de plate-forme qui souhaitent utiliser les fonctionnalités d'orchestration de conteneurs Kubernetes pour diffuser des modèles à l'aide de Ray, sur des TPU avec vLLM.
Contexte
Cette section décrit les principales technologies utilisées dans ce guide.
Service Kubernetes géré GKE
Google Cloud propose une large gamme de services, y compris GKE, qui est particulièrement adapté au déploiement et à la gestion des charges de travail d'IA/ML. GKE est un service Kubernetes géré qui simplifie le déploiement, la mise à l'échelle et la gestion des applications conteneurisées. GKE fournit l'infrastructure nécessaire, y compris des ressources évolutives, un calcul distribué et un réseau efficace, pour gérer les demandes de calcul des LLM.
Pour en savoir plus sur les concepts clés de Kubernetes, consultez Commencer à découvrir Kubernetes. Pour en savoir plus sur GKE et sur la façon dont il vous aide à faire évoluer, automatiser et gérer Kubernetes, consultez la présentation de GKE.
Opérateur Ray
Le module complémentaire Ray Operator sur GKE fournit une plate-forme AI/ML de bout en bout pour la diffusion, l'entraînement et l'ajustement des charges de travail de machine learning. Dans ce tutoriel, vous allez utiliser Ray Serve, un framework de Ray, pour diffuser des LLM populaires de Hugging Face.
TPU
Les TPU sont des circuits intégrés propres aux applications (Application-Specific Integrated Circuit ou ASIC), développés spécifiquement par Google et permettant d'accélérer le machine learning et les modèles d'IA créés à l'aide de frameworks tels que TensorFlow, PyTorch et JAX.
Ce tutoriel explique comment diffuser des modèles LLM sur des nœuds TPU v5e ou TPU Trillium (v6e) avec des topologies TPU configurées en fonction des exigences de chaque modèle pour diffuser des requêtes avec une faible latence.
vLLM
vLLM est un framework de diffusion LLM Open Source hautement optimisé qui peut augmenter le débit de diffusion sur les TPU, avec des fonctionnalités telles que:
- Implémentation optimisée du transformateur avec PagedAttention
- Traitement par lots continu pour améliorer le débit global de diffusion
- Parallélisme des Tensors et diffusion distribuée sur plusieurs GPU
Pour en savoir plus, consultez la documentation de vLLM.
Objectifs
Ce tutoriel couvre les étapes suivantes :
- Créer un cluster GKE avec un pool de nœuds TPU.
- Déployez une ressource personnalisée RayCluster avec une tranche de TPU à hôte unique. GKE déploie la ressource personnalisée RayCluster en tant que pods Kubernetes.
- Diffuser un LLM.
- Interagir avec les modèles.
Vous pouvez éventuellement configurer les ressources et techniques de diffusion de modèle suivantes compatibles avec le framework Ray Serve:
- Déployez une ressource personnalisée RayService.
- Composez plusieurs modèles avec la composition de modèles.
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 obtenir cet accès, vous devez généralement signer un contrat et demander l'accès au propriétaire du modèle sur la page du modèle Hugging Face.
Préparer votre environnement
Assurez-vous que votre projet Google Cloud dispose d'un quota suffisant pour un TPU v5e ou un TPU Trillium (v6e) à hôte unique. Pour gérer votre quota, consultez la section Quotas TPU.
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
Accédez au répertoire de travail :
cd ai-ml/gke-ray/rayserve/llm
Définissez les variables d'environnement par défaut pour la création du cluster GKE:
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="meta-llama/Meta-Llama-3-8B-Instruct" export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svcRemplacez les éléments suivants :
HUGGING_FACE_TOKEN
: votre jeton d'accès Hugging Face.REGION
: région dans laquelle vous disposez d'un quota de TPU. Assurez-vous que la version de TPU que vous souhaitez utiliser est disponible dans cette région. Pour en savoir plus, consultez la section Disponibilité des TPU dans GKE.ZONE
: zone avec quota de TPU disponible.VLLM_IMAGE
: image du TPU vLLM. Vous pouvez utiliser l'image publiquedocker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
ou créer votre propre image TPU.
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="mistralai/Mistral-7B-Instruct-v0.3" export TOKENIZER_MODE=mistral export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svcRemplacez les éléments suivants :
HUGGING_FACE_TOKEN
: votre jeton d'accès Hugging Face.REGION
: région dans laquelle vous disposez d'un quota de TPU. Assurez-vous que la version de TPU que vous souhaitez utiliser est disponible dans cette région. Pour en savoir plus, consultez la section Disponibilité des TPU dans GKE.ZONE
: zone avec quota de TPU disponible.VLLM_IMAGE
: image du TPU vLLM. Vous pouvez utiliser l'image publiquedocker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
ou créer votre propre image TPU.
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="llava-hf/llava-1.5-13b-hf" export DTYPE=bfloat16 export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svcRemplacez les éléments suivants :
HUGGING_FACE_TOKEN
: votre jeton d'accès Hugging Face.REGION
: région dans laquelle vous disposez d'un quota de TPU. Assurez-vous que la version de TPU que vous souhaitez utiliser est disponible dans cette région. Pour en savoir plus, consultez la section Disponibilité des TPU dans GKE.ZONE
: zone avec quota de TPU disponible.VLLM_IMAGE
: image du TPU vLLM. Vous pouvez utiliser l'image publiquedocker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
ou créer votre propre image TPU.
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CLUSTER_NAME=vllm-tpu export COMPUTE_REGION=
REGION export COMPUTE_ZONE=ZONE export HF_TOKEN=HUGGING_FACE_TOKEN export GSBUCKET=vllm-tpu-bucket export KSA_NAME=vllm-sa export NAMESPACE=default export MODEL_ID="meta-llama/Llama-3.1-70B" export MAX_MODEL_LEN=8192 export VLLM_IMAGE=docker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1 export SERVICE_NAME=vllm-tpu-head-svcRemplacez les éléments suivants :
HUGGING_FACE_TOKEN
: votre jeton d'accès Hugging Face.REGION
: région dans laquelle vous disposez d'un quota de TPU. Assurez-vous que la version de TPU que vous souhaitez utiliser est disponible dans cette région. Pour en savoir plus, consultez la section Disponibilité des TPU dans GKE.ZONE
: zone avec quota de TPU disponible.VLLM_IMAGE
: image du TPU vLLM. Vous pouvez utiliser l'image publiquedocker.io/vllm/vllm-tpu:866fa4550d572f4ff3521ccf503e0df2e76591a1
ou créer votre propre image TPU.
Extrayez l'image du conteneur vLLM:
docker pull ${VLLM_IMAGE}
Créer un cluster
Vous pouvez diffuser un LLM sur des TPU avec Ray dans un cluster GKE Autopilot ou Standard à l'aide du module complémentaire Ray Operator.
Utilisez un cluster 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.
Utilisez Cloud Shell pour créer un cluster Autopilot ou Standard:
Créez un cluster GKE Autopilot avec le module complémentaire Ray Operator activé:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --enable-ray-operator \ --release-channel=rapid \ --location=${COMPUTE_REGION}
Créez un cluster standard avec le module complémentaire Ray Operator activé:
gcloud container clusters create ${CLUSTER_NAME} \ --release-channel=rapid \ --location=${COMPUTE_ZONE} \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --machine-type="n1-standard-4" \ --addons=RayOperator,GcsFuseCsiDriver
Créez un pool de nœuds de tranche TPU à hôte unique:
gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct5lp-hightpu-8t \ --num-nodes=1
GKE crée un pool de nœuds TPU v5e avec un type de machine
ct5lp-hightpu-8t
.gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct5lp-hightpu-8t \ --num-nodes=1
GKE crée un pool de nœuds TPU v5e avec un type de machine
ct5lp-hightpu-8t
.gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct5lp-hightpu-8t \ --num-nodes=1
GKE crée un pool de nœuds TPU v5e avec un type de machine
ct5lp-hightpu-8t
.gcloud container node-pools create tpu-1 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=ct6e-standard-8t \ --num-nodes=1
GKE crée un pool de nœuds TPU v6e avec un type de machine
ct6e-standard-8t
.
Configurer kubectl pour communiquer avec votre cluster
Pour configurer kubectl de manière à communiquer avec votre cluster, exécutez la commande suivante:
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${COMPUTE_REGION}
gcloud container clusters get-credentials ${CLUSTER_NAME} \
--location=${COMPUTE_ZONE}
Créer un secret Kubernetes pour les identifiants Hugging Face
Pour créer un secret Kubernetes contenant le jeton Hugging Face, exécutez la commande suivante:
kubectl create secret generic hf-secret \
--from-literal=hf_api_token=${HF_TOKEN} \
--dry-run=client -o yaml | kubectl --namespace ${NAMESPACE} apply -f -
Créer un bucket Cloud Storage
Pour accélérer le temps de démarrage du déploiement de vLLM et réduire l'espace disque requis par nœud, utilisez le pilote CSI Cloud Storage FUSE pour installer le modèle téléchargé et le cache de compilation sur les nœuds Ray.
Dans Cloud Shell, exécutez la commande suivante :
gcloud storage buckets create gs://${GSBUCKET} \
--uniform-bucket-level-access
Cette commande crée un bucket Cloud Storage pour stocker les fichiers de modèle que vous téléchargez depuis Hugging Face.
Configurer un compte de service Kubernetes pour accéder au bucket
Créez le compte de service Kubernetes:
kubectl create serviceaccount ${KSA_NAME} \ --namespace ${NAMESPACE}
Accordez au compte de service Kubernetes un accès en lecture/écriture au bucket Cloud Storage:
gcloud storage buckets add-iam-policy-binding gs://${GSBUCKET} \ --member "principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/${KSA_NAME}" \ --role "roles/storage.objectUser"
GKE crée les ressources suivantes pour le LLM :
- Un bucket Cloud Storage pour stocker le modèle téléchargé et le cache de compilation. Un pilote CSI Cloud Storage FUSE lit le contenu du bucket.
- Volumes avec la mise en cache des fichiers activée et la fonctionnalité de téléchargement parallèle de Cloud Storage FUSE.
Bonne pratique : Utilisez un cache de fichiers basé sur
tmpfs
ouHyperdisk / Persistent Disk
en fonction de la taille attendue du contenu du modèle, par exemple les fichiers de poids. Dans ce tutoriel, vous allez utiliser le cache de fichiers Cloud Storage FUSE basé sur la RAM.
Déployer une ressource personnalisée RayCluster
Déployez une ressource personnalisée RayCluster, qui se compose généralement d'un pod système et de plusieurs pods de travail.
Créez la ressource personnalisée RayCluster pour déployer le modèle affiné Llama 3 8B en procédant comme suit:
Inspectez le fichier manifeste
ray-cluster.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-cluster.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.
GKE crée une ressource personnalisée RayCluster avec un workergroup
contenant un hôte unique TPU v5e dans une topologie 2x4
.
Créez la ressource personnalisée RayCluster pour déployer le modèle Mistral-7B en procédant comme suit:
Inspectez le fichier manifeste
ray-cluster.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-cluster.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.
GKE crée une ressource personnalisée RayCluster avec un workergroup
contenant un hôte unique TPU v5e dans une topologie 2x4
.
Créez la ressource personnalisée RayCluster pour déployer le modèle Llava-1.5-13b-hf en procédant comme suit:
Inspectez le fichier manifeste
ray-cluster.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-cluster.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.
GKE crée une ressource personnalisée RayCluster avec un workergroup
contenant un hôte unique TPU v5e dans une topologie 2x4
.
Créez la ressource personnalisée RayCluster pour déployer le modèle Llama 3.1 70 B en procédant comme suit:
Inspectez le fichier manifeste
ray-cluster.tpu-v6e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-cluster.tpu-v6e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.
GKE crée une ressource personnalisée RayCluster avec un workergroup
contenant un hôte unique TPU v6e dans une topologie 2x4
.
Se connecter à la ressource personnalisée RayCluster
Une fois la ressource personnalisée RayCluster créée, vous pouvez vous y connecter et commencer à diffuser le modèle.
Vérifiez que GKE a créé le service RayCluster:
kubectl --namespace ${NAMESPACE} get raycluster/vllm-tpu \ --output wide
Le résultat ressemble à ce qui suit :
NAME DESIRED WORKERS AVAILABLE WORKERS CPUS MEMORY GPUS TPUS STATUS AGE HEAD POD IP HEAD SERVICE IP vllm-tpu 1 1 ### ###G 0 8 ready ### ###.###.###.### ###.###.###.###
Attendez que la valeur de
STATUS
soitready
et que les colonnesHEAD POD IP
etHEAD SERVICE IP
contiennent une adresse IP.Établissez des sessions
port-forwarding
avec le nœud principal Ray:pkill -f "kubectl .* port-forward .* 8265:8265" pkill -f "kubectl .* port-forward .* 10001:10001" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8265:8265 2>&1 >/dev/null & kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 10001:10001 2>&1 >/dev/null &
Vérifiez que le client Ray peut se connecter à la ressource personnalisée RayCluster distante:
docker run --net=host -it ${VLLM_IMAGE} \ ray list nodes --address http://localhost:8265
Le résultat ressemble à ce qui suit :
======== List: YYYY-MM-DD HH:MM:SS.NNNNNN ======== Stats: ------------------------------ Total: 2 Table: ------------------------------ NODE_ID NODE_IP IS_HEAD_NODE STATE STATE_MESSAGE NODE_NAME RESOURCES_TOTAL LABELS 0 XXXXXXXXXX ###.###.###.### True ALIVE ###.###.###.### CPU: 2.0 ray.io/node_id: XXXXXXXXXX memory: #.### GiB node:###.###.###.###: 1.0 node:__internal_head__: 1.0 object_store_memory: #.### GiB 1 XXXXXXXXXX ###.###.###.### False ALIVE ###.###.###.### CPU: 100.0 ray.io/node_id: XXXXXXXXXX TPU: 8.0 TPU-v#e-8-head: 1.0 accelerator_type:TPU-V#E: 1.0 memory: ###.### GiB node:###.###.###.###: 1.0 object_store_memory: ##.### GiB tpu-group-0: 1.0
Déployer le modèle avec vLLM
Déployez le modèle avec vLLM:
docker run \
--env MODEL_ID=${MODEL_ID} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"MODEL_ID": "meta-llama/Meta-Llama-3-8B-Instruct"}}'
docker run \
--env MODEL_ID=${MODEL_ID} \
--env TOKENIZER_MODE=${TOKENIZER_MODE} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"MODEL_ID": "mistralai/Mistral-7B-Instruct-v0.3", "TOKENIZER_MODE": "mistral"}}'
docker run \
--env DTYPE=${DTYPE} \
--env MODEL_ID=${MODEL_ID} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"DTYPE": "bfloat16", "MODEL_ID": "llava-hf/llava-1.5-13b-hf"}}'
docker run \
--env MAX_MODEL_LEN=${MAX_MODEL_LEN} \
--env MODEL_ID=${MODEL_ID} \
--net=host \
--volume=./tpu:/workspace/vllm/tpu \
-it \
${VLLM_IMAGE} \
serve run serve_tpu:model \
--address=ray://localhost:10001 \
--app-dir=./tpu \
--runtime-env-json='{"env_vars": {"MAX_MODEL_LEN": "8192", "MODEL_ID": "meta-llama/Meta-Llama-3.1-70B"}}'
Afficher le tableau de bord Ray
Vous pouvez afficher votre déploiement Ray Serve et les journaux pertinents à partir du tableau de bord Ray.
- Cliquez sur le bouton
Aperçu sur le Web, qui se trouve en haut à droite de la barre des tâches Cloud Shell.
- Cliquez sur Change port (Modifier le port) et définissez le numéro de port sur
8265
. - Cliquez sur Change and Preview (Modifier et prévisualiser).
- Dans le tableau de bord Ray, cliquez sur l'onglet Diffuser.
Une fois que le déploiement de Serve a un état HEALTHY
, le modèle est prêt à commencer à traiter les entrées.
Diffuser le modèle
Ce guide met en avant les modèles compatibles avec la génération de texte, une technique qui permet de créer du contenu textuel à partir d'une requête.
Configurez le transfert de port vers le serveur:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
Envoyez une invite au point de terminaison Serve:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Développez la section suivante pour voir un exemple de sortie.
{"prompt": "What
are the top 5 most popular programming languages? Be brief.", "text": " (Note:
This answer may change over time.)\n\nAccording to the TIOBE Index, a widely
followed measure of programming language popularity, the top 5 languages
are:\n\n1. JavaScript\n2. Python\n3. Java\n4. C++\n5. C#\n\nThese rankings are
based on a combination of search engine queries, web traffic, and online
courses. Keep in mind that other sources may have slightly different rankings.
(Source: TIOBE Index, August 2022)", "token_ids": [320, 9290, 25, 1115, 4320,
1253, 2349, 927, 892, 9456, 11439, 311, 279, 350, 3895, 11855, 8167, 11, 264,
13882, 8272, 6767, 315, 15840, 4221, 23354, 11, 279, 1948, 220, 20, 15823,
527, 1473, 16, 13, 13210, 198, 17, 13, 13325, 198, 18, 13, 8102, 198, 19, 13,
356, 23792, 20, 13, 356, 27585, 9673, 33407, 527, 3196, 389, 264, 10824, 315,
2778, 4817, 20126, 11, 3566, 9629, 11, 323, 2930, 14307, 13, 13969, 304, 4059,
430, 1023, 8336, 1253, 617, 10284, 2204, 33407, 13, 320, 3692, 25, 350, 3895,
11855, 8167, 11, 6287, 220, 2366, 17, 8, 128009]}
Configurez le transfert de port vers le serveur:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
Envoyez une invite au point de terminaison Serve:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Développez la section suivante pour voir un exemple de sortie.
{"prompt": "What are the top 5 most popular programming languages? Be brief.",
"text": "\n\n1. JavaScript: Widely used for web development, particularly for
client-side scripting and building dynamic web page content.\n\n2. Python:
Known for its simplicity and readability, it's widely used for web
development, machine learning, data analysis, and scientific computing.\n\n3.
Java: A general-purpose programming language used in a wide range of
applications, including Android app development, web services, and
enterprise-level applications.\n\n4. C#: Developed by Microsoft, it's often
used for Windows desktop apps, game development (Unity), and web development
(ASP.NET).\n\n5. TypeScript: A superset of JavaScript that adds optional
static typing and other features for large-scale, maintainable JavaScript
applications.", "token_ids": [781, 781, 29508, 29491, 27049, 29515, 1162,
1081, 1491, 2075, 1122, 5454, 4867, 29493, 7079, 1122, 4466, 29501, 2973,
7535, 1056, 1072, 4435, 11384, 5454, 3652, 3804, 29491, 781, 781, 29518,
29491, 22134, 29515, 1292, 4444, 1122, 1639, 26001, 1072, 1988, 3205, 29493,
1146, 29510, 29481, 13343, 2075, 1122, 5454, 4867, 29493, 6367, 5936, 29493,
1946, 6411, 29493, 1072, 11237, 22031, 29491, 781, 781, 29538, 29491, 12407,
29515, 1098, 3720, 29501, 15460, 4664, 17060, 4610, 2075, 1065, 1032, 6103,
3587, 1070, 9197, 29493, 3258, 13422, 1722, 4867, 29493, 5454, 4113, 29493,
1072, 19123, 29501, 5172, 9197, 29491, 781, 781, 29549, 29491, 1102, 29539,
29515, 9355, 1054, 1254, 8670, 29493, 1146, 29510, 29481, 3376, 2075, 1122,
9723, 25470, 14189, 29493, 2807, 4867, 1093, 2501, 1240, 1325, 1072, 5454,
4867, 1093, 2877, 29521, 29491, 12466, 1377, 781, 781, 29550, 29491, 6475,
7554, 29515, 1098, 26434, 1067, 1070, 27049, 1137, 14401, 12052, 1830, 25460,
1072, 1567, 4958, 1122, 3243, 29501, 6473, 29493, 9855, 1290, 27049, 9197,
29491, 2]}
Configurez le transfert de port vers le serveur:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
Envoyez une invite au point de terminaison Serve:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Développez la section suivante pour voir un exemple de sortie.
{"prompt": "What are the top 5 most popular programming languages? Be brief.",
"text": " under 100 words.\n\nThe top 5 most popular programming languages
are:\n1. Python\n2. Java\n3. C#\n4. C++\n5. JavaScript.", "token_ids": [1090,
29871, 29896, 29900, 29900, 3838, 29889, 13, 13, 1576, 2246, 29871, 29945,
1556, 5972, 8720, 10276, 526, 29901, 13, 29896, 29889, 5132, 13, 29906, 29889,
3355, 13, 29941, 29889, 315, 29937, 13, 29946, 29889, 315, 1817, 13, 29945,
29889, 8286, 29889, 2]}
Configurez le transfert de port vers le serveur:
pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8000:8000 2>&1 >/dev/null &
Envoyez une invite au point de terminaison Serve:
curl -X POST http://localhost:8000/v1/generate -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'
Développez la section suivante pour voir un exemple de sortie.
{"prompt": "What are
the top 5 most popular programming languages? Be brief.", "text": " This is a
very subjective question, but there are some general guidelines to follow when
selecting a language. For example, if you\u2019re looking for a language
that\u2019s easy to learn, you might want to consider Python. It\u2019s one of
the most popular languages in the world, and it\u2019s also relatively easy to
learn. If you\u2019re looking for a language that\u2019s more powerful, you
might want to consider Java. It\u2019s a more complex language, but it\u2019s
also very popular. Whichever language you choose, make sure you do your
research and pick one that\u2019s right for you.\nThe most popular programming
languages are:\nWhy is C++ so popular?\nC++ is a powerful and versatile
language that is used in many different types of software. It is also one of
the most popular programming languages, with a large community of developers
who are always creating new and innovative ways to use it. One of the reasons
why C++ is so popular is because it is a very efficient language. It allows
developers to write code that is both fast and reliable, which is essential
for many types of software. Additionally, C++ is very flexible, meaning that
it can be used for a wide range of different purposes. Finally, C++ is also
very popular because it is easy to learn. There are many resources available
online and in books that can help anyone get started with learning the
language.\nJava is a versatile language that can be used for a variety of
purposes. It is one of the most popular programming languages in the world and
is used by millions of people around the globe. Java is used for everything
from developing desktop applications to creating mobile apps and games. It is
also a popular choice for web development. One of the reasons why Java is so
popular is because it is a platform-independent language. This means that it
can be used on any type of computer or device, regardless of the operating
system. Java is also very versatile and can be used for a variety of different
purposes.", "token_ids": [1115, 374, 264, 1633, 44122, 3488, 11, 719, 1070,
527, 1063, 4689, 17959, 311, 1833, 994, 27397, 264, 4221, 13, 1789, 3187, 11,
422, 499, 3207, 3411, 369, 264, 4221, 430, 753, 4228, 311, 4048, 11, 499,
2643, 1390, 311, 2980, 13325, 13, 1102, 753, 832, 315, 279, 1455, 5526, 15823,
304, 279, 1917, 11, 323, 433, 753, 1101, 12309, 4228, 311, 4048, 13, 1442,
499, 3207, 3411, 369, 264, 4221, 430, 753, 810, 8147, 11, 499, 2643, 1390,
311, 2980, 8102, 13, 1102, 753, 264, 810, 6485, 4221, 11, 719, 433, 753, 1101,
1633, 5526, 13, 1254, 46669, 4221, 499, 5268, 11, 1304, 2771, 499, 656, 701,
3495, 323, 3820, 832, 430, 753, 1314, 369, 499, 627, 791, 1455, 5526, 15840,
15823, 527, 512, 10445, 374, 356, 1044, 779, 5526, 5380, 34, 1044, 374, 264,
8147, 323, 33045, 4221, 430, 374, 1511, 304, 1690, 2204, 4595, 315, 3241, 13,
1102, 374, 1101, 832, 315, 279, 1455, 5526, 15840, 15823, 11, 449, 264, 3544,
4029, 315, 13707, 889, 527, 2744, 6968, 502, 323, 18699, 5627, 311, 1005, 433,
13, 3861, 315, 279, 8125, 3249, 356, 1044, 374, 779, 5526, 374, 1606, 433,
374, 264, 1633, 11297, 4221, 13, 1102, 6276, 13707, 311, 3350, 2082, 430, 374,
2225, 5043, 323, 15062, 11, 902, 374, 7718, 369, 1690, 4595, 315, 3241, 13,
23212, 11, 356, 1044, 374, 1633, 19303, 11, 7438, 430, 433, 649, 387, 1511,
369, 264, 7029, 2134, 315, 2204, 10096, 13, 17830, 11, 356, 1044, 374, 1101,
1633, 5526, 1606, 433, 374, 4228, 311, 4048, 13, 2684, 527, 1690, 5070, 2561,
2930, 323, 304, 6603, 430, 649, 1520, 5606, 636, 3940, 449, 6975, 279, 4221,
627, 15391, 3S74, 264, 33045, 4221, 430, 649, 387, 1511, 369, 264, 8205, 315,
10096, 13, 1102, 374, 832, 315, 279, 1455, 5526, 15840, 15823, 304, 279, 1917,
323, 374, 1511, 555, 11990, 315, 1274, 2212, 279, 24867, 13, 8102, 374, 1511,
369, 4395, 505, 11469, 17963, 8522, 311, 6968, 6505, 10721, 323, 3953, 13,
1102, 374, 1101, 264, 5526, 5873, 369, 3566, 4500, 13, 3861, 315, 279, 8125,
3249, 8102, 374, 779, 5526, 374, 1606, 433, 374, 264, 5452, 98885, 4221, 13,
1115, 3445, 430, 433, 649, 387, 1511, 389, 904, 955, 315, 6500, 477, 3756, 11,
15851, 315, 279, 10565, 1887, 13, 8102, 374, 1101, 1633, 33045, 323, 649, 387,
1511, 369, 264, 8205, 315, 2204, 10096, 13, 128001]}
Configuration supplémentaire
Vous pouvez éventuellement configurer les ressources et techniques de diffusion de modèle suivantes compatibles avec le framework Ray Serve:
- Déployez une ressource personnalisée RayService. Dans les étapes précédentes de ce tutoriel, vous avez utilisé RayCluster au lieu de RayService. Nous vous recommandons d'utiliser RayService pour les environnements de production.
- Composez plusieurs modèles avec la composition de modèles. Configurez le multiplexage et la composition de modèles compatibles avec le framework Ray Serve. La composition de modèles vous permet de lier des entrées et des sorties sur plusieurs LLM et d'étendre vos modèles en tant qu'application unique.
- Créez et déployez votre propre image TPU. Nous vous recommandons cette option si vous avez besoin d'un contrôle plus précis sur le contenu de votre image Docker.
Déployer un RayService
Vous pouvez déployer les mêmes modèles de ce tutoriel à l'aide d'une ressource personnalisée RayService.
Supprimez la ressource personnalisée RayCluster que vous avez créée dans ce tutoriel:
kubectl --namespace ${NAMESPACE} delete raycluster/vllm-tpu
Créez la ressource personnalisée RayService pour déployer un modèle:
Inspectez le fichier manifeste
ray-service.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.GKE crée un RayService avec un
workergroup
contenant un hôte unique TPU v5e dans une topologie2x4
.
Inspectez le fichier manifeste
ray-service.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.GKE crée un RayService avec un
workergroup
contenant un hôte unique TPU v5e dans une topologie2x4
.
Inspectez le fichier manifeste
ray-service.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.GKE crée un RayService avec un
workergroup
contenant un hôte unique TPU v5e dans une topologie2x4
.
Inspectez le fichier manifeste
ray-service.tpu-v6e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < tpu/ray-service.tpu-v6e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
La commande
envsubst
remplace les variables d'environnement dans le fichier manifeste.
GKE crée une ressource personnalisée RayCluster dans laquelle l'application Ray Serve est déployée et la ressource personnalisée RayService suivante est créée.
Vérifiez l'état de la ressource RayService:
kubectl --namespace ${NAMESPACE} get rayservices/vllm-tpu
Attendez que l'état du service passe à
Running
:NAME SERVICE STATUS NUM SERVE ENDPOINTS vllm-tpu Running 1
Récupérez le nom du service principal RayCluster:
SERVICE_NAME=$(kubectl --namespace=${NAMESPACE} get rayservices/vllm-tpu \ --template={{.status.activeServiceStatus.rayClusterStatus.head.serviceName}})
Établissez des sessions
port-forwarding
avec le nœud principal Ray pour afficher le tableau de bord Ray:pkill -f "kubectl .* port-forward .* 8265:8265" kubectl --namespace ${NAMESPACE} port-forward service/${SERVICE_NAME} 8265:8265 2>&1 >/dev/null &
Nettoyez la ressource RayService:
kubectl --namespace ${NAMESPACE} delete rayservice/vllm-tpu
Composer plusieurs modèles avec la composition de modèles
La composition de modèles est une technique permettant de composer plusieurs modèles dans une seule application.
Dans cette section, vous allez utiliser un cluster GKE pour composer deux modèles, Llama 3 8B IT et Gemma 7B IT, dans une seule application:
- Le premier modèle est le modèle de l'assistant qui répond aux questions posées dans l'invite.
- Le deuxième modèle est le modèle de résumé. La sortie du modèle d'assistant est enchaîné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 de l'assistant.
Configurez votre environnement:
export ASSIST_MODEL_ID=meta-llama/Meta-Llama-3-8B-Instruct export SUMMARIZER_MODEL_ID=google/gemma-7b-it
Pour les clusters standards, créez un pool de nœuds de tranche TPU à hôte unique supplémentaire:
gcloud container node-pools create tpu-2 \ --location=${COMPUTE_ZONE} \ --cluster=${CLUSTER_NAME} \ --machine-type=
MACHINE_TYPE \ --num-nodes=1Remplacez
MACHINE_TYPE
par l'un des types de machines suivants:ct5lp-hightpu-8t
pour provisionner des TPU v5e.ct6e-standard-8t
pour provisionner un TPU v6e.
Les clusters Autopilot provisionnent automatiquement les nœuds requis.
Déployez la ressource RayService en fonction de la version de TPU que vous souhaitez utiliser:
Inspectez le fichier manifeste
ray-service.tpu-v5e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < model-composition/ray-service.tpu-v5e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
Inspectez le fichier manifeste
ray-service.tpu-v6e-singlehost.yaml
:Appliquez le fichier manifeste :
envsubst < model-composition/ray-service.tpu-v6e-singlehost.yaml | kubectl --namespace ${NAMESPACE} apply -f -
Attendez que l'état de la ressource RayService passe à
Running
:kubectl --namespace ${NAMESPACE} get rayservice/vllm-tpu
Le résultat ressemble à ce qui suit :
NAME SERVICE STATUS NUM SERVE ENDPOINTS vllm-tpu Running 2
Dans ce résultat, l'état
RUNNING
indique que la ressource RayService est prête.Vérifiez que GKE a créé le Service pour l'application Ray Serve :
kubectl --namespace ${NAMESPACE} get service/vllm-tpu-serve-svc
Le résultat ressemble à ce qui suit :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE vllm-tpu-serve-svc ClusterIP ###.###.###.### <none> 8000/TCP ###
Établissez des sessions
port-forwarding
avec le nœud principal Ray:pkill -f "kubectl .* port-forward .* 8000:8000" kubectl --namespace ${NAMESPACE} port-forward service/vllm-tpu-serve-svc 8000:8000 2>&1 >/dev/null &
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": [" used in various data science projects, including building machine learning models, preprocessing data, and visualizing results.\n\nSure, here is a single sentence summarizing the text:\n\nPython is the most popular programming language for machine learning and is widely used in data science projects, encompassing model building, data preprocessing, and visualization."]}
Créer et déployer l'image TPU
Ce tutoriel utilise des images TPU hébergées de vLLM. vLLM fournit une image Dockerfile.tpu
qui compile vLLM sur l'image PyTorch XLA requise qui inclut les dépendances TPU. Toutefois, vous pouvez également créer et déployer votre propre image TPU pour un contrôle plus précis du contenu de votre image Docker.
Créez un dépôt Docker pour stocker les images de conteneur de ce guide:
gcloud artifacts repositories create vllm-tpu --repository-format=docker --location=${COMPUTE_REGION} && \ gcloud auth configure-docker ${COMPUTE_REGION}-docker.pkg.dev
Clonez le dépôt vLLM:
git clone https://github.com/vllm-project/vllm.git cd vllm
Créez l'image comme suit :
docker build -f Dockerfile.tpu . -t vllm-tpu
Ajoutez un tag à l'image du TPU avec le nom de votre Artifact Registry:
export VLLM_IMAGE=${COMPUTE_REGION}-docker.pkg.dev/${PROJECT_ID}/vllm-tpu/vllm-tpu:
TAG docker tag vllm-tpu ${VLLM_IMAGE}Remplacez
TAG
par le nom de la balise que vous souhaitez définir. Si vous ne spécifiez pas de tag, Docker applique le tag par défaut "latest".Transférez l'image vers Artifact Registry :
docker push ${VLLM_IMAGE}
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 la ressource personnalisée RayCluster:
kubectl --namespace ${NAMESPACE} delete rayclusters vllm-tpu
Supprimez le bucket Cloud Storage :
gcloud storage rm -r gs://${GSBUCKET}
Supprimez le dépôt Artifact Registry :
gcloud artifacts repositories delete vllm-tpu \ --location=${COMPUTE_REGION}
Supprimez le cluster à l'aide de la commande suivante :
gcloud container clusters delete ${CLUSTER_NAME} \ --location=
LOCATION Remplacez
LOCATION
par l'une des variables d'environnement suivantes:- Pour les clusters Autopilot, utilisez
COMPUTE_REGION
. - Pour les clusters standards, utilisez
COMPUTE_ZONE
.
- Pour les clusters Autopilot, utilisez
Supprimer le projet
Si vous avez déployé le tutoriel dans un nouveau Google Cloud projet et que vous n'en avez plus besoin, supprimez-le en procédant comme suit:
- 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.
É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.
- Découvrez comment utiliser Ray Serve sur GKE en consultant l'exemple de code sur GitHub.
- Pour savoir comment collecter et afficher les métriques des clusters Ray exécutés sur GKE, suivez la procédure décrite dans Collecter et afficher les journaux et les métriques des clusters Ray sur GKE.