Observação:
- Este tutorial requer acesso ao Oracle Cloud. Para se cadastrar em uma conta gratuita, consulte Conceitos básicos do Oracle Cloud Infrastructure Free Tier.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
Implantar NVIDIA NIM no OKE para Inferência com o Repositório de Modelos Armazenado no OCI Object Storage
Introdução
Este tutorial demonstra como implantar o NVIDIA NIM no Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) com o backend NVIDIA TensorRT-LLM e o servidor de inferência NVIDIA Triton para atender aos LMs (Large Language Models) em uma arquitetura Kubernetes. O modelo usado é Llama2-7B-chat
em uma GPU A10. Para escalabilidade, estamos hospedando o repositório de modelos em um bucket no OCI Object Storage.
Observação: Todos os testes deste tutorial foram lançados com uma versão de acesso antecipado do NVIDIA NIM para LLM's com
nemollm-inference-ms:24.02.rc4
.
Objetivos
- Obtenha uma implantação escalável de um servidor de inferência LLM.
Pré-requisitos
-
Acesso a uma tenancy do Oracle Cloud Infrastructure (OCI).
-
Acesso a formas com GPU NVIDIA, como GPUs A10 (ou seja,
VM.GPU.A10.1
). Para obter mais informações sobre solicitações para aumentar o limite, consulte Limites do Serviço. -
A capacidade da sua instância de se autenticar por meio do controlador de instâncias. Para obter mais informações, consulte Chamando os Serviços em uma Instância.
-
Acesso ao NVIDIA AI Enterprise para extrair os contêineres NVIDIA NIM. Para obter mais informações, consulte NVIDIA AI Enterprise.
-
Uma conta HuggingFace com um token de acesso configurado para fazer download de
llama2-7B-chat
. -
Conhecimento da terminologia básica de Kubernetes e Helm.
Tarefa 1: Criar uma Instância de GPU no OCI Compute
-
Faça log-in na Console do OCI, navegue até Menu do OCI, Compute, Instâncias e clique em Criar Instância.
-
Selecione
VM.GPU.A10.1
com a imagem da máquina NVIDIA GPU Cloud da imagem do Oracle Cloud Marketplace e um volume de inicialização de 250 GB. Para obter mais informações, consulte Usando a NVIDIA GPU Cloud com o Oracle Cloud Infrastructure. -
Quando a máquina estiver ativa, conecte-se a ela usando sua chave privada e o IP público da máquina.
ssh -i <private_key> ubuntu@<public_ip>
-
Certifique-se de que o volume de inicialização tenha maior espaço.
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
Tarefa 2: Atualizar os Drivers NVIDIA (Opcional)
É recomendável atualizar os drivers para a versão mais recente com base nas orientações fornecidas pela NVIDIA com a matriz de compatibilidade entre os drivers e a versão do CUDA. Para obter mais informações, consulte Compatibilidade com o CUDA e Downloads de Atualização 1 do CUDA Toolkit 12.4.
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
Verifique se você tem nvidia-container-toolkit
.
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
Execute o seguinte comando para verificar a nova versão.
nvidia-smi
/usr/local/cuda/bin/nvcc --version
Tarefa 3: Preparar o Registro de Modelo
É possível usar modelos pré-criados. No entanto, optamos por executar Llama2-7B-chat
em uma GPU A10. No momento da gravação, essa opção não está disponível e, portanto, temos que criar o repositório de modelos nós mesmos.
-
Crie um bucket chamado
NIM
no OCI Object Storage. Para obter mais informações, consulte Criando um Bucket de Armazenamento de Objetos. -
Vá para a janela do terminal, faça login no registro de contêiner NVIDIA com seu nome de usuário e senha e extraia o contêiner. Execute o seguinte comando.
docker login nvcr.io docker pull nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4
-
Clone o 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
-
Crie a configuração do modelo.
Copie o arquivo
model_config.yaml
e crie o diretório para hospedar o armazenamento de modelos. É aqui que o comando do gerador do repositório do modelo armazenará a saída.mkdir model-store chmod -R 777 model-store
-
Execute o comando do gerador de repositório de modelo.
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"
-
Exporte o repositório de modelos para um bucket do OCI Object Storage.
O repositório de modelos está localizado no diretório
model-store
. Você pode usar a Interface de Linha de Comando (CLI do OCI) do Oracle Cloud Infrastructure para fazer um upload em massa para um de seus buckets na região. Para este tutorial, o bucket éNIM
no qual queremos que o armazenamento de modelos seja submetido a upload emNIM/llama2-7b-hf
(no caso de fazer upload de uma configuração de modelo diferente para o mesmo bucket).cd model-store oci os object bulk-upload -bn NIM --src-dir . --prefix llama2-7b-hf/ --auth instance_principal
Tarefa 4: Enviar uma Solicitação à Máquina Virtual (Execução IaaS)
Agora, o upload do repositório de modelos é feito em um bucket do OCI Object Storage.
Observação: No momento, o parâmetro de opção
--model-repository
está codificado no contêiner. Não podemos simplesmente apontar para o bucket quando o iniciamos. Uma opção será adaptar o script Python dentro do contêiner, mas precisaremos do privilégio sudo. A outra será montar o bucket como um sistema de arquivos na máquina diretamente. Para este tutorial, escolhemos o segundo método com rclone. Certifique-se de quefuse3
ejq
estejam instalados na máquina. No Ubuntu, você pode executarsudo apt install fuse3 jq
.
-
Obtenha seu Namespace, OCID do Compartimento e Região, extraindo-os da Console do OCI ou executando os comandos a seguir na sua instância de computação.
#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`
-
Baixe e instale o rclone.
curl https://rclone.org/install.sh | sudo bash
-
Prepare o arquivo de configuração rclone. Certifique-se de atualizar
##NAMESPACE##
##COMPARTMENT_OCID##
##REGION##
com seus 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 o bucket usando 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
-
Em outra janela de terminal, você pode verificar se
ls $HOME/test_directory/model_bucket_oci
retorna o conteúdo do bucket. -
Em outra janela de terminal, inicie o contêiner passando o caminho para
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
-
Após 3 minutos, o servidor de inferência deve estar pronto para servir. Em outra janela de terminal, você pode executar a solicitação a seguir.
Observação: Se quiser executá-lo em sua máquina local, você precisará usar o IP público e abrir a porta
9999
no nível da máquina e da sub-rede.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"
Tarefa 5: Atualizar o Script cloud-init
Observação: Idealmente, uma maneira mais limpa de usar o rclone no Kubernetes seria usar o contêiner rclone como um sidecar antes de iniciar o servidor de inferência. Isso funciona bem localmente usando o Docker, mas como ele precisa da opção
--device
para usarfuse
, isso torna complicado o uso com o Kubernetes devido à falta de suporte para esse recurso (volumes FUSE, uma solicitação de recurso de 2015 ainda muito ativa a partir de março de 2024). Para este tutorial, a solução alternativa que escolhemos é configurar o rclone como um serviço no host e montar o bucket na inicialização.
No script cloud-init, substitua o valor das linhas 17, 18 e 19 de ##NAMESPACE##
, ##COMPARTMENT_OCID##
e ##REGION##
pelos valores recuperados na Tarefa 4.1. Você também pode atualizar o valor do bloco na linha 57. Por padrão, ele é chamado de NIM
e tem um diretório chamado llama2-7b-hf
.
Este script cloud-init
será submetido a upload no nó da GPU do cluster do OKE. A primeira parte consiste em aumentar o volume de inicialização para o conjunto de valores. Em seguida, ele baixa o rclone, cria os diretórios corretos e cria o arquivo de configuração, da mesma forma que fizemos na VM da GPU. Por fim, ele inicia o rclone como um serviço e monta o bucket em /opt/mnt/model_bucket_oci
.
Tarefa 6: Implantar no OKE
A arquitetura de destino no final da implantação é a mostrada na imagem a seguir.
Agora, junte tudo no OKE.
Crie um cluster do OKE com pequenas adaptações. Para obter mais informações, consulte Usando a Console para criar um Cluster com Definições Padrão no workflow "Criação Rápida".
-
Comece criando um pool de 1 nós chamado
monitoring
que será usado para monitoramento apenas com 1 nó (ou seja,VM.Standard.E4.Flex
com 5 OCPUs e 80 GB de RAM) com a imagem padrão. -
Depois que o cluster estiver ativo, crie outro pool de nós com 1 nó de GPU (ou seja,
VM.GPU.A10.1
) chamadoNIM
com a imagem padrão com os drivers de GPU (ou seja,Oracle-Linux-8.X-Gen2-GPU-XXXX.XX.XX
).Observação: certifique-se de aumentar o volume de inicialização (350 GB) e adicionar o script cloud-init modificado anteriormente em Mostrar opções avançadas e Script de inicialização.
Tarefa 7: Implantar usando Helm no OCI Cloud Shell
Para acessar o OCI Cloud Shell, consulte Para acessar o Cloud Shell pela Console.
-
Você pode encontrar a configuração do Helm no arquivo compactado
oke.zip
, no qual você precisa atualizarvalues.yaml
. Faça upload do arquivo compactado no OCI Cloud Shell e descompacte-o. Para obter mais informações, consulte Para fazer upload de um arquivo para o Cloud Shell usando o menu.unzip oke.zip cd oke
-
Verifique suas credenciais do segredo para extrair a imagem em
values.yaml
. Para obter mais informações, consulte Criando Segredos de Extração de Imagem.registry: nvcr.io username: $oauthtoken password: <YOUR_KEY_FROM_NVIDIA> email: someone@host.com
Tarefa 8: Implantar o Monitoramento
O monitoramento consiste em pods Grafana e Prometheus. A configuração vem de kube-prometheus-stack.
Aqui, adicionamos um balanceador de carga público para acessar o painel do Grafana pela Internet. Use username=admin
e password=xxxxxxxxx
para fazer log-in. O flag serviceMonitorSelectorNilUsesHelmValues
é necessário para que o Prometheus possa encontrar as métricas do servidor de inferência na release de exemplo implantada.
-
Implante os pods de monitoramento.
helm install example-metrics --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set grafana.service.type=LoadBalancer prometheus-community/kube-prometheus-stack --debug
Observação: O balanceador de carga padrão criado com uma forma fixa e uma largura de banda de 100Mbps. Você pode alternar para uma forma flexível e adaptar a largura de banda de acordo com seus limites da OCI, caso a largura de banda seja um gargalo. Para obter mais informações, consulte Provisionando Balanceadores de Carga do OCI para Serviços do Kubernetes do Tipo LoadBalancer.
-
Um exemplo de painel de controle do Grafana está disponível em
dashboard-review.json
localizado emoke.zip
. Use a função de importação no Grafana para importar e exibir este painel. -
Você pode ver o IP público do painel do Grafana executando o comando a seguir.
$ 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
Tarefa 9: Implantar o Servidor de Inferência
-
Execute o comando a seguir para implantar o servidor de inferência usando a configuração padrão.
cd <directory containing Chart.yaml> helm install example . -f values.yaml --debug
-
Use
kubectl
para ver o status e aguardar até que os pods do servidor de inferência estejam em execução. A primeira puxada pode levar alguns minutos. Depois que o contêiner é criado, o carregamento do modelo também leva alguns minutos. Você pode monitorar o pod com o comando a seguir.kubectl describe pods <POD_NAME> kubectl logs <POD_NAME>
-
Quando a configuração estiver concluída, o contêiner deverá estar em execução.
$ kubectl get pods NAME READY STATUS RESTARTS AGE example-triton-inference-server-5f74b55885-n6lt7 1/1 Running 0 2m21s
Tarefa 10: Usar o servidor de inferência Triton no seu contêiner NIM NVIDIA
O servidor de inferência está em execução. Você pode enviar solicitações HTTP ou gRPC (Google Remote Procedure Call) para executar inferência. Por padrão, o serviço de inferência é exposto com um tipo de serviço LoadBalancer. Use o seguinte para localizar o IP externo para o servidor de inferência. Neste tutorial, é 34.83.9.133
.
-
Obtenha os serviços para obter o IP público do seu servidor de inferência.
$ 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
-
O servidor de inferência expõe um ponto final HTTP na porta
8000
e um ponto final gRPC na porta8001
e um ponto final de métricas Prometheus na porta8002
. Você pode usar curl para obter os metadados do servidor de inferência do ponto final HTTP.$ curl 34.83.9.133:8000/v2
-
Na sua máquina cliente, você pode enviar uma solicitação ao IP público na 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"
A saída deve ser semelhante 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."
Tarefa 11: Limpar a Implantação
-
Depois de terminar de usar o servidor de inferência, use o helm para excluir a implantação.
$ 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 os serviços Prometheus e Grafana, você deve excluir explicitamente CRDs. Para obter mais informações, consulte Desinstalar Gráfico 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
-
Você também pode excluir o bucket do OCI Object Storage criado para conter o repositório de modelos.
$ oci os bucket delete --bucket-name NIM --empty
Links Relacionados
Confirmação
- Autor - Bruno Garbaccio (Especialista em AI Infra/GPU, EMEA)
Mais Recursos de Aprendizagem
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Deploy NVIDIA NIM on OKE for Inference with the Model Repository Stored on OCI Object Storage
F96577-01
April 2024