시간이 얼마 흐르지 않은 것 같은데 어느 덧 소프트웨어 마에스트로 13기 활동을 시작한지 3개월이라는 시간이 흘렀습니다. 이번 포스팅에서는 프로젝트에서 필요한 딥러닝 추론서버를 어떤 방법으로 구축했는지 소개하겠습니다.
현재 팀원들과 함께 진행하고 있는 프로젝트는 기존에 구하기 어려운 악보들을 인공지능 모델로 근음을 잡아줘서 사용자에게 제공하고 또 모델이 잡지 못하는 세부적인 악보를 직접 수정 & 공유를 가능하게 함으로써 양질의 악보를 제공해주는 프로젝트입니다.
악보생성로직은 아래와 같이 크게 3단계로 이루어져있습니다.
개발에 앞서 각 로직이 어떤 데이터가 필요한지 생각해봤고 순서도를 그려봤습니다.
악보 생성 로직은 서비스 단위로 구분하여 도커 컨테이너로 독립된 환경을 구축했습니다.
음원 분리와 근음 생성은 서로 다른 오픈소스 모델을 사용하고 있었습니다. 하나의 환경에 전부 묶어서 구축하면 파이썬 라이브러리 의존성과 독립 환경이 너무 무거워졌기에 도커라이징을 통해 분리했습니다.
각 컨테이너는 도커 컴포즈로 묶어서 일괄적으로 실행합니다. 도커 컴포즈는 Default로 네트워크 브릿지를 생성해서 각 컨테이너가 공유할 수 있도록 합니다.
따라서 컨트롤러 컨테이너는 도커 컴포즈에 정의된 서비스 네임으로 각 컨테이너에 HTTP 요청을 보낼 수 있습니다.
각 컨테이너는 도커 볼륨을 통해 자원을 공유합니다. 볼륨에 존재하는 모든 데이터는 악보 생성이 완료된 이후에 사용하지 않는 데이터였기 때문에 모두 삭제하였습니다.
추론서버를 구축하고 나서 사용자로부터 요청을 받고 악보를 제공하는 전체로직을 그려봤습니다.
악보가 이미 존재하면 사용자에게 바로 악보를 제공한다.
악보가 존재하지 않을 경우에 api 서버는 message broker 에게 악보생성 요청 메세지를 전송한다
진행 상황(state)는 아래와 같다
state 0: 음원 분리 전
state 1: 음원 분리 완료
state 2: 코드 생성 완료
state 3: 악보 생성 완료
사용자가 현재 상태를 체크하려고 계속 request를 서버에 보내는 방식은 비효율적이라고 생각했습니다. 그래서 좀더 greedy 한 접근인 long polling 방식을 채택했습니다.
기존에 클라이언트는 요청을 보내고 나서 악보 생성이 어느정도 진행되었는지 알 수 없다는 문제가 있었습니다.
위와 같은 문제를 해결하고자 Redis의 Pub Sub 을 사용해서 특정 Redis Channel 을 바라보고 있는 api server 들에게 일괄적으로 현재의 상태를 전달해줘서 결과적으로 클라이언트가 현재 진행상황을 알 수 있도록 구현하였습니다.
Mongo Database 와 redis 는 특정 security group 에서만 접근 가능하도록 하였습니다.
또한 api 서버와 추론 서버를 각각 다른 가용영역(subnet)에 위치시켰습니다.
2년동안 회사 생활을 하면서 앱 개발, 프론트엔드 개발 등 다양한 개발 업무를 맡아봤지만 백엔드 개발은 전무했기에 항상 팀원들과 우리가 현재 설계한 방식에서의 문제점은 없는지 있다면 어떻게 해결할 것인지에 대해 고민하고 있습니다.
다음 포스팅에서는 이후에 발생할 문제점을 어떻게 해결했는지 또 추가한 기능에 대한 내용을 소개하겠습니다 ㅎㅎㅎ