에이전트 개발 키트 (ADK) 및 자체 호스팅 LLM을 사용하여 GKE에 에이전트 AI 애플리케이션 배포

이 튜토리얼에서는 Google Kubernetes Engine (GKE)을 사용하여 컨테이너화된 에이전트 AI/ML 애플리케이션을 배포하고 관리하는 방법을 보여줍니다. Google 에이전트 개발 키트 (ADK)를 vLLM에서 제공하는 Llama 3.1과 같은 자체 호스팅 대규모 언어 모델 (LLM)과 결합하면 모델 스택을 완전히 제어하면서 AI 에이전트를 효율적이고 대규모로 운영할 수 있습니다. 이 튜토리얼에서는 Python 기반 에이전트를 개발에서 GPU 가속을 사용하는 GKE Autopilot 클러스터의 프로덕션 배포로 가져오는 엔드 투 엔드 프로세스를 안내합니다.

이 튜토리얼은 에이전트 AI/ML 애플리케이션을 서빙하기 위해 Kubernetes 컨테이너 조정 기능을 사용하는 데 관심이 있는 머신러닝 (ML) 엔지니어, 개발자, 클라우드 설계자를 대상으로 합니다. Google Cloud콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE Enterprise 사용자 역할 및 태스크를 참고하세요.

시작하기 전에 다음 사항을 숙지하세요.

배경

이 섹션에서는 이 튜토리얼에서 사용되는 주요 기술을 설명합니다.

에이전트 개발 키트(ADK)

에이전트 개발 키트(ADK)는 AI 에이전트를 개발하고 배포하기 위한 유연한 모듈식 프레임워크입니다. Gemini 및 Google 생태계에 최적화되어 있지만 ADK에서는 특정 모델이나 배포를 사용하지 않아도 되며 다른 프레임워크와의 호환성을 위해 빌드됩니다. ADK는 에이전트 개발이 소프트웨어 개발과 유사하도록 설계되어 개발자가 기본 작업부터 복잡한 워크플로에 이르기까지 다양한 에이전트 아키텍처를 쉽게 만들고, 배포하고, 조정할 수 있습니다.

자세한 내용은 ADK 문서를 참고하세요.

GKE 관리형 Kubernetes 서비스

Google Cloud 는 AI/ML 워크로드를 배포 및 관리하는 데 적합한 GKE 등의 다양한 서비스를 제공합니다. GKE는 컨테이너화된 애플리케이션을 쉽게 배포, 확장, 관리할 수 있는 관리형 Kubernetes 서비스입니다. GKE는 확장 가능한 리소스, 분산 컴퓨팅, 효율적인 네트워킹을 포함하여 LLM의 계산 요구를 처리하는 데 필요한 인프라를 제공합니다.

주요 Kubernetes 개념에 대한 자세한 내용은 Kubernetes 학습 시작을 참고하세요. GKE에 대한 정보 그리고 GKE가 Kubernetes를 확장, 자동화, 관리하는 데 어떻게 도움이 되는지 알아보려면 GKE 개요를 참고하세요.

vLLM

vLLM은 GPU의 제공 처리량을 늘릴 수 있는 고도로 최적화된 오픈소스 LLM 제공 프레임워크로, 다음과 같은 기능을 제공합니다.

  • PagedAttention으로 최적화된 Transformer 구현
  • 전체 제공 처리량을 개선하기 위한 연속적인 작업 일괄 처리
  • 여러 GPU에서 텐서 동시 로드 및 분산 서빙

자세한 내용은 vLLM 문서를 참고하세요.

환경 준비

이 튜토리얼에서는 Cloud Shell을 사용하여 Google Cloud에서 호스팅되는 리소스를 관리합니다. Cloud Shell에는 kubectl, terraform, Google Cloud CLI를 비롯해 이 튜토리얼에 필요한 소프트웨어가 사전 설치되어 있습니다.

Cloud Shell로 환경을 설정하려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 Cloud Shell 세션을 시작하고 Cloud Shell 활성화 아이콘 Cloud Shell 활성화를 클릭합니다. 그러면 Google Cloud 콘솔 창에서 세션이 실행됩니다.
  2. 기본 환경 변수를 설정합니다.

    gcloud config set project PROJECT_ID
    export GOOGLE_CLOUD_REGION=REGION
    export PROJECT_ID=PROJECT_ID
    

    다음 값을 바꿉니다.

    • PROJECT_ID: Google Cloud 프로젝트 ID
    • REGION: GKE 클러스터, Artifact Registry, 기타 리전별 리소스를 프로비저닝할 Google Cloud 리전(예: us-east4)입니다. L4 GPU 및 G2 머신 유형 인스턴스를 지원하는 리전을 지정해야 합니다. 리전 가용성을 확인하려면 Compute Engine 문서의 GPU 리전 및 영역을 참고하세요.

샘플 프로젝트 클론

  1. Cloud Shell 터미널에서 튜토리얼의 샘플 코드 저장소를 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  2. 가이드 디렉토리로 이동합니다.

    cd kubernetes-engine-samples/ai-ml/adk-vllm
    

Google Cloud 리소스 만들기 및 구성

에이전트를 배포하려면 먼저 필요한 Google Cloud리소스를 프로비저닝해야 합니다. gcloud CLI 또는 Terraform을 사용하여 GKE 클러스터와 Artifact Registry 저장소를 만들 수 있습니다.

gcloud

이 섹션에서는 GKE 클러스터와 Artifact Registry를 설정하는 gcloud CLI 명령어를 제공합니다.

  1. GKE 클러스터 만들기: GKE Autopilot 또는 Standard 클러스터에 컨테이너화된 에이전트형 애플리케이션을 배포할 수 있습니다. 완전 관리형 Kubernetes 환경에는 Autopilot 클러스터를 사용하는 것이 좋습니다. 워크로드에 가장 적합한 GKE 작업 모드를 선택하려면 GKE 작업 모드 정보를 참고하세요.

    Autopilot

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

    gcloud container clusters create-auto CLUSTER_NAME \
        --location=$GOOGLE_CLOUD_REGION
    

    CLUSTER_NAME을 GKE 클러스터 이름으로 바꿉니다.

    Autopilot을 사용하면 GKE가 워크로드의 리소스 요청에 따라 노드를 자동으로 프로비저닝합니다. LLM에 필요한 GPU는 nodeSelector을 사용하여 deploy-llm.yaml 매니페스트에서 요청됩니다.

    nvidia-l4 GPU에 nodeSelector 요청을 추가하려면 다음 단계를 따르세요.

    1. 편집기에서 kubernetes-engine-samples/ai-ml/adk-vllm/deploy-llm/deploy-llm.yaml을 엽니다.
    2. spec.template.spec 아래에 다음 nodeSelector를 추가합니다.

      nodeSelector:
      cloud.google.com/gke-accelerator: nvidia-l4
      

    표준

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

      gcloud container clusters create CLUSTER_NAME \
          --location=$GOOGLE_CLOUD_REGION
      

      CLUSTER_NAME을 GKE 클러스터 이름으로 바꿉니다.

    2. 다음 명령어를 실행하여 클러스터에 GPU 지원 노드 풀을 만듭니다.

      gcloud container node-pools create gpu-node-pool \
          --cluster=CLUSTER_NAME \
          --location=$GOOGLE_CLOUD_REGION \
          --machine-type=g2-standard-8 \
          --accelerator=type=nvidia-l4,count=1 \
          --enable-gvnic
      

      deploy-llm.yaml 파일은 G2 머신 시리즈에서 사용할 수 있는 nvidia-l4 GPU를 지정합니다. 이 머신 유형에 대한 자세한 내용은 Compute Engine 문서의 GPU 머신 유형을 참고하세요.

  2. Artifact Registry 저장소 만들기: 에이전트의 Docker 컨테이너 이미지를 안전하게 저장하고 관리할 Artifact Registry 저장소를 만듭니다.

    gcloud artifacts repositories create REPO_NAME \
        --repository-format=docker \
        --location=$GOOGLE_CLOUD_REGION
    

    REPO_NAME을 사용할 Artifact Registry 저장소의 이름 (예: adk-repo)으로 바꿉니다.

  3. 저장소 URL 가져오기: 이 명령어를 실행하여 저장소의 전체 경로를 확인합니다. 에이전트 이미지를 빌드할 때 이 형식을 사용하여 Docker 이미지에 태그를 지정합니다.

    gcloud artifacts repositories describe REPO_NAME \
        --location $GOOGLE_CLOUD_REGION
    

Terraform

이 섹션에서는 샘플 저장소에 포함된 Terraform 구성을 사용하여 Google Cloud 리소스를 자동으로 프로비저닝하는 방법을 설명합니다.

  1. Terraform 디렉터리로 이동: \terraform 디렉터리에는 GKE 클러스터와 기타 필수 리소스를 만드는 데 필요한 모든 구성 파일이 포함되어 있습니다.

    cd terraform
    
  2. Terraform 변수 파일 만들기: 제공된 변수 파일 예시 (example_vars.tfvars)를 복사하여 자체 vars.tfvars 파일을 만듭니다.

    cp example_vars.tfvars vars.tfvars
    

    편집기에서 vars.tfvars 파일을 열고 자리표시자 값을 특정 구성으로 바꿉니다. 최소한 PROJECT_ID를 Google Cloud 프로젝트 ID로 바꾸고 CLUSTER_NAME를 GKE 클러스터 이름으로 바꿔야 합니다.

  3. Terraform 초기화: Google Cloud에 필요한 공급자 플러그인을 다운로드하려면 다음 명령어를 실행합니다.

    terraform init
    
  4. 실행 계획 검토: 이 명령어는 Terraform에서 적용할 인프라 변경사항을 보여줍니다.

    terraform plan -var-file=vars.tfvars
    
  5. 구성 적용: Terraform 계획을 실행하여 Google Cloud 프로젝트에 리소스를 만듭니다. 메시지가 표시되면 yes로 확인합니다.

    terraform apply -var-file=vars.tfvars
    

이 명령어를 실행하면 Terraform이 GKE용 워크로드 아이덴티티 제휴를 비롯한 GKE 클러스터와 Artifact Registry 저장소를 프로비저닝하고 필요한 IAM 역할과 서비스 계정을 구성합니다.

Terraform 사용에 대한 자세한 내용은 Terraform으로 GKE 리소스 프로비저닝을 참고하세요.

클러스터와 통신하도록 kubectl을 구성합니다.

클러스터와 통신하도록 kubectl을 구성하려면 다음 명령어를 실행합니다.

gcloud container clusters get-credentials CLUSTER_NAME \
    --location=${GOOGLE_CLOUD_REGION}

CLUSTER_NAME을 GKE 클러스터 이름으로 바꿉니다.

에이전트 이미지 빌드

gcloud CLI 또는 Terraform을 사용하여 인프라를 만든 후 다음 단계에 따라 에이전트 애플리케이션을 빌드합니다.

  1. Cloud Build에 필요한 IAM 역할 부여: Cloud Build 서비스에는 에이전트의 컨테이너 이미지를 Artifact Registry에 푸시할 권한이 필요합니다. Cloud Build에서 사용하는 Compute Engine 기본 서비스 계정에 roles/artifactregistry.writer 역할을 부여합니다.

    1. Compute Engine 기본 서비스 계정의 이메일을 구성합니다.

      export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
      export COMPUTE_SA_EMAIL=${PROJECT_NUMBER}-compute@developer.gserviceaccount.com
      
    2. 서비스 계정에 roles/artifactregistry.writer 역할을 부여합니다.

      gcloud projects add-iam-policy-binding $PROJECT_ID \
          --member=serviceAccount:${COMPUTE_SA_EMAIL} \
          --role=roles/artifactregistry.writer
      
  2. 에이전트 컨테이너 이미지 빌드 및 푸시: 프로젝트 루트 디렉터리 (adk/llama/vllm)에서 다음 명령어를 실행하여 Docker 이미지를 빌드하고 Artifact Registry에 푸시합니다.

    export IMAGE_URL="${GOOGLE_CLOUD_REGION}-docker.pkg.dev/${PROJECT_ID}/REPO_NAME/adk-agent:latest"
    gcloud builds submit --tag $IMAGE_URL
    
  3. 이미지가 푸시되었는지 확인: 빌드 프로세스가 성공적으로 완료되면 저장소의 이미지를 나열하여 에이전트의 컨테이너 이미지가 Artifact Registry에 푸시되었는지 확인합니다.

    gcloud artifacts docker images list ${GOOGLE_CLOUD_REGION}-docker.pkg.dev/${PROJECT_ID}/REPO_NAME
    

    방금 푸시하고 latest로 태그한 이미지가 나열된 출력이 표시됩니다.

모델 배포

GKE 클러스터를 설정하고 에이전트 이미지를 빌드한 후 다음 단계는 자체 호스팅 Llama 3.1 모델을 클러스터에 배포하는 것입니다. 이렇게 하려면 Hugging Face에서 모델을 가져와 클러스터 내에서 내부적으로 제공하는 사전 구성된 vLLM 추론 서버를 배포합니다.

  1. Hugging Face 사용자 인증 정보용 Kubernetes 보안 비밀 만들기: GKE 클러스터가 게이트된 Llama 3.1 모델을 다운로드하도록 허용하려면 Hugging Face 토큰을 Kubernetes 보안 비밀로 제공해야 합니다. deploy-llm.yaml 매니페스트는 인증에 이 비밀을 사용하도록 구성됩니다.

    kubectl create secret generic hf-secret \
        --from-literal=hf-token-secret=HUGGING_FACE_TOKEN
    

    HUGGING_FACE_TOKEN을 토큰으로 바꿉니다.

  2. 매니페스트 보기: 프로젝트 루트 디렉터리(adk/llama/vllm)에서 모델 배포 매니페스트가 포함된 /deploy-llm 디렉터리로 이동합니다.

    cd deploy-llm
    
  3. 매니페스트 적용: 다음 명령어를 실행하여 deploy-llm.yaml 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f deploy-llm.yaml
    

    이 명령어는 다음과 같은 세 개의 Kubernetes 리소스를 만듭니다.

    • meta-llama/Llama-3.1-8B-Instruct 모델을 사용하도록 구성된 vLLM 서버를 실행하는 배포입니다.
    • 내부 클러스터 IP 주소에서 vLLM 서버를 노출하여 ADK 에이전트가 서버와 통신할 수 있도록 하는 vllm-llama3-service라는 서비스
    • Llama 3.1 모델에 필요한 Jinja 채팅 템플릿이 포함된 ConfigMap입니다.
  4. 모델 배포 확인: vLLM 서버가 Hugging Face에서 모델 파일을 가져옵니다. 이 프로세스는 몇 분이 소요될 수 있습니다. 포드의 상태를 모니터링하여 준비 상태를 확인할 수 있습니다.

    1. 배포를 사용할 수 있을 때까지 기다립니다.

      kubectl wait --for=condition=available --timeout=600s deployment/vllm-llama3-deployment
      
    2. 실행 중인 포드의 로그를 확인하여 서버가 성공적으로 시작되었는지 확인합니다.

      export LLM_POD=$(kubectl get pods -l app=vllm-llama3 -o jsonpath='{.items[0].metadata.name}')
      kubectl logs -f $LLM_POD
      

      LLM 서버가 시작되고 API 경로가 사용 가능함을 나타내는 다음과 비슷한 로그 출력이 표시되면 배포가 준비된 것입니다.

      INFO 07-16 14:15:16 api_server.py:129] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
      
    3. 모델 서버에 직접 요청을 보내 LLM이 준비되었는지 확인합니다. 이렇게 하려면 새 Cloud Shell 터미널을 열고 다음 명령어를 실행하여 vllm-llama3-service를 로컬 머신으로 전달합니다.

      kubectl port-forward service/vllm-llama3-service 8000:8000
      
    4. 다른 터미널에서 curl를 사용하여 모델의 API 엔드포인트에 샘플 요청을 보냅니다. 예를 들면 다음과 같습니다.

      curl -X POST http://localhost:8000/v1/completions \
        -H "Content-Type: application/json" \
        -d '{
          "model": "meta-llama/Llama-3.1-8B-Instruct",
          "prompt": "Hello!",
          "max_tokens": 10
        }'
      

      명령어가 성공적인 JSON 응답을 반환하면 LLM이 준비된 것입니다. 이제 터미널 창으로 돌아가 Ctrl+C를 눌러 포트 전달 프로세스를 종료하고 에이전트를 배포하면 됩니다.

에이전트 애플리케이션 배포

다음 단계는 ADK 기반 에이전트 애플리케이션을 배포하는 것입니다.

  1. /deploy-agent 디렉터리로 이동: 프로젝트 루트 디렉터리 (adk/llama/vllm)에서 에이전트의 소스 코드와 배포 매니페스트가 포함된 /deploy-agent 디렉터리로 이동합니다.

    cd ../deploy-agent
    
  2. 에이전트 배포 매니페스트를 업데이트합니다.

    1. 샘플 deploy-agent.yaml 매니페스트 파일에는 컨테이너 이미지 URL에 프로젝트 ID 자리표시자가 포함되어 있습니다. 자리표시자를 Google Cloud 프로젝트 ID로 바꿔야 합니다.

      image: us-central1-docker.pkg.dev/PROJECT_ID/adk-repo/adk-agent:latest
      

      이 치환을 인플레이스로 실행하려면 다음 명령어를 실행하면 됩니다.

      sed -i "s/<PROJECT_ID>/$PROJECT_ID/g" deploy-agent.yaml
      
    2. readinessProbe 경로가 /dev-ui 대신 /로 설정되어 있는지 확인합니다. 이 치환을 인플레이스로 실행하려면 다음 명령어를 실행하면 됩니다.

      sed -i "s|path: /dev-ui/|path: /|g" deploy-agent.yaml
      
  3. 매니페스트 적용: 다음 명령어를 실행하여 deploy-agent.yaml 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f deploy-agent.yaml
    

    이 명령어는 Kubernetes 리소스 두 개를 만듭니다.

    • 커스텀 빌드 에이전트 컨테이너 이미지를 실행하는 adk-agent라는 배포
    • 테스트를 위해 액세스할 수 있도록 에이전트 애플리케이션을 노출하는 NodePort 유형의 adk-agent라는 서비스
  4. 에이전트 배포 확인: 포드 상태를 확인하여 올바르게 실행 중인지 확인합니다.

    1. 배포를 사용할 수 있을 때까지 기다립니다.

      kubectl wait --for=condition=available --timeout=300s deployment/adk-agent
      
    2. 실행 중인 에이전트 포드의 로그를 봅니다.

      export AGENT_POD=$(kubectl get pods -l app=adk-agent -o jsonpath='{.items[0].metadata.name}')
      kubectl logs -f $AGENT_POD
      

Uvicorn 서버가 실행 중이며 요청을 수락할 준비가 되었음을 나타내는 다음과 비슷한 로그 출력이 표시되면 배포가 성공한 것입니다.

INFO:     Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)

배포된 에이전트 테스트

vLLM 서버와 에이전트 애플리케이션을 모두 성공적으로 배포한 후 에이전트의 웹 UI와 상호작용하여 엔드 투 엔드 기능을 테스트할 수 있습니다.

  1. 에이전트의 서비스를 로컬 머신으로 전달: adk-agent 서비스는 NodePort 유형이지만 Cloud Shell 환경에서 액세스하는 가장 직접적인 방법은 kubectl port-forward 명령어를 사용하는 것입니다. 다음 명령어를 실행하여 에이전트의 포드에 대한 보안 터널을 만듭니다.

    kubectl port-forward $AGENT_POD 8001:8001
    
  2. 에이전트의 웹 UI 액세스: Cloud Shell에서 웹 미리보기 버튼을 클릭하고 포트 8001에서 미리보기를 선택합니다. 새 브라우저 탭이 열리고 에이전트의 채팅 인터페이스가 표시됩니다.

  3. 에이전트와 상호작용: 에이전트의 get_weather 도구를 호출하는 질문을 합니다. 예를 들면 다음과 같습니다.

    What's the weather like in Tokyo?
    

    에이전트는 먼저 LLM을 호출하여 의도를 파악하고 get_weather 도구를 사용해야 하는지 확인합니다. 그런 다음 'Tokyo'를 매개변수로 사용하여 도구를 실행합니다. 마지막으로 도구의 출력을 사용하여 대답을 생성합니다. 다음과 비슷한 응답이 표시됩니다.

      The weather in Tokyo is 25°C and sunny.
    
  4. (선택사항) 로그에서 도구 호출 확인: 각 포드의 로그를 확인하여 에이전트와 LLM의 상호작용 및 도구 실행을 관찰할 수 있습니다.

    1. 에이전트 포드 로그: 새 터미널에서 adk-agent 포드의 로그를 확인합니다. 도구 호출과 그 결과가 표시됩니다.

      kubectl logs -f $AGENT_POD
      

      출력에는 도구가 호출되고 결과가 처리되는 것으로 표시됩니다.

    2. LLM 포드 로그: vllm-llama3-deployment 포드의 로그를 확인하여 에이전트의 수신 요청을 확인합니다.

      kubectl logs -f $LLM_POD
      

      로그에는 시스템 메시지, 질문, get_weather 도구의 정의를 비롯해 에이전트가 LLM에 보낸 전체 프롬프트가 표시됩니다.

테스트를 완료한 후 터미널 창으로 돌아가 Ctrl+C를 눌러 port-forward 프로세스를 종료할 수 있습니다.