Men-deploy aplikasi Ray Serve dengan model Stable Diffusion di Google Kubernetes Engine (GKE)

Panduan ini memberikan contoh cara men-deploy dan menayangkan model Stable Diffusion di Google Kubernetes Engine (GKE) menggunakan Ray Serve dan add-on Ray Operator sebagai contoh penerapan.

Tentang Ray dan Ray Serve

Ray adalah framework komputasi skalabel open source untuk aplikasi AI/ML. Ray Serve adalah library inferensi model untuk Ray yang digunakan untuk menskalakan dan menyajikan model di lingkungan terdistribusi. Untuk mengetahui informasi selengkapnya, lihat Ray Serve dalam dokumentasi Ray.

Anda dapat menggunakan resource RayCluster atau RayService untuk men-deploy aplikasi Ray Serve. Anda harus menggunakan resource RayService dalam produksi karena alasan berikut:

  • Update di tempat untuk aplikasi RayService
  • Upgrade tanpa periode nonaktif untuk resource RayCluster
  • Aplikasi Ray Serve dengan ketersediaan tinggi

Tujuan

Panduan ini ditujukan untuk pelanggan AI Generatif, pengguna baru atau lama GKE, Engineer ML, engineer MLOps (DevOps), atau administrator platform yang tertarik menggunakan kemampuan orkestrasi container Kubernetes untuk menyalurkan model menggunakan Ray.

  • Buat cluster GKE dengan node pool GPU.
  • Buat cluster Ray menggunakan resource kustom RayCluster.
  • Jalankan aplikasi Ray Serve.
  • Deploy resource kustom RayService.

Biaya

Dalam dokumen ini, Anda akan menggunakan komponen Google Cloudyang dapat ditagih sebagai berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga.

Pengguna Google Cloud baru mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, baca bagian Pembersihan.

Sebelum memulai

Cloud Shell telah diinstal dengan software yang Anda perlukan untuk tutorial ini, termasuk kubectl dan gcloud CLI. Jika Anda tidak menggunakan Cloud Shell, Anda harus menginstal gcloud CLI.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Jika Anda menggunakan penyedia identitas (IdP) eksternal, Anda harus login ke gcloud CLI dengan identitas gabungan Anda terlebih dahulu.

  4. Untuk melakukan inisialisasi gcloud CLI, jalankan perintah berikut:

    gcloud init
  5. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. Jika Anda menggunakan penyedia identitas (IdP) eksternal, Anda harus login ke gcloud CLI dengan identitas gabungan Anda terlebih dahulu.

  10. Untuk melakukan inisialisasi gcloud CLI, jalankan perintah berikut:

    gcloud init
  11. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable container.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/container.clusterAdmin, roles/container.admin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Replace the following:

    • PROJECT_ID: Your project ID.
    • USER_IDENTIFIER: The identifier for your user account. For example, myemail@example.com.
    • ROLE: The IAM role that you grant to your user account.
  15. Menyiapkan lingkungan Anda

    Untuk menyiapkan lingkungan Anda, ikuti langkah-langkah berikut:

    1. Luncurkan sesi Cloud Shell dari Google Cloud konsol, dengan mengklik Ikon aktivasi Cloud Shell Activate Cloud Shell di Google Cloud konsol. Tindakan ini akan meluncurkan sesi di panel bawah konsol Google Cloud .

    2. Menetapkan variabel lingkungan:

      export PROJECT_ID=PROJECT_ID
      export CLUSTER_NAME=rayserve-cluster
      export COMPUTE_REGION=us-central1
      export COMPUTE_ZONE=us-central1-c
      export CLUSTER_VERSION=CLUSTER_VERSION
      export TUTORIAL_HOME=`pwd`
      

      Ganti kode berikut:

      • PROJECT_ID: Project ID Google Cloud Anda.
      • CLUSTER_VERSION: versi GKE yang akan digunakan. Harus 1.30.1 atau setelahnya.
    3. Buat clone repositori GitHub:

      git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
      
    4. Ubah ke direktori kerja:

      cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/stable-diffusion
      
    5. Buat lingkungan virtual Python:

      venv

      python -m venv myenv && \
      source myenv/bin/activate
      

      Conda

      1. Instal Conda.

      2. Jalankan perintah berikut:

        conda create -c conda-forge python=3.9.19 -n myenv && \
        conda activate myenv
        

      Saat Anda men-deploy aplikasi Serve dengan serve run, Ray mengharapkan versi Python klien lokal cocok dengan versi yang digunakan di cluster Ray. Image rayproject/ray:2.37.0 menggunakan Python 3.9. Jika Anda menjalankan versi klien yang berbeda, pilih image Ray yang sesuai.

    6. Instal dependensi yang diperlukan untuk menjalankan aplikasi Serve:

      pip install ray[serve]==2.37.0
      pip install torch
      pip install requests
      

    Membuat cluster dengan node pool GPU

    Buat cluster GKE Autopilot atau Standard dengan node pool GPU:

    Autopilot

    Buat cluster Autopilot:

    gcloud container clusters create-auto ${CLUSTER_NAME}  \
        --enable-ray-operator \
        --cluster-version=${CLUSTER_VERSION} \
        --location=${COMPUTE_REGION}
    

    Standar

    1. Buat cluster Standard:

      gcloud container clusters create ${CLUSTER_NAME} \
          --addons=RayOperator \
          --cluster-version=${CLUSTER_VERSION}  \
          --machine-type=c3d-standard-8 \
          --location=${COMPUTE_ZONE} \
          --num-nodes=1
      
    2. Buat node pool GPU:

      gcloud container node-pools create gpu-pool \
          --cluster=${CLUSTER_NAME} \
          --machine-type=g2-standard-8 \
          --location=${COMPUTE_ZONE} \
          --num-nodes=1 \
          --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest
      

    Men-deploy resource RayCluster

    Untuk men-deploy resource RayCluster:

    1. Tinjau manifes berikut:

      apiVersion: ray.io/v1
      kind: RayCluster
      metadata:
        name: stable-diffusion-cluster
      spec:
        rayVersion: '2.37.0'
        headGroupSpec:
          rayStartParams:
            dashboard-host: '0.0.0.0'
          template:
            metadata:
            spec:
              containers:
              - name: ray-head
                image: rayproject/ray:2.37.0
                ports:
                - containerPort: 6379
                  name: gcs
                - containerPort: 8265
                  name: dashboard
                - containerPort: 10001
                  name: client
                - containerPort: 8000
                  name: serve
                resources:
                  limits:
                    cpu: "2"
                    ephemeral-storage: "15Gi"
                    memory: "8Gi"
                  requests:
                    cpu: "2"
                    ephemeral-storage: "15Gi"
                    memory: "8Gi"
              nodeSelector:
                cloud.google.com/machine-family: c3d
        workerGroupSpecs:
        - replicas: 1
          minReplicas: 1
          maxReplicas: 4
          groupName: gpu-group
          rayStartParams: {}
          template:
            spec:
              containers:
              - name: ray-worker
                image: rayproject/ray:2.37.0-gpu
                resources:
                  limits:
                    cpu: 4
                    memory: "16Gi"
                    nvidia.com/gpu: 1
                  requests:
                    cpu: 3
                    memory: "16Gi"
                    nvidia.com/gpu: 1
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-l4

      Manifes ini menjelaskan resource RayCluster.

    2. Terapkan manifes ke cluster Anda:

      kubectl apply -f ray-cluster.yaml
      
    3. Pastikan resource RayCluster sudah siap:

      kubectl get raycluster
      

      Outputnya mirip dengan hal berikut ini:

      NAME                       DESIRED WORKERS   AVAILABLE WORKERS   CPUS   MEMORY   GPUS   STATUS   AGE
      stable-diffusion-cluster   2                 2                   6      20Gi     0      ready    33s
      

      Dalam output ini, ready di kolom STATUS menunjukkan bahwa resource RayCluster sudah siap.

    Menghubungkan ke resource RayCluster

    Untuk terhubung ke resource RayCluster:

    1. Pastikan GKE membuat layanan RayCluster:

      kubectl get svc stable-diffusion-cluster-head-svc
      

      Outputnya mirip dengan hal berikut ini:

      NAME                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                AGE
      pytorch-mnist-cluster-head-svc   ClusterIP   34.118.238.247   <none>        10001/TCP,8265/TCP,6379/TCP,8080/TCP   109s
      
    2. Buat sesi penerusan port ke head Ray:

      kubectl port-forward svc/stable-diffusion-cluster-head-svc 8265:8265 2>&1 >/dev/null &
      kubectl port-forward svc/stable-diffusion-cluster-head-svc 10001:10001 2>&1 >/dev/null &
      
    3. Pastikan klien Ray dapat terhubung ke cluster Ray menggunakan localhost:

      ray list nodes --address http://localhost:8265
      

      Outputnya mirip dengan hal berikut ini:

      ======== List: 2024-06-19 15:15:15.707336 ========
      Stats:
      ------------------------------
      Total: 3
      
      Table:
      ------------------------------
          NODE_ID                                                   NODE_IP     IS_HEAD_NODE    STATE    NODE_NAME    RESOURCES_TOTAL                 LABELS
      0  1d07447d7d124db641052a3443ed882f913510dbe866719ac36667d2  10.28.1.21  False           ALIVE    10.28.1.21   CPU: 2.0                        ray.io/node_id: 1d07447d7d124db641052a3443ed882f913510dbe866719ac36667d2
      # Several lines of output omitted
      

    Menjalankan aplikasi Ray Serve

    Untuk menjalankan aplikasi Ray Serve:

    1. Jalankan aplikasi Stable Diffusion Ray Serve:

      serve run stable_diffusion:entrypoint --working-dir=. --runtime-env-json='{"pip": ["torch", "torchvision", "diffusers==0.12.1", "huggingface_hub==0.25.2", "transformers", "fastapi==0.113.0"], "excludes": ["myenv"]}' --address ray://localhost:10001
      
      

      Outputnya mirip dengan hal berikut ini:

      2024-06-19 18:20:58,444 INFO scripts.py:499 -- Running import path: 'stable_diffusion:entrypoint'.
      2024-06-19 18:20:59,730 INFO packaging.py:530 -- Creating a file package for local directory '.'.
      2024-06-19 18:21:04,833 INFO handle.py:126 -- Created DeploymentHandle 'hyil6u9f' for Deployment(name='StableDiffusionV2', app='default').
      2024-06-19 18:21:04,834 INFO handle.py:126 -- Created DeploymentHandle 'xo25rl4k' for Deployment(name='StableDiffusionV2', app='default').
      2024-06-19 18:21:04,836 INFO handle.py:126 -- Created DeploymentHandle '57x9u4fp' for Deployment(name='APIIngress', app='default').
      2024-06-19 18:21:04,836 INFO handle.py:126 -- Created DeploymentHandle 'xr6kt85t' for Deployment(name='StableDiffusionV2', app='default').
      2024-06-19 18:21:04,836 INFO handle.py:126 -- Created DeploymentHandle 'g54qagbz' for Deployment(name='APIIngress', app='default').
      2024-06-19 18:21:19,139 INFO handle.py:126 -- Created DeploymentHandle 'iwuz00mv' for Deployment(name='APIIngress', app='default').
      2024-06-19 18:21:19,139 INFO api.py:583 -- Deployed app 'default' successfully.
      
    2. Buat sesi penerusan port ke port Ray Serve (8000):

      kubectl port-forward svc/stable-diffusion-cluster-head-svc 8000:8000 2>&1 >/dev/null &
      
    3. Jalankan skrip Python:

      python generate_image.py
      

      Skrip menghasilkan gambar ke file bernama output.png. Gambar tersebut mirip dengan berikut:

      Pantai saat matahari terbenam. Gambar yang dihasilkan oleh Stable Diffusion.

    Men-deploy RayService

    Resource kustom RayService mengelola siklus proses resource RayCluster dan aplikasi Ray Serve.

    Untuk mengetahui informasi selengkapnya tentang RayService, lihat Deploy Ray Serve Applications dan Production Guide dalam dokumentasi Ray.

    Untuk men-deploy resource RayService, ikuti langkah-langkah berikut:

    1. Tinjau manifes berikut:

      apiVersion: ray.io/v1
      kind: RayService
      metadata:
        name: stable-diffusion
      spec:
        serveConfigV2: |
          applications:
            - name: stable_diffusion
              import_path: ai-ml.gke-ray.rayserve.stable-diffusion.stable_diffusion:entrypoint
              runtime_env:
                working_dir: "https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/archive/main.zip"
                pip: ["diffusers==0.12.1", "torch", "torchvision", "huggingface_hub==0.25.2", "transformers"]
        rayClusterConfig:
          rayVersion: '2.37.0'
          headGroupSpec:
            rayStartParams:
              dashboard-host: '0.0.0.0'
            template:
              spec:
                containers:
                - name: ray-head
                  image:  rayproject/ray:2.37.0
                  ports:
                  - containerPort: 6379
                    name: gcs
                  - containerPort: 8265
                    name: dashboard
                  - containerPort: 10001
                    name: client
                  - containerPort: 8000
                    name: serve
                  resources:
                    limits:
                      cpu: "2"
                      ephemeral-storage: "15Gi"
                      memory: "8Gi"
                    requests:
                      cpu: "2"
                      ephemeral-storage: "15Gi"
                      memory: "8Gi"
                nodeSelector:
                  cloud.google.com/machine-family: c3d
          workerGroupSpecs:
          - replicas: 1
            minReplicas: 1
            maxReplicas: 4
            groupName: gpu-group
            rayStartParams: {}
            template:
              spec:
                containers:
                - name: ray-worker
                  image: rayproject/ray:2.37.0-gpu
                  resources:
                    limits:
                      cpu: 4
                      memory: "16Gi"
                      nvidia.com/gpu: 1
                    requests:
                      cpu: 3
                      memory: "16Gi"
                      nvidia.com/gpu: 1
                nodeSelector:
                  cloud.google.com/gke-accelerator: nvidia-l4

      Manifes ini menjelaskan resource kustom RayService.

    2. Terapkan manifes ke cluster Anda:

      kubectl apply -f ray-service.yaml
      
    3. Pastikan bahwa Service sudah siap:

      kubectl get svc stable-diffusion-serve-svc
      

      Outputnya mirip dengan hal berikut ini:

      NAME                         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
      
      stable-diffusion-serve-svc   ClusterIP   34.118.236.0   <none>        8000/TCP   31m
      
    4. Konfigurasi penerusan port ke Layanan Ray Serve:

      kubectl port-forward svc/stable-diffusion-serve-svc 8000:8000 2>&1 >/dev/null &
      
    5. Jalankan skrip Python dari bagian sebelumnya:

      python generate_image.py
      

      Skrip ini menghasilkan gambar yang mirip dengan gambar yang dihasilkan di bagian sebelumnya.

    Mengamati workload Ray

    Untuk melihat detail RayJob, Anda dapat membuka bagian Kubernetes Engine > AI/ML > Jobs di konsol. Google Cloud

    Melihat RayJob di konsol Google Cloud

    Pembersihan

    Menghapus project

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Menghapus resource satu per satu

    Untuk menghapus cluster, ketik:

    gcloud container clusters delete ${CLUSTER_NAME}
    

    Langkah berikutnya