MUSEEK(Music Seek)
MBC 라디오 앱은 실시간 선곡 정보를 제공하기 위해 외부 서비스(멜론)를 이용하고 있었다. 그런데 이 서비스가 종료되며 급하게 서비스 개발 요청이 들어왔다.
사실 올해 계획한 프로젝트는 음악 추천 서비스였다. 작년 말부터 준비를 하고 있었는데, 본의 아니게 실시간 음악 인식 프로젝트가 시작됐다.
프로젝트를 시작하고 가장 먼저 마주한 현실은 숫자의 폭력이었다.
사내 등록된 곡이 약 200만 곡. 생각보다 많지 않다 싶었는데, AI가 음악을 인식하려면 이걸 작은 조각으로 나누어야 한다는 걸 알고 나서 상황이 달라졌다. 단순하게 계산해도 4억개가 넘는 음악 조각이 나왔다.
'이걸... 어떻게... 처리하지?'
4억이라는 숫자가 주는 압박감이란... 그래도 시작은 해야 했다.
첫 번째 미션: 음악을 컴퓨터가 이해할 수 있는 '언어'로 번역하기.
음악을 벡터로 바꾸는 AI 모델들을 하나씩 테스트해보기 시작했다.
"안녕, 나는 원래 음성 인식용이야. 근데 음악도 할 수 있어!"
장점: 성능이 괜찮다
단점: 좀 무겁다
"나는 최신 트랜스포머 기술이야. 핫하다고!"
장점: 이론적으로 멋있다
단점: 실제로는 그저 그렇다
"언어와 오디오를 동시에! 멀티플레이어야!"
장점: 대세 of 대세
단점: 우리 환경에선 오버스펙
결과는 의외였다. 음성 인식용으로 태어난 wav2vec 2.0이 우리 라디오 환경에서 가장 높은 정확도를 보였다. 역시 인생은 예측 불가능하다. 사실 이때까지만 해도 "AI가 알아서 다 해주겠지" 하는 순진한 생각을 가지고 있었다. 하지만 현실은 그렇게 호락호락하지 않았다.
음악을 벡터로 바꾸는 건 해결했다. 이제 이 4.2억 개의 벡터를 어딘가에 저장하고, 실시간으로 들어오는 라디오 음성과 비교해서 가장 유사한 걸 찾아야 했다.
그냥 반복문? 4억 번의 비교를 실시간으로? 컴퓨터가 과로사할 판이었다.
다행히 Facebook(지금의 Meta)에서 만든 FAISS(Facebook AI Similarity Search)라는 도구가 있었다. 이름부터 우리가 원하는 그것이었다.
FAISS는 정말 영리한 아이였다.
IVF 클러스터링: "비슷한 애들끼리 모여 있어봐. 나중에 찾기 쉽게."
PQ 벡터 양자화: "이렇게 자세할 필요 없어. 대충 압축하자."
이중 코드북: "효율적으로 관리하는 게 내 특기야."
덕분에 메모리 사용량은 줄이면서 검색 속도는 확보할 수 있었다. 하지만 여기서 첫 번째 현실의 벽을 만났다.
벡터 유사도만으로 음악을 찾는 게 생각만큼 쉽지 않았다. 실제 라디오 환경은 실험실과 달랐다.
DJ가 노래 위에 멘트를 하는 경우
광고나 효과음이 섞여 나오는 경우
원본과 라디오 버전의 음질 차이
같은 곡이지만 리마스터 버전인 경우
AI는 정직했다. 입력된 데이터와 정확히 일치하지 않으면 "모르겠어요"라고 대답했다. 융통성이라곤 찾아볼 수 없었다. 그래서 깨달았다. 완벽한 AI는 없다는 것을.
순수한 머신러닝만으로는 한계가 있다는 걸 인정하고, 도메인 지식을 활용한 MUSEEK-AI 알고리즘을 개발하기로 했다.
6초로 시작해서 안 되면 12초, 24초, 36초까지 점진적 확장
"한 번에 안 되면 좀 더 들어보자"는 인간적 접근
여러 청크에서 같은 곡이 나오면 "얘가 정답일 확률이 높아"
확률과 통계의 힘
같은 곡의 다른 버전들을 정리
"태연 - HAPPY"와 "태연 - HAPPY (Remastered)"는 같은 곡
확신이 없으면 차라리 "모르겠다"고 말하기
틀린 답보다는 솔직한 무응답이 낫다
특성 기반 예측 모델
지속적 피드백을 통한 자가 학습
결과는? 100%는 아니지만, 실용적으로는 충분한 수준이었다.
프로젝트 초기에는 "음성 들어오면 AI가 인식해서 결과 출력하면 끝"이라고 생각했다. 실제로는 그렇게 단순하지 않았다. 요구사항이 하나씩 추가될 때마다 시스템이 조금씩 복잡해졌다.
"실시간으로 처리해야 해요"
"에러가 나면 재시도해야 해요"
"일별 통계도 필요해요"
"API로도 제공해야 해요"
"모니터링도 할 수 있어야 해요"
마치 레고 블록을 하나씩 쌓아가듯이, 시스템이 점점 커져갔다.
"라디오 신호를 받아서 5초씩 쪼개드립니다"
HLS 스트리밍을 1초 간격으로 처리
YAMNet으로 "이거 음악 맞나?" 사전 검증
"음악을 숫자로 바꿔드립니다"
실시간 API와 일별 배치 처리 두 가지 모드
wav2vec 2.0이 열심히 일하는 곳
"4억 개 중에서 찾아드립니다"
FAISS가 메인, 속도가 생명
인덱스 관리까지 책임
"모든 걸 다 기억해드립니다"
메타데이터, 임시 벡터, 최종 결과까지
MySQL과 Redis의 협업
"외부에서 쓸 수 있게 해드립니다"
JSON으로 깔끔하게 응답
라디오 앱의 든든한 파트너
각 모듈을 독립적으로 만든 덕분에 하나가 문제 생겨도 전체가 멈추지 않았다. 마이크로서비스 아키텍처의 진정한 힘을 느꼈던 순간이었다.
가장 큰 착각은 "AI가 모든 걸 해결해줄 것"이라는 생각이었다.
AI도 컨텍스트를 모르면 바보가 된다
100% 정확도는 환상이다
실험실 성능과 실전 성능은 다르다
하지만 이런 어려움들을 하나씩 해결해가는 과정이 정말 즐거웠다:
"안 돼"에서 "돼!"로 바뀌는 순간의 쾌감
팀원들과 함께 밤늦게 디버깅하던 추억
사용자들이 "잘 된다"고 할 때의 뿌듯함
1. 모듈화의 힘 : 각 기능을 독립적인 서버로 만든 덕분에 문제가 생겨도 전체가 마비되지 않았다. 마이크로서비스의 진정한 가치를 체험했다.
2. 에러 처리가 핵심 : 완벽한 성공보다 우아한 실패가 더 중요하다. 에러 큐와 재처리 로직이 시스템 안정성의 핵심이었다.
3. 룰과 AI의 조화 : 순수한 머신러닝도, 순수한 룰 기반도 완벽하지 않다. 둘을 적절히 조합했을 때 최고의 결과가 나왔다.
4. 도메인 지식의 중요성 : 아무리 좋은 AI라도 해당 분야에 대한 이해 없이는 실용적인 결과를 내기 어렵다.
"지금 나오는 이 노래 뭐지?"라는 단순한 질문에서 시작된 프로젝트가 5개월 만에 하나의 서비스가 되었다.
기술적으로는 AI 음성 인식, 벡터 검색, 실시간 스트리밍 처리, 마이크로서비스 아키텍처 등 다양한 영역을 경험할 수 있었다. 하지만 가장 중요한 건 기술 자체가 아니라 실제 문제를 해결하는 것이라는 점을 배웠다.
완벽한 AI는 없다. 하지만 불완전한 AI라도 적절히 활용하면 충분히 가치 있는 서비스를 만들 수 있다. 중요한 건 기술의 한계를 인정하고, 그 한계를 보완할 수 있는 방법을 찾는 것이다.
이제 AI가 음악을 만드는 세상이다. 기술은 계속 발전하고, 우리의 상상력도 계속 확장된다. MUSEEK는 끝이 아니라 시작이다.