Nota
- Questa esercitazione richiede l'accesso a Oracle Cloud. Per iscriverti a un account gratuito, consulta Inizia a utilizzare Oracle Cloud Infrastructure Free Tier.
- Utilizza valori di esempio per le credenziali, la tenancy e i compartimenti di Oracle Cloud Infrastructure. Al termine del laboratorio, sostituisci questi valori con quelli specifici del tuo ambiente cloud.
Esegui il modello Elyza LLM sull'istanza di OCI Compute A10.2 con Oracle Resource Manager utilizzando la distribuzione con un clic
Introduzione
Oracle Cloud Infrastructure (OCI) Compute ti consente di creare diversi tipi di forme per testare i modelli GPU (Graphics Processing Unit) per l'intelligenza artificiale (AI) distribuiti localmente. In questa esercitazione verrà utilizzata la forma A10.2 con una VCN e risorse di subnet preesistenti che è possibile selezionare da Oracle Resource Manager.
Il codice Terraform include anche la configurazione dell'istanza per eseguire un modello o modelli Elyza Virtual Large Language Model (vLLM) locale per i task di elaborazione del linguaggio naturale.
Obiettivi
- Crea una forma A10.2 su OCI Compute, scarica il modello Elyza LLM ed esegui query sul modello vLLM locale.
Prerequisiti
-
Assicurarsi di disporre di una rete cloud virtuale (VCN) OCI e di una subnet in cui verrà distribuita la virtual machine (VM).
-
Comprensione dei componenti della rete e delle loro relazioni. Per ulteriori informazioni, vedere Panoramica della rete.
-
Comprensione del networking nel cloud. Per ulteriori informazioni, guarda il video seguente: Video for Networking in the Cloud EP.01: Virtual Cloud Networks.
-
Requisiti:
- Tipo di istanza: forma A10.2 con due GPU Nvidia.
- Sistema operativo: Oracle Linux.
- Selezione dell'immagine: lo script di distribuzione seleziona l'immagine Oracle Linux più recente con supporto GPU.
- Tag: aggiunge un tag in formato libero GPU_TAG = "A10-2".
- Dimensione volume di avvio: 250GB.
- Inizializzazione: utilizza cloud-init per scaricare e configurare il modello o i modelli vLLM Elyza.
Task 1: scaricare il codice Terraform per la distribuzione con un clic
Scaricare il codice Terraform ORM da qui: orm_stack_a10_2_gpu_elyza_models.zip, per implementare localmente i modelli Elyza vLLM che consentono di selezionare una VCN e una subnet esistenti per eseguire il test della distribuzione locale dei modelli Elyza vLLM in una forma di istanza A10.2.
Dopo aver scaricato localmente il codice Terraform ORM, seguire la procedura descritta di seguito: Creazione di uno stack da una cartella per caricare lo stack ed eseguire l'applicazione del codice Terraform.
Nota: assicurarsi di aver creato una rete cloud virtuale (VCN) OCI e una subnet in cui verrà distribuita la VM.
Task 2: creare una VCN su OCI (facoltativo se non è già stata creata)
Per creare una VCN in Oracle Cloud Infrastructure, consulta: Video per scoprire come creare una rete cloud virtuale su OCI.
o
Per creare una VCN, effettuare le operazioni riportate di seguito.
-
Eseguire il login a OCI Console, immettere Nome tenant cloud, Nome utente e Password.
-
Clicca sul menu hamburger (≡) dall'angolo in alto a sinistra.
-
Andare a Rete di rete, Reti cloud virtuali e selezionare il compartimento appropriato dalla sezione Elenco ambito.
-
Selezionare VCN con connettività Internet e fare clic su Avvia procedura guidata VCN.
-
Nella pagina Crea una VCN con connettività Internet, immettere le informazioni riportate di seguito e fare clic su Avanti.
- NOME della VCN: immettere
OCI_HOL_VCN
. - COMPARTMENT: selezionare il compartimento appropriato.
- Bloc CIDR VCN: immettere
10.0.0.0/16
. - BLOC CIDR SUBNET PUBLIC: immettere
10.0.2.0/24
. - BLOC CIDR PRIVATE SUBNET: immettere
10.0.1.0/24
. - Risoluzione DNS: selezionare USI HOSTNAMES DNS IN questa VCN.
- NOME della VCN: immettere
-
Nella pagina Rivedi, rivedere le impostazioni e fare clic su Crea.
Descrizione dell'immagine setupVCN4.png
La creazione della VCN richiederà un momento e una schermata di avanzamento ti manterrà al corrente del flusso di lavoro.
-
Dopo aver creato la VCN, fare clic su Visualizza rete cloud virtuale.
In situazioni reali, creerai più VCN in base alla loro necessità di accesso (quali porte aprire) e a chi può accedervi.
Task 3: vedere i dettagli di configurazione di cloud-init
Lo script cloud-init
installa tutte le dipendenze necessarie, avvia Docker, scarica e avvia il modello o i modelli vLLM Elyza. È possibile trovare il codice seguente nel file cloudinit.sh
scaricato nel task 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 scaricherà tutti i file necessari per eseguire il modello Elyza e non ha bisogno del token API predefinito in Hugging Face. Per l'avvio del modello Elyza con Docker nel task 6 sarà necessario il token API.
Task 4: Monitorare il sistema
Monitora il completamento dell'inizializzazione cloud e l'uso delle risorse GPU con i seguenti comandi (se necessario).
-
Monitora il completamento dell'inizializzazione cloud:
tail -f /var/log/cloud-init-output.log
. -
Monitorare l'utilizzo delle GPU:
nvidia-smi dmon -s mu -c 100 --id 0,1
. -
Distribuire e interagire con il modello vLLM Elyza utilizzando Python: (modificare i parametri solo se necessario - il comando è già incluso nello 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
Task 5: Test dell'integrazione del modello
Interagire con il modello nei modi seguenti utilizzando i comandi o i dettagli di Jupyter Notebook.
-
Eseguire il test del modello dall'interfaccia CLI (Command Line Interface) una volta completata l'inizializzazione del cloud.
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}'
-
Eseguire il test del modello da Jupyter Notebook (assicurarsi di aprire la porta
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)
-
Integra Gradio con Chatbot per eseguire query sul modello.
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)
Task 6: distribuire il modello utilizzando Docker (se necessario)
In alternativa, distribuire il modello utilizzando Docker per gli ambienti incapsulati:
-
Modello da origine esterna.
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
-
Modello in esecuzione con docker utilizzando i file locali già scaricati (avvia più rapidamente).
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
È possibile eseguire una query sul modello nei modi riportati di seguito.
-
Eseguire una query sul modello avviato con Docker da CLI (questa operazione richiede ulteriore attenzione):
-
Modello avviato con Docker da un'origine esterna.
(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 }'
-
Modello avviato localmente con 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 }'
-
-
Query the model started with Docker from a Jupyter Notebook.
-
Modello avviato da 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)
-
Container avviato localmente con 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)
-
-
Esamina il modello avviato con Docker utilizzando Gradio integrato con il chatbot.
-
Modello avviato con Docker da un'origine esterna.
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)
-
Container avviato localmente con Docker utilizzando 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)
Nota: i comandi del firewall per aprire la porta
8888
per Jupyter Notebook.sudo firewall-cmd --zone=public --permanent --add-port 8888/tcp sudo firewall-cmd --reload sudo firewall-cmd --list-all
-
Conferme
-
Autore - Bogdan Bazarca (ingegnere senior del cloud)
-
Contributori: team Oracle NACI-AI-CN-DEV
Altre risorse di apprendimento
Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare un Oracle Learning Explorer.
Per la documentazione del prodotto, visita l'Oracle Help Center.
Run Elyza LLM Model on OCI Compute A10.2 Instance with Oracle Resource Manager using One Click Deployment
G11826-01
July 2024