본문 바로가기

Study/Data Engineering

[요리고 Airflow 도입기] 0. Airflow 사용을 결정한 이유

SW마에스트로 과정에서 본인은 AI 및 데이터 파트를 담당하여 "요리고" 모델에 대한 2개의 AI 모델 개발 및 데이터 파이프라인(이라고 부르지만 서빙이 전부)을 개발하였다.

소마가 끝난 후에 여러모로 데이터 파이프라인 부분에 아쉬움이 많이 남았고, 간단한 사이드 프로젝트로 airflow를 활용하여 데이터 파이프라인을 개선해보려고 한다.

기존 "요리고"의 시스템 구성은 다음과 같다.

 

파란색 하이라이트된 부분이 ai 모델에 대한 데이터 흐름이다.

 

AI 모델의 경우, 서버비 절감을 위해서 Preprcessing, Inference, Postprocessing을 하나의 도커 이미지로 빌드하고 클라이언트의 요청이 있을 때마다 람다를 통해서 컨테이너를 생성하는 형태로 서빙을 진행했고 동작에는 무리가 없었으나 다음과 같은 문제점이 있었다.

 

1. Preprocessing이나 새로 학습한 모델같이 일부 코드에만 수정 사항이 있을 때에도 전체 Docker Image를 새로 빌드하여 ECR에 업데이트해주어야 했다.

이 때, 짧게는 5분 길게는 수시간 정도 컨테이너가 띄워지지 않아서 추론 요청이 실패하는 경우가 있었다.

 

2. Preprocessing 직후, Inference 직후 등 중간 과정에서 Data에 대한 검증이 어려웠다.

요청한 서버 입장에서는 Handler에 포함되어 있는 통신 성공 / 실패 정도만 확인이 가능하고 어느 과정에서 오류가 났는지를 파악하려면 Print 문을 통해서 로그를 남겨주어야 했다. 이마저도 어떤 오류가 났는지는 파악이 어려웠다.

 

3. 새로운 파이프라인을 추가하기 어려운 탓에 확장성이 떨어졌다.

추론 완료된 데이터들로 재학습을 시키거나 다른 모델로 재사용하는 등의 새로운 파이프라인 추가가 어려워서 AWS Lambda를 사용한 것이 무색하게 파이프라인 자체의 확장성이 떨어졌다.

 

이러한 문제점을 해결하기 위해서 필요한 것은 다음과 같다고 판단하였다.

 

1. 하나의 도커 이미지로 퉁쳐져 있는 각각의 과정들을 서로 독립적인 별개의 Task로 분리

Task 단위로 분리할 경우에 코드의 수정이나 오류 탐지가 용이하고 중간에 새로운 Task가 추가되거나 삭제되더라도 전체 파이프라인을 전부 업데이트하는 일이 줄어들 것이라고 예상하였다.

 

2. 이러한 별개의 Task들을 관리할 수 있는 워크플로우 스케쥴링 & 모니터링

각각의 Task들의 실행 실패 / 성공 여부와 버저닝 등을 관리할 수 있는 컨트롤 타워가 필요하다고 판단하였다.

 

 

Airflow는 본인에게 익숙한 언어인 Python을 사용하여 이러한 해결 요건들을 충족시킬 수 있었고, 커뮤니티가 넓어서 Custom Operator나 다른 서드파티 메소드들을 사용할 수 있다는 점이 마음에 들어서 선택하게 되었다.

도입을 결정할 당시에 Airflow에 대해서 아는거라곤 Python쓴다, 워크플로우 오케스트레이션하는 프레임워크다 정도였기 때문에 공식 도큐먼트와 유튜브를 통해서 공부해가면서 프로젝트를 진행하였다.

다음 포스팅부터는 환경 설정부터 DAG 설계까지 프로젝트 전과정에 대해서 포스팅해보려고 한다.

읽어주셔서 너무 감사하고 다음 포스팅도 많은 관심 부탁드립니다 :)