주:
- 이 사용지침서에서는 Oracle Cloud에 액세스해야 합니다. 무료 계정에 등록하려면 Oracle Cloud Infrastructure Free Tier 시작하기를 참조하십시오.
- Oracle Cloud Infrastructure 인증서, 테넌시 및 구획에 대한 예제 값을 사용합니다. 실습을 마칠 때는 이러한 값을 클라우드 환경과 관련된 값으로 대체하십시오.
OCI Object Storage에 저장된 모델 저장소를 사용하여 추론을 위해 OKE에 NVIDIA NIM 배포
소개
이 사용지침서에서는 NVIDIA TensorRT-LLM 백엔드와 NVIDIA Triton 추론 서버가 있는 OKE(Oracle Cloud Infrastructure Container Engine for Kubernetes)에 NVIDIA NIM을 배포하여 Kubernetes 아키텍처에서 LLM(Large Language Models)을 제공하는 방법을 보여줍니다. 사용된 모델은 GPU A10에서 Llama2-7B-chat
입니다. 확장성을 위해 OCI Object Storage의 버킷에서 모델 저장소를 호스팅하고 있습니다.
주: 이 자습서의 모든 테스트는
nemollm-inference-ms:24.02.rc4
를 사용하여 LLM용 NVIDIA NIM의 초기 액세스 버전으로 릴리스되었습니다.
목표
- LLM 추론 서버의 확장 가능한 배포를 달성합니다.
필요 조건
-
OCI(Oracle Cloud Infrastructure) 테넌시에 액세스합니다.
-
NVIDIA GPU를 사용하는 셰이프(예: A10 GPU(예:
VM.GPU.A10.1
))에 액세스합니다. 제한 증가 요청에 대한 자세한 내용은 서비스 제한을 참조하십시오. -
인스턴스 주체를 통해 인증할 수 있는 기능입니다. 자세한 내용은 인스턴스에서 서비스 호출을 참조하십시오.
-
NVIDIA AI Enterprise에 액세스하여 NVIDIA NIM 컨테이너를 가져옵니다. 자세한 내용은 NVIDIA AI Enterprise를 참조하십시오.
-
액세스 토큰이
llama2-7B-chat
를 다운로드하도록 구성된 HuggingFace 계정입니다. -
Kubernetes 및 Helm의 기본 용어에 대한 지식
작업 1: OCI 컴퓨트에 GPU 인스턴스 생성
-
OCI 콘솔에 로그인한 후 OCI 메뉴, 컴퓨트, 인스턴스로 이동하고 인스턴스 생성을 누릅니다.
-
Oracle Cloud Marketplace 이미지 NVIDIA GPU 클라우드 머신 이미지와 부팅 볼륨이 250GB인
VM.GPU.A10.1
을 선택합니다. 자세한 내용은 Oracle Cloud Infrastructure에서 NVIDIA GPU 클라우드 사용을 참조하십시오. -
시스템이 작동되면 개인 키와 시스템 공용 IP를 사용하여 시스템에 연결합니다.
ssh -i <private_key> ubuntu@<public_ip>
-
부트 볼륨의 공간이 증가했는지 확인합니다.
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
작업 2: NVIDIA 드라이버 업데이트(선택사항)
드라이버와 CUDA 버전 간의 호환성 매트릭스를 사용하여 NVIDIA에서 제공하는 지침에 따라 드라이버를 최신 버전으로 업데이트하는 것이 좋습니다. 자세한 내용은 CUDA Compatibility 및 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
nvidia-container-toolkit
가 있는지 확인합니다.
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
다음 명령을 실행하여 새 버전을 확인하십시오.
nvidia-smi
/usr/local/cuda/bin/nvcc --version
작업 3: 모델 레지스트리 준비
사전 구축된 모델을 사용할 수 있습니다. 그러나 A10 GPU에서 Llama2-7B-chat
를 실행하도록 선택합니다. 작성 시 이 선택 항목을 사용할 수 없으므로 모델 저장소를 직접 빌드해야 합니다.
-
OCI Object Storage에
NIM
이라는 버킷을 생성합니다. 자세한 내용은 Object Storage 버킷 생성을 참조하십시오. -
터미널 창으로 이동하여 사용자 이름과 암호를 사용하여 NVIDIA 컨테이너 레지스트리에 로그인하고 컨테이너를 가져옵니다. 다음 명령을 실행합니다.
docker login nvcr.io docker pull nvcr.io/ohlfw0olaadg/ea-participants/nemollm-inference-ms:24.02.rc4
-
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
-
모델 구성을 생성합니다.
model_config.yaml
파일을 복사하고 모델 저장소를 호스트할 디렉토리를 만듭니다. 모델 저장소 생성기 명령이 출력을 저장하는 위치입니다.mkdir model-store chmod -R 777 model-store
-
모델 저장소 생성기 명령을 실행합니다.
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"
-
모델 저장소를 OCI Object Storage 버킷으로 익스포트합니다.
모델 저장소는
model-store
디렉토리에 있습니다. Oracle Cloud Infrastructure 명령행 인터페이스(OCI CLI)를 사용하여 해당 지역의 버킷 중 하나에 대량 업로드를 수행할 수 있습니다. 이 자습서의 경우 버킷은NIM
입니다. 여기서 모델 저장소를NIM/llama2-7b-hf
로 업로드하려고 합니다(다른 모델 구성을 동일한 버킷에 업로드하는 경우).cd model-store oci os object bulk-upload -bn NIM --src-dir . --prefix llama2-7b-hf/ --auth instance_principal
작업 4: 가상 머신에 요청 제출(IaaS 실행)
이제 모델 저장소가 하나의 OCI Object Storage 버킷에 업로드됩니다.
주: 옵션 매개변수
--model-repository
는 현재 컨테이너에서 하드코딩되어 있으므로 버킷을 시작할 때 간단히 가리킬 수 없습니다. 한 가지 옵션은 컨테이너 내에서 Python 스크립트를 적용하는 것이지만 sudo 권한이 필요합니다. 다른 하나는 버킷을 시스템에 파일 시스템으로 직접 마운트하는 것입니다. 이 자습서에서는 rclone을 사용하여 두번째 방법을 선택합니다.fuse3
및jq
가 시스템에 설치되어 있는지 확인합니다. Ubuntu에서는sudo apt install fuse3 jq
를 실행할 수 있습니다.
-
OCI 콘솔에서 인출하거나 컴퓨트 인스턴스에서 다음 명령을 실행하여 이름 공간, 구획 OCID 및 영역을 가져옵니다.
#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`
-
rclone을 다운로드하고 설치합니다.
curl https://rclone.org/install.sh | sudo bash
-
rclone 구성 파일을 준비합니다.
##NAMESPACE##
##COMPARTMENT_OCID##
##REGION##
를 해당 값으로 업데이트해야 합니다.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
-
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
-
다른 터미널 window에서
ls $HOME/test_directory/model_bucket_oci
가 버킷의 내용을 반환하는지 확인할 수 있습니다. -
다른 터미널 window에서 경로를
model-store
에 인수로 전달하는 컨테이너를 시작합니다.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
-
3분 후 추론 서버를 사용할 준비가 되어야 합니다. 다른 터미널 window에서 다음 요청을 실행할 수 있습니다.
주: 로컬 시스템에서 실행하려면 공용 IP를 사용하고 시스템과 서브넷 레벨에서
9999
포트를 열어야 합니다.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"
작업 5: cloud-init
스크립트 업데이트
참고: Kubernetes에서 rclone을 사용하는 보다 깨끗한 방법은 추론 서버를 시작하기 전에 rclone container를 사이드카로 사용하는 것입니다. 이 기능은 Docker를 사용하여 로컬에서 제대로 작동하지만
fuse
를 사용하려면--device
옵션이 필요하기 때문에 이 기능에 대한 지원 부족으로 인해 Kubernetes에서 사용하기가 복잡합니다(2015년의 기능 요청인 FUSE 볼륨은 2024년 3월 현재 매우 활성 상태임). 이 자습서에서는 호스트에서 rclone을 서비스로 설정하고 시작 시 버킷을 마운트하는 것이 좋습니다.
cloud-init 스크립트에서 ##NAMESPACE##
, ##COMPARTMENT_OCID##
및 ##REGION##
행 17, 18 및 19의 값을 작업 4.1에서 검색된 값으로 바꿉니다. 57행에서 버킷 값을 업데이트할 수도 있습니다. 기본적으로 이 디렉토리는 NIM
이며 llama2-7b-hf
이라는 디렉토리를 가집니다.
이 cloud-init
스크립트는 OKE 클러스터의 GPU 노드에 업로드됩니다. 첫번째 부분은 부트 볼륨을 값 세트로 늘리는 것입니다. 그런 다음 rclone을 다운로드하고 올바른 디렉토리를 만들고 GPU VM에서 수행한 것과 동일한 방식으로 구성 파일을 만듭니다. 마지막으로 서비스로 rclone을 시작하고 버킷을 /opt/mnt/model_bucket_oci
에 마운트합니다.
작업 6: OKE에 배치
배치 종료 시 대상 구조는 다음 이미지와 같습니다.
이제 모든 것을 OKE에 넣으십시오.
약간의 조정으로 OKE 클러스터를 만듭니다. 자세한 내용은 콘솔을 사용하여 '빠른 생성' 워크플로우의 기본 설정으로 클러스터 생성을 참조하십시오.
-
기본 이미지로 노드 1개(즉, OCPU 5개 및 80GB RAM이 있는
VM.Standard.E4.Flex
)로만 모니터링하는 데 사용할monitoring
이라는 노드 풀 1개를 생성하여 시작합니다. -
클러스터가 작동되면 GPU 드라이버(예:
Oracle-Linux-8.X-Gen2-GPU-XXXX.XX.XX
)가 포함된 기본 이미지가 포함된NIM
라는 GPU 노드 1개(예:VM.GPU.A10.1
)가 있는 다른 노드 풀을 생성합니다.주: 부트 볼륨(350GB)을 늘리고 Show advanced options 및 Initialization script에서 이전에 수정된 cloud-init 스크립트를 추가해야 합니다.
작업 7: OCI Cloud Shell에서 Helm을 사용하여 배치
OCI Cloud Shell에 액세스하려면 콘솔을 통해 Cloud Shell에 액세스하려면을 참조하십시오.
-
Helm 구성은
oke.zip
아카이브에서 찾을 수 있습니다. 여기서values.yaml
를 업데이트해야 합니다. 아카이브를 OCI Cloud Shell에 업로드하고 압축을 해제합니다. 자세한 내용은 메뉴를 사용하여 Cloud Shell에 파일을 업로드하려면을 참조하십시오.unzip oke.zip cd oke
-
values.yaml
에서 이미지를 가져오려면 암호에 대한 인증서를 검토하십시오. 자세한 내용은 Creating Image Pull Secrets를 참조하십시오.registry: nvcr.io username: $oauthtoken password: <YOUR_KEY_FROM_NVIDIA> email: someone@host.com
작업 8: 모니터링 배치
모니터링은 Grafana 및 Prometheus Pod로 구성됩니다. 구성은 kube-prometheus-stack에서 제공됩니다.
여기서는 공용 로드 밸런서를 추가하여 인터넷에서 Grafana 대시보드에 연결합니다. username=admin
및 password=xxxxxxxxx
를 사용하여 로그인합니다. Prometheus가 배포된 예제 릴리스에서 추론 서버 측정항목을 찾을 수 있도록 serviceMonitorSelectorNilUsesHelmValues
플래그가 필요합니다.
-
모니터링 포드를 배치합니다.
helm install example-metrics --set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false --set grafana.service.type=LoadBalancer prometheus-community/kube-prometheus-stack --debug
주: 고정 구성 및 대역폭 100Mbps로 생성된 기본 로드 밸런서입니다. 대역폭이 병목 현상인 경우 OCI 제한에 따라 유연한 구성으로 전환하고 대역폭을 조정할 수 있습니다. 자세한 내용은 LoadBalancer 유형의 Kubernetes 서비스에 대한 OCI 로드 밸런서 프로비전을 참조하십시오.
-
Grafana 대시보드의 예는
oke.zip
에 있는dashboard-review.json
에서 사용할 수 있습니다. Grafana에서 임포트 기능을 사용하여 이 대시보드를 임포트하고 봅니다. -
다음 명령을 실행하여 Grafana 대시보드의 공용 IP를 볼 수 있습니다.
$ 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
작업 9: 추론 서버 배포
-
다음 명령을 실행하여 기본 구성을 사용하여 추론 서버를 배치합니다.
cd <directory containing Chart.yaml> helm install example . -f values.yaml --debug
-
kubectl
를 사용하여 상태를 확인하고 추론 서버 POD가 실행될 때까지 기다립니다. 첫 번째 풀은 몇 분 정도 걸릴 수 있습니다. 컨테이너가 생성되면 모델을 로드하는 데 몇 분 정도 걸립니다. 다음 명령을 통해 포드를 모니터링할 수 있습니다.kubectl describe pods <POD_NAME> kubectl logs <POD_NAME>
-
설정이 완료되면 컨테이너가 실행 중이어야 합니다.
$ kubectl get pods NAME READY STATUS RESTARTS AGE example-triton-inference-server-5f74b55885-n6lt7 1/1 Running 0 2m21s
작업 10: NVIDIA NIM 컨테이너에서 Triton 추론 서버 사용
추론 서버가 실행 중입니다. 추론을 수행하기 위해 HTTP 또는 Google RPC(원격 프로시저 호출) 요청을 전송할 수 있습니다. 기본적으로 추론 서비스는 LoadBalancer 서비스 유형으로 표시됩니다. 다음을 사용하여 추론 서버에 대한 외부 IP를 찾습니다. 이 자습서에서 34.83.9.133
입니다.
-
추론 서버의 공용 IP를 가져오기 위한 서비스를 가져옵니다.
$ 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
-
추론 서버는 포트
8000
에 HTTP 끝점을, 포트8001
에 gRPC 끝점을, 포트8002
에 Prometheus 측정항목 끝점을 노출합니다. curl을 사용하여 HTTP 끝점에서 추론 서버의 메타데이터를 가져올 수 있습니다.$ curl 34.83.9.133:8000/v2
-
클라이언트 시스템에서
9999
포트의 공용 IP로 요청을 보낼 수 있습니다.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"
출력은 다음과 같습니다.
"\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."
작업 11: 배치 정리
-
추론 서버 사용을 완료했으면 helm을 사용하여 배포를 삭제해야 합니다.
$ 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
-
Prometheus 및 Grafana 서비스의 경우 CRD를 명시적으로 삭제해야 합니다. 자세한 내용은 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
-
모델 저장소를 보유하기 위해 생성된 OCI Object Storage 버킷을 삭제할 수도 있습니다.
$ oci os bucket delete --bucket-name NIM --empty
관련 링크
확인
- 작성자 - Bruno Garbaccio(EMEA, AI Infra/GPU 전문가)
추가 학습 자원
docs.oracle.com/learn에서 다른 실습을 살펴보거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하십시오. 또한 education.oracle.com/learning-explorer를 방문하여 Oracle Learning Explorer가 되십시오.
제품 설명서는 Oracle Help Center를 참조하십시오.
Deploy NVIDIA NIM on OKE for Inference with the Model Repository Stored on OCI Object Storage
F96576-01
April 2024