이 튜토리얼에서는 최대 12시간 동안 실행되는 복원력이 우수한 GPU 지원 Cloud Run 작업을 설계하고 배포하는 방법을 설명합니다.
Cloud Run은 확장된 태스크 제한 시간을 지원하지만 중단 없는 실행을 위한 SLA를 제공하지 않습니다. GPU 지원 태스크는 라이브 마이그레이션되지 않으므로 일상적인 주간 유지보수로 인해 실행 중에 종료됩니다. 따라서 장기 실행 태스크는 최소 한 번은 중단될 것으로 예상해야 합니다. 컴퓨팅 리소스를 낭비하지 않고 작업을 성공적으로 완료하려면 중단되지 않는 단일 실행에 의존하는 대신 체크포인트 및 재개하도록 애플리케이션을 설계합니다.
이 튜토리얼에서는 체크포인트를 구현하고, 플랫폼 SIGTERM 신호를 처리하고, 최대 재시도 횟수를 구성하는 방법을 안내합니다.
목표
이 튜토리얼에서 학습할 내용은 다음과 같습니다.
- 체크포인트를 구현하고
SIGTERM신호를 처리하는 Python 애플리케이션을 준비합니다. - 체크포인트를 유지할 Cloud Storage 버킷을 만듭니다.
- GPU가 사용 설정되고, 태스크 제한 시간이 12시간이며, 재시도 정책이 구성된 Cloud Run 작업을 빌드하고 배포합니다.
- 작업을 실행하고 로그에서 선점 이벤트를 모니터링하는 방법을 알아봅니다.
비용
이 문서에서는 비용이 청구될 수 있는 Google Cloud구성요소를 사용합니다.
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
시작하기 전에
-
Google Cloud CLI를 설치합니다.
-
gcloud CLI에서 제휴 ID를 사용하도록 구성합니다.
자세한 내용은 제휴 ID로 gcloud CLI에 로그인을 참조하세요.
-
gcloud CLI를 초기화하려면, 다음 명령어를 실행합니다.
gcloud init -
Google Cloud 프로젝트를 만들거나 선택합니다.
프로젝트를 선택하거나 만드는 데 필요한 역할
- 프로젝트 선택: 프로젝트를 선택하는 데 특정 IAM 역할이 필요하지 않습니다. 역할이 부여된 모든 프로젝트를 선택할 수 있습니다.
-
프로젝트 만들기: 프로젝트를 만들려면
resourcemanager.projects.create권한이 포함된 프로젝트 생성자 역할(roles/resourcemanager.projectCreator)이 필요합니다. 역할 부여 방법 알아보기
-
Google Cloud 프로젝트를 만듭니다.
gcloud projects create PROJECT_ID
PROJECT_ID를 만들려는 Google Cloud 프로젝트의 이름으로 바꿉니다. -
만든 Google Cloud 프로젝트를 선택합니다.
gcloud config set project PROJECT_ID
PROJECT_ID을 Google Cloud 프로젝트 이름으로 바꿉니다.
Cloud Run, Artifact Registry, Cloud Build, Cloud Storage API를 사용 설정합니다(아직 사용 설정되지 않은 경우).
API 사용 설정에 필요한 역할
API를 사용 설정하려면
serviceusage.services.enable권한이 필요합니다. 프로젝트를 만든 경우 소유자 역할 (roles/owner)을 통해 이 권한이 이미 있을 수 있습니다. 그렇지 않으면 서비스 사용량 관리자 역할 (roles/serviceusage.serviceUsageAdmin)을 통해 이 권한을 얻을 수 있습니다. 역할 부여 방법 알아보기gcloud services enable run.googleapis.com
cloudbuild.googleapis.com artifactregistry.googleapis.com storage.googleapis.com - 리전을 환경 변수로 설정합니다.
export REGION=REGION
- 작업에 대한 서비스 계정을 만듭니다.
gcloud iam service-accounts create gpu-job-sa
- 선택한 리전에 [충분한 GPU 할당량](/run/docs/configuring/jobs/gpu#request-quota)(예: Nvidia L4)이 있는지 확인합니다.
애플리케이션 준비
장기 실행 작업의 복원력을 높이려면 애플리케이션에서 다음을 수행해야 합니다.
마운트된 Cloud Storage 버킷과 같은 영구 위치에 진행 상황 (체크포인트)을 주기적으로 저장합니다.
SIGTERM후 약 10초가 지나면 태스크가 종료됩니다. 이 시간은 대규모 모델 체크포인트를 작성하기에 충분하지 않습니다.SIGTERM핸들러를 작은 상태의 최선의 플러시로만 처리하고 주기적인 체크포인트를 기본 보호 수단으로 사용합니다. 체크포인트가 많을수록 유용한 작업에 소요되는 시간이 줄어든다는 점을 염두에 두고 손실을 감당할 수 있는 작업량에 따라 체크포인트 간격을 선택합니다. 목표는 사용 사례에 적합한 균형을 달성하는 것입니다.시작 시 마지막 체크포인트에서 상태를 복원합니다.
Cloud Run이 유지보수 프로세스 10초 전에 전송하는
SIGTERM신호를 수신 대기하고 종료하기 전에 최종 체크포인트를 저장하려고 시도합니다.
다음 예는 이러한 기능을 구현하는 방법을 보여줍니다.
애플리케이션 코드 만들기
프로젝트의 디렉터리를 만듭니다.
mkdir gc-run-gpu-resilience cd gc-run-gpu-resiliencetask.py라는 파일을 만들고 다음 스크립트를 붙여넣어 체크포인트 및 신호 처리를 지원하는 학습 또는 일괄 처리를 시뮬레이션합니다.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)Dockerfile을 만들어 애플리케이션을 컨테이너화합니다.
더 자세하고 현실적인 구현은 이 예를 참고하세요.
체크포인트용 Cloud Storage 버킷 만들기
체크포인트 파일을 저장할 Cloud Storage 버킷을 만들고 작업의 서비스 계정에 액세스 권한을 부여합니다.
버킷을 만듭니다.
gcloud storage buckets create gs://gpu-checkpoints-PROJECT_ID \ --location REGION작업의 서비스 계정에 스토리지 객체 관리자 역할을 부여합니다.
gcloud storage buckets add-iam-policy-binding gs://gpu-checkpoints-PROJECT_ID \ --member="serviceAccount:gpu-job-sa@PROJECT_ID." \ --role="roles/storage.objectAdmin"
작업 배포
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
다음과 같은 중요한 플래그에 유의하세요.
--task-timeout 168h: 태스크를 최대 12시간 동안 실행할 수 있습니다.--max-retries 3: 제한 시간이 1시간을 초과하는 GPU 작업의 경우 기본 구성인 재시도 3회를 설정하는 것이 좋습니다. 플랫폼 유지보수 중에 자동 실패를 방지하려면 재시도 횟수를 0으로 설정하지 않는 것이 좋습니다. 마지막으로 유지보수 관련 실패에 대해 최소 1회 재시도하고 12시간 실행 기간 동안 애플리케이션 실패에 대해 추가 재시도를 수행하도록 예산을 책정하는 것이 좋습니다.--add-volume및--add-volume-mount: 애플리케이션이 태스크 재시도 간에 상태를 유지할 수 있도록 Cloud Storage 버킷을/checkpoints에 마운트합니다.
작업 실행 및 모니터링
작업 실행:
gcloud run jobs execute gpu-resilient-job --region REGION이 명령어는 다음과 유사한 메시지를 반환합니다.
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-abcdegpu-resilient-job-abcde문자열은 이 특정 실행 시도에 대해 자동 생성된 고유 ID입니다. 이 특정 실행을 모니터링하거나 취소하는 데 사용할 수 있습니다. 출력에는 작업 태스크의 출력 또는 오류를 볼 수 있는 Google Cloud 콘솔의 로그 탐색기 페이지에 대한 직접 링크도 포함됩니다.로그를 모니터링합니다. 유지보수 이벤트가 발생하면 Cloud Run에서 경고를 로깅합니다. 다음과 같이 표시됩니다.
- 애플리케이션 로그:
Received SIGTERM signal from platform. Initiating graceful shutdown...다음에Saving checkpoint...가 옵니다. - 선점을 나타내는 시스템 로그:
Container instance preemption initiated by the platform due to underlying hardware maintenance.(이유:INSTANCE_PREEMPTED) - Cloud Run이 작업을 자동으로 다시 시작합니다.
- 다시 시작 시 애플리케이션 로그:
Resuming from checkpointed step X.
- 애플리케이션 로그:
삭제
Google Cloud 계정에 추가 비용이 청구되지 않게 하려면 이 빠른 시작으로 배포한 모든 리소스를 삭제합니다.
저장소 삭제
Cloud Run은 작업이 실행되는 시간에 대해서만 비용을 청구합니다. 하지만 Artifact Registry에 컨테이너 이미지를 저장하는 요금이 청구될 수 있습니다. Artifact Registry 저장소를 삭제하려면 Artifact Registry 문서의 저장소 삭제 단계를 따르세요.
작업 삭제
Cloud Run 작업은 작업 태스크가 실행될 때만 비용이 발생합니다. Cloud Run 작업을 삭제하려면 다음 단계 중 하나를 따르세요.
콘솔
작업을 삭제하려면 다음 안내를 따르세요.
Google Cloud 콘솔에서 Cloud Run으로 이동합니다.
작업 목록에서 삭제할 작업을 찾은 다음 체크박스를 클릭하여 선택합니다.
삭제를 클릭합니다. 그러면 진행 중인 모든 작업 실행과 실행 중인 모든 컨테이너 인스턴스가 종료됩니다.
gcloud
작업을 삭제하려면 다음 명령어를 실행하세요.
gcloud run jobs delete JOB_NAME
JOB_NAME을 작업 이름으로 바꿉니다.
테스트 프로젝트 삭제
Google Cloud 프로젝트를 삭제하면 해당 프로젝트의 모든 리소스에 대한 비용 청구가 중단됩니다. 프로젝트의 모든 Google Cloud 리소스를 해제하려면 다음 단계를 따르세요.
Google Cloud 프로젝트 삭제:
gcloud projects delete PROJECT_ID
Cloud Storage 버킷을 삭제합니다.
gcloud storage buckets delete gs://gpu-checkpoints-PROJECT_ID
다음 단계
- 작업 재시도 및 체크포인트 자세히 알아보기
- GPU 성능 권장사항 검토하기