Zettelkasten

텍스트 임베딩으로 광역 후보를 좁히고 CLIP 이미지 유사도로 시각 정밀 탐색하는 2단계 검색 구조

·수정 1

요약

  • 텍스트 쿼리로 의미 기반 광역 후보를 좁히고, 그 결과 중 마음에 드는 이미지를 클릭하면 CLIP 시각 유사도로 정밀 탐색하는 2단계 구조
  • 단일 임베딩(텍스트 또는 이미지) 검색이 잡지 못하는 시그널을, 단계별로 다른 모델·다른 인덱스에 위임해서 보완

본문

왜 단일 임베딩으로는 부족한가

캡션 임베딩 단일 검색은 캡션 기반이라 미묘한 시각적 차이를 못 잡아낸다. VLM이 묘사하지 않은 색감·구도·톤은 캡션 텍스트에 안 들어가므로, 임베딩 공간에서도 안 잡힌다. 반대로 CLIP 단일 검색만 두면 한국어 도메인 어휘("임상 그래프 잘 보여준 거", "쫀쫀한 텍스처")가 약하다. CLIP은 시각 시그널엔 강하지만 의미 시그널엔 약하다.

두 모델의 역할 분담

  • 캡션 임베딩 (multilingual-e5): 의미 시그널 — 무엇을 묘사하는가, 어떤 효능 카피인가, 어떤 섹션 타입인가
  • CLIP 이미지 임베딩: 시각 시그널 — 색감, 구도, 레이아웃, 톤

두 신호는 직교에 가까워서 한 모델로 합치는 것보다 분리해서 쓰는 게 깨끗하다.

단계 분리의 또 다른 이유: 인터페이스

자연어 쿼리가 사용자 인터페이스로 가장 편하다. "임상 그래프 잘 보여준 거" 같은 의도는 텍스트로 시작하고, 후보 중 하나가 마음에 들면 "이거랑 비슷한 거 더" 가 자연스러운 다음 액션이다. 즉 광역 → 정밀의 흐름이 사용자 사고 흐름과 일치한다.

구체 구조

[텍스트 쿼리]
   │ multilingual-e5 (768d)
   ▼
[캡션 임베딩 인덱스] ─ cosine ─► Top-K (광역 후보)
                                      │
                            [사용자가 한 장 클릭]
                                      ▼
                              [그 이미지의 CLIP 벡터]
                                      │ CLIP-ViT-B-32 (512d)
                                      ▼
                            [이미지 임베딩 인덱스] ─ cosine ─► Top-K (시각 정밀)

핵심: 인덱스를 두 개 따로 만든다. 같은 record(=한 PDP 이미지)를 두 모델이 각자 다른 벡터로 인코딩하고, 같은 행 순서를 유지한다. 검색 시점에 모드만 갈아끼우면 된다.

한계

  • CLIP은 224×224로 리사이즈해서 인코딩하므로 텍스트 디테일(작은 그래프 라벨, 카피 문구)은 잃는다. 시각 시그널을 잡지만 텍스트 콘텐츠는 못 잡음
  • 두 인덱스를 따로 빌드/유지해야 함 — 데이터가 늘면 비용 ↑
  • 더 정교하게 가려면 두 점수를 가중합하거나 query-time rerank를 추가하는 방향이 자연스럽다

참고