1. Introduction
Présentation
Dans cet atelier de programmation, vous allez apprendre à créer un pipeline de traitement d'IA asynchrone et axé sur les événements. Vous allez déployer un modèle Open Source à l'aide d'Ollama sur un pool de nœuds de calcul Cloud Run. Le pool de nœuds de calcul extrait les messages d'un sujet Pub/Sub et les traite à l'aide d'un modèle gemma3:4b.
Points abordés
- Utiliser des pools de nœuds de calcul avec un abonnement pull Pub/Sub
- Utiliser Ollama pour effectuer l'inférence en tant que pool de nœuds de calcul
2. Avant de commencer
Activer les API
Avant de commencer à utiliser cet atelier de programmation, activez les API suivantes en exécutant la commande :
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
pubsub.googleapis.com \
storage.googleapis.com
3. Préparation
Pour configurer les ressources requises, procédez comme suit :
- Définissez les variables d'environnement pour cet atelier de programmation :
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
- Créer un compte de service pour le pool de nœuds de calcul
gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
--display-name="Ollama Worker Service Account"
- Accorder l'accès à Pub/Sub au compte de service
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--role="roles/pubsub.subscriber"
- Créer un dépôt AR pour l'image du pool de nœuds de calcul
gcloud artifacts repositories create ${AR_REPO_NAME} \
--repository-format=docker \
--location=${REGION}
- Créer le sujet et l'abonnement Pub/Sub
gcloud pubsub topics create $TOPIC_NAME
gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_NAME
4. Télécharger et héberger le modèle sur GCS
Au lieu d'extraire le modèle directement dans le conteneur pendant le processus de compilation, ce qui peut être lent et inefficace, nous allons l'extraire sur une machine locale à l'aide de l'interface de ligne de commande Ollama, puis importer les fichiers du modèle dans un bucket GCS. Le pool de nœuds de calcul montera ensuite ce bucket pour accéder au modèle.
- Installez Ollama sur votre ordinateur local :
Exécutez la commande suivante pour installer Ollama sur Linux. Pour les autres systèmes d'exploitation, veuillez consulter le site Web d'Ollama.
curl -fsSL https://ollama.com/install.sh | sh
- Démarrez le service Ollama et extrayez le modèle :
Commencez par démarrer le service Ollama en arrière-plan.
ollama serve &
ollama pull gemma3:4b
- Créez un bucket GCS :
Créez le bucket GCS à l'aide de la variable d'environnement BUCKET_NAME que vous avez définie précédemment.
gsutil mb gs://${BUCKET_NAME}
- Importez les fichiers du modèle dans votre bucket GCS :
Ollama stocke les fichiers de modèle dans le répertoire ~/.ollama/models. Importez le contenu de ce répertoire dans votre bucket GCS. Tous les modèles que vous avez téléchargés seront copiés.
gsutil -m cp -r ~/.ollama/models/* gs://${BUCKET_NAME}/
- Accorder au compte de service l'accès au bucket Cloud Storage
gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \
--member=serviceAccount:${SERVICE_ACCOUNT_EMAIL} \
--role=roles/storage.objectViewer
5. Créer le job Cloud Run
Le job Cloud Run utilise deux conteneurs :
- ollama-coordinator : pour héberger Ollama et diffuser le modèle Gemma 3 4B
- pubsub-pull-msg : pour extraire les messages d'un abonnement Pub/Sub et les transmettre au conteneur ollama-coordinator
Commencez par créer le conteneur ollama-coordinator.
- Créez un répertoire parent pour l'atelier de programmation :
mkdir codelab-ollama-wp
cd codelab-ollama-wp
- Créez un répertoire pour le conteneur ollama-coordinator.
mkdir ollama-coordinator
cd ollama-coordinator
- Créez un fichier
Dockerfileavec le contenu suivant :
# 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"]
- Créer le conteneur Ollama
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${OLLAMA_IMAGE_NAME} --timeout=20m
Vous allez ensuite créer le conteneur pubsub-pull-msg.
- Créez un répertoire pour le conteneur pubsub-pull-msg.
cd ..
mkdir pubsub-pull-msg
cd pubsub-pull-msg
- Créer un objet
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"]
- Créez un fichier
requirements.txtavec le contenu suivant :
google-cloud-pubsub
requests
- Créez un fichier
main.pyavec le contenu suivant :
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()
- Créez maintenant le conteneur pubsub-pull-msg.
gcloud builds submit --tag ${REGION}-docker.pkg.dev/${PROJECT_ID}/${AR_REPO_NAME}/${PULL_MSG_IMAGE_NAME}
6. Déployer et exécuter le job
Dans cette étape, vous allez créer le job Cloud Run en déployant un fichier YAML.
Accédez au dossier racine pour créer le fichier YAML.
cd ..
- Créez un fichier
worker-pool.template.yamlavec le contenu suivant :
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
Définissez ensuite les URL complètes des images et utilisez sed pour remplacer les variables dans le fichier modèle, ce qui créera le fichier worker-pool.yaml final.
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
Vous pouvez maintenant déployer
gcloud beta run worker-pools replace worker-pool.yaml
Et test
gcloud pubsub topics publish ${TOPIC_NAME} --message="What is 1 + 1?"
Affichez ensuite les journaux. Vous devrez peut-être attendre une minute ou accéder à la page du pool de nœuds de calcul Cloud Console et regarder les journaux en temps réel.
gcloud alpha run worker-pools logs read "codelab-ollama-wp" --limit 10
et vous devriez voir un message indiquant
Ollama response: {"model": "gemma3:4b", "created_at": "2025-11-06T23:48:39.572079369Z", "response": "1 + 1 = 2\n", ...
7. Félicitations !
Bravo ! Vous avez terminé cet atelier de programmation.
Nous vous recommandons de consulter la documentation Cloud Run.
Points abordés
- Utiliser des pools de nœuds de calcul Cloud Run avec un abonnement Pub/Sub par extraction
- Utiliser Ollama pour effectuer l'inférence en tant que pool de nœuds de calcul Cloud Run
8. Effectuer un nettoyage
Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez chaque ressource individuellement.
Supprimer le projet
Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.
Pour supprimer le projet :
- Dans la console Google Cloud, accédez à la page Gérer les ressources.
- Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
- Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.
Supprimer des ressources individuelles
Pour supprimer les ressources individuelles, exécutez les commandes suivantes :
- Supprimez le pool de nœuds de calcul Cloud Run :
gcloud beta run worker-pools delete codelab-ollama-wp --region ${REGION}
- Supprimez le bucket GCS :
gsutil -m rm -r gs://${BUCKET_NAME}
- Supprimez l'abonnement et le sujet Pub/Sub :
gcloud pubsub subscriptions delete ${SUBSCRIPTION_NAME}
gcloud pubsub topics delete ${TOPIC_NAME}
- Supprimez le dépôt Artifact Registry :
gcloud artifacts repositories delete ${AR_REPO_NAME} --location=${REGION} --quiet
- Supprimez le compte de service :
gcloud iam service-accounts delete ${SERVICE_ACCOUNT_EMAIL} --quiet
Nettoyer les fichiers locaux
Pour nettoyer les fichiers locaux, procédez comme suit :
- Arrêtez le service Ollama local : si vous avez démarré Ollama avec
ollama serve &, vous pouvez l'arrêter en trouvant son ID de processus (PID), puis en utilisant la commandekill.# Find the process ID of the Ollama server pgrep ollama # Replace <PID> with the actual process ID obtained from the previous command kill <PID> - Supprimez les modèles téléchargés :
rm -rf ~/.ollama/models
- Désinstallez Ollama :
Suivez les instructions sur le site Web d'Ollama pour désinstaller Ollama de votre ordinateur local.