ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ML Ops 음악 추천 시스템 프로젝트 회고
    프로그래밍/Project 2024. 10. 16. 12:13
    프로젝트 개요

     

    이번 프로젝트는 MLFlow와 Airflow를 활용한 ML Ops를 메인으로 진행됐다.

     

    우리 팀은 ML Ops를 적용할 서비스로 음악 추천 시스템을 선정했다.

     

    주제 선정 이유

     

    기존에도 관심이 있던 추천 시스템 분야였고, 서비스를 만들기 위해서는 데이터가 있어야 하는데 음악 추천 시스템을 할 경우, 스포티파이 API에서 제공되는 Audio Features를 이용하면 데이터를 수집하기에도 비교적 용이하고, 곡 추천 시에도 비교적 명확한 기준을 가지고 추천하는게 가능하겠다는 생각이 들어 주제로 선정했다.

     

    담당한 역할

     

    이번 프로젝트는 ML "Ops"가 메인이었기 때문에 ML 부분에만 모든 사람이 달려들기보다는 전체적으로 시스템을 만드는데 집중하는게 좋을 것 같았고, 그래서 나는 FastAPI와 Streamlit을 이용해 서비스를 적용한 웹페이지를 구현하기로 했다.

     

    추가로 데이터 수집에 있어서 스포티파이 API를 사용하면 간편하게 곡 목록을 받아 올 수 있을 거라는 기대와는 다르게 Search 기능을 이용해서 곡을 각각 검색해서 가져와야하는 문제가 있었다.

    그래서 비교적 초반에 여유가 있었던 내가 도움을 주기로 했다.

     

    데이터 수집

     

    앞에서 말했다시피 스포티파이 API로 간편하게 곡 목록을 가져오는게 불가능해서 어떻게 해결을 해야할까 고민했다.

     

    고민해본 결과, 국내 음원 서비스에서 차트 목록을 받아와서 그 목록을 기준으로 스포티파이 API의 Search 기능으로 곡 데이터를 검색해 가져오는 것이 국내 이용자를 타겟으로 서비스를 만든다는 목표에도 부합했다.

     

    따라서 아래와 같은 순서로 데이터 수집을 진행했다.

    1. 벅스(Bugs) 의 주간 앨범 순위를 크롤링해서 2020년부터 2024년 9월까지의 앨범 목록을 가져온다.
    2. 스포티파이 API의 파이썬 라이브러리 버전인 Spotipy를 이용해 앨범 정보를 Search 한다. (앨범 ID)
    3. 앞에서 획득한 앨범 ID를 이용해 앨범의 Track 데이터를 가져온다. (트랙 ID)
    4. 앞에서 획득한 트랙 ID를 이용해 각 트랙의 Audio Features 데이터를 가져온다. (Audio Features)

     

    중복 데이터들을 제외하고 최종적으로 수집된 벅스 기준 데이터는 약 2만개 였다.

     

    이에 더해 해외 곡의 수요도 감안해 다른 팀원이 찾아낸 스포티파이에서 제공하는 해외 곡 데이터 20만개 중 랜덤으로 2만개를 골라 사용하기로 했다.

     

    모델 학습

     

    모델을 학습 시키는데는 Auto Encoder와 KMean 클러스터링, GNN을 이용해 각 곡의 Audio Features를 기준으로 곡 별로 전체적인 특성이 유사한 곡의 목록이 출력 되도록 했다.

     

    하이퍼 파라미터를 변경했을 때 어떻게 변하는지, 최종 선택한 방법과 PCA와 KMeans 클러스터링, DBSCAN 을 이용한 방법 두 가지 모델의 결과를 Silhouette Score 와 Calinski-Score 두가지로 성능을 비교할 수 있도록 MLFlow를 이용해 적용된 파라미터, 방식, 점수 등이 기록된다.

     

    여기서 추가로 유사한 곡을 코사인 유사도와 유클리디언 거리 기반으로 계산하도록 해 총 두가지 추천 목록을 보여준다.

    이 두가지 목록을 비교해 보니 아래와 같은 경향을 보였다.

     

    코사인 유사도 기반 추천 목록 : 노래 스타일, 장르가 비슷한 곡이 추천됨
    유클리디언 거리 기반 추천 목록 : 템포, 음향 등 수치적으로 매우 유사한 곡이 추천됨

     

    Airflow 구현

     

     

    최종적으로 위와 같은 구조로 폴더를 구성했고 이를 기준으로 Airflow를 실행하면 작동하는 구조는 아래와 같다.

    1. S3에서 데이터 다운로드 => Airflow의 S3Hook을 사용하여 AWS S3 버킷에 연결
    2. 필요 파일을 S3 버킷에서 로컬로
    3. EDA 수행 및 ML 모델 훈련 (병렬 실행)
    4. EDA 결과 및 ML 모델을 S3에 업로드 => S3Hook을 사용하여 EDA 결과와 훈련된 모델을 S3 버킷에 업로드
    5. FastAPI 서버 시작

     

    태스크는 t1 >> [t2, t3] >> t4 >> t5 순으로 진행된다.

    데이터 다운로드(t1) 후 EDA(t2)와 모델 훈련(t3)이 병렬로 실행
    다음 결과 업로드(t4)가 실행되고, 마지막으로 FastAPI 서버(t5)가 시작

     

    FastAPI & Streamlit (최종 결과물)

     

     

    최종적으로 위와 같은 서비스를 만들었다.

    기본적으로 곡 목록을 보여주고 곡을 선택하면 선택한 곡과 유사한 곡 목록을 보여주도록 했다.

     

    이렇게 두가지 추천 방법을 선택 가능하도록 했고, 선택한 추천 방법에 따라 추천되는 곡 전체가 다른 경향을 보이거나 하지는 않지만 세부적으로 유사한 순위가 다르게 나온다.

     

    검색 부분에서는 fuzz 라이브러리를 이용해 검색어와 유사한 곡들을 우선적으로 상위에 보여주도록 하는 등 세세한 부분들을 조정하기도 했다.

     

    아쉬웠던 점 및 결론

     

    우선 가장 아쉬웠던 점은 '사용자 취향 맞춤 추천' 을 구현하지 못했다는 점이다.

    다른 것 보다도 데이터 수집에 시간이 너무 오래 걸려 절대적으로 시간이 부족했다.

    그리고 사용자 취향에 맞추려면 웹페이지에서 곡 목록을 보여주고 해당 곡에 대한 사용자의 선호도를 저장하고 그렇게 저장된 선호도를 기반으로 모델이 따로 학습을 진행해야하는데, 모델 학습에 너무 오래 걸리는 점이 실시간으로 추천 시스템을 제공하기에는 무리가 있다고 판단해 각 곡 별로 유사한 곡의 목록을 보여주는 방식으로 선회하게 되었다.

     

    두번째는 데이터 수집에 너무 오랜 시간이 걸렸다는 점이다.

    수집해야하는 데이터의 종류와 양이 이미 정해져 있는 상황이었음에도 불구하고 데이터 수집에 오랜 시간이 걸린 가장 큰 원인은 스포티파이 API의 호출 제한이 생각보다 빡빡하게 걸려있다는 것이었다.

    이제 데이터를 받아오기 시작했다 싶으면 호출 제한이 걸려 짧게는 1시간, 길게는 다음날이 되어야 다시 정상적으로 작동을 하는 모습을 보였다.

    이 부분은 결과적으로 배치(batch) 처리를 적용해서 해결했는데, 이 배치처리를 빠르게 생각해내지 못해서 그냥 날려버린 시간이 너무 많아서 아쉽다.

Designed by Tistory.