본문 바로가기
📚도서 공부/LangChain으로 구현하는 LLM

5-2(챗봇이란?, 벡터 저장소) 챗봇 만들기

by Majestyblue 2024. 5. 9.

 

나. 벡터 저장소

벡터 저장소란, 벡터 임베딩을 저장하고 검색하는 데 사용되는 메커니즘을 나타낸다. 벡터 저장소는 벡터 임베딩을 효율적으로 저장하고 검색하기 위해 특별히 설계된 독립적인 솔루션이다. 벡터 데이터베이스는 벡터 임베딩을 관리하고 Faiss와 같은 독립적인 벡터 인덱스를 사용하는 것 보다 여러 이점을 제공하기 위해 설계되었다.

아래와 같이 세 가지 수준이 있다.

  • 인덱싱은 벡터를 조직화해 벡터를 빠르게 검색할 수 있도록 구조화 한다. k-d 트리나 Annoy(Approximate nearest neighbors oh yeah)와 같은 다양한 알고리즘이 있다.
  • 벡터 라이브러리는 점곱 및 벡터 인덱싱과 같은 벡터 작업을 수행하는 기능을 제공한다.
  • Milvus나 Pinecone과 같은 벡터 데이터베이스는 대규모 벡터 집합을 저장, 관리 및 검색하기 위해 설계됐다. 이러한 벡터에 대한 효율적인 유사성 검색을 용이하게 하기 위해 인덱싱 메커니즘을 사용한다.

1) 벡터 인덱싱

임베딩의 맥락에서, 인덱싱은 데이터를 검색 또는 저장을 최적화하기 위한 방법이다. 인덱싱을 통해 데이터 레코드에 빠르게 접근할 수 있다. 벡터 임베딩의 경우로 생각하면 비슷한 벡터가 서로 인접하게 저장돼 빠른 근접 또는 유사성 검색이 가능하도록 하는 것이 목표이다.

유사성 검색 인덱싱엔 일반적으로 사용되는 여러 유형의 알고리즘들이 있다.

  • 제품 양자화(PQ, Product Quantization) : 벡터 공간을 작은 하위 공간으로 나누고 각 하위 공간을 따로 양자화하는 기술이다. 빠른 검색 속도로 알려져 있지만 일부 정확성이 희생될 수 있다. k-d 트리와 ball 트리가 있다.
  • 지역 민감 해싱(LSH, Locality Sensitive Hashing): 유사한 데이터 점을 동일한 해시 버킷에 매핑하는 해싱 기반 방법이다. 고차원 데이터에 효과적이지만 잘못된 양석 및 음성의 확률이 높아질 수 있다. Annoy 알고리즘이 있다.
  • HNSW(Hierarchical Navigable Small World): 벡터를 조직하는 계층적 그래프 구조를 구성하는 그래프 기반 인덱싱 알고리즘이다. 랜덤화와 그리디(greedy) 검색의 조합을 사용한다. 높은 검색 정확도와 확장성으로 알려져있다.
  • 그래프 신경망(GNN, Graph Neural Network), 합성곱망(GCN, Graph Convolutional Network) 등 그래프 기반 방법이 있으며, 이들은 유사성 검색을 위해 그래프 구조를 활용한다.

2) 벡터 라이브러리

벡터 라이브러리는 벡터 데이터를 처리하는데 사용되는 기능을 제공한다. 벡터 검색의 맥락에서 벡터 임베딩을 저장하고 유사도 검색 수행을 위해 설계되었다. 효율적으로 벡터를 검색하고 가장 유사한 벡터를 찾기 위해 클러스터링, 트리 기반 등의 ANN 알고리즘을 사용한다.

  • Faiss는 Facebook(현 Meta)에서 개발한 라이브러리로 밀도가 높은 벡터의 효율적인 유사성 검색과 클러스터링을 제공한다. PQ, LSH, HNSW 등 다양한 인덱싱 알고리즘을 지원하고 CPU 및 GPU 가속을 지원한다.
  • Annoy는 Spotify에서 유지 및 개발되는 고차원 공간에서의 근사 최근접 이웃 검색을 위한 C++ 라이브러리로, Annoy 알고리즘을 구현한다. 효율적이고 확장 가능하도록 설계돼 대규모 벡터 데이터에 적합하다.
  • hnswlib는 HNSW 알고리즘을 사용한 근사 최근접 이웃 검색을 위한 C++ 라이브러리로, 고차원 벡터 데이터에 대한 빠르고 효율적인 인덱싱 검색 기능을 제공한다.
  • nmslib(Non-Metric Space Libary)는 비측정(non-metric) 공간에서 효율적인 유사성 검색을 제공하는 오픈 소스 라이브러리다 HNSW, SW-graph, SPTAG와 같은 다양한 인덱싱 알고리즘을 제공한다.
  • Microsoft의 SPTAG는 분산 ANN을 구현한 것으로 k-d 트리 및 상대 이웃 그래프와 균형 잡힌 k-평균 트리 및 상대 이웃 그래프를 포함한다.

3) 벡터 데이터베이스

벡터 데이터베이스는 데이터 관리, 메타데이터 저장 및 필터링, 확장성과 같은 추가 기능을 제공한다. 즉, 벡터 데이터를 관리하고 쿼리하기 위한 더 포괄적인 솔루션을 제공하며 텍스트, 이미지, 오디오, 비디오 등 어려 유형의 벡터화된 애플리케이션에 유용하다. 벡터 데이터베이스의 사용 예시는 아래와 같다.

  • 이상 감지: 사기 탐지, 네트워크 보아 ㄴ또는 모니터링 시스템과 같이 이상한 패턴이나 행동을 식별하는데 중요할 수 있다.
  • 개인화: 사용자 선호도나 행동을 기반으로 유사한 벡터를 찾아 개인화된 추천 시스템을 만들 수 있다.
  • 자연어 처리: 자연어 처리 작업에 널리 사용되며 텍스트를 벡터 임베딩으로 표현하면 텍스트 데이터를 비교하고 분석하기가 쉬워진다.

벡터 데이터베이스의 특징은 아래와 같다.

  • 유사한 벡터의 효율적인 검색: 역이미지 검색, 유사도 기반 추천과 같은 작업
  • 특정 작업에 특화된 기능: 가까운 임베딩 찾기 등 → 대량의 벡터 데이터를 효과적으로 처리할 수 있다.
  • 고차원 공간 지원: 수천 차원의 벡터를 처리 → 자연어 처리나 이미지 인식과 같은 작업
  • 고급 검색 기능 활성화: 유사한 벡터나 임베딩을 검색 → 콘텐츠 추천 시스템이나 의미 기반 검색과 같은 애플리케이션 가능

벡터 데이터베이스의 종류는 Chroma, Qdrant, Milvus, Weaviate, Pinecone, Vespa, Marqo 등이 있다.

4) LangChain 벡터 저장소 구현 예

Chroma를 사용해여 pdf 논문을 분석해 보자. pymupdf 가 필요하다.

pip install pymupdf pip install chromadb

아래는 Mistral 7B에 관한 논문을 로드하고 나누는 과정이다. 다운로드는 PDF 형식이다.

from langchain_community.embeddings import HuggingFaceEmbeddings

embeddings_model = HuggingFaceEmbeddings(
    model_name='jinaai/jina-embeddings-v2-small-en',
    model_kwargs={'device':'cpu'},
    encode_kwargs={'normalize_embeddings':True},
)
from langchain.document_loaders import ArxivLoader
from langchain.text_splitter import CharacterTextSplitter

loader = ArxivLoader(query="2310.06825")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

print(docs)
<출력결과>
[Document(page_content='Mistral 7B\\nAlbert Q. Jiang, Alexandre Sablayrolles, Arthur Mensch, Chris Bamford,\\nDevendra Singh Chaplot, Diego de las Casas, Florian Bressand, Gianna Lengyel,\\nGuillaume Lample, Lucile Saulnier, Lélio Renard Lavaud, Marie-Anne Lachaux,\\nPierre Stock, Teven Le Scao, Thibaut Lavril, Thomas Wang, Timothée Lacroix,\\nWilliam El Sayed\\nAbstract\\nWe introduce Mistral 7B, a 7–billion-parameter language model engineered for\\nsuperior performance and efficiency...

Chroma의 인스턴스를 생성하고 문서(분할) 및 임베딩을 제공한다.

from langchain.vectorstores import Chroma

vectorstore = Chroma.from_documents(documents=docs, embedding = embeddings_model)