소속: 4by4 Inc. · Pixell Lab 역할: MLOps Engineer 기간: 2025.02 – 2025.05 산업 도메인: 미디어 AI SaaS (Video Enhancement)


Situation

PMS v2.0은 SaaS 정식 오픈과 상용 고객 확보에 성공했으나, 운영 안정성에 문제가 있었다. Inference Service에서 월 1~2회 스케줄러 장애가 발생했고, 장애 복구에 약 2시간이 소요되었다. v2.0의 회고에서 도출된 운영 부채가 구체적이었다: 클러스터 증감 시 스케줄러 재시작 필요, 장애 알람 부재, ORM 없이 직접 쿼리 사용으로 인한 스키마 변경 실수 위험, Redis/DB 연결 끊김 보호 대책 부재.

또한 GPU 자원 부족 시를 대비하여 타 Region으로 빠르게 확장할 수 있는 Multi Region 대응 역량이 필요했다. 내부적으로 고객층을 VFX 스튜디오로 확장하고자 했으며, VFX에서 사용하는 주요 포맷인 OpenEXR 지원이 필요했다.


Task

  • 팀 구성:
    • Sales & PM ×1: BM 기획, 프로젝트 관리
    • DL Researcher ×2: Model 개발
    • Frontend Engineer ×1: Frontend Service 개발
    • Backend Engineer ×1: Backend Service 개발
    • ML Engineer(본인) ×1: Inference Service 개발
  • 담당 영역:
    • Inference Service 구조 개선으로 장애 발생 감소
    • 장애 대응 시간 최소화를 위한 모니터링 기능 구축
    • EKS Multi Region 대응
    • FastAPI 기반 API 서버 전환, DI Container 및 Repository/Service Layer 패턴 도입
    • OpenEXR 포맷 지원

Action

기술 스택 & 시스템 구성

분류기술
LanguagePython
FrameworkFastAPI, Ray
InferenceTensorRT
DIdependency-injector
ORMSQLAlchemy
ML OpsMLflow
MonitoringInfluxDB, Grafana, MS Teams (Alarm)
InfrastructureAWS EKS, Terraform, Karpenter, Packer
CI/CDGitHub Actions, Docker, GHCR

이전 버전 대비 변경점

항목v2.0v3.0개선 효과
컨테이너 구조관련 컨테이너 2개1개로 단순화운영 복잡도 감소
환경변수30개17개43% 축소
클러스터 통신Remote Actor 직접 핸들링Ray Job Submission스케줄러 중단 없이 클러스터 증감 가능
클러스터 증감시간30초5초83% 단축
스케줄러 장애율월 1~2회0회100% 감소
장애 복구 시간약 2시간약 5분24배 단축
API 구조단순 Python AppFastAPI + DI Container + Repository/Service Layer안정성, 유지보수성 향상
DB 접근직접 쿼리SQLAlchemy ORM스키마 변경 실수 방지
DB/Redis 보호없음연결 끊김, 요청 실패 보호 로직간헐적 연결 오류 해결
모니터링없음InfluxDB + Grafana + MS Teams 알람장애 즉시 감지
AMI 생성수동Packer 자동화AMI 자동 생성
모델 수5개6개 (+Film Grain)VFX 고객 대응

핵심 구현 사례

1. Remote Actor → Ray Job Submission 전환 및 RayJobLogObserver 구현

문제: v2.0에서는 Remote Actor를 직접 핸들링하는 방식이었기 때문에, 클러스터를 추가/삭제하려면 스케줄러를 재시작해야 했다. 또한 관련 컨테이너가 2개로 분리되어 있어 관리 복잡도가 높았고, 환경변수가 30개에 달했다.

구현: 클러스터 통신 방식을 Remote Actor 직접 핸들링에서 Ray Job Submission 방식으로 전환했다. 이를 통해 주 프로세서를 중단하지 않고도 클러스터를 증감할 수 있게 되었으며, 관련 컨테이너를 2개에서 1개로 단순화하고 환경변수를 30개에서 17개로 43% 축소했다. 클러스터 증감 시간도 30초에서 5초로 83% 단축되었다.

다만 Ray Job Submission은 클러스터에 Job을 던지는 방식이라 실행 중인 Job과의 접점이 없어지는 문제가 있었다. 이를 해결하기 위해 RayJobLogObserver를 구현하여, 각 작업마다 비동기로 해당 Job의 로그 스트림을 감시하고 진행 상황, 작업 성공/실패 여부를 파악하여 이벤트를 발생시킬 수 있게 했다. 이를 통해 스케줄러 장애율을 월 1~2회에서 0회로 100% 감소시켰다.

2. FastAPI + dependency-injector 기반 DI Container 및 Repository/Service Layer 도입

문제: v2.0에서는 ORM 없이 쿼리문을 직접 사용하여 스키마 변경 시 실수가 발생할 수밖에 없는 구조였고, Redis/DB 연결 끊김에 대한 보호 대책이 없어 간헐적 오류가 발생했다.

구현: 단순 Python 애플리케이션에서 FastAPI 기반으로 전환하면서 dependency-injector 라이브러리를 활용한 DI Container와 Repository/Service Layer 패턴을 도입했다. Container가 리포지토리 및 서비스 객체 생성을 위임받으면서 Singleton Class 등을 따로 네이밍하고 구현할 필요가 사라졌다. DB, Redis에 대한 세션도 명시적으로 관리할 수 있게 되었다.

DB, Redis에 대한 보호 로직(연결 끊김, 요청 실패 핸들링)을 추가하고, 각 데이터 객체를 SQLAlchemy ORM으로 관리하여 유지보수성을 높이고 스키마 변경 시 실수할 여지를 줄였다. 또한 Container 내부를 보면 전체적인 구조를 파악할 수 있어 신규 인원 온보딩에도 유리한 구성이 되었다.

3. InfluxDB + Grafana + MS Teams 알람 기반 모니터링 체계 구축

문제: v2.0에서는 모니터링 체계가 없어 장애 발생을 즉시 감지하기 어려웠고, 복구에 약 2시간이 소요되었다.

구현: 상태 모니터링 API를 구현하고, InfluxDB에 각 클러스터의 사용량 데이터를 시계열로 저장했다. Grafana를 연동하여 클러스터 사용량, Job 상태 등을 실시간으로 시각화하는 대시보드를 구축했다. 문제 발생 시 Grafana Alarm을 통해 MS Teams로 알림이 전달되도록 설정하여, 장애 복구 시간을 약 2시간에서 약 5분으로 24배 단축했다.

4. EKS Multi Region 대응 및 Packer AMI 자동화

문제: GPU 자원이 부족할 때 타 Region으로 빠르게 확장할 수 있는 역량이 필요했다. v2.0에서는 AMI 생성 과정이 수동이어서 번거로웠다.

구현: Packer를 통해 GPU AMI를 리전별로 자동 생성하는 자동화를 구축했다. 이를 통해 1시간 내에 준비되지 않은 리전에 EKS Cluster를 구축하고 GPU Cluster로 사용할 수 있게 되었다.

5. OpenEXR 포맷 지원 및 Film Grain 모델 추가

VFX 스튜디오 고객층 확장을 위해 OpenEXR 포맷 입출력을 지원하고, Film Grain 모델을 추가하여 총 6개 모델(SharpClear, SR, Color Enhance, Deinterlacing, Frame Interpolation, Film Grain)을 지원하게 되었다.


Result

기술 성과

  • Remote Actor → Ray Job Submission 전환, RayJobLogObserver로 비동기 Job 모니터링 구현
  • 컨테이너 2→1 단순화, 환경변수 43% 축소 (30→17)
  • 클러스터 증감 시간 83% 단축 (30s → 5s), 스케줄러 중단 없이 증감 가능
  • 스케줄러 장애율 100% 감소 (월 1~2회 → 0회)
  • 장애 복구 시간 24배 단축 (2h → 5m)
  • InfluxDB + Grafana + MS Teams 기반 실시간 모니터링 및 장애 알람 체계 구축
  • dependency-injector 기반 DI Container + SQLAlchemy ORM으로 유지보수성 향상
  • Packer 기반 리전별 GPU AMI 자동 생성, 1시간 내 미준비 리전 EKS Cluster 구축 가능
  • 6개 모델 + OpenEXR 지원으로 VFX 고객 대응

비즈니스 임팩트

  • Financial Times “High Growth Companies Asia-Pacific 2025” 선정 (Rank 293)

회고

잘한 점

기술적으로 목표했던 바를 모두 달성했다. v2.0에서 도출된 5가지 운영 부채(스케줄러 재시작 필요, 알람 부재, ORM 미사용, AMI 수동 생성, Redis/DB 보호 부재)를 v3.0에서 체계적으로 해결하여 서비스 안정성을 근본적으로 개선했다. 특히 Ray Job Submission + RayJobLogObserver 조합은 클러스터 운영의 유연성과 관측성을 동시에 확보한 설계였다.

아쉬운 점 / 다시 한다면

dependency-injector를 도입하여 DI Container 기반 구조를 확립했지만, 목업 기반 테스트 체계까지는 구축하지 못했다. DI의 핵심 이점 중 하나인 테스트 용이성을 충분히 활용하지 못한 것이 아쉽다. 테스트 코드가 있었다면 이후 구조 변경 시 회귀 검증이 가능했을 것이다.

또한 Preview(미리보기) 시 기존 추론 파이프라인과 동일한 경로를 타야 했기 때문에, GPU 노드 프로비저닝 후 전체 파이프라인을 거쳐야 했다. 빠르게 결과를 확인해야 하는 용도로는 불편했으며, Preview 전용 경량 추론 경로를 별도로 분리했다면 사용자 경험을 크게 개선할 수 있었을 것이다.

배운 점

alpha부터 v3.0까지 4번의 메이저 버전을 거치며, 기능 구현과 운영 안정화는 별개의 과제라는 것을 체감했다. v2.0에서 기능적으로는 목표를 달성했지만 운영 부채가 쌓여 서비스 안정성이 저하되었고, v3.0에서 이를 체계적으로 해결하면서 진정한 프로덕션 서비스의 완성도를 높일 수 있었다. 또한 Ray Job Submission 전환 시 Job과의 접점이 사라지는 문제를 RayJobLogObserver로 해결한 경험을 통해, 분산 시스템에서 관측성(Observability)을 확보하는 것이 안정적 운영의 전제 조건이라는 것을 배웠다.