OpenSearch로 벡터 데이터베이스 구축하기
최근 벡터 데이터베이스가 LLM(대형 언어 모델) 어플리케이션에서 중요한 역할을 하고 있습니다. 벡터는 다차원 공간에서 특정 점을 나타내는 수치 집합이며, 문장의 의미를 효과적으로 표현할 수 있는 방식으로 자주 사용됩니다. 이와 같은 벡터 데이터베이스를 사용하면 문장 간 유사성을 비교하거나 의미론적 검색을 구현할 수 있어 자연어 처리(NLP) 및 추천 시스템에 많은 이점을 제공합니다.
이번 블로그에서는 OpenSearch를 활용해 벡터 데이터베이스를 구축하고, 이를 LLM 어플리케이션에 적용하는 방법을 알아보겠습니다. 코드 예시와 설정 파일을 제공하니 쉽게 따라 하실 수 있을 겁니다.
OpenSearch를 벡터 데이터베이스로 사용하는 이유
OpenSearch는 벡터 데이터베이스 기능을 제공하며, 특히 k-NN (k-Nearest Neighbors) 알고리즘을 활용한 의미론적 검색 기능이 강력합니다. 이를 사용하면 텍스트 데이터를 벡터로 변환한 후 유사한 데이터를 빠르게 검색할 수 있습니다. OpenSearch를 벡터 데이터베이스로 사용하면 다음과 같은 장점이 있습니다:
- 오픈소스 솔루션: OpenSearch는 AWS에서 제공하는 오픈소스 프로젝트로, 누구나 클러스터를 쉽게 설정하고 사용할 수 있습니다.
- 확장성: OpenSearch는 대규모 데이터셋 처리에 적합하며, 수평적 확장이 용이합니다.
- k-NN 알고리즘 지원: 내장된 k-NN 플러그인을 통해 고성능의 벡터 검색을 수행할 수 있습니다.
1. OpenSearch 클러스터 설정하기
먼저, 로컬 환경에서 OpenSearch 클러스터를 실행해야 합니다. 다음과 같은 Docker Compose 파일을 사용하면 두 개의 노드와 대시보드를 설정할 수 있습니다.
version: '3'
services:
opensearch-node1:
image: opensearchproject/opensearch:2.1.0
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node1
- discovery.seed_hosts=opensearch-node1,opensearch-node2
- cluster.initial_master_nodes=opensearch-node1,opensearch-node2
- bootstrap.memory_lock=true
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data
ports:
- 9200:9200
- 9600:9600
networks:
- opensearch-net
opensearch-node2:
image: opensearchproject/opensearch:2.1.0
container_name: opensearch-node2
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node2
volumes:
- opensearch-data2:/usr/share/opensearch/data
networks:
- opensearch-net
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.1.0
container_name: opensearch-dashboards
ports:
- 5601:5601
networks:
- opensearch-net
volumes:
opensearch-data1:
opensearch-data2:
networks:
opensearch-net:
위 YAML 파일을 docker-compose.yml로 저장한 후, 같은 디렉터리에서 아래 명령어로 클러스터를 실행하세요
$ docker-compose up
2. Python으로 데이터 삽입 및 벡터 검색 구현
벡터 데이터베이스를 구축한 후, Python을 이용해 데이터를 삽입하고 k-NN 검색을 실행할 수 있습니다. 필요한 라이브러리를 설치한 후, 영화 데이터셋을 불러와 처리하는 코드를 작성해 보겠습니다.
필수 라이브러리 설치
pip install opensearch-py==2.4.2
pip install sentence-transformers==2.2.2
데이터 로드 및 벡터화
import pandas as pd
from sentence_transformers import SentenceTransformer
from opensearchpy import OpenSearch
# OpenSearch 클라이언트 생성
client = OpenSearch(
hosts=["https://localhost:9200"],
http_auth=("admin", "admin"),
verify_certs=False
)
# 영화 데이터셋 로드
file_path = 'tmdb_5000_movies.csv'
df_movies = pd.read_csv(file_path, usecols=['id', 'original_title', 'overview'])
df_movies = df_movies.dropna()
# SentenceTransformer 모델로 벡터화
model = SentenceTransformer("all-MiniLM-L6-v2")
df_movies['embedding'] = df_movies['overview'].apply(lambda x: model.encode([x])[0])
# OpenSearch에 인덱스 생성
index_body = {
"settings": {
"index": {
"knn": True,
"knn.algo_param.ef_search": 100
}
},
"mappings": {
"properties": {
"embedding": {
"type": "knn_vector",
"dimension": 384, # 모델 차원
"method": {
"name": "hnsw",
"space_type": "l2",
"engine": "nmslib"
}
}
}
}
}
client.indices.create(index="movies", body=index_body)
# 데이터 삽입
for i, row in df_movies.iterrows():
doc = {
"id": row["id"],
"title": row["original_title"],
"plot": row["overview"],
"embedding": row["embedding"]
}
client.index(index="movies", body=doc, id=str(i), refresh=True)
검색 쿼리 실행
user_query = "A spy goes on a mission"
query_embedding = model.encode([user_query])[0]
query_body = {
"query": {
"knn": {
"embedding": {
"vector": query_embedding,
"k": 3
}
}
},
"_source": False,
"fields": ["id", "title", "plot"]
}
results = client.search(body=query_body, index="movies")
for result in results["hits"]["hits"]:
title = result["fields"]["title"][0]
plot = result["fields"]["plot"][0]
print(f"Title: {title}, Plot: {plot}")
이처럼 OpenSearch를 활용해 쉽게 벡터 데이터베이스를 구축하고, 대형 언어 모델을 통한 의미론적 검색을 구현할 수 있습니다. 이 방법은 다양한 자연어 처리(NLP) 애플리케이션, 특히 LLM 기반 서비스에서 매우 유용하게 사용될 수 있습니다. OpenSearch의 유연한 확장성과 k-NN 기능을 활용해 더욱 강력한 검색 시스템을 구축해보세요!
참고 : https://medium.com/marvelous-mlops/creating-vector-database-with-opensearch-7562b7451978
'DB' 카테고리의 다른 글
Pinecone 벡터 데이터베이스: AI 시대의 필수 도구 (0) | 2024.09.13 |
---|---|
AI 시대를 선도하는 5가지 인기 벡터 데이터베이스: Chroma, Pinecone, Weaviate, Faiss, Qdrant의 특징과 활용 (0) | 2024.09.12 |
[REDIS] Redis 클러스터에서 첫 노드에 데이터가 없을 때: 다른 노드가 어떻게 데이터를 찾아내는가? (0) | 2024.08.26 |
[Graph DB] 그래프 데이터베이스란 무엇인가? (0) | 2024.07.09 |
[데이터베이스] 샤딩(Sharding)이란 무엇인가? (0) | 2024.06.04 |