대규모 데이터를 효율적으로 검색하기 위해 벡터 데이터베이스(VectorDB)를 활용하는 경우가 매우 많아지고 있습니다.특히나 이미지 검색, 추천 시스템, 자연어 처리(NLP) 등과 같은 분야에서는 고차원 벡터를 빠르게 검색할 수 있는 데이터베이스가 필요합니다. 대표적인 벡터 검색 솔루션으로는 Qdrant, FAISS(Facebook AI Similarity Search), ElasticSearch가 있으며, 각각의 특성과 사용 방식이 상이합니다. 이에 따라서, 세 가지 VectorDB의 비교 및 어떤 DB를 채택하면 좋을지, 각 DB 활용 방법에 대한 예시 코드를 함께 살펴보겠습니다.
1. Qdrant: 스케일러블한 벡터 데이터베이스
Qdrant는 Rust 기반으로 개발된 벡터 검색 엔진이며, 고성능을 제공하면서도 확장성이 뛰어난 점이 특징입니다. API 기반의 서비스로 쉽게 사용할 수 있으며, 웹 애플리케이션, AI 검색 시스템 등에 적합합니다.
Qdrant의 주요 특징은 아래와 같습니다.
- 실시간 검색 - API 기반으로 실시간 벡터 검색을 제공하며, 빠른 응답 속도를 가집니다.
- 분산 시스템 지원 - 클러스터링을 통해 데이터 분산이 가능하여 확장성이 뛰어납니다.
- JSON 데이터와 결합 - 벡터와 함께 JSON 메타데이터를 저장할 수 있어 다양한 필터링이 가능합니다.
Qdrant를 Python에서 사용하는 예제를 코드로 함께 살펴보겠습니다. 참고로, 해당 패키지는 conda 또는 pip install을 통해 설치 후 사용할 수 있습니다. (기본적으로 제공되는 패키지는 아닙니다.)
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct
# Qdrant 클라이언트 연결
client = QdrantClient("http://localhost:6333")
# 데이터베이스에 새로운 컬렉션 생성
client.create_collection(
collection_name="test_collection",
vectors_config={"size": 128, "distance": "Cosine"}
)
# 벡터 데이터 추가
client.upsert(
collection_name="test_collection",
points=[
PointStruct(id=1, vector=[0.1, 0.2, 0.3] * 42, payload={"category": "A"}),
PointStruct(id=2, vector=[0.3, 0.4, 0.5] * 42, payload={"category": "B"})
]
)
# 검색 수행
search_results = client.search(
collection_name="test_collection",
query_vector=[0.2, 0.3, 0.4] * 42,
limit=5
)
print(search_results)
2. FAISS: 고속 벡터 검색 라이브러리
FAISS는 Facebook AI Research에서 개발한 오픈소스 벡터 검색 라이브러리로, GPU 가속을 지원하며 대규모 데이터셋을 처리하는 데 최적화되어 있습니다. 특히, 고차원 벡터를 저장하고 빠르게 검색할 수 있는 효율적인 인덱싱 기법을 제공합니다.
FAISS의 주요 특징은 다음과 같습니다.
- 고속 검색 - Approximate Nearest Neighbor(ANN) 검색을 지원하여 대량의 벡터를 빠르게 탐색할 수 있습니다.
- GPU 가속 - CUDA를 지원하여 GPU를 활용한 고속 연산이 가능합니다.
- 다양한 인덱스 방식 - HNSW, IVF-Flat 등 다양한 인덱싱 기법을 지원하여 상황에 맞게 최적화할 수 있습니다.
FAISS를 Python에서 사용하는 예제 또한 함께 살펴보겠습니다.
import faiss
import numpy as np
# 128차원 랜덤 벡터 생성
dimension = 128
num_vectors = 10000
vectors = np.random.random((num_vectors, dimension)).astype('float32')
# FAISS L2 거리 기반 인덱스 생성
index = faiss.IndexFlatL2(dimension)
index.add(vectors)
# 검색 수행
query_vector = np.random.random((1, dimension)).astype('float32')
distances, indices = index.search(query_vector, 5) # 가장 가까운 5개 검색
print(indices)
3. ElasticSearch: 텍스트 기반 검색과 벡터 검색 통합
ElasticSearch는 오픈소스 검색 엔진으로, 주로 텍스트 검색에 강점을 가지고 있습니다. 그러나 최근에는 k-NN(최근접 이웃) 검색을 지원하면서 벡터 데이터도 효율적으로 검색할 수 있는 기능이 추가되었습니다.
ElasticSearch의 주요 특징은 다음과 같습니다.
- 텍스트 및 벡터 검색 통합 - 벡터 검색뿐만 아니라 자연어 검색도 함께 수행할 수 있습니다.
- 확장성 - 분산 환경에서 대량의 데이터를 효율적으로 처리할 수 있습니다.
- k-NN 검색 지원 - ANN(Approximate Nearest Neighbor) 검색을 활용하여 벡터 데이터를 빠르게 조회할 수 있습니다.
ElasticSearch에서 벡터 검색을 수행하는 Python 예제는 다음과 같습니다.
from elasticsearch import Elasticsearch
# ElasticSearch 클라이언트 연결
es = Elasticsearch("http://localhost:9200")
# 인덱스 생성
index_body = {
"mappings": {
"properties": {
"vector": {
"type": "dense_vector",
"dims": 128
}
}
}
}
es.indices.create(index="vector_index", body=index_body)
# 데이터 삽입
doc1 = {"vector": [0.1, 0.2, 0.3] * 42}
es.index(index="vector_index", id=1, body=doc1)
# 벡터 검색 수행
query_body = {
"query": {
"script_score": {
"query": {"match_all": {}},
"script": {
"source": "cosineSimilarity(params.query_vector, 'vector') + 1.0",
"params": {"query_vector": [0.2, 0.3, 0.4] * 42}
}
}
}
}
response = es.search(index="vector_index", body=query_body)
print(response)
Qdrant vs FAISS vs ElasticSearch 비교
세 가지 벡터 데이터베이스는 각각의 강점을 가지며, 사용 목적에 따라 적절한 선택이 필요합니다.
- Qdrant - API 기반으로 벡터 검색을 쉽게 구현할 수 있으며, 메타데이터 필터링 기능이 뛰어납니다. 실시간 검색과 분산 처리가 필요한 경우 적합합니다.
- FAISS - 고속 벡터 검색이 필요한 경우 강력한 성능을 제공합니다. 특히, GPU 가속이 가능하여 대규모 데이터셋에서 빠르게 검색할 수 있습니다.
- ElasticSearch - 텍스트 검색과 벡터 검색을 동시에 수행할 수 있으며, 대규모 엔터프라이즈 시스템에서 활용하기에 적합합니다.
특정한 요구 사항에 따라 다음과 같이, VectorDB를 선택하여 실무에 활용할 수 있게 됩니다.
- 메타데이터와 함께 벡터 검색이 필요한 경우 Qdrant이 적합합니다.
- 대규모 벡터 검색을 고속으로 수행해야 하는 경우 FAISS가 적합합니다.
- 텍스트 검색과 벡터 검색을 동시에 활용하려면 ElasticSearch가 적합합니다.
각 데이터베이스는 특정한 목적에 따라 차별화된 강점을 가지므로, 시스템의 요구사항을 고려하여 용도에 맞게 활용하여 LLM 서비스 및 저장 시스템 구현에 큰 도움을 얻을 있겠습니다.