
딥러닝 모델의 크기가 커짐에 따라 서빙에 필요한 GPU 인프라 비용은 기업의 가장 큰 부담 중 하나가 되었습니다. 특히 거대 언어 모델(LLM)이나 고해상도 이미지 생성 모델을 상시 운영할 때, 온디맨드(On-demand) 인스턴스 비용은 기하급수적으로 상승합니다. 이를 해결하기 위한 최선의 대안이 바로 Spot Instance(스팟 인스턴스) 활용입니다. 하지만 스팟 인스턴스는 공급업체의 리소스 회수 시 '중단 알림(Preemption Notice)' 후 강제 종료된다는 치명적인 단점이 있습니다. 본 포스팅에서는 파이썬을 기반으로 스팟 인스턴스의 중단을 선제적으로 감지하고, 상태를 보존하며, 복구하는 전문적인 체크포인트 전략을 상세히 다룹니다.
1. 온디맨드 vs 스팟 인스턴스: 경제성 및 리스크 차이 분석
스팟 인스턴스를 실무에 도입하기 전, 인프라의 특성을 정확히 이해하는 것이 중요합니다. 아래 표는 AWS, GCP, Azure와 같은 주요 클라우드 환경에서의 특성을 비교한 것입니다.
| 비교 항목 | 온디맨드 (On-Demand) | 스팟 인스턴스 (Spot Instance) |
|---|---|---|
| 비용 절감율 | 0% (표준 가격) | 최대 60% ~ 90% 저렴 |
| 가용성 보장 | SLA에 따른 99.9% 보장 | 보장 없음 (언제든 중단 가능) |
| 사전 알림 | 없음 (유지) | 30초 ~ 2분 전 중단 알림 발생 |
| 주요 용도 | 중단 불가능한 핵심 서비스 | 배치 추론, 유연한 확장 노드, 학습 |
| 복구 전략 | 자동 복구(Auto Healing) | 체크포인트 및 상태 관리 필수 |
2. 스팟 중단 해결을 위한 아키텍처적 접근
스팟 인스턴스를 활용한 추론 서버 구축 시 가장 큰 해결 과제는 '진행 중인 요청(In-flight Request)의 유실 방지'입니다. 이를 위해 다음과 같은 전략을 수립해야 합니다.
- 시그널 감지: 클라우드 메타데이터 엔드포인트를 주기적으로 폴링하여 중단 신호를 획득합니다.
- Graceful Shutdown: 신호 감지 시 더 이상 새로운 요청을 받지 않고, 현재 처리 중인 요청을 안전하게 마무리합니다.
- 상태 외부 저장: 인스턴스 내부 디스크가 아닌 Redis, S3, NFS 등에 체크포인트와 로그를 실시간 동기화합니다.
3. [Practical Examples] 실무 적용을 위한 Python 코드 가이드
엔지니어가 자신의 인프라에 즉시 이식할 수 있는 핵심 파이썬 스크립트 모음입니다.
Example 1: AWS Spot Instance 중단 알림 모니터링 스레드
import requests
import time
import threading
def monitor_spot_interruption():
"""AWS 메타데이터 서비스를 통한 중단 신호 감지"""
url = "http://169.254.169.254/latest/meta-data/spot/instance-action"
while True:
try:
response = requests.get(url, timeout=1)
if response.status_code == 200:
print("!!! Spot Interruption Warning Detected !!!")
initiate_graceful_shutdown()
break
except Exception:
pass
time.sleep(5)
def initiate_graceful_shutdown():
# 추론 서비스 중지 로직 구현
pass
# 모니터링 시작
threading.Thread(target=monitor_spot_interruption, daemon=True).start()
Example 2: Redis를 활용한 추론 요청 큐 체크포인트 관리
import redis
import json
r = redis.StrictRedis(host='localhost', port=6379, db=0)
def save_request_checkpoint(request_id, payload):
"""중단 시 재처리를 위해 Redis에 임시 저장"""
data = {"payload": payload, "status": "processing"}
r.setex(f"checkpoint:{request_id}", 300, json.dumps(data))
def mark_as_completed(request_id):
"""성공 시 체크포인트 삭제"""
r.delete(f"checkpoint:{request_id}")
Example 3: Graceful Shutdown 처리를 위한 FastAPI Signal Handler
from fastapi import FastAPI
import signal
import sys
app = FastAPI()
@app.on_event("shutdown")
def shutdown_event():
print("Saving model state and cleaning up resources...")
# S3로 로그 업로드 등 마무리 작업 수행
def handle_sigterm(sig, frame):
print("SIGTERM received, exiting...")
sys.exit(0)
signal.signal(signal.SIGTERM, handle_sigterm)
Example 4: 배치 추론 진행도(Offset) 외부 저장 및 복구
import os
CHECKPOINT_FILE = "/mnt/efs/inference_offset.txt"
def get_last_offset():
if os.path.exists(CHECKPOINT_FILE):
with open(CHECKPOINT_FILE, "r") as f:
return int(f.read().strip())
return 0
def update_offset(new_offset):
with open(CHECKPOINT_FILE, "w") as f:
f.write(str(new_offset))
# 추론 루프 시작 시
current_idx = get_last_offset()
Example 5: 중단 시 모델 추론 상태 S3 업로드 (boto3)
import boto3
def upload_state_to_s3(local_path, s3_bucket, s3_key):
s3 = boto3.client('s3')
try:
s3.upload_file(local_path, s3_bucket, s3_key)
print("Final state uploaded to S3 successfully.")
except Exception as e:
print(f"Failed to upload: {e}")
Example 6: 비대칭 추론 워커 구조 (RabbitMQ 이용)
import pika
def consume_requests():
connection = pika.BlockingConnection(pika.ConnectionParameters('msg-broker'))
channel = connection.channel()
# 중단 시 메시지가 큐로 복구되도록 auto_ack=False 설정
def callback(ch, method, properties, body):
process_inference(body)
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_consume(queue='inference_tasks', on_message_callback=callback)
channel.start_consuming()
Example 7: Docker Compose를 활용한 자동 재시작 정책
# docker-compose.yml 예시
services:
inference-server:
image: my-model-server:latest
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
volumes:
- /shared/checkpoints:/app/checkpoints
4. 전문적인 운영 팁: 가용성을 유지하는 3단계 전략
단순히 기술적으로 복구하는 것 외에도 운영 전략이 동반되어야 비용과 안정성의 균형을 잡을 수 있습니다.
- Spot Fleet 및 Mixed Instance Group 사용: 단일 인스턴스 타입만 쓰지 말고 여러 가용 영역(AZ)과 여러 타입을 섞어 회수 리스크를 분산합니다.
- Fallback to On-Demand: 모든 스팟 리소스가 회수되었을 때를 대비해 소량의 온디맨드 인스턴스를 최소한(Baseline)으로 유지하십시오.
- Warm-up 최적화: 인스턴스 복구 속도를 높이기 위해 모델 가중치를 미리 베이크인(Bake-in)한 커스텀 AMI나 컨테이너 이미지를 사용하십시오.
5. 결론 및 향후 전망
클라우드 비용 효율화(FinOps) 관점에서 스팟 인스턴스는 강력한 무기입니다. 파이썬의 강력한 라이브러리 생태계와 클라우드 네이티브 API를 결합하면, 중단 가능성이라는 위험 요소를 통제 가능한 변수로 바꿀 수 있습니다. 이제 단순한 추론을 넘어 '지속 가능한 추론 인프라'를 구축해 보시기 바랍니다.
참고 문헌 및 출처
- AWS Documentation: "Best Practices for Handling Spot Instance Interruptions" (2025-2026 Updated)
- Google Cloud Architecture Center: "Running Batch Workloads on Spot VMs"
- FinOps Foundation: "Cost Optimization for Machine Learning Inference"
- Python Software Foundation: "Signal Handling in Distributed Systems"
'Artificial Intelligence > 60. Python' 카테고리의 다른 글
| [PYTHON] TensorRT FP16 양자화 오차를 해결하는 3가지 Calibration 데이터 선정 방법 (0) | 2026.04.20 |
|---|---|
| [PYTHON] BentoML vs Ray Serve : 확장성 있는 모델 서빙을 위한 2가지 프레임워크 비교 및 해결 방법 (0) | 2026.04.20 |
| [PYTHON] 대규모 데이터 셔플링 시 메모리 부족을 해결하는 np.memmap 활용 방법 7가지 (0) | 2026.04.19 |
| [PYTHON] SQL과 Pandas 간의 효율적인 데이터 로딩 전략 7가지 방법과 성능 차이 해결 (0) | 2026.04.19 |
| [PYTHON] 시계열 데이터 처리 시 Windowing 함수 최적화 7가지 방법과 성능 차이 해결 (0) | 2026.04.19 |