- Published on
SageMaker 엔드포인트 5xx 급증 원인·해결 9가지
- Authors
- Name
- 스타차일드
- https://x.com/ETFBITX
서빙 중인 SageMaker 실시간 엔드포인트에서 5xx가 급증하면 대개 모델 자체 문제라기보다 인프라 스케일링, 컨테이너 리소스, 타임아웃, 페이로드, 의존성/네트워크 같은 운영 이슈가 겹쳐서 발생합니다. 특히 트래픽이 순간적으로 튀거나, 배포 직후 워밍업이 안 된 상태에서 요청이 몰리면 ModelError 혹은 InternalFailure 형태로 빠르게 확산됩니다.
이 글은 “어디부터 봐야 하는지”를 먼저 정리하고, 현장에서 자주 맞닥뜨리는 원인과 해결을 9가지로 압축합니다. (실시간 엔드포인트 기준)
먼저 확인할 관측 지표 6개
원인 파악은 관측부터입니다. 아래 지표 조합만으로도 문제 영역이 크게 좁혀집니다.
- CloudWatch
Invocations,Invocation5XXErrors,Invocation4XXErrors ModelLatency,OverheadLatency(네트워크 및 프록시 오버헤드 추정)CPUUtilization,MemoryUtilization, (GPU 사용 시)GPUUtilization,GPUMemoryUtilization- 오토스케일링 사용 시
DesiredInstanceCount,InServiceInstances - 엔드포인트 로그: CloudWatch Logs의 컨테이너 표준 출력, 프레임워크 로그
- (가능하면) 로드테스트의 p50, p95, p99 지연 및 동시성
아래 CLI로 최근 5xx를 빠르게 확인할 수 있습니다.
aws cloudwatch get-metric-statistics \
--namespace AWS/SageMaker \
--metric-name Invocation5XXErrors \
--dimensions Name=EndpointName,Value=YOUR_ENDPOINT \
--statistics Sum \
--period 60 \
--start-time 2026-02-25T00:00:00Z \
--end-time 2026-02-25T01:00:00Z
1) 오토스케일링 지연 및 콜드 스타트
증상
- 트래픽 급증 직후
5xx가 짧게 폭발하고, 몇 분 뒤 정상화 InServiceInstances가DesiredInstanceCount를 뒤늦게 따라감ModelLatency가 급증하기보다OverheadLatency가 튀는 경우도 있음
원인
- 인스턴스 추가에 수 분이 걸리며, 그 사이 큐가 쌓이거나 타임아웃 발생
- 컨테이너/모델 로딩이 길어 워밍업 전 요청이 실패
해결
- 최소 인스턴스 수를
1이상으로 유지해 콜드 스타트 완화 - 스케일 아웃 기준을 보수적으로 조정 (예:
InvocationsPerInstance임계값 낮추기) - 모델 로딩 최적화 및 워밍업 엔드포인트 호출(헬스 체크) 추가
오토스케일링 정책 예시입니다.
aws application-autoscaling register-scalable-target \
--service-namespace sagemaker \
--resource-id endpoint/YOUR_ENDPOINT/variant/AllTraffic \
--scalable-dimension sagemaker:variant:DesiredInstanceCount \
--min-capacity 2 \
--max-capacity 10
aws application-autoscaling put-scaling-policy \
--service-namespace sagemaker \
--resource-id endpoint/YOUR_ENDPOINT/variant/AllTraffic \
--scalable-dimension sagemaker:variant:DesiredInstanceCount \
--policy-name invocations-per-instance \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration 'TargetValue=30,PredefinedMetricSpecification={PredefinedMetricType=SageMakerVariantInvocationsPerInstance},ScaleInCooldown=60,ScaleOutCooldown=30'
2) 컨테이너 메모리 부족으로 OOM Kill
증상
- 갑자기
5xx가 늘고, 컨테이너가 재시작을 반복 - 로그에
Killed,OOM,Out of memory류 메시지 MemoryUtilization이 90퍼센트 이상에서 천장에 붙음
원인
- 배치 크기 증가, 토크나이저/모델 캐시 누적, 요청당 텐서 메모리 급증
- 모델이 CPU 메모리와 GPU 메모리를 동시에 많이 점유
해결
- 인스턴스 타입 업그레이드 또는 모델 경량화(양자화, distillation)
- 요청당 최대 입력 길이 제한, 배치/동시성 제한
- 프레임워크별 메모리 설정 튜닝 (예: PyTorch 캐시 정리)
간단한 방어 코드 예시입니다.
# inference.py
import gc
import torch
def predict_fn(data, model):
try:
with torch.inference_mode():
return model(data)
finally:
# 누수성 캐시가 있다면 주기적으로 정리
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
3) CPU 포화 또는 스레드 과다로 인한 응답 지연 후 5xx
증상
CPUUtilization이 100퍼센트에 붙고ModelLatency가 증가- 동시 요청이 늘면 선형이 아니라 급격히 무너짐
원인
- 토크나이징, JSON 파싱, 전처리 로직이 CPU 병목
- 라이브러리의 스레드 풀 과다 (예:
OMP_NUM_THREADS기본값)
해결
- 전처리 최적화, 불필요한 변환 제거
- 스레드 수 제한 및 워커 모델 조정
# Dockerfile
ENV OMP_NUM_THREADS=1
ENV MKL_NUM_THREADS=1
또는 엔드포인트 앞단에서 입력을 정규화해 CPU 부담을 줄이는 것도 방법입니다.
4) 모델 서버 타임아웃 및 상위 타임아웃 불일치
증상
- 특정 요청에서만
5xx가 발생하고, p99 지연이 길어짐 - 클라이언트는 타임아웃으로 끊었는데 서버는 계속 처리하다가 리소스가 잠김
원인
- 모델 로직이 최악 케이스에서 오래 걸림
- 클라이언트 타임아웃, 로드밸런서 타임아웃, 모델 서버 타임아웃이 서로 다름
해결
- 타임아웃을 계층별로 정렬: 클라이언트
T1lt게이트웨이T2lt모델 서버T3 - 최악 케이스를 줄이기 위한 입력 제한(토큰 수, 이미지 크기)
- 장시간 작업은 비동기 추론으로 분리
관련해서 “타임아웃이 누적되어 장애가 커지는 패턴”은 분산 시스템에서도 흔합니다. 트랜잭션 경계 없이 보상 흐름을 설계하는 관점은 DDD에서 분산 트랜잭션 없이 SAGA 구현하기 글도 같이 참고할 만합니다.
5) 페이로드 크기 초과 또는 직렬화 문제
증상
- 큰 입력에서만 실패, 로그에
PayloadTooLarge또는 직렬화 예외 4xx가 아니라5xx로 보이는 경우는 컨테이너에서 예외 처리 미흡일 때
원인
- 요청 바디가 제한을 넘거나, base64 인코딩으로 예상보다 커짐
- JSON 직렬화가 느리거나, 바이너리 데이터를 비효율적으로 전달
해결
- 입력을 S3에 두고 키만 전달하는 패턴으로 전환
- ContentType을 명확히 하고 바이너리 포맷(예:
application/x-npy) 사용 고려 - 컨테이너에서 예외를 잡아
4xx로 정상 변환
import json
def input_fn(request_body, content_type):
if len(request_body) > 5 * 1024 * 1024:
raise ValueError("payload too large")
if content_type == "application/json":
return json.loads(request_body)
raise ValueError("unsupported content type")
6) 모델 로딩 실패 또는 의존성 충돌(배포 직후 5xx)
증상
- 배포 직후부터 지속적으로
5xx - 로그에
ModuleNotFoundError,GLIBC오류, CUDA 라이브러리 불일치
원인
- 이미지 빌드와 런타임 환경 불일치
requirements.txt업데이트로 ABI 충돌
해결
- 컨테이너 이미지를 고정 태그로 관리하고, 의존성 버전 핀ning
- 로컬에서만 되는 경우, SageMaker 베이스 이미지와 동일한 환경에서 재현
- 배포 전 “모델 로드만 수행하는 스모크 테스트”를 CI에 추가
의존성 충돌은 Node 생태계에서도 흔한데, 원인 분류 방식은 Node.js ESM/CJS 충돌 ERR_REQUIRE_ESM 해결법처럼 “환경과 로더 차이”를 먼저 의심하는 접근이 유효합니다.
7) 헬스 체크와 readiness 미구현으로 트래픽 조기 유입
증상
- 인스턴스가 뜨자마자 요청이 들어와 실패
- 초기 몇 분간만
5xx가 높고 이후 정상
원인
- 모델 로딩 중인데도 서버가
200을 반환하거나, 반대로 준비됐는데도 불필요하게 실패
해결
- 애플리케이션 레벨 readiness 신호 구현
- 모델 로딩 완료 전에는 명확히 실패시키되, 상위에서 재시도 가능한 상태 코드로 정리
FastAPI 기반 예시입니다.
from fastapi import FastAPI, Response
app = FastAPI()
ready = False
@app.on_event("startup")
def load_model():
global ready
# heavy init
# model = ...
ready = True
@app.get("/health")
def health(resp: Response):
if not ready:
resp.status_code = 503
return {"status": "starting"}
return {"status": "ok"}
8) 네트워크 및 VPC 설정 이슈(외부 의존 호출)
증상
- 특정 시간대 또는 특정 서브넷에서만
5xx - 모델이 외부 API, Feature Store, DB를 호출할 때 실패
원인
- VPC 엔드포인트 미구성, NAT 게이트웨이 포화, DNS 이슈
- 외부 호출이 느려져 전체 서빙이 타임아웃
해결
- 외부 의존을 서빙 경로에서 제거하거나 캐시 도입
- VPC 엔드포인트 구성, NAT 대역폭 및 연결 수 점검
- 외부 호출에 명시적 타임아웃과 회로 차단기 적용
import requests
def fetch_feature(url: str):
# connect timeout 0.3s, read timeout 0.7s
r = requests.get(url, timeout=(0.3, 0.7))
r.raise_for_status()
return r.json()
9) 재시도 폭풍과 동시성 제어 부재
증상
- 처음엔 작은 지연이었는데, 곧
5xx와 지연이 함께 폭발 - 클라이언트가 무한 재시도 또는 짧은 간격 재시도
원인
- 타임아웃
lt재시도 간격, 지수 백오프 없음 - 엔드포인트가 과부하인데도 더 많은 요청이 유입
해결
- 클라이언트 재시도 정책을
지수 백오프 + 지터 + 최대 시도 횟수로 제한 429또는 명확한 오류를 돌려 상위에서 제어 가능하게 설계- 동시성 제한(세마포어)로 서버를 보호
Python 클라이언트 재시도 예시입니다.
import random
import time
def call_with_retry(fn, max_attempts=4, base_delay=0.2):
for attempt in range(1, max_attempts + 1):
try:
return fn()
except Exception:
if attempt == max_attempts:
raise
delay = base_delay * (2 ** (attempt - 1))
delay = delay * (0.5 + random.random())
time.sleep(delay)
이 패턴은 gRPC의 타임아웃 문제에서도 거의 동일하게 나타납니다. 재시도와 데드라인이 만나면 장애가 증폭되므로, 원인별로 정리된 체크리스트는 Go gRPC DEADLINE_EXCEEDED 원인별 해결 7가지도 참고하면 좋습니다.
실전 트러블슈팅 순서(10분 컷)
5xx 급증 상황에서 빠르게 좁히는 순서입니다.
Invocation5XXErrors와 같은 시각의CPUUtilization,MemoryUtilization,ModelLatency,OverheadLatency를 한 화면에 겹쳐본다.InServiceInstances가 따라오지 못하면 오토스케일링 지연 또는 콜드 스타트를 의심한다.- 컨테이너 로그에서
OOM, 재시작, import 에러, 타임아웃 스택트레이스를 찾는다. - 큰 입력에서만 발생하면 페이로드 크기, 직렬화, 입력 제한을 점검한다.
- 외부 호출이 있다면 타임아웃을 강제하고, 실패 시 빠르게 반환하도록 바꾼다.
- 재시도 정책을 즉시 완화해 폭풍을 멈춘다.
마무리: 5xx는 “서빙 시스템”이 보내는 신호
SageMaker 엔드포인트의 5xx는 단일 원인이라기보다, 스케일링 지연, 리소스 포화, 타임아웃 불일치, 입력 폭주, 의존성 실패가 연쇄적으로 겹친 결과인 경우가 많습니다. 그래서 해결도 “모델 정확도”보다 “서빙 경로의 안정성”을 먼저 다루는 편이 빠릅니다.
다음 장애를 줄이려면 최소 인스턴스 유지, 입력 상한, 명시적 타임아웃, 재시도 정책, readiness 구현을 기본 세트로 깔고, 그 위에 모델 최적화를 올리는 접근이 가장 효율적입니다.