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.
Exécuter le modèle Elyza LLM sur l'instance OCI Compute A10.2 avec Oracle Resource Manager à l'aide d'un déploiement en un clic
Introduction
Oracle Cloud Infrastructure (OCI) Compute vous permet de créer différents types de formes pour tester les modèles d'unité de traitement graphique (GPU) pour l'intelligence artificielle (IA) déployés localement. Dans ce tutoriel, nous allons utiliser la forme A10.2 avec un VCN et des ressources de sous-réseau préexistants que vous pouvez sélectionner dans Oracle Resource Manager.
Le code Terraform inclut également la configuration de l'instance afin qu'elle exécute un ou plusieurs modèles Elyza vLLM (Virtual Large Language Model) locaux pour les tâches de traitement du langage naturel.
Objectifs
- Créez une forme A10.2 sur OCI Compute, téléchargez le modèle Elyza LLM et interrogez le modèle vLLM local.
Prérequis
-
Assurez-vous que vous disposez d'un réseau cloud virtuel OCI (VCN) et d'un sous-réseau où la machine virtuelle sera déployée.
-
Compréhension des composants réseau et de leurs relations. Pour plus d'informations, reportez-vous à Présentation de Networking.
-
Compréhension de la mise en réseau dans le cloud. Pour plus d'informations, regardez la vidéo suivante : Vidéo for Networking in the Cloud EP.01 : Virtual Cloud Networks.
-
Exigences :
- Type d'instance : forme A10.2 avec deux GPU Nvidia.
- Système d'exploitation : Oracle Linux.
- Sélection d'image : le script de déploiement sélectionne la dernière image Oracle Linux avec prise en charge des GPU.
- Balises : ajoute une balise à format libre GPU_TAG = "A10-2".
- Taille de volume d'initialisation : 250 Go.
- Initialisation : utilise cloud-init pour télécharger et configurer les modèles vLLM Elyza.
Tâche 1 : téléchargement du code Terraform pour un déploiement en un clic
Téléchargez le code ORM Terraform à partir d'ici : orm_stack_a10_2_gpu_elyza_models.zip, pour implémenter localement des modèles Elyza vLLM qui vous permettront de sélectionner un VCN existant et un sous-réseau afin de tester le déploiement local des modèles Elyza vLLM dans une forme d'instance A10.2.
Une fois le code Terraform ORM téléchargé en local, suivez les étapes ci-après : Création d'une pile à partir d'un dossier pour télécharger la pile et exécuter l'application du code Terraform.
Remarque : assurez-vous d'avoir créé un réseau cloud virtuel (VCN) OCI et un sous-réseau où la machine virtuelle sera déployée.
Tâche 2 : création d'un VCN sur OCI (facultatif s'il n'est pas déjà créé)
Pour créer un VCN dans Oracle Cloud Infrastructure, reportez-vous à : Vidéo pour découvrir comment créer un réseau cloud virtuel sur OCI.
ou
Pour créer un VCN, procédez comme suit :
-
Connectez-vous à la console OCI, entrez Nom de locataire cloud, Nom utilisateur et Mot de passe.
-
Cliquez sur le menu hamburger (≡) dans le coin supérieur gauche.
-
Accédez à Fonctions de réseau, à Réseaux cloud virtuels et sélectionnez le compartiment approprié dans la section Portée de la liste.
-
Sélectionnez Réseau cloud virtuel avec connectivité Internet, et cliquez sur Lancer l'assistant de réseau cloud virtuel.
-
Sur la page Créer un VCN avec une connectivité Internet, entrez les informations suivantes et cliquez sur Suivant.
- NOM du VCN : entrez
OCI_HOL_VCN
. - COMPARTMENT : sélectionnez le compartiment approprié.
- Bloc CIDR VCN : entrez
10.0.0.0/16
. - BLOCK de CIDR de sous-réseau PUBLIC : entrez
10.0.2.0/24
. - Bloc CIDR de sous-réseau privé : entrez
10.0.1.0/24
. - Résolution DNS : sélectionnez Utiliser des hôtes DNS dans ce VCN.
- NOM du VCN : entrez
-
Sur la page Vérifier, vérifiez les paramètres et cliquez sur Créer.
Description de l'image setupVCN4.png
Il vous faudra un moment pour créer le VCN et un écran de progression vous tiendra au courant du workflow.
-
Une fois le VCN créé, cliquez sur Visualiser le réseau cloud virtuel.
Dans des situations réelles, vous allez créer plusieurs réseaux cloud virtuels en fonction de leur besoin d'accès (les ports à ouvrir) et des utilisateurs autorisés à y accéder.
Tâche 3 : voir les détails de configuration de cloud-init
Le script cloud-init
installe toutes les dépendances nécessaires, démarre Docker, télécharge et démarre le ou les modèles vLLM Elyza. Vous pouvez trouver le code suivant dans le fichier cloudinit.sh
téléchargé dans la tâche 1.
dnf install -y dnf-utils zip unzip
dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
dnf remove -y runc
dnf install -y docker-ce --nobest
systemctl enable docker.service
dnf install -y nvidia-container-toolkit
systemctl start docker.service
...
Cloud-init télécharge tous les fichiers nécessaires à l'exécution du modèle Elyza et n'a pas besoin de votre jeton API prédéfini dans Hugging Face. Le jeton d'API sera nécessaire pour le lancement du modèle Elyza à l'aide de Docker dans la tâche 6.
Tâche 4 : surveiller le système
Suivez l'achèvement de l'initialisation du cloud et l'utilisation des ressources GPU à l'aide des commandes suivantes (si nécessaire).
-
Surveiller l'achèvement de cloud-init :
tail -f /var/log/cloud-init-output.log
. -
Surveiller l'utilisation des GPU :
nvidia-smi dmon -s mu -c 100 --id 0,1
. -
Déployez le modèle vLLM Elyza et interagissez avec lui à l'aide de Python : (modifiez les paramètres uniquement si nécessaire ; la commande est déjà incluse dans le script
cloud-init
) :python -O -u -m vllm.entrypoints.api_server \ --host 0.0.0.0 \ --port 8000 \ --model /home/opc/models/${MODEL} \ --tokenizer hf-internal-testing/llama-tokenizer \ --enforce-eager \ --max-num-seqs 1 \ --tensor-parallel-size 2 \ >> /home/opc/${MODEL}.log 2>&1
Tâche 5 : tester l'intégration du modèle
Interagissez avec le modèle de la manière suivante à l'aide des commandes ou des détails de Jupyter Notebook.
-
Testez le modèle à partir de l'interface de ligne de commande (CLI) une fois cloud-init terminé.
curl -X POST "http://0.0.0.0:8000/generate" \ -H "accept: application/json" \ -H "Content-Type: application/json" \ -d '{"prompt": "Write a humorous limerick about the wonders of GPU computing.", "max_tokens": 64, "temperature": 0.7, "top_p": 0.9}'
-
Testez le modèle à partir de Jupyter Notebook (assurez-vous d'ouvrir le port
8888
).import requests import json url = "http://0.0.0.0:8000/generate" headers = { "accept": "application/json", "Content-Type": "application/json", } data = { "prompt": "Write a short conclusion.", "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 } response = requests.post(url, headers=headers, json=data) if response.status_code == 200: result = response.json() # Pretty print the response for better readability formatted_response = json.dumps(result, indent=4) print("Response:", formatted_response) else: print("Request failed with status code:", response.status_code) print("Response:", response.text)
-
Intégrez Gradio au chatbot pour interroger le modèle.
import requests import gradio as gr import os # Function to interact with the model via API def interact_with_model(prompt): url = 'http://0.0.0.0:8000/generate' headers = { "accept": "application/json", "Content-Type": "application/json", } data = { "prompt": prompt, "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 } response = requests.post(url, headers=headers, json=data) if response.status_code == 200: result = response.json() completion_text = result["text"][0].strip() # Extract the generated text return completion_text else: return {"error": f"Request failed with status code {response.status_code}"} # Retrieve the MODEL environment variable model_name = os.getenv("MODEL") # Example Gradio interface iface = gr.Interface( fn=interact_with_model, inputs=gr.Textbox(lines=2, placeholder="Write a prompt..."), outputs=gr.Textbox(type="text", placeholder="Response..."), title=f"{model_name} Interface", # Use model_name to dynamically set the title description=f"Interact with the {model_name} deployed locally via Gradio.", # Use model_name to dynamically set the description live=True ) # Launch the Gradio interface iface.launch(share=True)
Tâche 6 : déployer le modèle à l'aide de Docker (si nécessaire)
Vous pouvez également déployer le modèle à l'aide de Docker pour les environnements encapsulés :
-
Modèle à partir d'une source externe.
docker run --gpus all \ --env "HUGGING_FACE_HUB_TOKEN=$TOKEN_ACCESS" \ -p 8000:8000 \ --ipc=host \ --restart always \ vllm/vllm-openai:latest \ --tensor-parallel-size 2 \ --model elyza/$MODEL
-
Modèle exécuté avec docker utilisant les fichiers locaux déjà téléchargés (démarre plus rapidement).
docker run --gpus all \ -v /home/opc/models/$MODEL/:/mnt/model/ \ --env "HUGGING_FACE_HUB_TOKEN=$TOKEN_ACCESS" \ -p 8000:8000 \ --env "TRANSFORMERS_OFFLINE=1" \ --env "HF_DATASET_OFFLINE=1" \ --ipc=host vllm/vllm-openai:latest \ --model="/mnt/model/" \ --tensor-parallel-size 2
Vous pouvez interroger le modèle de l'une des manières suivantes :
-
Interroger le modèle lancé avec Docker à partir de la CLI (cette opération nécessite une attention particulière) :
-
Modèle démarré avec Docker à partir d'une source externe.
(elyza) [opc@a10-2-gpu ~]$ curl -X 'POST' 'http://0.0.0.0:8000/v1/chat/completions' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "model": "elyza/'${MODEL}'", "messages": [{"role": "user", "content": "Write a humorous limerick about the wonders of GPU computing."}], "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 }'
-
Modèle démarré localement avec Docker.
curl -X 'POST' 'http://0.0.0.0:8000/v1/chat/completions' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "model": "/mnt/model/", "messages": [{"role": "user", "content": "Write a humorous limerick about the wonders of GPU computing."}], "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 }'
-
-
Interrogez le modèle démarré avec Docker à partir d'un bloc-notes Jupyter Notebook.
-
Modèle démarré à partir de Docker Hub.
import requests import json import os url = "http://0.0.0.0:8000/v1/chat/completions" headers = { "accept": "application/json", "Content-Type": "application/json", } # Assuming `MODEL` is an environment variable set appropriately model = f"elyza/{os.getenv('MODEL')}" data = { "model": model, "messages": [{"role": "user", "content": "Write a humorous limerick about the wonders of GPU computing."}], "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 } response = requests.post(url, headers=headers, json=data) if response.status_code == 200: result = response.json() # Extract the generated text from the response completion_text = result["choices"][0]["message"]["content"].strip() print("Generated Text:", completion_text) else: print("Request failed with status code:", response.status_code) print("Response:", response.text)
-
Conteneur démarré localement avec Docker.
import requests import json import os url = "http://0.0.0.0:8000/v1/chat/completions" headers = { "accept": "application/json", "Content-Type": "application/json", } # Assuming `MODEL` is an environment variable set appropriately model = f"/mnt/model/" # Adjust this based on your specific model path or name data = { "model": model, "messages": [{"role": "user", "content": "Write a humorous limerick about the wonders of GPU computing."}], "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 } response = requests.post(url, headers=headers, json=data) if response.status_code == 200: result = response.json() # Extract the generated text from the response completion_text = result["choices"][0]["message"]["content"].strip() print("Generated Text:", completion_text) else: print("Request failed with status code:", response.status_code) print("Response:", response.text)
-
-
Interrogez le modèle démarré avec Docker à l'aide de Gradio intégré au chatbot.
-
Modèle démarré avec Docker à partir d'une source externe.
import requests import gradio as gr import os # Function to interact with the model via API def interact_with_model(prompt): url = 'http://0.0.0.0:8000/v1/chat/completions' # Update the URL to match the correct endpoint headers = { "accept": "application/json", "Content-Type": "application/json", } # Assuming `MODEL` is an environment variable set appropriately model = f"elyza/{os.getenv('MODEL')}" data = { "model": model, "messages": [{"role": "user", "content": prompt}], # Use the user-provided prompt "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 } response = requests.post(url, headers=headers, json=data) if response.status_code == 200: result = response.json() completion_text = result["choices"][0]["message"]["content"].strip() # Extract the generated text return completion_text else: return {"error": f"Request failed with status code {response.status_code}"} # Retrieve the MODEL environment variable model_name = os.getenv("MODEL") # Example Gradio interface iface = gr.Interface( fn=interact_with_model, inputs=gr.Textbox(lines=2, placeholder="Write a prompt..."), outputs=gr.Textbox(type="text", placeholder="Response..."), title=f"{model_name} Interface", # Use model_name to dynamically set the title description=f"Interact with the {model_name} model deployed locally via Gradio.", # Use model_name to dynamically set the description live=True ) # Launch the Gradio interface iface.launch(share=True)
-
Conteneur démarré localement avec Docker à l'aide de Gradio
import requests import gradio as gr import os # Function to interact with the model via API def interact_with_model(prompt): url = 'http://0.0.0.0:8000/v1/chat/completions' # Update the URL to match the correct endpoint headers = { "accept": "application/json", "Content-Type": "application/json", } # Assuming `MODEL` is an environment variable set appropriately model = "/mnt/model/" # Adjust this based on your specific model path or name data = { "model": model, "messages": [{"role": "user", "content": prompt}], "max_tokens": 64, "temperature": 0.7, "top_p": 0.9 } response = requests.post(url, headers=headers, json=data) if response.status_code == 200: result = response.json() completion_text = result["choices"][0]["message"]["content"].strip() return completion_text else: return {"error": f"Request failed with status code {response.status_code}"} # Example Gradio interface iface = gr.Interface( fn=interact_with_model, inputs=gr.Textbox(lines=2, placeholder="Write a humorous limerick about the wonders of GPU computing."), outputs=gr.Textbox(type="text", placeholder="Response..."), title="Model Interface", # Set your desired title here description="Interact with the model deployed locally via Gradio.", live=True ) # Launch the Gradio interface iface.launch(share=True)
Remarque : commandes de pare-feu permettant d'ouvrir le port
8888
pour Jupyter Notebook.sudo firewall-cmd --zone=public --permanent --add-port 8888/tcp sudo firewall-cmd --reload sudo firewall-cmd --list-all
-
Remerciements
-
Auteur - Bogdan Bazarca (ingénieur cloud senior)
-
Contributeurs - Équipe Oracle NACI-AI-CN-DEV
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.
Run Elyza LLM Model on OCI Compute A10.2 Instance with Oracle Resource Manager using One Click Deployment
G11825-01
July 2024