GKE에서 단일 GPU로 모델 서빙


이 튜토리얼에서는 Google Kubernetes Engine(GKE) 모드에서 GPU로 단순 모델을 제공하는 방법을 보여줍니다. 이 튜토리얼에서는 단일 L4 Tensor Core GPU를 사용하는 GKE 클러스터를 만들고 온라인 추론을 수행하도록 GKE 인프라를 준비합니다. 이 튜토리얼에서는 온라인 서빙을 위해 가장 자주 사용되는 두 가지 프레임워크를 사용합니다.

목표

이 튜토리얼은 GKE 클러스터에서 사전 학습된 머신 러닝(ML) 모델을 호스팅하려는 인프라 엔지니어, MLOps 엔지니어, DevOps 엔지니어, 클러스터 관리자를 대상으로 합니다.

이 가이드는 다음 과정을 다룹니다.

  1. GKE Autopilot 또는 Standard 클러스터를 만듭니다.
  2. 선행 학습된 모델이 포함되는 Cloud Storage 버킷을 구성합니다.
  3. 선택한 온라인 추론 프레임워크를 배포합니다.
  4. 배포된 서비스에 테스트 요청을 수행합니다.

비용

이 튜토리얼에서는 다음과 같은 Google Cloud 구성요소를 사용하며 여기에는 비용이 청구될 수 있습니다.

  • GKE
  • Cloud Storage
  • L4 GPU 가속기
  • 이그레스 트래픽

가격 계산기를 사용하여 예상 사용량을 기준으로 예상 비용을 산출합니다.

이 튜토리얼을 마치면 만든 리소스를 삭제하여 비용이 계속 청구되지 않도록 할 수 있습니다. 자세한 내용은 삭제를 참조하세요.

시작하기 전에

프로젝트 설정

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Enable the GKE API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  7. Enable the GKE API.

    Enable the API

Google Cloud CLI 기본값 설정

  1. Google Cloud 콘솔에서 Cloud Shell 인스턴스를 시작합니다.
    Cloud Shell 열기

  2. 이 샘플 앱의 소스 코드를 다운로드합니다.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/ai-ml/gke-online-serving-single-gpu
    
  3. 기본 환경 변수를 설정합니다.

    gcloud config set project PROJECT_ID
    gcloud config set compute/region COMPUTE_REGION
    

    다음 값을 바꿉니다.

    • PROJECT_ID: Google Cloud 프로젝트 ID입니다.
    • COMPUTE_REGION: 사용하려는 가속기 유형을 지원하는 Compute Engine 리전(예: L4 GPU의 경우 us-central1)입니다.
  4. Cloud Shell에서 다음 변수를 만듭니다.

    export PROJECT_ID=$(gcloud config get project)
    export REGION=$(gcloud config get compute/region)
    export K8S_SA_NAME=gpu-k8s-sa
    export GSBUCKET=$PROJECT_ID-gke-bucket
    export MODEL_NAME=mnist
    export CLUSTER_NAME=online-serving-cluster
    

GKE 클러스터 만들기

GKE Autopilot 또는 Standard 클러스터의 단일 GPU에서 모델을 서빙할 수 있습니다. 완전 관리형 Kubernetes 환경을 위해서는 Autopilot 클러스터를 사용하는 것이 좋습니다. GKE Autopilot를 사용해서 리소스가 모델 요청에 따라 자동으로 확장됩니다.

워크로드에 가장 적합한 GKE 작업 모드를 선택하려면 GKE 작업 모드 선택을 참조하세요.

Autopilot

다음 명령어를 실행하여 GKE Autopilot 클러스터를 만듭니다.

  gcloud container clusters create-auto ${CLUSTER_NAME} \
      --region=${REGION} \
      --project=${PROJECT_ID} \
      --release-channel=rapid

GKE는 배포된 워크로드의 요청에 따라 CPU 및 GPU 노드를 사용하여 Autopilot 클러스터를 만듭니다.

표준

  1. 다음 명령어를 실행하여 GKE Standard 클러스터를 만듭니다.

      gcloud container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID}  \
        --region=${REGION}  \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --addons GcsFuseCsiDriver \
        --release-channel=rapid \
        --num-nodes=1
    

    클러스터 만들기는 몇 분 정도 걸릴 수 있습니다.

  2. 다음 명령어를 실행하여 노드 풀을 만듭니다.

      gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --node-locations=${REGION}-a \
        --cluster=${CLUSTER_NAME} \
        --machine-type=g2-standard-8 \
        --num-nodes=1
    

    GKE는 노드마다 L4 GPU 하나가 포함된 단일 노드 풀을 만듭니다.

Cloud Storage 버킷 만들기

제공되는 선행 학습된 모델을 저장하기 위한 Cloud Storage 버킷을 만듭니다.

Cloud Shell에서 다음을 실행합니다.

gcloud storage buckets create gs://$GSBUCKET

GKE용 워크로드 아이덴티티 제휴를 사용하여 버킷에 액세스하도록 클러스터 구성

클러스터가 Cloud Storage 버킷에 액세스하도록 하려면 다음을 수행합니다.

  1. Google Cloud 서비스 계정을 생성합니다.
  2. 클러스터에 Kubernetes ServiceAccount를 만듭니다.
  3. Kubernetes ServiceAccount를 Google Cloud 서비스 계정에 바인딩합니다.

Google Cloud 서비스 계정 생성

  1. Google Cloud 콘솔에서 서비스 계정 만들기 페이지로 이동합니다.

    서비스 계정 만들기로 이동

  2. 서비스 계정 ID 필드에 gke-ai-sa를 입력합니다.

  3. 만들고 계속하기를 클릭합니다.

  4. 역할 목록에서 Cloud Storage > Storage Insights 수집기 서비스 역할을 선택합니다.

  5. 다른 역할 추가를 클릭합니다.

  6. 역할 선택 목록에서 Cloud Storage > 스토리지 객체 관리자 역할을 선택합니다.

  7. 계속을 클릭한 다음 완료를 클릭합니다.

클러스터에 Kubernetes ServiceAccount 만들기

Cloud Shell에서 다음을 수행합니다.

  1. Kubernetes 네임스페이스를 만듭니다.

    kubectl create namespace gke-ai-namespace
    
  2. 네임스페이스에 Kubernetes ServiceAccount를 만듭니다.

    kubectl create serviceaccount gpu-k8s-sa --namespace=gke-ai-namespace
    

Kubernetes ServiceAccount를 Google Cloud 서비스 계정에 바인딩

Cloud Shell에서 다음 명령어를 실행합니다.

  1. Google Cloud 서비스 계정에 IAM 바인딩을 추가합니다.

    gcloud iam service-accounts add-iam-policy-binding gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-ai-namespace/gpu-k8s-sa]"
    

    --member 플래그는 Google Cloud에서 Kubernetes ServiceAccount의 전체 ID를 제공합니다.

  2. Kubernetes ServiceAccount에 주석을 추가합니다.

    kubectl annotate serviceaccount gpu-k8s-sa \
        --namespace gke-ai-namespace \
        iam.gke.io/gcp-service-account=gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com
    

온라인 추론 서버 배포

각 온라인 추론 프레임워크는 특정 형식으로 사전 학습된 ML 모델을 찾습니다. 다음 섹션에서는 사용하려는 프레임워크에 따라 추론 서버를 배포하는 방법을 보여줍니다.

Triton

  1. Cloud Shell에서 사전 학습된 ML 모델을 Cloud Storage 버킷에 복사합니다.

    gsutil cp -r src/triton-model-repository gs://$GSBUCKET
    
  2. Kubernetes에서 프레임워크를 배포합니다.

    envsubst < src/gke-config/deployment-triton.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. GKE가 프레임워크를 배포했는지 검증합니다.

    kubectl get deployments --namespace=gke-ai-namespace
    

    프레임워크가 준비되었으면 출력이 다음과 비슷합니다.

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    triton-deployment    1/1     1            1           5m29s
    
  4. 배포에 액세스하도록 서비스를 배포합니다.

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-triton.yaml
    
  5. 외부 IP가 할당되었는지 확인합니다.

    kubectl get services --namespace=gke-ai-namespace
    

    출력은 다음과 비슷합니다.

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    triton-server   LoadBalancer   34.118.227.176   35.239.54.228   8000:30866/TCP,8001:31035/TCP,8002:30516/TCP   5m14s
    

    EXTERNAL-IP 열에서 triton-server의 IP 주소를 기록해 둡니다.

  6. 서비스 및 배포가 올바르게 작동하는지 확인합니다.

    curl -v EXTERNAL_IP:8000/v2/health/ready
    

    출력은 다음과 비슷합니다.

    ...
    < HTTP/1.1 200 OK
    < Content-Length: 0
    < Content-Type: text/plain
    ...
    

TF 제공

  1. Cloud Shell에서 사전 학습된 ML 모델을 Cloud Storage 버킷에 복사합니다.

    gsutil cp -r src/tfserve-model-repository gs://$GSBUCKET
    
  2. Kubernetes에서 프레임워크를 배포합니다.

    envsubst < src/gke-config/deployment-tfserve.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. GKE가 프레임워크를 배포했는지 검증합니다.

    kubectl get deployments --namespace=gke-ai-namespace
    

    프레임워크가 준비되었으면 출력이 다음과 비슷합니다.

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    tfserve-deployment   1/1     1            1           5m29s
    
  4. 배포에 액세스하도록 서비스를 배포합니다.

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-tfserve.yaml
    
  5. 외부 IP가 할당되었는지 확인합니다.

    kubectl get services --namespace=gke-ai-namespace
    

    출력은 다음과 비슷합니다.

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    tfserve-server  LoadBalancer   34.118.227.176   35.239.54.228   8500:30003/TCP,8000:32194/TCP                  5m14s
    

    EXTERNAL-IP 열에서 tfserve-server의 IP 주소를 기록해 둡니다.

  6. 서비스 및 배포가 올바르게 작동하는지 확인합니다.

    curl -v EXTERNAL_IP:8000/v1/models/mnist
    

    EXTERNAL_IP를 외부 IP 주소로 바꿉니다.

    출력은 다음과 비슷합니다.

    ...
    < HTTP/1.1 200 OK
    < Content-Type: application/json
    < Date: Thu, 12 Oct 2023 19:01:19 GMT
    < Content-Length: 154
    <
    {
      "model_version_status": [
            {
            "version": "1",
            "state": "AVAILABLE",
            "status": {
              "error_code": "OK",
              "error_message": ""
            }
          }
        ]
    }
    

모델 제공

Triton

  1. Cloud Shell에서 Python 가상 환경을 만듭니다.

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. 필요한 Python 패키지를 설치합니다.

    pip install -r src/client/triton-requirements.txt
    
  3. 이미지를 로드하여 Triton 추론 서버를 테스트합니다.

    cd src/client
    python triton_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

    다음을 바꿉니다.

    • EXTERNAL_IP: 외부 IP 주소입니다.
    • TEST_IMAGE: 테스트하려는 이미지에 해당하는 파일의 이름입니다. src/client/images에 저장된 이미지를 사용할 수 있습니다.

    사용하는 이미지에 따라 출력이 다음과 비슷합니다.

    Calling Triton HTTP Service      ->      Prediction result: 7
    

TF 제공

  1. Cloud Shell에서 Python 가상 환경을 만듭니다.

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. 필요한 Python 패키지를 설치합니다.

    pip install -r src/client/tfserve-requirements.txt
    
  3. 몇 가지 이미지로 TensorFlow Serving을 테스트합니다.

    cd src/client
    python tfserve_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

다음을 바꿉니다.

  • EXTERNAL_IP: 외부 IP 주소입니다.
  • TEST_IMAGE: 0~9 사이의 값입니다. src/client/images에 저장된 이미지를 사용할 수 있습니다.

사용하는 이미지에 따라 다음과 비슷한 출력이 표시됩니다.

  Calling TensorFlow Serve HTTP Service    ->      Prediction result: 5

삭제

이 가이드에서 만든 리소스에 대해 Google Cloud 계정에 비용이 발생하지 않도록 하려면 다음 중 하나를 수행합니다.

  • GKE 클러스터 유지: 클러스터의 Kubernetes 리소스 및 Google Cloud 리소스를 삭제합니다.
  • Google Cloud 프로젝트 유지: GKE 클러스터와 Google Cloud 리소스를 삭제합니다.
  • 프로젝트 삭제

클러스터의 Kubernetes 리소스 및 Google Cloud 리소스 삭제

  1. 배포한 Kubernetes 네임스페이스와 워크로드를 삭제합니다.

Triton

kubectl -n gke-ai-namespace delete -f src/gke-config/service-triton.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-triton.yaml
kubectl delete namespace gke-ai-namespace

TF 제공

kubectl -n gke-ai-namespace delete -f src/gke-config/service-tfserve.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-tfserve.yaml
kubectl delete namespace gke-ai-namespace
  1. Cloud Storage 버킷을 삭제합니다.

    1. 버킷 페이지로 이동합니다.

      버킷으로 이동

    2. PROJECT_ID-gke-bucket의 체크박스를 선택합니다.

    3. 삭제를 클릭합니다.

    4. 삭제를 확인하려면 DELETE를 입력하고 삭제를 클릭합니다.

  2. Google Cloud 서비스 계정을 삭제합니다.

    1. 서비스 계정 페이지로 이동합니다.

      서비스 계정으로 이동

    2. 프로젝트를 선택합니다.

    3. gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com의 체크박스를 선택합니다.

    4. 삭제를 클릭합니다.

    5. 삭제를 확인하려면 삭제를 클릭합니다.

GKE 클러스터 및 Google Cloud 리소스 삭제

  1. GKE 클러스터를 삭제합니다.

    1. 클러스터 페이지로 이동합니다.

      클러스터로 이동

    2. online-serving-cluster의 체크박스를 선택합니다.

    3. 삭제를 클릭합니다.

    4. 삭제를 확인하려면 online-serving-cluster를 입력하고 삭제를 클릭합니다.

  2. Cloud Storage 버킷을 삭제합니다.

    1. 버킷 페이지로 이동합니다.

      버킷으로 이동

    2. PROJECT_ID-gke-bucket의 체크박스를 선택합니다.

    3. 삭제를 클릭합니다.

    4. 삭제를 확인하려면 DELETE를 입력하고 삭제를 클릭합니다.

  3. Google Cloud 서비스 계정을 삭제합니다.

    1. 서비스 계정 페이지로 이동합니다.

      서비스 계정으로 이동

    2. 프로젝트를 선택합니다.

    3. gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com의 체크박스를 선택합니다.

    4. 삭제를 클릭합니다.

    5. 삭제를 확인하려면 삭제를 클릭합니다.

프로젝트 삭제

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

다음 단계