2023 AWS re: Invent — 스푼라디오의 목소리 추천과 MongoDB Atlas의 Vector Search
반갑습니다. 스푼라디오에서 머신러닝 엔지니어로 근무 중인 Tyler 입니다. 감사하게도 회사의 배려로 2023 AWS re:Invent에 참석하고 블로그를 작성하게 되었습니다.
라스베가스 후기
저는 어린 나이가 아니지만 해외에 한 번도 나가본 적이 없고, 제주도가 맥시멈 입니다. 여행도 즐기는 성향이 아니라서 해외가 왜 좋은지도 몰랐습니다. 그래서 솔직히 번거롭다는 생각이 마음 속에 있었는데요.
정말 좋았습니다. 이래서 다들 해외 해외 하는구나 싶었습니다.
그리고 메가존 클라우드가 준비해 주신 코스 속에서 광활한 그랜드 캐년도 밟아 봤습니다.
오디오 팀의 Ben께서 구성원들의 사진을 정말 많이 찍어주셔서 좋은 추억을 많이 남겨 왔네요. 감사합니다.
카지노의 도시 라스베가스는 낮보다 밤이 더 빛나는 도시입니다. 밤마다 걷는 재미가 쏠쏠했던 기억이 있네요.
사막이다보니 건조해서, 물을 하루 4~5리터씩 마시는 저 때문에 룸메이트 Andy 가 밤마다 물을 사러 가느라 고생을 해 주셨습니다. 미안합니다.
이제 여행 이야기는 마무리 하고, 기술적인 이야기를 하려 합니다.
AWS re:Invent 에는 전 세계의 엔지니어가 한 데 모여 놀라운 사이즈의 축제를 만들었습니다.
연일 이어지는 KeyNote와 세션을 구경하며 확실히 느낀 것은, 도메인을 막론하고 생성형 AI가 현재의 중심에 있다는 것이었습니다.
스푼 라디오는 오디오 스트리밍 서비스입니다. 물론 우리 서비스에 머신러닝은 text / image / audio 모든 도메인에 녹아들어 있지만, 저는 현재 오디오를 위한 ML 모델 그 자체와 음성 처리를 위한 노하우에 깊게 관심을 갖고 있습니다. 하지만 AWS re:Invent가 ML의 리서치 결과를 공유하는 자리는 아닌지라 제 관심사에 딱 들어맞는 세션이 보이지는 않았습니다.
그래서 메가존 클라우드에서 준비 한 Solutions Day를 훑어 보던 와중에, 우리 서비스에서 사용중인 목소리 추천 시스템(Lucy)의 핵심 알고리즘이 떠오르는 세션을 발견 하였습니다.
AWS의 파트너인 MongoDB에서 제공하는 Atlas 에 대해 발표한 세션 이었습니다. Atlas는 클라우드 상의 다양한 데이터 처리를 지원하는 데이터 플랫폼입니다. AI가 주류를 이루는 흐름에 맞게 이번 세션에서 Vector Search 라는 기능을 새로 출시하여 소개 하였는데요.
이제부터 MongoDB 에서 제안하는 Atlas Vector Search 의 특장점을 소개 해 드리고, 스푼의 목소리 추천 시스템 Lucy를 곁들여 설명하려 합니다.
스푼라디오에서 Vector Search는 언제 사용하는가?
“A의 목소리를 좋아하는 유저에게 A와 목소리가 비슷한 사람들을 추천하자”
스푼라디오 데이터 테크팀이 Lucy를 처음 고안할 때 출발점이 되었던 핵심 아이디어 이며, 지금도 이 핵심은 바뀌지 않았습니다. 하지만 너무 직관적인 말이니 구현하는 엔지니어 입장에서는 더 구체화 해야겠지요. 이 문장을 머신러닝에 맞게 바꾸어 보겠습니다.
“A의 목소리를 좋아하는 유저에게 A의 목소리 벡터와 유사도가 가장 높은 사람들을 찾아서 추천하자"
이제 Vector Search가 어디에 쓰일 지 느낌이 오실 것 같습니다. 이 문장이 Lucy의 핵심 기능이며, 이걸 잘 해내야 청취자에게 취향을 저격한 목소리들을 추천 할 수 있습니다.
그리고 이 작업은 두 페이스로 쪼개집니다.
- Embedding : A를 비롯한 DJ들의 목소리를 벡터로 추출하여 저장한다
- Vector Search : 저장 된 목소리 벡터를 탐색하여, A와 유사한 사람들을 빠르고 정확하게 가져온다
1번 작업 : 머신러닝 용어로 Embedding(임베딩)이라고 부릅니다. 날것의 오디오 파일에서 ML 모델을 활용하여 목소리 벡터를 추출하고 벡터 공간에 집어 넣는다는 의미입니다.
우리는 이 Embedding 된 목소리 벡터를 성문(Voiceprint)이라고 부르며, 이 벡터에는 다른 사람과 차별화 되는 당사자의 목소리 특징이 담겨 있습니다.
그러니 성문이 벡터 공간에서 서로 비슷한 곳에 위치한다면, 두 사람은 유사한 목소리를 가질 것이라 기대할 수 있겠지요?
사실은 목소리가 비슷한 사람이 정말 유사한 벡터를 갖도록 Embedding(임베딩)을 잘 해내는 것이 성능을 판가름 짓는 근원입니다. 때문에 스푼라디오의 데이터 테크팀은 지속적인 연구를 거치며 자체 학습시킨 성문 추출 모델을 활용하고 있지만, 임베딩에 대한 이야기는 기회가 되면 따로 소개 하겠습니다. 일단은 모든 목소리 벡터가 잘 준비되어 있다고 상정 하고 이야기를 진행합니다.
2번 작업 : Vector Search가 이루어지는 부분입니다.
수 많은 DJ들의 성문 벡터들이 저장되어 있고, 내가 원하는 DJ의 성문 v를 가지고, v와 가장 유사도가 높은 벡터의 주인공을 가져오는 것이지요.
어떤 산식으로 벡터 간 유사도를 측정할 지 결정하는 것은 사용자의 재량이며 Euclidean distance, Cosine distance 등의 선택지가 있습니다. Lucy에서는 Cosine distance를 사용 합니다.
바로 이 부분에서 Lucy가 Atlas의 서비스 Vector Search와 핵심을 공유하고 있습니다. 더하여 Atlas에서는 부가적인 장점들을 제시하고 있습니다. 이제부터 Atlas Vector Search를 살펴보려 합니다.
Atlas의 Vector Search
1. 데이터와 함께 저장 된 Vector
Atlas의 Vector Search는 MongoDB에서 개발한 서비스임을 다시 새길 필요가 있습니다. 단순한 DB의 저장과 검색 기능을 넘어 데이터 그 자체보다, 데이터의 내재 된 의미를 활용한 검색을 제공하기 위해 고안 되었습니다.
의미론적 검색을 이해하게 쉽게 설명 하려면, ML의 자연어 처리를 예시로 드는 게 좋겠습니다.
- {
“user_id”: “1234567”,
“sentence”: “밥 먹었어?”,
“saved”: “2022–05–01”,
“gender”: Female,
“os” : iOS
} - {
“user_id”: “4815019”,
“sentence”: “식사 하셨나요?”,
“saved”: “2023–10–29”,
“gender”: Male,
“os” : Android
}
의미가 거의 동일한 두 문장의 데이터가 DB에 저장 되어있다고 가정 합시다.
그런데, 만약 “밥 먹었니?" 라는 문장이 담긴 데이터 1번을 쿼리로 날려 의미가 비슷한 데이터를 가져오고 싶다면 어떻게 해야할까요?
두 문장이 의미가 똑같다는 걸 인간이라면 모두가 알 수 있지만.. 놀랍게도 단 한글자도 겹치지 않습니다. 1번의 검색 결과가 2번이 되도록 할 방법이 떠오르지 않네요.
이럴 때 의미론적 검색이 필요합니다. 만약 두 문장을, 앞서 소개한 Lucy의 사례와 같이 비슷한 벡터로 벡터 공간에 임베딩 한다면, 벡터 유사도 기반의 검색으로 두 문장이 서로의 검색 결과로 도출 될 수 있을 것입니다.
Atlas의 Vector Search는 아래의 스키마를 제공합니다.
Document DB의 형태에 Embedding Vector가 함께 저장 되어있는 형태입니다. 이런 구조를 통해서 기존 Atlas Search 처럼 데이터 자체를 활용하는 검색과, 벡터 유사도 기반의 의미론적 검색을 동시에 고려한 강력한 기능을 가능하게 합니다.
또한 이렇게 벡터와 데이터를 함께 저장하는 구조는 벡터와 데이터의 싱크를 맞추는 매우 번거로운 작업을 해결 해 줍니다.
우리 서비스는 현재 목소리 벡터(성문)의 주인이 누구인 지 식별하기 위한 정보만 저장하고 있습니다. 만약 Atlas Vector Search를 활용하면 아래 데이터를 목소리 벡터(성문)와 함께 저장 할 수 있겠습니다.
- 성문의 주인 성별
- 성문이 추출 된 시점
- 추출한 오디오의 각종 메타데이터
- 발화자가 읽은 문장
이런 데이터를 함께 저장 한다면 성문 유사도 검색과 동시에 성별, 연령대 등유저의 취향을 타게팅 할 정보를 동시에 쉽게 검색할 수 있겠다는 생각이 듭니다.
Vector Search는 2048 차원의 실수형 벡터까지 지원한다고 하니 다행히 우리 성문의 차원과 딱 맞네요.
2. 매우 빠른 유사도 기반의 검색 속도
제가 Vector Search에 흥미를 느낀 핵심 기능입니다.
Lucy를 개발할 때, 성문을 Embedding 하는 모델을 학습시키고 벡터를 확보한 뒤 서비스 적용에서 어려움을 겪었던 부분은 바로 유사도 기반의 검색이었습니다.
우리는 Cosine distance를 유사도로 활용 하는데요, 문제는 타겟 벡터와 가장 유사한 벡터를 가져오려면 우리가 가진 모든 벡터와 유사도 계산을 해야한다는 것입니다.
우리가 보유한 DJ들의 성문은 한국 4만명, 일본 8만명에 달하며, 지금도 수량이 계속 늘어나고 있습니다. 성문이 늘어 날 때마다 DJ끼리 서로의 유사도 랭킹을 새로 계산해야 하니 복잡도가 O(n²) 단위로 늘어나게 됩니다.
이것은 매우 많은 시간을 소요하는 작업으로, 배치성으로 추천 리스트를 생성하는 현재와 달리 추후 실시간에 가까운 추천이 이루어져야 하는 상황이 오면 반드시 해결해야 하는 골칫거리였습니다.
Atlas Vector Search에서는 HNSW 라는 계층형 벡터 유사도 검색 알고리즘을 적용해 속도 문제를 해결했습니다. 그림에 보시다시피 벡터 공간을 계층화 하여 각 계층에서 가장 가까운 벡터를 찾아 다음 계층으로 내보내는 방식의 검색입니다. (논문 링크)
정확한 유사도 검색을 조금 포기 하더라도, 실시간에 가까운 응답이 더 중요한 상황에 사용한다고 합니다. 우리 스푼라디오 역시 실시간 목소리 추천이 필요한 상황이 온다면 Atlas Vector Search를 사용하지 않더라도 반드시 구현하여 적용 해야겠네요.
전체 프로세스 정리
모든 과정을 다시 한 번 짚어보겠습니다. 위 도식에 원천데이터에서 출발해서 Vector Search까지 이루어지는 과정이 잘 나와 있습니다.
우리 스푼라디오의 Lucy 에 맞추어 보자면,
- Unstructured Data는 DJ의 발화가 담긴 오디오
- Embedding Model은 우리가 자체적으로 학습시켜 개발한 뉴럴 네트워크 모델
- Embeddings 는 목소리 특징이 담긴 성문 벡터
이렇게 매칭이 되겠네요. 이렇게 추출 된 벡터는 그대로 Document DB에 저장이 되거나, 바로 다른 벡터와의 유사도 검색에 사용 되겠습니다.
우리 팀에서는 현재 클라우드 상에서 발화 오디오를 활용한 실시간 성문 추출과 추천 리스트 응답을 고려하고 있습니다. 필요할 시 MongoDB의 Atlas 사용을 진지하게 검토할 수 있겠네요.
마치며
AWS re:Invent에 다녀온 덕에 기술에 대한 시야가 넓어졌고, 스푼라디오의 목소리 추천 Lucy도 간단히 소개 하며 정신을 환기하는 시간을 가졌습니다.
좋은 기회를 주신 스푼라디오에게 다시 한 번 감사드리고, 저는 AWS 이벤트 출장 기회가 있다면 신청하시는 것을 적극 추천합니다.
이 글을 보시는 여러분이 스푼라디오의 목소리 추천과 Atlas Vector Search를 이해하시는 데 도움을 드렸다면 좋겠습니다.