Note:
- Este tutorial requiere acceso a Oracle Cloud. Para registrarse en una cuenta gratuita, consulte Introducción a la capa gratuita de Oracle Cloud Infrastructure.
- Utiliza valores de ejemplo para credenciales, arrendamiento y compartimentos de Oracle Cloud Infrastructure. Al completar el laboratorio, sustituya estos valores por otros específicos de su entorno en la nube.
Despliegue de NVIDIA NIM en OKE para la inferencia con el repositorio de modelos almacenado en OCI Object Storage
Introducción
En este tutorial se muestra cómo desplegar NVIDIA NIM en Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) con el backend NVIDIA TensorRT-LLM y el servidor de inferencia NVIDIA Triton para ofrecer modelos de lenguaje grande (LLM) en una arquitectura de Kubernetes. El modelo utilizado es Llama2-7B-chat
en una GPU A10. Para la escalabilidad, alojamos el repositorio de modelos en un cubo de OCI Object Storage.
Nota: Todas las pruebas de este tutorial se han publicado con una versión de acceso anticipado de NVIDIA NIM para LLM con
nemollm-inference-ms:24.02.rc4
.
Objetivos
- Lograr una implementación escalable de un servidor de inferencia LLM.
Requisitos
-
Acceso a un arrendamiento de Oracle Cloud Infrastructure (OCI).
-
Acceso a unidades con GPU NVIDIA como GPU A10 (es decir,
VM.GPU.A10.1
). Para obtener más información sobre las solicitudes para aumentar el límite, consulte Límites de servicio. -
Capacidad de la instancia para autenticarse mediante el principal de instancia. Para obtener más información, consulte Llamada a servicios desde una instancia.
-
Acceso a NVIDIA AI Enterprise para extraer los contenedores NVIDIA NIM. Para obtener más información, consulte NVIDIA AI Enterprise.
-
Cuenta HuggingFace con un token de acceso configurado para descargar
llama2-7B-chat
. -
Conocimiento de la terminología básica de Kubernetes y Helm.
Tarea 1: Creación de una instancia de GPU en OCI Compute
-
Conéctese a la consola de OCI, vaya al menú de OCI, Recursos informáticos, Instancias y haga clic en Crear instancia.
-
Seleccione
VM.GPU.A10.1
con la imagen de Oracle Cloud Marketplace, la imagen de la máquina NVIDIA GPU Cloud y un volumen de inicio de 250 GB. Para obtener más información, consulte Uso de NVIDIA GPU Cloud con Oracle Cloud Infrastructure. -
Una vez que la máquina esté activa, conéctese a ella utilizando su clave privada y la IP pública de la máquina.
ssh -i <private_key> ubuntu@<public_ip>
-
Asegúrese de que el volumen de inicio haya aumentado el espacio.
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
Tarea 2: Actualización de los controladores NVIDIA (Opcional)
Se recomienda actualizar los controladores a la última versión según la guía proporcionada por NVIDIA con la matriz de compatibilidad entre los controladores y su versión CUDA. Para obtener más información, consulte CUDA Compatibility y 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
Asegúrese de tener nvidia-container-toolkit
.
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Ejecute el siguiente comando para comprobar la nueva versión.
nvidia-smi
/usr/local/cuda/bin/nvcc --version
Tarea 3: Preparación del registro del modelo
Es posible utilizar modelos incorporados. Sin embargo, elegimos ejecutar Llama2-7B-chat
en una GPU A10. En el momento de escribir, esta opción no está disponible y, por lo tanto, tenemos que crear el repositorio de modelos nosotros mismos.
-
Cree un cubo denominado
NIM
en OCI Object Storage. Para obtener más información, consulte Creación de un cubo de Object Storage. -
Vaya a la ventana de terminal, conéctese al registro de contenedores de NVIDIA con su nombre de usuario y contraseña y extraiga el contenedor. Ejecute el siguiente comando.
docker login nvcr.io docker pull nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4
-
Clone el modelo 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
-
Cree la configuración del modelo.
Copie el archivo
model_config.yaml
y cree el directorio para alojar el almacén de modelos. Aquí es donde el comando del generador del repositorio del modelo almacenará la salida.mkdir model-store chmod -R 777 model-store
-
Ejecute el comando del generador del repositorio de modelos.
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"
-
Exportar el repositorio de modelos a un cubo de OCI Object Storage.
El repositorio de modelos se encuentra en el directorio
model-store
. Puede utilizar la interfaz de línea de comandos (CLI de OCI) de Oracle Cloud Infrastructure para realizar una carga masiva en uno de sus cubos de la región. Para este tutorial, el cubo esNIM
donde queremos que se cargue el almacén de modelos enNIM/llama2-7b-hf
(en caso de que cargamos una configuración de modelo diferente en el mismo cubo).cd model-store oci os object bulk-upload -bn NIM --src-dir . --prefix llama2-7b-hf/ --auth instance_principal
Tarea 4: Envío de una solicitud a la máquina virtual (IaaS Ejecución)
Ahora, el repositorio de modelos se carga en un cubo de OCI Object Storage.
Nota: El parámetro de opción
--model-repository
está actualmente codificado en el contenedor; no podemos simplemente apuntar al cubo cuando lo iniciamos. Una opción será adaptar el script de Python dentro del contenedor, pero necesitaremos el privilegio sudo. El otro será montar el cubo como un sistema de archivos en la máquina directamente. Para este tutorial, elegimos el segundo método con rclone. Asegúrese de quefuse3
yjq
están instalados en la máquina. En Ubuntu, puede ejecutarsudo apt install fuse3 jq
.
-
Obtenga el espacio de nombres, el OCID de compartimento y la región, recuperándolos de la consola de OCI o ejecutando los siguientes comandos desde la instancia informática.
#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`
-
Descargue e instale rclone.
curl https://rclone.org/install.sh | sudo bash
-
Prepare el archivo de configuración de rclone. Asegúrese de actualizar
##NAMESPACE##
##COMPARTMENT_OCID##
##REGION##
con los valores.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
-
Monte el cubo mediante 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
-
En otra ventana de terminal, puede comprobar que
ls $HOME/test_directory/model_bucket_oci
devuelve el contenido del cubo. -
En otra ventana de terminal, inicie el contenedor transfiriendo la ruta de acceso a
model-store
como argumento.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
-
Después de 3 minutos, el servidor de inferencia debe estar listo para servir. En otra ventana de terminal, puede ejecutar la siguiente solicitud.
Nota: Si desea ejecutarlo desde la máquina local, tendrá que utilizar la IP pública y abrir el puerto
9999
en el nivel de máquina y de subred.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"
Tarea 5: Actualización del script cloud-init
Nota: Idealmente, una forma más limpia de utilizar rclone en Kubernetes sería utilizar el contenedor rclone como sidecar antes de iniciar el servidor de inferencia. Esto funciona bien localmente mediante Docker, pero debido a que necesita la opción
--device
para utilizarfuse
, esto dificulta su uso con Kubernetes debido a la falta de soporte para esta función (Volúmenes FUSE, una solicitud de función de 2015 todavía muy activa a partir de marzo de 2024). Para este tutorial, la solución alternativa que elegimos es configurar rclone como servicio en el host y montar el cubo en el inicio.
En la secuencia de comandos cloud-init, sustituya el valor de las líneas 17, 18 y 19 de ##NAMESPACE##
, ##COMPARTMENT_OCID##
y ##REGION##
por los valores recuperados en la tarea 4.1. También puede actualizar el valor del bloque en la línea 57. Por defecto, se denomina NIM
y tiene un directorio denominado llama2-7b-hf
.
Este script cloud-init
se cargará en el nodo de GPU del cluster de OKE. La primera parte consiste en aumentar el volumen de inicio al conjunto de valores. A continuación, descarga rclone, crea los directorios correctos y crea el archivo de configuración, de la misma manera que lo hemos hecho en la máquina virtual de GPU. Por último, inicia rclone como servicio y monta el cubo en /opt/mnt/model_bucket_oci
.
Tarea 6: Despliegue en OKE
La arquitectura de destino al final del despliegue es la que se muestra en la siguiente imagen.
Ahora, reúna todo en OKE.
Cree un cluster de OKE con ligeras adaptaciones. Para obtener más información, consulte Uso de la consola para crear un cluster con valores por defecto en el flujo de trabajo "Creación rápida".
-
Para empezar, cree 1 pool de nodos denominado
monitoring
que se utilizará para la supervisión solo con 1 nodo (es decir,VM.Standard.E4.Flex
con 5 OCPU y 80 GB de RAM) con la imagen por defecto. -
Una vez que el cluster esté activo, cree otro pool de nodos con 1 nodo de GPU (es decir,
VM.GPU.A10.1
) denominadoNIM
con la imagen por defecto con los controladores de GPU (es decir,Oracle-Linux-8.X-Gen2-GPU-XXXX.XX.XX
).Nota: Asegúrese de aumentar el volumen de inicio (350 GB) y agregar el script cloud-init modificado anteriormente en Mostrar opciones avanzadas y secuencia de comandos de inicialización.
Tarea 7: Despliegue con Helm en OCI Cloud Shell
Para acceder a OCI Cloud Shell, consulte Para acceder a Cloud Shell mediante la consola.
-
Puede encontrar la configuración de Helm en el archivo
oke.zip
, donde debe actualizarvalues.yaml
. Cargue el archivo en OCI Cloud Shell y descomprímalo. Para obtener más información, consulte Para cargar un archivo en Cloud Shell mediante el menú.unzip oke.zip cd oke
-
Revise las credenciales del secreto para extraer la imagen en
values.yaml
. Para obtener más información, consulte Creación de secretos de extracción de imágenes.registry: nvcr.io username: $oauthtoken password: <YOUR_KEY_FROM_NVIDIA> email: someone@host.com
Tarea 8: Despliegue de Monitoring
La supervisión consta de pods de Grafana y Prometheus. La configuración proviene de kube-prometheus-stack.
Aquí agregamos un equilibrador de carga público para acceder al panel de control de Grafana desde Internet. Utilice username=admin
y password=xxxxxxxxx
para conectarse. El indicador serviceMonitorSelectorNilUsesHelmValues
es necesario para que Prometheus pueda encontrar las métricas del servidor de inferencia en la versión de ejemplo desplegada.
-
Despliegue los pods de supervisión.
helm install example-metrics --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set grafana.service.type=LoadBalancer prometheus-community/kube-prometheus-stack --debug
Nota: El equilibrador de carga por defecto creado con una unidad fija y un ancho de banda de 100 Mbps. Puede cambiar a una unidad flexible y adaptar el ancho de banda según sus límites de OCI en caso de que el ancho de banda sea un cuello de botella. Para obtener más información, consulte Aprovisionamiento de equilibradores de carga de OCI para servicios de Kubernetes de tipo LoadBalancer.
-
Un ejemplo de panel de control de Grafana está disponible en
dashboard-review.json
, ubicado enoke.zip
. Utilice la función de importación de Grafana para importar y ver este panel de control. -
Puede ver la IP pública del panel de control de Grafana ejecutando el siguiente comando.
$ 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
Tarea 9: Despliegue del servidor de inferencia
-
Ejecute el siguiente comando para desplegar el servidor de inferencia con la configuración predeterminada.
cd <directory containing Chart.yaml> helm install example . -f values.yaml --debug
-
Utilice
kubectl
para ver el estado y esperar hasta que se estén ejecutando los pods del servidor de inferencia. El primer tirón puede tardar unos minutos. Una vez creado el contenedor, la carga del modelo también tarda unos minutos. Puede supervisar el pod con el siguiente comando.kubectl describe pods <POD_NAME> kubectl logs <POD_NAME>
-
Una vez completada la configuración, el contenedor debe estar en ejecución.
$ kubectl get pods NAME READY STATUS RESTARTS AGE example-triton-inference-server-5f74b55885-n6lt7 1/1 Running 0 2m21s
Tarea 10: Uso del servidor de inferencia Triton en el contenedor NVIDIA NIM
El servidor de inferencia se está ejecutando, puede enviarle solicitudes HTTP o de llamada a procedimiento remoto de Google (gRPC) para realizar la inferencia. Por defecto, el servicio de inferencia se expone con un tipo de servicio LoadBalancer. Utilice lo siguiente para buscar la IP externa para el servidor de inferencia. En este tutorial, se trata de 34.83.9.133
.
-
Obtenga los servicios para obtener la IP pública de su servidor de inferencia.
$ 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
-
El servidor de inferencia muestra un punto final HTTP en el puerto
8000
y un punto final gRPC en el puerto8001
y un punto final de métricas de Prometheus en el puerto8002
. Puede utilizar curl para obtener los metadatos del servidor de inferencia del punto final HTTP.$ curl 34.83.9.133:8000/v2
-
Desde la máquina cliente, puede enviar una solicitud a la IP pública en el puerto
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 salida debe ser similar a:
"\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."
Tarea 11: Limpiar el despliegue
-
Una vez que haya terminado de utilizar el servidor de inferencia, debe utilizar el timón para suprimir el despliegue.
$ 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
-
Para los servicios Prometheus y Grafana, debe suprimir de forma explícita las CRD. Para obtener más información, consulte Desinstalación del gráfico de 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
-
También puede suprimir el cubo de OCI Object Storage creado para contener el repositorio de modelos.
$ oci os bucket delete --bucket-name NIM --empty
Enlaces relacionados
Agradecimientos
- Autor: Bruno Garbaccio (especialista en infraestructura de IA/GPU, EMEA)
Más recursos de aprendizaje
Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en Oracle Learning Explorer.
Para obtener documentación sobre el producto, visite Oracle Help Center.
Deploy NVIDIA NIM on OKE for Inference with the Model Repository Stored on OCI Object Storage
F96571-01
April 2024