Remarques :
- Ce tutoriel nécessite un accès à Oracle Cloud. Pour vous inscrire à un compte gratuit, reportez-vous à Introduction au niveau gratuit d'Oracle Cloud Infrastructure.
- Il utilise des exemples de valeur pour les informations d'identification, la location et les compartiments Oracle Cloud Infrastructure. A la fin de l'exercice, remplacez ces valeurs par des valeurs propres à votre environnement cloud.
Déployer NVIDIA NIM sur OKE pour l'inférence avec le référentiel de modèles stocké sur OCI Object Storage
Introduction
Ce tutoriel explique comment déployer NVIDIA NIM sur Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) avec le back-end NVIDIA TensorRT-LLM et le serveur d'inférence NVIDIA Triton pour servir les modèles LLM (Large Language Models) dans une architecture Kubernetes. Le modèle utilisé est Llama2-7B-chat
sur un GPU A10. Pour plus d'évolutivité, nous hébergeons le référentiel de modèles sur un bucket dans OCI Object Storage.
Remarque : tous les tests de ce tutoriel ont été publiés avec une version d'accès anticipé de NVIDIA NIM pour les LLM avec
nemollm-inference-ms:24.02.rc4
.
Objectifs
- Réaliser un déploiement évolutif d'un serveur d'inférence LLM.
Prérequis
-
Accès à une location Oracle Cloud Infrastructure (OCI).
-
Accès aux formes avec un GPU NVIDIA tel que les GPU A10 (par exemple,
VM.GPU.A10.1
). Pour plus d'informations sur les demandes d'augmentation de la limite, reportez-vous à Limites de service. -
Possibilité pour votre instance de s'authentifier via le principal d'instance. Pour plus d'informations, reportez-vous à appel de services à partir d'une instance.
-
Accès à NVIDIA AI Enterprise pour extraire les conteneurs NVIDIA NIM. Pour plus d'informations, reportez-vous à NVIDIA AI Enterprise.
-
Compte HuggingFace avec un jeton d'accès configuré pour télécharger
llama2-7B-chat
. -
Connaissance de la terminologie de base de Kubernetes et Helm.
Tâche 1 : créer une instance de GPU dans OCI Compute
-
Connectez-vous à la console OCI, accédez au menu OCI, à Compute, à Instances et cliquez sur Créer une instance.
-
Sélectionnez
VM.GPU.A10.1
avec l'image Oracle Cloud Marketplace NVIDIA GPU Cloud et un volume d'initialisation de 250 Go. Pour plus d'informations, reportez-vous à Utilisation de NVIDIA GPU Cloud avec Oracle Cloud Infrastructure. -
Une fois l'ordinateur démarré, connectez-vous à l'aide de votre clé privée et de l'adresse IP publique de l'ordinateur.
ssh -i <private_key> ubuntu@<public_ip>
-
Assurez-vous que le volume d'initialisation a augmenté l'espace.
df -h # check the initial space on disk sudo growpart /dev/sda 1 sudo resize2fs /dev/sda1 df -h # check the space after the commands execution
Tâche 2 : mise à jour des pilotes NVIDIA (facultatif)
Il est recommandé de mettre à jour vos pilotes vers la dernière version en fonction des conseils fournis par NVIDIA avec la matrice de compatibilité entre les pilotes et votre version CUDA. Pour plus d'informations, reportez-vous aux sections CUDA Compatibility et CUDA Toolkit 12.4 Update 1 Downloads.
sudo apt purge nvidia* libnvidia*
sudo apt-get install -y cuda-drivers-545
sudo apt-get install -y nvidia-kernel-open-545
sudo apt-get -y install cuda-toolkit-12-3
sudo reboot
Assurez-vous que vous disposez de nvidia-container-toolkit
.
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Exécutez la commande suivante pour vérifier la nouvelle version.
nvidia-smi
/usr/local/cuda/bin/nvcc --version
Tâche 3 : préparer le registre de modèles
Il est possible d'utiliser des modèles prédéfinis. Cependant, nous choisissons d'exécuter Llama2-7B-chat
sur un GPU A10. Au moment de la rédaction du présent document, ce choix n'est pas disponible et nous devons donc créer le référentiel de modèles nous-mêmes.
-
Créez un bucket nommé
NIM
dans OCI Object Storage. Pour plus d'informations, reportez-vous à Création d'un bucket Object Storage. -
Accédez à la fenêtre de terminal, connectez-vous au registre de conteneurs NVIDIA avec votre nom d'utilisateur et votre mot de passe, puis récupérez le conteneur. Exécutez la commande suivante .
docker login nvcr.io docker pull nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4
-
Clonez le modèle HuggingFace.
# Install git-lfs curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs # clone the model from HF git clone https://huggingface.co/meta-llama/Llama-2-7b-chat-hf
-
Créez la configuration du modèle.
Copiez le fichier
model_config.yaml
et créez le répertoire pour héberger la banque de modèles. C'est là que la commande Model Repository Generator stockera la sortie.mkdir model-store chmod -R 777 model-store
-
Exécutez la commande Model Repository Generator.
docker run --rm -it --gpus all -v $(pwd)/model-store:/model-store -v $(pwd)/model_config.yaml:/model_config.yaml -v $(pwd)/Llama-2-7b-chat-hf:/engine_dir nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4 bash -c "model_repo_generator llm --verbose --yaml_config_file=/model_config.yaml"
-
Exportez le référentiel de modèles vers un bucket OCI Object Storage.
Le référentiel de modèles se trouve dans le répertoire
model-store
. Vous pouvez utiliser l'interface de ligne de commande Oracle Cloud Infrastructure (interface de ligne de commande OCI) pour effectuer un téléchargement en masse vers l'un de vos buckets de la région. Pour ce tutoriel, le bucket estNIM
, où nous voulons que la banque de modèles soit téléchargée dansNIM/llama2-7b-hf
(si nous téléchargeons une configuration de modèle différente vers le même bucket).cd model-store oci os object bulk-upload -bn NIM --src-dir . --prefix llama2-7b-hf/ --auth instance_principal
Tâche 4 : soumettre une demande à la machine virtuelle (exécution IaaS)
Désormais, le référentiel de modèles est téléchargé vers un bucket OCI Object Storage.
Remarque : le paramètre d'option
--model-repository
est actuellement codé en dur dans le conteneur. Nous ne pouvons pas simplement pointer vers le bucket au démarrage. Une option consiste à adapter le script Python dans le conteneur, mais nous aurons besoin du privilège sudo. L'autre consiste à monter le bucket en tant que système de fichiers directement sur l'ordinateur. Pour ce tutoriel, nous choisissons la deuxième méthode avec rclone. Assurez-vous quefuse3
etjq
sont installés sur l'ordinateur. Sur Ubuntu, vous pouvez exécutersudo apt install fuse3 jq
.
-
Obtenez votre espace de noms, votre OCID de compartiment et votre région, en les extrayant de la console OCI ou en exécutant les commandes suivantes à partir de votre instance de calcul.
#NAMESPACE: echo namespace is : `oci os ns get --auth instance_principal | jq .data` #COMPARTMENT_OCID: echo compartment ocid is: `curl -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/instance/ | jq .compartmentId` #REGION: echo region is: `curl -H "Authorization: Bearer Oracle" -L http://169.254.169.254/opc/v2/instance/ | jq .region`
-
Téléchargez et installez rclone.
curl https://rclone.org/install.sh | sudo bash
-
Préparez le fichier de configuration du clone. Veillez à mettre à jour
##NAMESPACE##
##COMPARTMENT_OCID##
##REGION##
avec vos valeurs.mkdir -p ~/rclone mkdir -p ~/test_directory/model_bucket_oci cat << EOF > ~/rclone/rclone.conf [model_bucket_oci] type = oracleobjectstorage provider = instance_principal_auth namespace = ##NAMESPACE## compartment = ##COMPARTMENT_OCID## region = ##REGION## EOF
-
Montez le bucket à l'aide de rclone.
sudo /usr/bin/rclone mount --config=$HOME/rclone/rclone.conf --tpslimit 50 --vfs-cache-mode writes --allow-non-empty --transfers 10 --allow-other model_bucket_oci:NIM/llama2-7b-hf $HOME/test_directory/model_bucket_oci
-
Dans une autre fenêtre de terminal, vous pouvez vérifier que
ls $HOME/test_directory/model_bucket_oci
renvoie le contenu du bucket. -
Dans une autre fenêtre de terminal, démarrez le conteneur en transmettant le chemin à
model-store
en tant qu'argument.docker run --gpus all -p9999:9999 -p9998:9998 -v $HOME/test_directory/model_bucket_oci:/model-store nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4 nemollm_inference_ms --model llama2-7b-chat --openai_port="9999" --nemo_port="9998" --num_gpus 1
-
Au bout de 3 minutes, le serveur d'inférence doit être prêt à être utilisé. Dans une autre fenêtre de terminal, vous pouvez exécuter la demande suivante.
Remarque : si vous voulez l'exécuter à partir de votre ordinateur local, vous devez utiliser l'adresse IP publique et ouvrir le port
9999
au niveau de l'ordinateur et du sous-réseau.curl -X "POST" 'http://localhost:9999/v1/completions' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "model": "llama2-7b-chat", "prompt": "Can you briefly describe Oracle Cloud?", "max_tokens": 100, "temperature": 0.7, "n": 1, "stream": false, "stop": "string", "frequency_penalty": 0.0 }' | jq ".choices[0].text"
Tâche 5 : mettre à jour le script cloud-init
Remarque : idéalement, une façon plus propre d'utiliser rclone dans Kubernetes consisterait à utiliser le conteneur rclone en tant que sidecar avant de démarrer le serveur d'inférence. Cela fonctionne très bien localement avec Docker, mais comme il a besoin de l'option
--device
pour utiliserfuse
, son utilisation avec Kubernetes est compliquée en raison du manque de prise en charge de cette fonctionnalité (volumes FUSE, une demande de fonctionnalité de 2015 toujours très active en mars 2024). Pour ce tutoriel, la solution de contournement que nous choisissons consiste à configurer rclone en tant que service sur l'hôte et à monter le bucket au démarrage.
Dans le script cloud-init, remplacez la valeur des lignes 17, 18 et 19 des lignes ##NAMESPACE##
, ##COMPARTMENT_OCID##
et ##REGION##
par les valeurs extraites dans la tâche 4.1. Vous pouvez également mettre à jour la valeur du regroupement à la ligne 57. Par défaut, il est appelé NIM
et dispose d'un répertoire appelé llama2-7b-hf
.
Ce script cloud-init
sera téléchargé sur le noeud de GPU de votre cluster OKE. La première partie consiste à augmenter le volume d'initialisation à la valeur définie. Il télécharge ensuite rclone, crée les répertoires appropriés et crée le fichier de configuration, comme nous l'avons fait sur la machine virtuelle GPU. Enfin, il démarre rclone en tant que service et monte le bucket vers /opt/mnt/model_bucket_oci
.
Tâche 6 : déploiement sur OKE
L'architecture cible à la fin du déploiement est comme indiqué dans l'image suivante.
Maintenant, mettez tout ensemble dans OKE.
Créez un cluster OKE avec de légères adaptations. Pour plus d'informations, reportez-vous à Utilisation de la console pour créer un cluster avec des paramètres par défaut dans le workflow Création rapide.
-
Commencez par créer 1 pool de noeuds nommé
monitoring
qui sera utilisé pour la surveillance avec 1 seul noeud (par exemple,VM.Standard.E4.Flex
avec 5 OCPU et 80 Go de RAM) avec l'image par défaut. -
Une fois le cluster démarré, créez un autre pool de noeuds avec 1 noeud GPU (par exemple,
VM.GPU.A10.1
) appeléNIM
avec l'image par défaut avec les pilotes GPU (par exemple,Oracle-Linux-8.X-Gen2-GPU-XXXX.XX.XX
).Remarque : veillez à augmenter le volume d'initialisation (350 Go) et à ajouter le script cloud-init précédemment modifié dans Afficher les options avancées et Script d'initialisation.
Tâche 7 : déploiement à l'aide de Helm dans OCI Cloud Shell
Pour accéder à OCI Cloud Shell, reportez-vous à Procédure d'accès à Cloud Shell via la console.
-
Vous pouvez trouver la configuration Helm dans l'archive
oke.zip
, où vous devez mettre à jourvalues.yaml
. Téléchargez l'archive vers OCI Cloud Shell et décompressez-la. Pour plus d'informations, reportez-vous à Procédure de téléchargement d'un fichier vers Cloud Shell à l'aide du menu.unzip oke.zip cd oke
-
Vérifiez les informations d'identification de la clé secrète pour extraire l'image dans
values.yaml
. Pour plus d'informations, reportez-vous à Création de clés secrètes d'extraction d'image.registry: nvcr.io username: $oauthtoken password: <YOUR_KEY_FROM_NVIDIA> email: someone@host.com
Tâche 8 : déployer la surveillance
La surveillance se compose de pods Grafana et Prometheus. La configuration provient de kube-prometheus-stack.
Ici, nous ajoutons un équilibreur de charge public pour accéder au tableau de bord Grafana à partir d'Internet. Utilisez username=admin
et password=xxxxxxxxx
pour vous connecter. L'indicateur serviceMonitorSelectorNilUsesHelmValues
est nécessaire pour que Prometheus puisse trouver les mesures du serveur d'inférence dans l'exemple de version déployée.
-
Déployez les pods de surveillance.
helm install example-metrics --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set grafana.service.type=LoadBalancer prometheus-community/kube-prometheus-stack --debug
Remarque : équilibreur de charge par défaut créé avec une forme fixe et une bande passante de 100 Mbits/s. Vous pouvez passer à une forme flexible et adapter la bande passante en fonction de vos limites OCI au cas où la bande passante serait un goulet d'étranglement. Pour plus d'informations, reportez-vous à Provisionnement des équilibreurs de charge OCI pour les services Kubernetes de type LoadBalancer.
-
Un exemple de tableau de bord Grafana est disponible dans
dashboard-review.json
situé dansoke.zip
. Utilisez la fonction d'importation dans Grafana pour importer et afficher ce tableau de bord. -
Vous pouvez voir l'adresse IP publique de votre tableau de bord Grafana en exécutant la commande suivante.
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 2m33s example-metrics-grafana LoadBalancer 10.96.82.33 141.145.220.114 80:31005/TCP 2m38s
Tâche 9 : déployer le serveur d'inférence
-
Exécutez la commande suivante pour déployer le serveur d'inférence à l'aide de la configuration par défaut.
cd <directory containing Chart.yaml> helm install example . -f values.yaml --debug
-
Utilisez
kubectl
pour voir le statut et attendre que les pods du serveur d'inférence soient en cours d'exécution. La première traction peut prendre quelques minutes. Une fois le conteneur créé, le chargement du modèle prend également quelques minutes. Vous pouvez surveiller le pod à l'aide de la commande suivante.kubectl describe pods <POD_NAME> kubectl logs <POD_NAME>
-
Une fois la configuration terminée, votre conteneur doit être en cours d'exécution.
$ kubectl get pods NAME READY STATUS RESTARTS AGE example-triton-inference-server-5f74b55885-n6lt7 1/1 Running 0 2m21s
Tâche 10 : utiliser le serveur d'inférence Triton sur votre conteneur NIM NVIDIA
Le serveur d'inférence est en cours d'exécution. Vous pouvez lui envoyer des demandes HTTP ou Google Remote Procedure Call (gRPC) pour effectuer l'inférence. Par défaut, le service d'inférence est exposé avec un type de service LoadBalancer. Utilisez ce qui suit pour rechercher l'adresse IP externe du serveur d'inférence. Dans ce tutoriel, il s'agit de 34.83.9.133
.
-
Obtenez les services pour obtenir l'adresse IP publique de votre serveur d'inférence.
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ... example-triton-inference-server LoadBalancer 10.18.13.28 34.83.9.133 8000:30249/TCP,8001:30068/TCP,8002:32723/TCP 47m
-
Le serveur d'inférence expose une adresse HTTP sur le port
8000
, et une adresse gRPC sur le port8001
et une adresse de mesures Prometheus sur le port8002
. Vous pouvez utiliser curl pour obtenir les métadonnées du serveur d'inférence à partir de l'adresse HTTP.$ curl 34.83.9.133:8000/v2
-
Sur votre ordinateur client, vous pouvez envoyer une demande à l'adresse IP publique sur le port
9999
.curl -X "POST" 'http://34.83.9.133:9999/v1/completions' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "model": "llama2-7b-chat", "prompt": "Can you briefly describe Oracle Cloud?", "max_tokens": 100, "temperature": 0.7, "n": 1, "stream": false, "stop": "string", "frequency_penalty": 0.0 }' | jq ".choices[0].text"
La sortie doit ressembler à :
"\n\nOracle Cloud is a comprehensive cloud computing platform offered by Oracle Corporation. It provides a wide range of cloud services, including Infrastructure as a Service (IaaS), Platform as a Service (PaaS), and Software as a Service (SaaS). Oracle Cloud offers a variety of benefits, including:\n\n1. Scalability: Oracle Cloud allows customers to scale their resources up or down as needed, providing the flexibility to handle changes in business demand."
Tâche 11 : nettoyer le déploiement
-
Une fois que vous avez terminé d'utiliser le serveur d'inférence, vous devez utiliser helm pour supprimer le déploiement.
$ helm list NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE example 1 Wed Feb 27 22:16:55 2019 DEPLOYED triton-inference-server-1.0.0 1.0 default example-metrics 1 Tue Jan 21 12:24:07 2020 DEPLOYED prometheus-operator-6.18.0 0.32.0 default $ helm uninstall example --debug $ helm uninstall example-metrics
-
Pour les services Prometheus et Grafana, vous devez supprimer explicitement les CRD. Pour plus d'informations, reportez-vous à Désinstallation du graphique Helm.
$ kubectl delete crd alertmanagerconfigs.monitoring.coreos.com alertmanagers.monitoring.coreos.com podmonitors.monitoring.coreos.com probes.monitoring.coreos.com prometheuses.monitoring.coreos.com prometheusrules.monitoring.coreos.com servicemonitors.monitoring.coreos.com thanosrulers.monitoring.coreos.com
-
Vous pouvez également supprimer le bucket OCI Object Storage créé pour contenir le référentiel de modèles.
$ oci os bucket delete --bucket-name NIM --empty
Liens connexes
Remerciements
- Auteur - Bruno Garbaccio (Spécialiste AI Infra/GPU, EMEA)
Ressources de formation supplémentaires
Parcourez d'autres ateliers sur docs.oracle.com/learn ou accédez à davantage de contenus de formation gratuits sur le canal Oracle Learning YouTube. De plus, rendez-vous sur education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.
Pour obtenir de la documentation sur le produit, visitez Oracle Help Center.
Deploy NVIDIA NIM on OKE for Inference with the Model Repository Stored on OCI Object Storage
F96573-01
April 2024