Cara menghosting Ollama sebagai kumpulan pekerja untuk inferensi

1. Pengantar

Ringkasan

Dalam codelab ini, Anda akan mempelajari cara membuat pipeline pemrosesan AI asinkron berbasis peristiwa. Anda akan men-deploy model open source menggunakan Ollama di Pool Worker Cloud Run. Kumpulan pekerja menarik pesan dari topik Pub/Sub dan memprosesnya menggunakan model gemma3:4b.

Yang akan Anda pelajari

  • Cara menggunakan kumpulan pekerja dengan langganan Pull Pub/Sub
  • Cara menggunakan Ollama untuk melakukan inferensi sebagai kumpulan pekerja

2. Sebelum memulai

Mengaktifkan API

Sebelum Anda dapat mulai menggunakan codelab ini, aktifkan API berikut dengan menjalankan:

gcloud services enable run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    pubsub.googleapis.com \
    storage.googleapis.com

3. Penyiapan dan Persyaratan

Untuk menyiapkan resource yang diperlukan, ikuti langkah-langkah berikut:

  1. Tetapkan variabel lingkungan untuk codelab ini:
export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>

export BUCKET_NAME=$PROJECT_ID-gemma3-4b
export SERVICE_ACCOUNT_NAME=ollama-worker-sa
export SERVICE_ACCOUNT_EMAIL=${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
export TOPIC_NAME=ollama-prompts
export SUBSCRIPTION_NAME=ollama-prompts-sub
export AR_REPO_NAME=ollama-worker-repo
export PULL_MSG_IMAGE_NAME=pubsub-pull-msg
export OLLAMA_IMAGE_NAME=ollama-coordinator
  1. Buat akun layanan untuk kumpulan pekerja
gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
  --display-name="Ollama Worker Service Account"
  1. Memberi SA akses ke Pub/Sub
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
  --role="roles/pubsub.subscriber"
  1. Buat repositori AR untuk image worker pool
gcloud artifacts repositories create ${AR_REPO_NAME} \
  --repository-format=docker \
  --location=${REGION}
  1. Buat topik dan langganan PubSub
gcloud pubsub topics create $TOPIC_NAME
gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_NAME

4. Mendownload dan Menghosting Model di GCS

Daripada menarik model langsung di dalam container selama proses build, yang bisa lambat dan tidak efisien, kita akan menarik model ke mesin lokal menggunakan Ollama CLI, lalu mengupload file model ke bucket GCS. Kemudian, worker pool akan me-mount bucket ini untuk mengakses model.

  1. Instal Ollama di komputer lokal Anda:

Jalankan perintah berikut untuk menginstal Ollama di Linux. Untuk sistem operasi lainnya, lihat situs Ollama.

curl -fsSL https://ollama.com/install.sh | sh
  1. Mulai layanan Ollama dan tarik model:

Pertama, mulai layanan Ollama di latar belakang.

ollama serve &
ollama pull gemma3:4b
  1. Buat bucket GCS:

Buat bucket GCS menggunakan variabel lingkungan BUCKET_NAME yang Anda tetapkan sebelumnya.

gsutil mb gs://${BUCKET_NAME}
  1. Upload file model ke bucket GCS Anda:

Ollama menyimpan file model di direktori ~/.ollama/models. Upload konten direktori ini ke bucket GCS Anda. Tindakan ini akan menyalin semua model yang telah Anda download.

gsutil -m cp -r ~/.ollama/models/* gs://${BUCKET_NAME}/
  1. Memberi SA akses ke bucket Cloud Storage
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \
     --member=serviceAccount:${SERVICE_ACCOUNT_EMAIL} \
     --role=roles/storage.objectViewer

5. Buat tugas Cloud Run

Tugas Cloud Run menggunakan 2 container:

  • ollama-coordinator - untuk menghosting ollama dan menayangkan model gemma 3 4B
  • pubsub-pull-msg - untuk menarik dari langganan pubsub dan meneruskan pesan ke container ollama-coordinator

Pertama, Anda akan membuat penampung ollama-coordinator.

  1. Buat direktori induk untuk codelab:
mkdir codelab-ollama-wp
cd codelab-ollama-wp
  1. Buat direktori untuk container ollama-coordinator
mkdir ollama-coordinator
cd ollama-coordinator
  1. Buat Dockerfile dengan konten berikut
# Use the official Ollama image as a base image
FROM ollama/ollama

# Expose the port that Ollama listens on
EXPOSE 11434

# Set the entrypoint to start the Ollama server
ENTRYPOINT ["ollama", "serve"]
  1. Membangun container ollama
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${OLLAMA_IMAGE_NAME} --timeout=20m

Selanjutnya, Anda akan membuat penampung pubsub-pull-msg.

  1. Buat direktori untuk container pubsub-pull-msg
cd ..
mkdir pubsub-pull-msg
cd pubsub-pull-msg
  1. Membuat Dockerfile
# Use the official Python image as a base image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY requirements.txt .

# Install the required Python packages
RUN pip install --no-cache-dir -r requirements.txt

# Copy the Python script into the container
COPY main.py .

# Set the entrypoint to run the Python script
CMD ["python", "main.py"]
  1. Buat file requirements.txt dengan konten berikut
google-cloud-pubsub
requests
  1. Buat file main.py dengan konten berikut
import os
import sys
import requests
import json
from google.cloud import pubsub_v1

# --- Main Application Logic ---
print("--- Sidecar container script started ---")

# --- Environment and Configuration ---
project_id = os.environ.get("PROJECT_ID")
subscription_name = os.environ.get("SUBSCRIPTION_NAME")
ollama_api_url = "http://localhost:11434/api/generate"

if not project_id or not subscription_name:
    print("FATAL: PROJECT_ID and SUBSCRIPTION_NAME must be set.")
    sys.exit(1)

print(f"PROJECT_ID: {project_id}")
print(f"SUBSCRIPTION_NAME: {subscription_name}")

def callback(message):
    """Processes a single Pub/Sub message."""
    print(f"Received message ID: {message.message_id}")
    try:
        prompt = message.data.decode("utf-8")
        print(f"Decoded prompt: '{prompt}'")
        
        data = {"model": "gemma3:4b", "prompt": prompt, "stream": False}
        
        print("Sending request to Ollama...")
        response = requests.post(ollama_api_url, json=data, timeout=300)
        response.raise_for_status()
        
        print("Successfully received response from Ollama.")
        ollama_response = response.json()
        print(f"Ollama response: {json.dumps(ollama_response)[:200]}...")

        message.ack()
        print(f"Message {message.message_id} acknowledged.")

    except requests.exceptions.RequestException as e:
        print(f"Error calling Ollama API: {e}")
        message.nack()
        print(f"Message {message.message_id} not acknowledged.")
    except Exception as e:
        print(f"An unexpected error occurred in callback: {e}")
        message.nack()
        print(f"Message {message.message_id} not acknowledged.")

def main():
    """Starts the Pub/Sub subscriber."""
    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(project_id, subscription_name)
    
    streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
    print(f"Subscribed to {subscription_path}. Listening for messages...")

    try:
        # .result() will block indefinitely.
        streaming_pull_future.result()
    except Exception as e:
        print(f"A fatal error occurred in the subscriber: {e}")
        streaming_pull_future.cancel()
        streaming_pull_future.result()

if __name__ == "__main__":
    main()
  1. Sekarang buat container pubsub-pull-msg
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${PULL_MSG_IMAGE_NAME}

6. Men-deploy dan menjalankan tugas

Pada langkah ini, Anda akan membuat tugas Cloud Run dengan men-deploy file yaml.

Pindah ke folder root untuk membuat file yaml.

cd ..
  1. Buat file worker-pool.template.yaml dengan konten berikut
apiVersion: run.googleapis.com/v1
kind: WorkerPool
metadata:
  name: codelab-ollama-wp
  labels:
    cloud.googleapis.com/location: europe-west1
  annotations:
    run.googleapis.com/launch-stage: BETA
    run.googleapis.com/scalingMode: manual
    run.googleapis.com/manualInstanceCount: '1'
    run.googleapis.com/gcs-fuse-mounter-enabled: "true"
spec:
  template:
    metadata:
      annotations:
        run.googleapis.com/gpu: "1"
        run.googleapis.com/gpu-zonal-redundancy-disabled: 'true'        
    spec:
      serviceAccountName: ${SERVICE_ACCOUNT_EMAIL}
      nodeSelector:
        run.googleapis.com/accelerator: nvidia-l4
      volumes:
      - name: gcs-bucket
        csi:
          driver: gcsfuse.run.googleapis.com
          readOnly: true
          volumeAttributes: 
            bucketName: ${BUCKET_NAME}
      containers:
      - image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${PULL_MSG_IMAGE_NAME}
        name: pubsub-pull-msg
        env:
        - name: PROJECT_ID
          value: ${PROJECT_ID}
        - name: SUBSCRIPTION_NAME
          value: "ollama-prompts-sub"
        - name: PYTHONUNBUFFERED
          value: "1"
        resources:
          limits:
            cpu: '1'
            memory: 1Gi
      - image: ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${OLLAMA_IMAGE_NAME}
        name: ollama-coordinator
        env:
        - name: OLLAMA_MODELS
          value: /mnt/models
        volumeMounts:
        - name: gcs-bucket
          mountPath: /mnt/models
        resources:
          limits:
            cpu: '6'
            nvidia.com/gpu: '1'
            memory: 16Gi

Kemudian, tentukan URL gambar lengkap dan gunakan sed untuk mengganti variabel dalam file template, sehingga membuat worker-pool.yaml akhir.

sed -e "s|\${SERVICE_ACCOUNT_EMAIL}|${SERVICE_ACCOUNT_EMAIL}|g" \
     -e "s|\${BUCKET_NAME}|${BUCKET_NAME}|g" \
     -e "s|\${PULL_MSG_IMAGE_NAME}|${PULL_MSG_IMAGE_NAME}|g" \
     -e "s|\${OLLAMA_IMAGE_NAME}|${OLLAMA_IMAGE_NAME}|g" \
     -e "s|\${PROJECT_ID}|${PROJECT_ID}|g" \
     -e "s|\${REGION}|${REGION}|g" \
     -e "s|\${AR_REPO_NAME}|${AR_REPO_NAME}|g" \
     worker-pool.template.yaml > worker-pool.yaml

Sekarang Anda dapat Men-deploy

gcloud beta run worker-pools replace worker-pool.yaml

Dan Test

gcloud pubsub topics publish ${TOPIC_NAME} --message="What is 1 + 1?"

Kemudian, lihat log. Anda mungkin perlu menunggu beberapa menit atau Anda dapat membuka halaman worker pool Cloud Console dan melihat log secara real time.

gcloud alpha run worker-pools logs read "codelab-ollama-wp" --limit 10

dan Anda akan melihat sesuatu yang bertuliskan

Ollama response: {"model": "gemma3:4b", "created_at": "2025-11-06T23:48:39.572079369Z", "response": "1 + 1 = 2\n", ...

7. Selamat!

Selamat, Anda telah menyelesaikan codelab.

Sebaiknya tinjau dokumentasi Cloud Run.

Yang telah kita bahas

  • Cara menggunakan kumpulan pekerja Cloud Run dengan langganan Pull Pub/Sub
  • Cara menggunakan Ollama untuk melakukan inferensi sebagai kumpulan pekerja Cloud Run

8. Pembersihan

Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus project

Cara termudah untuk menghilangkan penagihan adalah dengan menghapus project yang Anda buat untuk tutorial.

Untuk menghapus project:

  1. Di Konsol Google Cloud, buka halaman Manage resources.
  2. Dalam daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Menghapus resource satu per satu

Untuk menghapus setiap resource, jalankan perintah berikut:

  1. Hapus kumpulan pekerja Cloud Run:
gcloud beta run worker-pools delete codelab-ollama-wp --region ${REGION}
  1. Hapus bucket GCS:
gsutil -m rm -r gs://${BUCKET_NAME}
  1. Hapus langganan dan topik Pub/Sub:
gcloud pubsub subscriptions delete ${SUBSCRIPTION_NAME}
gcloud pubsub topics delete ${TOPIC_NAME}
  1. Hapus repositori Artifact Registry:
gcloud artifacts repositories delete ${AR_REPO_NAME} --location=${REGION} --quiet
  1. Hapus akun layanan:
gcloud iam service-accounts delete ${SERVICE_ACCOUNT_EMAIL} --quiet

Membersihkan file lokal

Untuk membersihkan file lokal, lakukan hal berikut:

  1. Hentikan layanan Ollama lokal:Jika Anda memulai Ollama dengan ollama serve &, Anda dapat menghentikannya dengan menemukan ID proses (PID), lalu menggunakan perintah kill.
    # Find the process ID of the Ollama server
    pgrep ollama
    
    # Replace <PID> with the actual process ID obtained from the previous command
    kill <PID>
    
  2. Hapus model yang didownload:
rm -rf ~/.ollama/models
  1. Uninstal Ollama:

Ikuti petunjuk di situs Ollama untuk meng-uninstal Ollama dari komputer lokal Anda.