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.
Distribuire NVIDIA NIM su OKE per inferenza con il repository di modelli memorizzato nello storage degli oggetti OCI
Introduzione
Questa esercitazione descrive come distribuire NVIDIA NIM su Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) con il backend NVIDIA TensorRT-LLM e il server di inferenza NVIDIA Triton per servire Large Language Models (LLM) in un'architettura Kubernetes. Il modello utilizzato è Llama2-7B-chat
su una GPU A10. Per la scalabilità, stiamo ospitando il repository dei modelli in un bucket in OCI Object Storage.
Nota: tutti i test di questa esercitazione sono stati rilasciati con una versione di accesso anticipato di NVIDIA NIM per LLM con
nemollm-inference-ms:24.02.rc4
.
Obiettivi
- Ottieni una distribuzione scalabile di un server di inferenza LLM.
Prerequisiti
-
Accesso a una tenancy Oracle Cloud Infrastructure (OCI).
-
Accesso alle forme con GPU NVIDIA, ad esempio le GPU A10 (ad esempio,
VM.GPU.A10.1
). Per ulteriori informazioni sulle richieste di aumento del limite, vedere Limiti del servizio. -
Possibilità per l'istanza di eseguire l'autenticazione tramite il principal dell'istanza. Per ulteriori informazioni, vedere Chiamata di servizi da un'istanza.
-
Accedi a NVIDIA AI Enterprise per estrarre i container NVIDIA NIM. Per ulteriori informazioni, vedere NVIDIA AI Enterprise.
-
Un account HuggingFace con un token di accesso configurato per il download di
llama2-7B-chat
. -
Conoscenza della terminologia di base di Kubernetes ed Helm.
Task 1: creare un'istanza GPU in OCI Compute
-
Eseguire il login a OCI Console, passare al menu OCI, alla computazione, alle istanze e fare clic su Crea istanza.
-
Seleziona
VM.GPU.A10.1
con l'immagine del computer NVIDIA GPU Cloud di Oracle Cloud Marketplace e un volume di avvio di 250 GB. Per ulteriori informazioni, vedere Utilizzo di NVIDIA GPU Cloud con Oracle Cloud Infrastructure. -
Una volta che il computer è attivo, connettiti ad esso utilizzando la tua chiave privata e l'IP pubblico del computer.
ssh -i <private_key> ubuntu@<public_ip>
-
Accertarsi che il volume di avvio abbia aumentato lo spazio.
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
Task 2: aggiornare i driver NVIDIA (facoltativo)
Si consiglia di aggiornare i driver alla versione più recente in base alle indicazioni fornite da NVIDIA con la matrice di compatibilità tra i driver e la versione CUDA. Per ulteriori informazioni, vedere Compatibilità CUDA e Download di CUDA Toolkit 12.4 Update 1.
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
Assicurarsi di disporre di nvidia-container-toolkit
.
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Eseguire il comando seguente per controllare la nuova versione.
nvidia-smi
/usr/local/cuda/bin/nvcc --version
Task 3: Preparare il Registro modello
È possibile utilizzare modelli predefiniti. Tuttavia, scegliamo di eseguire Llama2-7B-chat
su una GPU A10. Al momento della scrittura, questa scelta non è disponibile e, pertanto, dobbiamo creare il repository dei modelli da soli.
-
Creare un bucket denominato
NIM
nello storage degli oggetti OCI. Per ulteriori informazioni, consulta la sezione relativa alla creazione di un bucket di storage degli oggetti. -
Vai alla finestra del terminale, accedi al registro del contenitore NVIDIA con il tuo nome utente e password e tira il contenitore. eseguire il comando seguente.
docker login nvcr.io docker pull nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4
-
Duplicare il modello 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
-
Creare la configurazione del modello.
Copiare il file
model_config.yaml
e creare la directory per ospitare l'area di memorizzazione dei modelli. Questo è dove il comando generatore del repository modelli memorizzerà l'output.mkdir model-store chmod -R 777 model-store
-
Eseguire il comando generatore del repository modelli.
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"
-
Esporta il repository del modello in un bucket di OCI Object Storage.
Il repository dei modelli si trova nella directory
model-store
. Puoi utilizzare l'interfaccia della riga di comando di Oracle Cloud Infrastructure (OCI CLI) per eseguire un caricamento di massa in uno dei tuoi bucket nell'area. Per questa esercitazione, il bucket èNIM
in cui si desidera che l'area di memorizzazione modelli venga caricata inNIM/llama2-7b-hf
(nel caso in cui venga caricata una configurazione modello diversa nello stesso bucket).cd model-store oci os object bulk-upload -bn NIM --src-dir . --prefix llama2-7b-hf/ --auth instance_principal
Task 4: inviare una richiesta alla Virtual Machine (esecuzione IaaS)
Ora il repository dei modelli viene caricato in un bucket di storage degli oggetti OCI.
Nota: il parametro di opzione
--model-repository
è attualmente non modificabile nel contenitore. Non è possibile puntare semplicemente al bucket all'avvio. Un'opzione sarà quella di adattare lo script Python all'interno del contenitore, ma avremo bisogno del privilegio sudo. L'altro sarà quello di montare direttamente il bucket come file system sul computer. Per questa esercitazione, viene scelto il secondo metodo con rclone. Assicurarsi che sul sistema siano installatifuse3
ejq
. Su Ubuntu, è possibile eseguiresudo apt install fuse3 jq
.
-
Ottenere lo spazio di nomi, l'OCID compartimento e l'area, recuperandoli dalla console OCI o eseguendo i comandi seguenti dall'istanza di computazione.
#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`
-
Scaricare e installare rclone.
curl https://rclone.org/install.sh | sudo bash
-
Preparare il file di configurazione rclone. Assicurarsi di aggiornare
##NAMESPACE##
##COMPARTMENT_OCID##
##REGION##
con i valori specificati.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
-
Installare il bucket utilizzando 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
-
In un'altra finestra del terminale, è possibile controllare che
ls $HOME/test_directory/model_bucket_oci
restituisca il contenuto del bucket. -
In un'altra finestra del terminale, avviare il contenitore che passa il percorso a
model-store
come argomento.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
-
Dopo 3 minuti, il server di inferenza deve essere pronto per essere utilizzato. In un'altra finestra del terminale, è possibile eseguire la richiesta seguente.
Nota: se si desidera eseguirlo dal computer locale, sarà necessario utilizzare l'IP pubblico e aprire la porta
9999
sia a livello di computer che di subnet.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"
Task 5: aggiornare lo script cloud-init
Nota: in teoria, un modo più semplice per utilizzare rclone in Kubernetes sarebbe quello di utilizzare il contenitore rclone come sidecar prima di avviare il server di inferenza. Funziona bene localmente utilizzando Docker, ma poiché ha bisogno dell'opzione
--device
per utilizzarefuse
, questo rende complicato l'uso con Kubernetes a causa della mancanza di supporto per questa funzione (volumi FUSE, una richiesta di funzionalità del 2015 ancora molto attiva a partire da marzo 2024). Per questa esercitazione, la soluzione che scegliamo è impostare rclone come servizio sull'host e installare il bucket all'avvio.
Nello script cloud-init, sostituire il valore delle righe 17, 18 e 19 ##NAMESPACE##
, ##COMPARTMENT_OCID##
e ##REGION##
con i valori recuperati nel task 4.1. È inoltre possibile aggiornare il valore del periodo fisso nella riga 57. Per impostazione predefinita, è denominata NIM
e dispone di una directory denominata llama2-7b-hf
.
Questo script cloud-init
verrà caricato sul nodo GPU nel cluster OKE. La prima parte consiste nell'aumentare il volume di avvio al set di valori. Quindi scarica rclone, crea le directory corrette e crea il file di configurazione, allo stesso modo in cui abbiamo fatto sulla VM GPU. Infine, avvia rclone come servizio e installa il bucket in /opt/mnt/model_bucket_oci
.
Task 6: Distribuisci su OKE
L'architettura di destinazione alla fine della distribuzione è illustrata nella seguente immagine.
Ora, mettere tutto insieme in OKE.
Creare un cluster OKE con lievi adattamenti. Per ulteriori informazioni, vedere Utilizzo della console per creare un cluster con impostazioni predefinite nel workflow 'Creazione rapida'.
-
Iniziare creando un pool di 1 nodo denominato
monitoring
che verrà utilizzato per il monitoraggio solo con 1 nodo (ad esempio,VM.Standard.E4.Flex
con 5 OCPU e 80 GB di RAM) con l'immagine predefinita. -
Una volta che il cluster è attivo, creare un altro pool di nodi con 1 nodo GPU (ad esempio,
VM.GPU.A10.1
) chiamatoNIM
con l'immagine predefinita con i driver GPU (ad esempio,Oracle-Linux-8.X-Gen2-GPU-XXXX.XX.XX
).Nota: assicurarsi di aumentare il volume di avvio (350 GB) e aggiungere lo script cloud-init modificato in precedenza in Mostra opzioni avanzate e Script di inizializzazione.
Task 7: Distribuisci utilizzando Helm in OCI Cloud Shell
Per accedere a OCI Cloud Shell, vedere Per accedere a Cloud Shell tramite la console.
-
La configurazione Helm è disponibile nell'archivio
oke.zip
, in cui è necessario aggiornarevalues.yaml
. Caricare l'archivio nella Cloud Shell OCI ed estrarlo. Per ulteriori informazioni, vedere Per caricare un file in Cloud Shell utilizzando il menu.unzip oke.zip cd oke
-
Rivedere le credenziali per il segreto per estrarre l'immagine in
values.yaml
. Per ulteriori informazioni, vedere Creazione di segreti pull immagine.registry: nvcr.io username: $oauthtoken password: <YOUR_KEY_FROM_NVIDIA> email: someone@host.com
Task 8: Distribuire il monitoraggio
Il monitoraggio consiste in pod Grafana e Prometheus. La configurazione proviene da kube-prometheus-stack.
Qui aggiungiamo un load balancer pubblico per raggiungere il dashboard Grafana da Internet. Utilizzare username=admin
e password=xxxxxxxxx
per eseguire il login. Il flag serviceMonitorSelectorNilUsesHelmValues
è necessario in modo che Prometheus possa trovare le metriche del server di inferenza nella release di esempio distribuita.
-
Distribuire i pod di monitoraggio.
helm install example-metrics --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set grafana.service.type=LoadBalancer prometheus-community/kube-prometheus-stack --debug
Nota: il load balancer predefinito creato con una forma fissa e una larghezza di banda di 100Mbps. Puoi passare a una forma flessibile e adattare la larghezza di banda in base ai tuoi limiti OCI nel caso in cui la larghezza di banda sia un collo di bottiglia. Per ulteriori informazioni, vedere Provisioning dei load balancer OCI per i servizi Kubernetes di tipo LoadBalancer.
-
Un dashboard Grafana di esempio è disponibile in
dashboard-review.json
inoke.zip
. Utilizzare la funzione di importazione in Grafana per importare e visualizzare questo dashboard. -
È possibile visualizzare l'IP pubblico del dashboard Grafana eseguendo il comando seguente.
$ 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
Task 9: Distribuzione del server inferenziale
-
Eseguire il comando seguente per distribuire il server inferenza utilizzando la configurazione predefinita.
cd <directory containing Chart.yaml> helm install example . -f values.yaml --debug
-
Utilizzare
kubectl
per visualizzare lo stato e attendere l'esecuzione dei pod del server di inferenza. La prima estrazione potrebbe richiedere alcuni minuti. Una volta creato il contenitore, il caricamento del modello richiede anche alcuni minuti. Il comando seguente consente di monitorare il pod.kubectl describe pods <POD_NAME> kubectl logs <POD_NAME>
-
Una volta completata l'impostazione, il contenitore dovrebbe essere in esecuzione.
$ kubectl get pods NAME READY STATUS RESTARTS AGE example-triton-inference-server-5f74b55885-n6lt7 1/1 Running 0 2m21s
Task 10: Utilizza Triton Inference Server sul tuo NIM Container NVIDIA
Il server di inferenza è in esecuzione. È possibile inviare richieste HTTP o Google Remote Procedure Call (gRPC) per eseguire l'inferenza. Per impostazione predefinita, il servizio di inferenza viene esposto con un tipo di servizio LoadBalancer. Utilizzare quanto segue per trovare l'IP esterno per il server inferenza. In questa esercitazione si trova 34.83.9.133
.
-
Ottenere i servizi per ottenere l'IP pubblico del server inferenza.
$ 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
-
Il server di inferenza espone un endpoint HTTP sulla porta
8000
e un endpoint gRPC sulla porta8001
e un endpoint delle metriche Prometheus sulla porta8002
. È possibile utilizzare curl per ottenere i metadati del server inferenza dall'endpoint HTTP.$ curl 34.83.9.133:8000/v2
-
Dal computer client, è possibile inviare una richiesta all'IP pubblico sulla porta
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"
L'output dovrebbe essere il seguente:
"\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."
Task 11: eseguire il cleanup della distribuzione
-
Una volta terminato l'utilizzo del server inferenza, è necessario utilizzare la timeline per eliminare la distribuzione.
$ 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
-
Per i servizi Prometheus e Grafana, è necessario eliminare in modo esplicito i CRD. Per ulteriori informazioni, vedere Disinstalla grafico 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
-
Puoi anche eliminare il bucket di storage degli oggetti OCI creato per contenere il repository dei modelli.
$ oci os bucket delete --bucket-name NIM --empty
Collegamenti correlati
Conferme
- Autore - Bruno Garbaccio (esperto AI Infra/GPU, EMEA)
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.
Deploy NVIDIA NIM on OKE for Inference with the Model Repository Stored on OCI Object Storage
F96574-01
April 2024