Questo tutorial spiega come progettare ed eseguire il deployment di job Cloud Run resilienti con GPU abilitate, in esecuzione per un massimo di 12 ore.
Sebbene Cloud Run supporti timeout delle attività estesi, non offre uno SLA per l'esecuzione senza interruzioni. Poiché non viene eseguita la migrazione live delle attività abilitate per la GPU, la manutenzione settimanale di routine le interromperà a metà esecuzione. Di conseguenza, è prevedibile che qualsiasi attività estesa venga interrotta almeno una volta. Per assicurarti che il job venga completato correttamente senza sprecare risorse di computing, progetta l'applicazione in modo che esegua il checkpoint e riprenda, anziché fare affidamento su una singola esecuzione senza interruzioni.
Questo tutorial ti guida nell'implementazione del checkpointing, nella gestione dei segnali della piattaforma SIGTERM e nella configurazione dei tentativi massimi.
Obiettivi
In questo tutorial imparerai a:
- Prepara un'applicazione Python che implementi il checkpointing e gestisca i segnali
SIGTERM. - Crea un bucket Cloud Storage per rendere persistenti i checkpoint.
- Crea ed esegui il deployment di un job Cloud Run con GPU abilitata, un timeout delle attività di 12 ore e una policy di ripetizione configurata.
- Esegui il job e scopri come monitorare gli eventi di prerilascio nei log.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi.
Prima di iniziare
-
Installa Google Cloud CLI.
-
Configura gcloud CLI per utilizzare la tua identità federata.
Per saperne di più, consulta Accedi a gcloud CLI con la tua identità federata.
-
Per inizializzare gcloud CLI, esegui questo comando:
gcloud init -
Crea o seleziona un progetto Google Cloud .
Ruoli richiesti per selezionare o creare un progetto
- Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per cui ti è stato concesso un ruolo.
-
Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (
roles/resourcemanager.projectCreator), che contiene l'autorizzazioneresourcemanager.projects.create. Scopri come concedere i ruoli.
-
Crea un progetto Google Cloud :
gcloud projects create PROJECT_ID
Sostituisci
PROJECT_IDcon un nome per il progetto Google Cloud che stai creando. -
Seleziona il progetto Google Cloud che hai creato:
gcloud config set project PROJECT_ID
Sostituisci
PROJECT_IDcon il nome del progetto Google Cloud .
-
Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .
Abilita le API Cloud Run, Artifact Registry, Cloud Build e Cloud Storage, se non sono già abilitate:
Ruoli richiesti per abilitare le API
Per abilitare le API, devi disporre dell'autorizzazione
serviceusage.services.enable. Se hai creato il progetto, probabilmente disponi già di questa autorizzazione tramite il ruolo Proprietario (roles/owner). In caso contrario, puoi ottenere questa autorizzazione tramite il ruolo Amministratore Service Usage (roles/serviceusage.serviceUsageAdmin). Scopri come concedere i ruoli.gcloud services enable run.googleapis.com
cloudbuild.googleapis.com artifactregistry.googleapis.com storage.googleapis.com - Imposta la regione come variabile di ambiente:
export REGION=REGION
- Crea un account di servizio per il job:
gcloud iam service-accounts create gpu-job-sa
- Assicurati di disporre di una [quota GPU sufficiente](/run/docs/configuring/jobs/gpu#request-quota) (ad esempio Nvidia L4) nella regione scelta.
Prepara l'applicazione
Per rendere resiliente un job a lunga esecuzione, la tua applicazione deve:
Salva periodicamente i progressi (checkpointing) in una posizione permanente, ad esempio un bucket Cloud Storage montato.
Hai circa 10 secondi dopo
SIGTERMprima che l'attività venga terminata. Questo tempo non è sufficiente per scrivere un checkpoint di un modello di grandi dimensioni. Tratta il gestoreSIGTERMcome un flush best-effort solo di stati di piccole dimensioni e affidati al checkpoint periodico come protezione principale. Scegli l'intervallo di checkpoint in base alla quantità di lavoro che puoi permetterti di perdere, tenendo presente che checkpoint più frequenti significano più tempo non dedicato a un lavoro utile. L'obiettivo è raggiungere il giusto equilibrio per il tuo caso d'uso.Ripristina lo stato dall'ultimo checkpoint all'avvio.
Ascolta il segnale
SIGTERM, che Cloud Run invia 10 secondi prima del processo di manutenzione, e tenta di salvare un checkpoint finale prima di uscire.
L'esempio seguente illustra come implementare queste funzionalità.
Crea il codice dell'applicazione
Crea una directory per il progetto:
mkdir gc-run-gpu-resilience cd gc-run-gpu-resilienceCrea un file denominato
task.pye incolla lo script seguente per simulare un processo di addestramento o elaborazione batch che supporta il checkpointing e la gestione dei segnali:import os import sys import time import signal # The checkpoint directory will be mounted to this path CHECKPOINT_DIR = "/checkpoints" # Cloud Run sets these variables automatically JOB_NAME = os.environ.get("CLOUD_RUN_JOB", "local-job") TASK_INDEX = os.environ.get("CLOUD_RUN_TASK_INDEX", "0") CHECKPOINT_FILE = os.path.join( CHECKPOINT_DIR, f"{JOB_NAME}-task-{TASK_INDEX}-checkpoint.txt") TOTAL_STEPS = 100 current_step = 0 is_exiting = False def save_checkpoint(step): print(f"Saving checkpoint at step {step} to {CHECKPOINT_FILE}...") try: # Write to a temp file and rename to ensure atomicity temp_file = CHECKPOINT_FILE + ".tmp" with open(temp_file, "w") as f: f.write(str(step)) os.rename(temp_file, CHECKPOINT_FILE) print("Checkpoint saved successfully.") except Exception as e: print(f"Failed to save checkpoint: {e}") def load_checkpoint(): print(f"Looking for a checkpoint at {CHECKPOINT_FILE}...") global current_step if os.path.exists(CHECKPOINT_FILE): try: with open(CHECKPOINT_FILE, "r") as f: current_step = int(f.read().strip()) print(f"Resuming from checkpointed step {current_step}.") except Exception as e: print(f"Failed to load checkpoint: {e}. Starting from scratch.") else: print("No checkpoint found. Starting from scratch.") def sigterm_handler(signum, frame): global is_exiting print("Received SIGTERM signal from platform. Initiating graceful shutdown...") is_exiting = True # Register the signal handler for SIGTERM signal.signal(signal.SIGTERM, sigterm_handler) # Load existing checkpoint if any to resume work load_checkpoint() # Simulate work loop while current_step < TOTAL_STEPS and not is_exiting: print(f"Processing step {current_step}/{TOTAL_STEPS}...") # Simulate heavy GPU computation time.sleep(1) current_step += 1 # Periodically save checkpoint (e.g., every 5 steps) if current_step % 5 == 0: save_checkpoint(current_step) if is_exiting: # Save final state before exiting due to preemption # Best-effort only: with ~10s before SIGKILL this will not complete for # large state. Periodic checkpointing (above) is what actually protects # you. save_checkpoint(current_step) # Note that save_checkpoint already writes-then-renames for atomicity, # which is good, but the reason it matters here is that a truncated # checkpoint from an interrupted final save must not clobber the last # good one. print("Graceful shutdown complete. Exiting with error code to trigger retry.") # Exit with a non-zero code to signal to Cloud Run that the task # was interrupted and needs to be retried from the checkpoint. sys.exit(143) # Note that this statement deliberately consumes of the configured retry # attempts. print("Task completed successfully.") sys.exit(0)Crea un
Dockerfileper containerizzare l'applicazione:
Consulta questo esempio per un'implementazione più dettagliata e realistica.
Crea un bucket Cloud Storage per i checkpoint
Crea un bucket Cloud Storage per archiviare i file di checkpoint e concedi al account di servizio del job l'autorizzazione per accedervi.
Crea il bucket:
gcloud storage buckets create gs://gpu-checkpoints-PROJECT_ID \ --location REGIONConcedi il ruolo Amministratore oggetti Storage al account di servizio del job:
gcloud storage buckets add-iam-policy-binding gs://gpu-checkpoints-PROJECT_ID \ --member="serviceAccount:gpu-job-sa@PROJECT_ID." \ --role="roles/storage.objectAdmin"
Esegui il deployment del job
Esegui il deployment del job in Cloud Run:
gcloud beta run jobs deploy gpu-resilient-job \
--source=. \
--region REGION \
--gpu 1 \
--gpu-type nvidia-l4 \
--no-gpu-zonal-redundancy \
--task-timeout 168h \
--max-retries 3 \
--service-account gpu-job-sa@PROJECT_ID. \
--add-volume=name=checkpoint-volume,type=cloud-storage,bucket=gpu-checkpoints-PROJECT_ID \
--add-volume-mount=volume=checkpoint-volume,mount-path=/checkpoints
Tieni presente i seguenti flag critici:
--task-timeout 168h: consente l'esecuzione dell'attività per un massimo di 12 ore.--max-retries 3: per i job GPU con un timeout superiore a 1 ora, ti consigliamo di impostare la configurazione predefinita di 3 nuovi tentativi. Per evitare errori silenziosi durante la manutenzione della piattaforma, ti consigliamo di non impostare 0 tentativi. Infine, ti consigliamo di prevedere un budget per almeno un nuovo tentativo per gli errori relativi alla manutenzione, nonché per nuovi tentativi aggiuntivi per gli errori dell'applicazione in un periodo di esecuzione di 12 ore.--add-volumee--add-volume-mount: monta il bucket Cloud Storage su/checkpointsin modo che l'applicazione possa rendere persistente lo stato tra i nuovi tentativi di attività.
Esegui e monitora il job
Esegui il job:
gcloud run jobs execute gpu-resilient-job --region REGIONQuesto comando restituisce un messaggio simile al seguente:
Execution [gpu-resilient-job-abcde] has been successfully started. View details about this execution by running `gcloud run jobs executions describe gpu-resilient-job-abcde`. See logs for this execution at: https://console.cloud.google.com/logs/viewer?project=YOUR_PROJECT_ID&resource=cloud_run_job/job_name/my-job/location/my-region/execution_id/gpu-resilient-job-abcdeLa stringa
gpu-resilient-job-abcdeè l'ID univoco generato automaticamente per questo tentativo di esecuzione specifico. Puoi utilizzarlo per monitorare o annullare questa esecuzione specifica. L'output include anche un link diretto alla pagina Esplora log nella console Google Cloud per visualizzare l'output o gli errori delle attività del job.Monitora i log. Se si verifica un evento di manutenzione, Cloud Run registra un avviso. Vedrai:
- I log dell'applicazione:
Received SIGTERM signal from platform. Initiating graceful shutdown...seguito daSaving checkpoint.... - Un log di sistema che indica il prerilascio:
Container instance preemption initiated by the platform due to underlying hardware maintenance.con motivoINSTANCE_PREEMPTED. - Cloud Run riavvia automaticamente l'attività.
- I log dell'applicazione al riavvio:
Resuming from checkpointed step X..
- I log dell'applicazione:
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi aggiuntivi, elimina tutte le risorse di cui hai eseguito il deployment con questa guida rapida.
Elimina il repository
Cloud Run addebita solo il tempo di esecuzione del job. Tuttavia, ti potrebbero comunque essere addebitati i costi di archiviazione dell'immagine container in Artifact Registry. Per eliminare i repository Artifact Registry, segui i passaggi descritti in Elimina i repository nella documentazione di Artifact Registry.
Elimina il job
I job Cloud Run comportano costi solo quando è in esecuzione un'attività del job. Per eliminare il job Cloud Run, segui uno di questi passaggi:
Console
Per eliminare un job:
Nella console Google Cloud , vai a Cloud Run:
Individua il job che vuoi eliminare nell'elenco dei job e fai clic sulla relativa casella di controllo per selezionarlo.
Fai clic su Elimina. In questo modo, vengono terminate tutte le esecuzioni dei job in corso e tutte le istanze di container in esecuzione.
gcloud
Per eliminare un job, esegui questo comando:
gcloud run jobs delete JOB_NAME
Sostituisci JOB_NAME con il nome del job.
Elimina il progetto di test
L'eliminazione del progetto Google Cloud interrompe la fatturazione per tutte le risorse al suo interno. Per rilasciare tutte le risorse Google Cloud del progetto, segui questi passaggi:
Elimina un progetto Google Cloud :
gcloud projects delete PROJECT_ID
Elimina il bucket Cloud Storage:
gcloud storage buckets delete gs://gpu-checkpoints-PROJECT_ID
Passaggi successivi
- Scopri di più su tentativi di ripetizione e checkpoint dei job.
- Consulta le best practice per le prestazioni della GPU.