20220805

sentence-transformers 한글 검색 임베딩

상품 검색에 한국어 임베딩을 넣어보려고 sentence-transformers 몇 개 시도. 올해 초 Milvus vs Weaviate 비교할 때 임베딩 품질 아쉬웠던 걸 개선하는 작업.

테스트한 모델

  • paraphrase-multilingual-MiniLM-L12-v2 — 다국어, 가벼움(384d)
  • paraphrase-multilingual-mpnet-base-v2 — 다국어, 품질 더 좋은 대신 느림(768d)
  • jhgan/ko-sroberta-multitask — 허깅페이스의 한국어 특화 모델
  • BM-K/KoSimCSE-roberta-multitask — KoSimCSE. 한국어 STS 벤치 높음

평가 기준

사내에서 직접 라벨링한 상품 쿼리→정답 상품 1,200쌍. MRR@10, Recall@10.

from sentence_transformers import SentenceTransformer

m = SentenceTransformer("jhgan/ko-sroberta-multitask")
q_emb = m.encode(queries, batch_size=64, normalize_embeddings=True)
d_emb = m.encode(docs, batch_size=64, normalize_embeddings=True)

결과

모델MRR@10Recall@10인코딩 속도
multilingual-MiniLM0.410.58빠름
multilingual-mpnet0.520.69중간
ko-sroberta0.610.74중간
KoSimCSE-roberta0.630.76중간

한국어 전용 모델들이 확연히 좋다. 특히 상품명의 축약/약어("삼디충", "갤S22" 등)에서 차이가 큼. 다국어 mpnet도 나쁘진 않아서 영문 혼합 도메인이면 괜찮은 선택.

실운영 적용

KoSimCSE 기반으로 벡터 인덱싱. Weaviate에 올리고 BM25와 하이브리드 검색(70:30 가중). BM25 단독 대비 Recall@10이 0.55 → 0.78로 개선.

임베딩 모델도 주기적으로 재학습해야 함. 신규 카테고리 상품 들어오면 cold start 발생. 사내 쿼리 로그를 모아서 파인튜닝(contrastive loss) 하는 파이프라인을 분기별로 돌리는 걸로.

토막

  • 임베딩 차원 768 → 256으로 줄일 때 Matryoshka 방식 잘 안 맞는 모델도 있음. PCA로 줄이는 게 차라리 안정적이었다.
  • CPU 인코딩이 느려서 대량 색인은 GPU 필수. 100만 건 mpnet 기준 T4 GPU에서 약 20분.

댓글 없음: