본 포스팅은 2024년 1월 8일 작성되었습니다.
분야를 막론하고, 이미지 검색에 대한 수요는 계속 증가하고 있습니다.
온라인 쇼핑몰에서 특정 제품의 이미지와 유사한 제품을 탐색하거나,
텍스트를 통한 검색으로 원하는 이미지를 확인하거나,
이미지 간 유사도 비교를 통해 무단 도용 여부를 탐지할 수도 있습니다.
Elastic의 통합 기능 중 하나인 벡터 검색을 사용하면 유사 이미지 검색을 쉽게 구현할 수 있습니다. 머신 러닝 전문가가 아니더라도 Elastic에서는 이미 벡터 검색이 가능하고, 데이터를 벡터화시킬 수 있는 모델의 import를 별도의 추가 작업 없이 수행할 수 있기 때문입니다.
이미지 검색을 위해서는 필수적으로 해당 이미지 데이터의 벡터화 과정이 필요합니다.
텍스트 검색과는 다르게, 이미지 검색은 검색 내용을 토큰화하거나, 일치도를 단순히 비교하는 것으로는 수행할 수 없습니다.
각 이미지들을 다차원의 벡터로 변환해주는 벡터 모델을 사용해 저장한 데이터들을 벡터 유사도를 사용해서 검색하는 방식이 현재 대부분의 이미지 검색에서 사용하고 있는 검색 방식입니다.
그렇다면 Elasticsearch가 이미지 벡터화 검색에 있어 유리한 점은 무엇일까요?
먼저 Elasticsearch가 아닌 기존 아키텍처 내에서 이미지 검색을 구현하는 방법을 확인해보겠습니다.
검색을 위해 사용되는 대부분의 프레임워크는 벡터 검색을 진행하는데 필요한 기능들을 기본적으로 지원하지 않습니다.
따라서 기존 아키텍처에서 이미지 검색을 수행하기 위해서는 데이터 보관소, NLP 모델, 벡터 검색 엔진 등의 여러 서비스와 상호작용해야 합니다.
Elasticsearch 벡터 유사도 검색의 실행, 이미지의 벡터화를 수행하기 위해 별도의 서비스가 필요하지 않습니다. 벡터 검색과 NLP 추론이 Elasticsearch 플랫폼 내에 이미 통합되어 있기 때문입니다. 이미지 검색을 개발하면서 별도로 전문가를 고용하거나, 오랜 시간을 들여 필요한 서비스들을 찾을 필요 없이 간단하게 이미지 검색을 수행할 수 있습니다.
앞서 이야기한 것처럼, 이미지 유사도 검색은 벡터 검색을 사용합니다.
이미지 데이터를 벡터화하여, 각 벡터들 간의 거리를 계산하는 근접 이웃 알고리즘을 사용하여 유사한 데이터를 찾습니다.
데이터를 벡터화하는 과정에서 사용되는 것이 바로 벡터 임베딩 모델입니다.
모델은 정확한 결과를 제공하기 위해 수 백만 개의 예제를 통한 학습이 필요합니다.
사용처에 따라서 우리가 직접 모델을 학습시키는 것이 검색 정확도에 있어서는 제일 좋겠지만, 머신러닝 전문가가 아니거나 학습에 필요한 컴퓨터 사양이 모자랄 경우에는 어려울 것입니다.
이를 위해 Elasticsearch에서는 HuggingFace에서 모델을 임포트해 스택 내에서 실행시킬 수 있는 기능이 존재합니다.
텍스트 데이터의 경우, BERT가 대표적인 벡터 임베딩 모델입니다.
이미지 검색을 위해서는 이미지 벡터화 모델이 필요한데, 이 Demo에서는 OpenAI에서 배포하는 Clip을 통해 학습시킨 모델 중 하나인
sentence-transformers/clip-ViT-B-32-multilingual-v1 을 사용했습니다.
다언어 모델이기 때문에 별도의 번역 기능 없이도 어느 정도 수준의 한국어 검색이 가능하다는 장점이 있습니다.
모델을 Elasticsearch에 Deploy하는 방법은 공식 문서를 확인하시면 됩니다.
문자열 데이터 벡터화의 경우, Elasticsearch의 Ingest Pipeline Inference Processor를 사용해 Elasticsearch 환경 내에서 벡터화 후 인덱싱하는 것이 가능합니다.
하지만 이미지 데이터의 경우에는 Elasticsearch에 직접 업로드가 불가능하기 때문에, 검색 대상 이미지를 Vector화 하여 Elasticsearch 환경에 업로드하는 과정이 필요합니다.
Python Code를 통해 Image를 Vector화 후 인덱싱하는 코드는 Elasticsearch 공식 블로그의 Github를 참고해 구성할 수 있습니다.
이미지 벡터화에 사용한 모델이 sentence-transformer이기 때문에, 텍스트로 특정 이미지에 대해서 검색하게 되면 그 검색어를 동일한 모델로 벡터화 후 가장 유사한 이미지를 검색할 수 있습니다.
Elasticsearch kNN Search의 query_vector_bulider Object를 사용하면 특정 모델을 사용하여 검색어를 Vector화 한 후 검색 대상 벡터 필드에 검색을 진행할 수 있습니다. 벡터화된 검색어와 가장 가까운 벡터값을 가진 이미지 데이터 순서가 검색 결과로 반환됩니다.
텍스트와 동일한 방식으로 이미지를 직접 업로드하여 검색을 진행할 수 있습니다.
다만 텍스트 검색에서 진행했던 것과의 차이는 앞서 이야기한 것처럼 텍스트 데이터는 Elasticsearch에 import한 모델을 통해 바로 벡터화를 할 수 있지만 이미지는 그 점이 불가능하기 때문에, 검색 대상 이미지를 업로드한 후, Python 코드를 통해 해당 이미지를 벡터로 변환한 값을 Elasticsearch kNN Search의 Query Vector로 입력하여 검색을 진행합니다.
검색 내용과 가장 유사한 이미지들을 보여주는 방식의 검색뿐만 아니라, 두 개의 이미지의 유사도를 직접 비교하는 방식의 검색도 가능합니다.
Elastic 공식 문서 | https://www.elastic.co/kr/what-is/vector-search