GKE 추론 게이트웨이를 사용하여 LLM 서빙

이 튜토리얼에서는 GKE Inference Gateway를 사용하여 Google Kubernetes Engine(GKE)에 대규모 언어 모델(LLM)을 배포하는 방법을 설명합니다. 이 튜토리얼에는 클러스터 설정, 모델 배포, GKE Inference Gateway 구성, LLM 요청 처리에 관한 단계가 포함되어 있습니다.

이 튜토리얼은 GKE Inference Gateway를 사용하여 GKE에서 LLM 애플리케이션을 배포하고 관리하려는 머신러닝(ML) 엔지니어, 플랫폼 관리자 및 운영자, 데이터 및 AI 전문가를 대상으로 작성되었습니다.

이 페이지를 읽기 전 다음 내용을 숙지해야 합니다.

GKE Inference Gateway는 Google Kubernetes Engine (GKE) 게이트웨이를 개선하여 GKE에서 생성형 AI 애플리케이션과 워크로드 서빙을 최적화합니다. 이는 AI 워크로드의 효율적인 관리 및 확장을 제공하고, 지연 시간과 같은 워크로드별 성능 목표를 사용 설정하고, 리소스 활용률, 모니터링 가능성, AI 안전성을 향상시킵니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
  • 필요한 경우 Compute Engine API, Kubernetes Engine API, Network Services API, Model Armor API를 사용 설정합니다.

    API 액세스 사용 설정으로 이동하여 안내를 따릅니다.

  • 프로젝트에 roles/container.admin, roles/iam.serviceAccountAdmin 역할이 있는지 확인합니다.

  • 프로젝트에 H100 GPU 할당량이 충분한지 확인합니다. 자세한 내용은 GPU 할당량 계획배정 할당량을 참조하세요.

  • Hugging Face 계정이 아직 없으면 이 계정을 만듭니다. 이 튜토리얼의 모델 리소스에 액세스하려면 이 권한이 필요합니다.

  • Llama 3.1 모델에 대한 액세스 권한을 요청하고 액세스 토큰을 생성합니다. 이 모델에 액세스하려면 Hugging Face에서 요청이 승인되어야 하며 액세스 권한이 부여되지 않으면 배포가 실패합니다.

    • 라이선스 동의 계약 서명: Llama 3.1 모델을 사용하려면 동의 계약에 서명해야 합니다. Hugging Face에서 모델 페이지로 이동하여 계정을 확인하고 약관에 동의합니다.
    • 액세스 토큰 생성: 모델에 액세스하려면 Hugging Face 토큰이 필요합니다. Hugging Face 계정에서 내 프로필 > 설정 > 액세스 토큰으로 이동하여 읽기 권한이 있는 새 토큰을 만들고 클립보드에 복사합니다.

GKE Gateway Controller 요구사항

  • GKE 버전 1.32.3 이상
  • Google Cloud CLI 버전 407.0.0 이상
  • Gateway API는 VPC 기반 클러스터에서만 지원됩니다.
  • 프록시 전용 서브넷을 사용 설정해야 합니다.
  • 클러스터에 HttpLoadBalancing 부가기능이 사용 설정되어 있어야 합니다.
  • Istio를 사용하는 경우 Istio를 다음 버전 중 하나로 업그레이드해야 합니다.
    • 1.15.2 이상
    • 1.14.5 이상
    • 1.13.9 이상
  • 공유 VPC를 사용하는 경우 호스트 프로젝트에서 서비스 프로젝트에 대해 GKE 서비스 계정에 Compute Network User 역할을 할당해야 합니다.

제한 및 한도

다음 제한사항이 적용됩니다.

  • 멀티 클러스터 게이트웨이는 지원되지 않습니다.
  • GKE Inference Gateway는 gke-l7-regional-external-managedgke-l7-rilb GatewayClass 리소스에서만 지원됩니다.
  • 교차 리전 내부 애플리케이션 부하 분산기는 지원되지 않습니다.
  • InferencePool에는 최대 8개의 targetPorts가 있을 수 있습니다.

GKE Inference Gateway 구성

GKE Inference Gateway를 구성하려면 다음 예시를 참조하세요. 한 팀이 vLLMLlama3 모델을 실행하고 'food-review' 및 'cad-fabricator'라는 두 개의 서로 다른 LoRA 미세 조정 어댑터를 적극적으로 실험합니다.

GKE Inference Gateway 구성의 개략적인 워크플로는 다음과 같습니다.

  1. 환경 준비: 필요한 인프라와 구성요소를 설정합니다.
  2. 추론 풀 만들기: InferencePool 커스텀 리소스를 사용하여 모델 서버 풀을 정의합니다.
  3. 추론 목표 지정: InferenceObjective 커스텀 리소스를 사용하여 추론 목표를 지정합니다.
  4. 게이트웨이 만들기: 게이트웨이 API를 사용하여 추론 서비스를 노출합니다.
  5. HTTPRoute 만들기: HTTP 트래픽이 추론 서비스로 라우팅되는 방식을 정의합니다.
  6. 추론 요청 보내기: 배포된 모델에 요청을 보냅니다.

게이트웨이 만들기

게이트웨이 리소스는 Kubernetes 클러스터로 들어오는 외부 트래픽의 진입점입니다. 수신 연결을 수락하는 리스너를 정의합니다.

GKE Inference Gateway는 다음 게이트웨이 클래스와 함께 작동합니다.

  • gke-l7-rilb: 리전 내부 애플리케이션 부하 분산기의 경우
  • gke-l7-regional-external-managed: 리전 외부 애플리케이션 부하 분산기의 경우

자세한 내용은 게이트웨이 클래스 문서를 참조하세요.

게이트웨이를 만들려면 다음 단계를 수행하세요.

  1. 다음 샘플 매니페스트를 gateway.yaml로 저장합니다.

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
    spec:
      gatewayClassName: GATEWAY_CLASS
      listeners:
        - protocol: HTTP
          port: 80
          name: http
    

    다음을 바꿉니다.

    • GATEWAY_NAME: 게이트웨이 리소스의 고유한 이름. 예를 들면 inference-gateway입니다.
    • GATEWAY_CLASS: 사용할 게이트웨이 클래스. 예를 들면 gke-l7-regional-external-managed입니다.
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f gateway.yaml
    

참고: HTTPS로 게이트웨이를 보호하기 위해 TLS를 구성하는 방법에 대한 자세한 내용은 TLS 구성에 관한 GKE 문서를 참조하세요.

개발 환경 준비

  1. Helm을 설치합니다.

  2. GKE 클러스터를 만듭니다.

    • 버전 1.32.3 이상으로 GKE Autopilot 또는 Standard 클러스터를 만듭니다. 원클릭 배포 참조 설정은 cluster-toolkit gke-a3-highgpu 샘플을 참조하세요.
    • 선호하는 컴퓨팅 제품군과 가속기로 노드를 구성합니다.
    • 선택한 가속기, 모델, 성능 요구사항에 따라 사전 구성되고 테스트된 배포 매니페스트를 위해 GKE Inference Quickstart를 사용하세요.
  3. GKE 클러스터에 필요한 커스텀 리소스 정의(CRD)를 설치합니다.

    • GKE 버전 1.34.0-gke.1626000 이상에서는 InferencePool CRD가 기본적으로 포함됩니다. 따라서 알파 InferenceObjective CRD만 설치합니다.

      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/raw/v1.5.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml
      
    • 1.34.0-gke.1626000 이전 버전의 GKE의 경우 v1 InferencePool과 알파 InferenceObjective CRD를 모두 설치합니다.

      kubectl apply -f  https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v1.5.0/manifests.yaml
      

      자세한 내용은 호환성 매트릭스를 참조하세요.

  4. v1.32.2-gke.1182001 이전 버전의 GKE를 사용하고 GKE Inference Gatewa와 함께 Model Armor를 사용하려면 트래픽 및 라우팅 확장 프로그램 CRD를 설치해야 합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficextensions.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcproutingextensions.yaml
    
  5. 다음 환경 변수를 설정합니다.

    export GAIE_VERSION=v1.5.0
    export GUIDE_NAME="optimized-baseline"
    export NAMESPACE=llm-d-optimized-baseline
    export INFRA_PROVIDER=gke   # gke | base
    
  6. llm-d 엔드포인트 선택기 (EPP)에 필요한 Gateway API 추론 확장 프로그램 커스텀 리소스 정의 (CRD)를 설치합니다.

    kubectl apply -k \
      "https://github.com/kubernetes-sigs/gateway-api-inference-extension/config/crd?ref=${GAIE_VERSION}"
    
  7. 타겟 네임스페이스를 만듭니다.

    kubectl create namespace ${NAMESPACE}
    

모델 서버 및 모델 배포 만들기

이 섹션에서는 모델 서버와 모델을 배포하는 방법을 보여줍니다. 이 예시에서는 Llama3 모델이 있는 vLLM 모델 서버를 사용합니다. 배포에 app:vllm-llama3-8b-instruct 라벨이 지정됩니다. 이 배포에서는 Hugging Face의 food-reviewcad-fabricator라는 두 개의 LoRA 어댑터도 사용합니다.

자체 모델 서버 컨테이너와 모델, 서빙 포트, 배포 이름으로 이 예시를 조정할 수 있습니다. 배포에서 LoRA 어댑터를 구성하거나 기본 모델을 배포할 수도 있습니다. 다음 단계에서는 필요한 Kubernetes 리소스를 만드는 방법을 설명합니다.

  1. Hugging Face 토큰을 저장할 Kubernetes 보안 비밀을 만듭니다. 이 토큰은 기본 모델과 LoRA 어댑터에 액세스하는 데 사용됩니다.

    kubectl create secret generic hf-token --from-literal=token=HF_TOKEN
    

    HF_TOKEN을 Hugging Face 토큰으로 바꿉니다.

  2. llm-d 최적화 기준 가이드에서 GKE 전용 Kustomize 오버레이를 사용하여 vLLM 모델 서버를 배포합니다. INFRA_PROVIDER=gke를 설정하면 Cloud Monitoring 통합을 비롯한 GKE 관련 구성이 적용됩니다.

    kubectl apply -n ${NAMESPACE} \
      -k guides/${GUIDE_NAME}/modelserver/gpu/vllm/${INFRA_PROVIDER}/
    

참고: GKE는 기본적으로 자동 애플리케이션 모니터링을 제공합니다. llm-d 모니터링 스택은 GKE에 필요하지 않지만 원하는 경우 사용할 수 있습니다.

모델 서버에 여러 포트가 필요한 경우 컨테이너 사양이 각 포트를 노출하는지 확인하세요. 다음 예에서는 컨테이너가 세 개의 포트를 노출하는 배포를 정의합니다.

멀티포트 배포 예

apiVersion: apps/v1
kind: Deployment
metadata:
  name: multiport-model-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: multiport-model-server
  template:
    metadata:
      labels:
        app: multiport-model-server
    spec:
      containers:
      - name: model-server
        image: your-model-server-image
        ports:
        - containerPort: 8080
        - containerPort: 8081
        - containerPort: 9000

추론 풀 만들기

InferencePool Kubernetes 커스텀 리소스는 공통 기본 대규모 언어 모델 (LLM) 및 컴퓨팅 구성이 있는 포드 그룹을 정의합니다. selector 필드는 이 풀에 속하는 포드를 지정합니다. 이 선택기의 라벨은 모델 서버 포드에 적용된 라벨과 정확히 일치해야 합니다. targetPorts 필드는 포드 내에서 모델 서버가 사용하는 포트를 정의합니다. 포트를 최대 8개까지 지정할 수 있습니다. extensionRef 필드는 추론 풀에 추가 기능을 제공하는 확장 프로그램 서비스를 참조합니다. InferencePool을 사용하면 GKE Inference Gateway가 모델 서버 포드로 트래픽을 라우팅할 수 있습니다.

다음 InferencePool 매니페스트는 모델 서버 배포에서 노출하는 포트에 해당하는 여러 targetPorts를 지정합니다.

Multiport InferencePool 예시

apiVersion: inference.networking.k8s.io/v1
kind: InferencePool
metadata:
  name: my-multiport-pool
  namespace: default
spec:
  selector:
    matchLabels:
      app: multiport-model-server
  targetPorts:
    - number: 8080
    - number: 8081
    - number: 9000

InferencePool을 만들기 전에 InferencePool이 선택하는 모델 서버 포드가 이미 실행 중인지 확인합니다.

llm-d GitHub 저장소에서 InferencePool의 레시피와 추천을 클론합니다. 이 단계는 필수입니다.

git clone https://github.com/llm-d/llm-d -b v0.7.0 && cd llm-d

Helm을 사용하여 InferencePool을 만들려면 다음 단계를 따르세요.

helm install ${GUIDE_NAME} \
  -f guides/recipes/scheduler/base.values.yaml \
  -f guides/${GUIDE_NAME}/scheduler/${GUIDE_NAME}.values.yaml \
  --set provider.name=gke \
  --set inferenceExtension.monitoring.gke.enabled=true \
  -n ${NAMESPACE} \
  --version ${GAIE_VERSION} \
  oci://LLM_D_REGISTRY_PATH

다음을 바꿉니다.

  • GAIE_VERSION: Helm 차트의 버전입니다. 예를 들면 v1.5.0입니다.
  • LLM_D_REGISTRY_PATH: Helm 차트의 OCI 레지스트리 경로입니다. 예를 들면 registry.k8s.io/gateway-api-inference-extension/charts/inferencepool입니다.

guides/recipes/scheduler/base.values.yaml 파일에서 다음 필드를 모델 배포 포드의 라벨과 일치하도록 변경합니다.

  • inferencePool.modelServers.matchLabels: 모델 서버 포드를 선택하는 데 사용되는 라벨의 키와 값입니다.

    참고: 키와 값이 optimized-baseline 가이드 예시와 일치하므로 배포 포드 라벨과 일치하도록 바꿉니다.

모니터링의 경우 Google Cloud Managed Service for Prometheus의 측정항목 스크래핑이 기본적으로 사용 설정됩니다.

  • 이 기능을 사용 중지하려면 명령어에 --set inferenceExtension.monitoring.prometheus.enabled=false 플래그를 추가합니다.
  • GKE Autopilot 클러스터에서 기본 모니터링을 사용하는 경우 --set provider.gke.autopilot=true 플래그도 추가해야 합니다.

Helm 설치는 필요한 시간 제한 정책, 엔드포인트 선택기, 모니터링 가능성에 필요한 포드를 자동으로 설치합니다.

이렇게 하면 포드 내의 모델 엔드포인트 서비스를 참조하는 추론 풀 객체 vllm-llama3-8b-instruct가 생성됩니다. 또한 생성된 InferencePool에 대해 app:vllm-llama3-8b-instruct-epp라는 엔드포인트 선택기 배포가 생성됩니다.

HTTPRoute 만들기

HTTPRoute 리소스는 GKE Gateway가 수신되는 HTTP 요청을 InferencePool과 같은 백엔드 서비스로 라우팅하는 방법을 정의합니다. HTTPRoute 리소스는 일치 규칙 (예: 헤더 또는 경로)과 트래픽을 전달해야 하는 백엔드를 지정합니다.

  1. HTTPRoute를 만들려면 다음 샘플 매니페스트를 httproute.yaml로 저장합니다.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: HTTPROUTE_NAME
    spec:
      parentRefs:
      - name: GATEWAY_NAME
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: PATH_PREFIX
        backendRefs:
        - name: INFERENCE_POOL_NAME
          group: "inference.networking.k8s.io"
          kind: InferencePool
    

    다음을 바꿉니다.

    • HTTPROUTE_NAME: HTTPRoute 리소스의 고유한 이름. 예를 들면 my-route입니다.
    • GATEWAY_NAME: 만든 Gateway 리소스의 이름. 예를 들면 inference-gateway입니다.
    • PATH_PREFIX: 수신 요청을 일치시키는 데 사용하는 경로 접두사. 예를 들어 /는 모두 일치를 의미합니다.
    • INFERENCE_POOL_NAME: 트래픽을 라우트하려는 InferencePool 리소스의 이름. 예를 들면 vllm-llama3-8b-instruct입니다.
  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f httproute.yaml
    

추론 목표 지정

InferenceObjective 커스텀 리소스를 사용하면 요청의 우선순위를 지정할 수 있습니다.

InferenceObjective 리소스의 metadata.name 필드는 추론 목표의 이름을 지정하고, Priority 필드는 서빙의 중요도를 지정하며, poolRef 필드는 모델이 서빙되는 InferencePool을 지정합니다.

apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceObjective
metadata:
  name: NAME
spec:
  priority: VALUE
  poolRef:
    name: INFERENCE_POOL_NAME
    group: "inference.networking.k8s.io"

다음을 바꿉니다.

  • NAME: 추론 목표의 이름입니다. 예를 들면 food-review입니다.
  • VALUE: 추론 목표의 우선순위입니다. 이는 정수값으로, 값이 클수록 더 중요한 요청임을 나타냅니다. 예: 10
  • INFERENCE_POOL_NAME: 이전 단계에서 만든 InferencePool의 이름입니다. 예를 들면 vllm-llama3-8b-instruct입니다.

InferenceObjective을 만들려면 다음 단계를 따르세요.

  1. 다음 매니페스트를 inference-objectives.yaml로 저장합니다. 이 매니페스트는 InferenceObjective 리소스 두 개를 만듭니다. 첫 번째는 우선순위가 10인 vllm-llama3-8b-instruct InferencePool에서 food-review 추론 목표를 구성합니다. 두 번째는 llama3-base-model 추론 목표를 우선순위 20으로 더 높게 제공하도록 구성합니다.

    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceObjective
    metadata:
      name: food-review
    spec:
      priority: 10
      poolRef:
        name: vllm-llama3-8b-instruct
        group: "inference.networking.k8s.io"
    ---
    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceObjective
    metadata:
      name: llama3-base-model
    spec:
      priority: 20 # Higher priority
      poolRef:
        name: vllm-llama3-8b-instruct
    
  2. 샘플 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f inference-objectives.yaml
    

배포를 확인합니다.

모든 구성요소가 실행 중인지 확인하려면 다음 명령어를 실행하세요.

kubectl get inferencepool
kubectl get inferenceobjective
kubectl get pods -l app=vllm-llama3-8b-instruct-epp

추론 요청 보내기

GKE Inference Gateway를 구성한 후 배포된 모델에 추론 요청을 보낼 수 있습니다. 이를 통해 입력 프롬프트와 지정된 파라미터를 기반으로 텍스트를 생성할 수 있습니다.

추론 요청을 보내려면 다음 단계를 따르세요.

  1. 다음 환경 변수를 설정합니다.

    export GATEWAY_NAME=GATEWAY_NAME
    export PORT_NUMBER=PORT_NUMBER # Use 80 for HTTP
    

    다음을 바꿉니다.

    • GATEWAY_NAME: 게이트웨이 리소스의 이름
    • PORT_NUMBER: 게이트웨이에서 구성한 포트 번호
  2. 게이트웨이 엔드포인트를 가져오려면 다음 명령어를 실행합니다.

    echo "Waiting for the Gateway IP address..."
    IP=""
    while [ -z "$IP" ]; do
      IP=$(kubectl get gateway/${GATEWAY_NAME} -o jsonpath='{.status.addresses[0].value}' 2>/dev/null)
      if [ -z "$IP" ]; then
        echo "Gateway IP not found, waiting 5 seconds..."
        sleep 5
      fi
    done
    
    echo "Gateway IP address is: $IP"
    PORT=${PORT_NUMBER}
    
  3. curl을 사용하여 /v1/completions 엔드포인트에 요청을 전송하려면 다음 명령어를 실행합니다.

    curl -i -X POST ${IP}:${PORT}/v1/completions \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer $(gcloud auth application-default print-access-token)' \
    -d '{
        "model": "MODEL_NAME",
        "prompt": "PROMPT_TEXT",
        "max_tokens": MAX_TOKENS,
        "temperature": "TEMPERATURE"
    }'
    

    다음을 바꿉니다.

    • MODEL_NAME: 사용할 모델 또는 LoRA 어댑터의 이름
    • PROMPT_TEXT: 모델의 입력 프롬프트
    • MAX_TOKENS: 응답에서 생성할 최대 토큰 수
    • TEMPERATURE: 출력의 무작위성 제어. 값을 0으로 설정하면 결정론적 출력을 얻을 수 있고, 더 큰 값을 사용하면 더 창의적인 출력을 얻을 수 있습니다.

다음 예시에서는 GKE Inference Gateway에 샘플 요청을 보내는 방법을 보여줍니다.

curl -i -X POST ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -H 'Authorization: Bearer $(gcloud auth application-default print-access-token)' -d '{
    "model": "food-review-1",
    "prompt": "What is the best pizza in the world?",
    "max_tokens": 2048,
    "temperature": 0
}'

다음 동작에 유의하세요.

  • 요청 본문: 요청 본문에는 stop, top_p와 같은 추가 파라미터가 포함될 수 있습니다. 전체 옵션 목록은 OpenAI API 사양을 참조하세요.
  • 오류 처리: 응답의 잠재적 오류를 처리하기 위해 클라이언트 코드에서 적절한 오류 처리를 구현합니다. 예를 들어 curl 응답의 HTTP 상태 코드를 확인합니다. 200이 아닌 상태 코드는 일반적으로 오류를 나타냅니다.
  • 인증 및 승인: 프로덕션 배포의 경우 인증 및 승인 메커니즘으로 API 엔드포인트를 보호합니다. 요청에 적절한 헤더(예: Authorization)를 포함합니다.

다음 단계