장난감 연구소
졸업 작품 돌아보기, 하모나이즈 (1/2) 본문
올해를 끝으로 소프트웨어학과 4년 생활이 끝난다고 하니 뭔가 아쉬운 마음이 든다. 2주 전 캡스톤 디자인 전시회를 치렀는데, 많이 부족하긴 해도 오랜 시간 공들인 프로젝트라 그런지 신경 썼던 점이나 아쉬웠던 점을 꼭 기록해야만 할 것 같아 써보려고 한다.
프로젝트 소개
프로젝트의 정식 주제는 "사용자 음역 및 선호 기반 노래방 음악 추천 시스템"이다. 이는 사용자의 음역대와 개인의 선호도를 활용해 부르기 좋은 노래를 추천하는 서비스라는 의미를 담고 있다. "사용자 목소리 기반 노래방 음악 추천 시스템"이란 더 직관적인 이름도 고려했으나, 이는 목소리 톤과 같은 더 다양한 특성을 분석한다는 오해를 불러일으킬 수 있어 좀 더 구체적인 현재의 주제명을 선택했다.
이 주제를 처음 시도하는 것은 아니었다. 3학년 1학기 오픈소스개발프로젝트 란 과목에서 음역대 기반으로 부르기 좋은 노래를 추천해주는 앱을 4인 팀프로젝트로 개발한 적이 있다. 당시 과목 담당 교수님께서 "추천시스템 기법을 더 공부하고 적용해서 완성도를 높이면 졸업작품으로도 손색이 없겠다"고 조언해 주셔서 이 주제로 결정하게 되었다. 팀은 기본 4인 중 휴학한 한 명을 제외한 3인으로 구성하였다. 이전에 프로젝트를 진행하면서 부족했던 관리자 기능이나 API 서버와 모델의 통신 방식 등을 개선하고자 했으며, 코드도 완전히 새로 작성했다.
기존 음악 스트리밍 서비스의 추천과 비교했을 때, 내 목소리를 통해 부르기에 적합한 노래를 추천해준다는 점에서 기존의 음악 추천시스템과 차별점이 있다고 생각하였다.
역할
나는 API 서버의 음악 관련 기능과 안드로이드 앱 개발을 주로 담당하였다. 또한 추천시스템의 컨텐츠 기반 추천과 협업 필터링 추천 기능에도 기여하였다.
보안을 공부하고 있는 팀원에게 API 서버의 회원 관련 기능과 관리자 페이지 기능을 분배하였고, 기계학습 관련해 지식을 갖고 있는 팀장이 목소리 분석 모델을 담당해주었다.
주요 기능
서비스의 주요 기능은 아래와 같다.
- 음악과 가수를 등록하고 음원을 분석해 음역대를 추출할 수 있다.
- 회원가입 및 로그인할 수 있다.
- 회원의 목소리를 입력 받아 음역대를 예측할 수 있다.
- 회원의 음역대의 일치 정도와 성별/나이/선호 장르, 로그에 기반한 예측 평점으로 음악을 추천할 수 있다.
- 음악을 검색, 북마크할 수 있다.
- 한 음악과 유사한 음악을 조회할 수 있다.
시스템 구조
시스템 구조는 위와 같았다. 사용자용 클라이언트로 안드로이드 앱을 개발하였고, 관리자용으로 React 웹앱을 만들었다. 서버는 Spring Boot 프레임워크를 사용해 API 서버를 만들어 요청을 처리하도록 하고, Kafka를 활용해 분석 모델과 추천 시스템에 요청을 전달하는 구조로 설계하였다.
프로젝트 개발 과정
디자인
프로젝트에서 가장 먼저 시작한 것은 디자인이다. 디자인은 Figma를 사용했으며, 3학년 1학기 때의 디자인 틀을 바탕으로, 홈 화면을 더욱 다채롭게 구성하고 전반적인 완성도를 높이는 데 중점을 두었다.
안드로이드 앱
사용자 애플리케이션 개발 시 React Native나 Flutter도 고려했으나, 기존에 안드로이드 네이티브 앱으로 개발한 적 있기 때문에, 그 경험을 활용하고자 순수 안드로이드로 개발을 진행했다. 또한 서버와의 프로그래밍 언어 통일성을 위해 Java를 선택했다.
안드로이드 앱 개발을 잘할 수 있을까 검증 차원에서 서버 기능 개발보다 안드로이드 개발을 먼저 시작했던 것 같다. 주로 한 것은 Figma로 만든 디자인을 안드로이드 XML 파일로 표현하는 데 집중하였다. 이 과정에서 아래 디자인의 탭 구현에 가장 많은 시간이 소요된 것 같다.
서버 기능이 개발된 뒤에, 앱 쪽에서 요청을 보내거나 하는 기능이 작동하도록 붙였다.
관리자 페이지
관리자 페이지는 사용자에게 직접 보여지지 않는 부분이라 개발 효율성을 높이는 데 중점을 두었다. 그래서 방법을 찾던 중 React의 UI 라이브러리인 Joy UI를 사용하기로 결정했다. Joy UI는 버튼이나 Input box 같은 기본 컴포넌트를 사용할 때 디자인에 대한 고민을 줄여주었을 뿐만 아니라, 'Order Dashboard' 템플릿을 활용해 변형하는 방식으로 개발을 시작하여 테이블 등 복잡한 요소도 만들 때 수고를 줄이고, 품질을 높일 수 있었다.
결과물을 전시한 캡스톤 디자인 전시회에서도 앱과 관리자 페이지의 디자인을 보고 여러 사람에게 칭찬받을 수 있었다.
API 서버
API 서버는 Spring Boot 프레임워크를 사용하고, DBMS로 MariaDB를 택했다.
이후 신경 쓴 부분과 부족한 점으로 작성하고자 하지만, 테스트 코드를 작성하거나 Hibernate-validator로 입력값을 검증하는 등 개발 과정에서 개인 백엔드 개발 능력 면에서 성장할 수 있었다. 다만 처음해보다 보니 추후 개선할 부분도 많이 존재한다.
모델로 요청 전송
3학년 1학기 때 개발했을 때는 API 서버에서 음악 분석 시스템으로 요청을 보낼 때 소켓 통신을 사용하였다. 그러나 어느 쪽이 먼저 켜지느냐에 따라 소켓 통신이 작동하지 않거나, 분석 시스템이 작업을 하는 동안 다른 요청은 무시되는 것과 같은 문제를 겪었다.
그래서 이번에는 음악 분석 시스템이나 음악 추천 시스템으로 요청을 보낼 때 Kafka를 도입하였다. 이를 통해 보다 안정적으로 요청을 전송하고, 큐를 통해 다른 작업을 하는 도중 전송된 것도 무시되지 않고 대기열에 쌓이는 장점을 얻을 수 있었다.
목소리 분석 모델
목소리 분석 모델은 사용자의 목소리를 분석해 음역대를 예측하는 기능을 가졌다. 이 부분은 다른 팀원이 담당하여 Tensorflow와 SVM을 사용해 다른 가수들과 목소리의 유사도를 통해 예측하도록 만들었다고 한다.
음악 분석 시스템
음악 분석 시스템은 음원 파일로부터 보컬의 Pitch를 추출하는 기능을 가졌다. Pitch Estimation을 목적으로 학습된 모델이 SPICE, CREPE, PESTO 등이 있었는데, 비교적 좋은 결과를 나타낸 Google의 SPICE 모델을 가져와 사용하였다.
음악 추천 시스템
음악 추천은 두 가지 기능으로, 한 음악과 유사한 음악을 추천하는 기능과 사용자의 선호와 음역대에 적합한 음악을 추천하는 두 가지 기능을 가졌다. 추천시스템에 대해 깊은 지식을 갖고 시작한 것은 아니기 때문에 딥러닝을 사용한 기법 등 최신 기법을 사용하지는 않았다.
한 음악과 유사한 음악을 추천할 때는 먼저 음악 관련 정보(장르, 가수, 연도 등)를 문자열로 변환하였다. 변환된 문자열을 TF-IDF 벡터로 벡터화한 뒤, 벡터들 간의 코사인 유사도로 음악 간의 유사도를 판단하도록 콘텐츠 기반 필터링 방식을 사용하였다.
사용자와 적합한 음악을 추천할 때는 먼저 우선 로그(음악 상세 조회, 북마크, 추천 피드백)를 바탕으로 사용자의 음악에 대한 평점을 계산한다. 다음으로 잠재요인(Latent Factor) 협업 필터링의 행렬 분해와 복구 방식에 따라 모든 음악에 대한 예측 평점을 만든다. 마지막으로 성별/나이/장르에 따른 가산점과 노래와 사용자간 음역대 일치 정도에 따른 가산점을 더해 추천에 적합한 곡을 찾도록 개발하였다.
처음에는 추천 시스템이 동기적으로 작동하도록 개발했으나, 다수의 동시 요청을 처리하기 힘들다는 한계를 깨달을 수 있는 계기가 있었다. 이를 개선하기 위해 ThreadPool을 도입하여 최대 5개의 쓰레드로 병렬 처리하도록 음악 추천 시스템을 개선했다.
CI 도구
마지막으로 CI 툴로서 Github Actions를 처음으로 사용하였다. Github Actions를 사용해 커밋할 때마다 테스트를 실행하도록 하였다.
글이 길어져 신경 쓴 부분과 겪은 문제점, 아쉬웠던 점, 프로젝트 결과를 다음 글로 작성한다.
'토이프로젝트' 카테고리의 다른 글
음 높이(Pitch) 예측 모델 정리 (0) | 2024.07.24 |
---|---|
재생 중인 동영상과 음악 컨트롤하기 [실패] (0) | 2021.06.02 |
#2 라즈베리파이 웹 서버 운영하기 - 고정 IP 설정, 포트포워딩 (3) | 2020.02.04 |
#1 라즈베리파이 웹 서버 운영하기 - 우분투 설치, SSH 설정 (0) | 2020.01.21 |
프로그래밍으로 새해 인사말 보내기 (0) | 2020.01.05 |