유튜브 요리 검색사이트 주소: https://can-cook.com 아직 아쉬운 점이 많은데 먼저 출시부터 했다. 반응이 있으면 더 개선하기로 했다. 이번 개발에서 주로 고민했던 부분들은 ai와 검색품질, 그리고 인프라였다. 하나씩 회고해보자.
ai
요리 유튜브 영상의 제목과 설명, 그리고 자막 데이터를 인풋으로 요리 레시피 정보를 생성했다. 결과물이 사용하는 ai의 모델에 따라 영향을 많이 받았다. 낮은 품질의 ai 모델을 사용하면 여러가지 문제가 생긴다. 예를들어 검색 용이성을 위해서 재료 이름에 가급적 수식어를 넣지 말라고 프롬프트를 작성했다. 그러나 낮은 성능의 모델에서는 ‘신선한 스페인산 돼지고기 앞다리살 600g’와 같은 재료 이름을 줬다.
요리 영상 데이터를 만드는데는 최소한 claude3 sonet 정도 성능의 모델은 되어야겠다고 생각했다. 그러고 나니 비용문제가 걱정되었다. 데이터 2000개 정도 생성하면 대략 100달러정도다. 비용을 줄이려고 llama3 파인튜닝도 알아봤고(실패), 저렴한 모델로 해당 영상이 요리영상인지 필터링 하는 전처리 단계도 추가하기도 했다.
이것저것 고민 많이 했는데, 결과적으로는 7월 현재 gpt-4o-mini라는 모델이 나와서 모두 해결되었다. 정말 저렴하게 데이터 생성이 가능해졌다.
검색
meilisearch라는 오픈소스 검색 라이브러리를 사용했다. 엘라스틱서치는 어렵고, 알고리아는 비싸서 대안으로 선택했다. 기능은 만족한다. 사용하기 쉽고 성능도 괜찮았다. db 동기화쪽이 문제였다. 프로젝트에서 데이터베이스를 sqlite 확장인 turso의 libsql를 사용하는데, meilisync에서 지원을 안해주는게 문제다. 이에 해결책으로 생각해본건
- 내가 직접 동기화 코드를 작성한다. 요리 레시피 테이블에서 배치로 전체 조회를 한번씩 하고 meilisearch 인스턴스에 저장되어 있는지 비교하는 방식을 고려했다.
- dump파일을 버저닝해서 관리하는 방식. dump를 r2에 업로드하고, 도커파일 생성시에 다운로드받아서 인스턴스에 적용하는 방법을 생각했는데 관리 포인트가 더 많아지는 것 같아서 포기했다.
- 기본적으로 데이터는 로컬 파일로 저장된다. 스냅샷 저장이 되는 볼륨을 사용해서 만약 문제가 생기면
인프라
현재 인프라 셋팅은 이러하다. 웹은 cloudflare-pages로 배포, 검색서버는 fly.io로 배포, db는 turso를 사용하고 있다. 문제는 fly.io의 서버는 한 서버에 하나의 볼륨을 할당가능하다. 쿠버네티스의 pvc처럼 별도의 영구 저장소가 있고 여러 pod가 이를 공유하는 식으로 사용하기 어려운 것 같다. 그래서 수평으로 자동스케일링 되는 기능을 사용할 수가 없다. (직접 모니터링 하다가 수직 확장을 해주면 문제없긴하다.) 고민했는데 트래픽이 늘어나면 쿠버네티스로 인프라를 이전할 생각이다. fly의 볼륨 문제도 있고, 여러개의 인프라 플랫폼을 사용하는게 피곤하기도 하다. 쿠버네티스 하나만 관리할 수 있으면 좋을 것 같다. 공급자는 vultr의 vke를 사용할 듯 싶다.
많이 부족하지만 출시를 했다는 점에서 만족한다. 컨텐츠만 채워넣고 반년정도 자연유입이 되는지 지켜보자. 다음 프로젝트는 뭘 할지 고민 중이다.