이 블로그 게시물에서는 비교 가능한 벡터의 저장 및 검색을 용이하게 하는 벡터 데이터베이스, 벡터 검색 및 Python의 Langchain 패키지의 기본 사항을 안내합니다.
여정을 시작하기 위해 "임베딩"이라는 핵심 개념부터 시작하겠습니다.
이 글에서는 기계가 쉽게 이해할 수 있는 형식으로 텍스트 데이터를 표현할 수 있게 해주는 기계 학습의 기본 측면인 임베딩의 개념을 살펴보겠습니다.
기본적으로 임베딩은 텍스트의 벡터 표현 역할을 하며 복잡한 단어, 문장 및 구절의 웹을 기계가 처리할 수 있는 숫자 형식으로 변환합니다.
한 가지 긴급한 문제가 발생합니다. 인간이 이러한 임베딩을 해독할 수 있습니까? 내 대답은 아니오 야. 임베딩은 기본적으로 텍스트 정보를 캡슐화하는 일련의 숫자입니다.
결과적으로 임베딩 벡터를 이해하고 작업하는 것은 인간에게는 어려운 작업이 될 수 있지만 기계는 이를 쉽게 처리합니다.
텍스트에서 임베딩을 생성하는 기술은 무수히 많습니다. 주목할만한 방법으로는 TF-IDF, Word2Vec, Glove 및 BERT 등이 있습니다. 현대 머신러닝 영역에서는 문장 임베딩이 단어 임베딩보다 인기를 얻었습니다.
텍스트의 본질을 나타내는 이러한 문장 임베딩은 "all-MiniLM-L6-V2" 및 "all-mpnet-base-v2"와 같은 사전 훈련된 문장 변환기 모델에서 얻을 수 있습니다.
이러한 모델은 특정 텍스트에 대해 고정된 크기(일반적으로 384 또는 768 크기)의 임베딩을 생성합니다.
이제 임베딩의 기초와 임베딩 생성을 위한 다양한 기술을 살펴보았으므로 이러한 고차원 임베딩 벡터를 벡터 저장소에 저장하는 문제로 초점을 옮겨 보겠습니다.
벡터 데이터 저장소는 오디오, 비디오, 이미지, 텍스트 등을 포함한 다양한 데이터 유형의 고차원 임베딩 표현을 저장하도록 설계된 특수 데이터베이스입니다.
핵심 기능 중 하나는 주어진 쿼리 벡터와 매우 유사한 저장소 내 벡터를 효율적으로 검색하는 기능입니다.
벡터 저장소는 임베딩을 저장하고 이러한 벡터 간의 유사성 검색을 수행하는 프로세스를 간소화하여 고차원 데이터 표현의 관리 및 검색을 단순화합니다.
벡터 임베딩 영역에서 유사성 검색에는 두 개 이상의 임베딩 간의 근접성 또는 관련성을 정량화하는 작업이 포함됩니다. 일반적으로 이는 다양한 거리 측정법을 사용하여 유사성을 계산하여 수행됩니다. 일반적으로 사용되며 널리 알려진 거리 측정법으로는 유클리드 거리, 맨해튼 거리, 코사인 거리 등이 있습니다. 이러한 측정항목은 벡터 간의 유사성 또는 비 유사성 정도를 측정하는 데 도움이 되며 데이터 내에서 효과적인 유사성 검색을 촉진합니다.
예를 들어, 그래프의 두 점 사이의 유사성 또는 근접성을 판단할 때 일반적으로 유클리드 거리(Euclidean distance)가 사용됩니다. 이 거리는 다음 공식을 사용하여 계산할 수 있습니다.
유클리드 거리 = [(x2 - x1)^2 + (y2 - y1)^2]^0.5
여기서 (x1, y1)은 그래프의 첫 번째 점의 좌표를 나타내고, (x2, y2)는 그래프의 두 번째 점의 좌표를 나타냅니다. 이 계산의 결과는 두 점 사이의 공간적 분리에 대한 측정값을 제공하여 그래프 내 위치 측면에서 유사성 또는 차이점을 나타냅니다.
마찬가지로 유사성 검색에서는 임베딩이 고차원 공간 내에 표시되며 각 레코드는 데이터 포인트 역할을 합니다.
아래 코드 줄은 주어진 입력 데이터에 대해 상위 5개의 유사한 임베딩을 검색하는 방법을 보여줍니다.
distance, n = vector_store.search(input_embedding, k=5)
이 코드는 입력 데이터와 매우 유사한 상위 5개 임베딩 목록을 반환하므로 추천 시스템, 콘텐츠 검색 등과 같은 다양한 애플리케이션에 유용한 도구가 됩니다.
vector_store.search() 함수 출력은 input_embedding으로부터의 각각의 거리와 함께 상위 k개의 유사한 임베딩으로 구성됩니다. 매개변수 "k"는 유사성 검색에서 검색할 가장 가까운 임베딩 수를 결정하는 구성 가능한 값입니다. "k"를 설정하여 검색 작업에서 반환되는 원하는 결과 수를 제어할 수 있습니다.
이제 벡터 스토어에 대한 기본적인 이해를 마쳤으므로 LangChain 패키지와 FAISS에 대해 자세히 살펴보겠습니다. 이러한 도구는 고차원 임베딩 작업 및 효율적인 유사성 검색 수행 능력을 더욱 향상시킵니다.
간단히 말해서 LangChain은 LLM(대형 언어 모델)의 기능을 활용하는 애플리케이션을 구축하기 위해 설계된 프레임워크입니다. 더 자세한 정보와 리소스는 공식 LangChain 문서를 참조하세요.
반대로, "Facebook AI 유사성 검색"의 약자인 FAISS는 기존의 해시 기반 접근 방식에서 벗어나 유사 임베딩을 검색할 수 있는 빠르고 효율적인 수단을 개발자에게 제공하는 Python 라이브러리입니다.
이 라이브러리는 Facebook AI 팀이 개발했으며 고차원 공간에서 유사성 검색 작업을 위한 강력한 기능을 제공합니다.
FAISS는 자체 서버에서 호스팅할 수 있는 오픈 소스 라이브러리입니다.
LangChain과 FAISS를 탐색하면서 우리는 이제 LangChain 프레임워크 내에서 FAISS를 구현하는 것을 목표로 할 것입니다. 다음은 이 기사에서 중점을 둘 LangChain FAISS 통합의 몇 가지 주요 API입니다.
add_documents() : 이 함수를 사용하면 추가 문서를 벡터 저장소에 통합할 수 있습니다.
add_embeddings() : 벡터 저장소에 더 많은 임베딩을 추가할 수 있습니다.
from_documents() : 이 API는 제공된 문서를 기반으로 VectorStore를 반환합니다.
from_embeddings() : 이 함수는 지정된 임베딩에서 생성된 FAISS 인덱스를 제공합니다.
load_local() : 디스크에서 FAISS 인덱스를 로드하는 데 사용합니다.
save_local() : FAISS 인덱스를 디스크에 저장할 수 있습니다.
유사성_검색() : 이 함수는 주어진 쿼리와 가장 유사한 문서를 검색합니다.
유사성_검색_바이_벡터() : 주어진 임베딩과 가장 유사한 문서를 검색합니다.
이러한 API는 LangChain의 기능을 FAISS와 결합하기 위한 기반을 형성하여 임베딩 작업을 수행하고 애플리케이션 내에서 효율적인 유사성 검색을 수행할 수 있도록 합니다.
메타 필터링은 LangChain FAISS에서 검색 쿼리 결과를 구체화하는 데 사용되는 귀중한 기술입니다. 일반적으로 메타 필터링에는 사전 필터링과 사후 필터링이라는 두 가지 유형이 있습니다. 우리 프레임워크에서는 특히 검색어에 대한 사후 필터링을 지원합니다.
검색 결과에 대한 메타 필터링 개념은 FAISS의 LangChain 버전에서 사용할 수 있는 기능이며 FAISS의 원래 구현에는 존재하지 않는다는 점에 유의하는 것이 중요합니다. 이 사후 필터링 기능은 검색 결과의 정확성과 관련성을 향상시켜 사용자에게 더욱 맞춤화된 결과를 제공합니다.
LangChain FAISS API에 대한 지식으로 무장하여 LangChain FAISS의 Python 구현을 살펴보겠습니다. 이 구현을 통해 임베딩 작업, 유사성 검색 수행, 사후 필터링 기술 적용을 통해 LangChain 프레임워크 내에서 검색 결과를 미세 조정할 수 있습니다.
이러한 기능을 자유롭게 탐색하고 활용하여 FAISS를 통한 대형 언어 모델 및 고급 유사성 검색의 기능을 활용하는 애플리케이션을 만들 수 있습니다.
이 지침 가이드에서는 Stanford Dataset을 기본 데이터세트로 선택하고 LangChain FAISS의 메타 필터링 작업을 보여주기 위해 몇 개의 열을 추가했습니다.
필요한 패키지를 설치하고 가져오는 것부터 시작하겠습니다.
!pip install langchain[all] !pip3 install Langchain[FAISS] !pip install faiss-cpu # WARNING: langchain 0.0.74 does not provide the extra 'faiss'
from langchain import FAISS import pandas as pd import numpy as np import os import time import pickle
이제 데이터 세트를 가져옵니다.
passage_data = pd.read_csv("/Users/shyam/Python_Programs/Text Similarity Codes/Standford_Edited.csv") passage_data.drop(columns=["Unnamed: 0"],axis=1, inplace=True) passage_data
데이터 세트가 있으면 텍스트 데이터를 벡터로 변환하는 임베딩 함수를 초기화해야 합니다. 우리는 384차원의 임베딩을 생성하는 "sentence-transformers/all-MiniLM-L6-V2"를 사용했습니다.
from langchain.embeddings import SentenceTransformerEmbeddings embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
메타데이터 정보를 설정하겠습니다. 메타데이터에는 각 임베딩(콘텐츠)에 대한 문서 ID와 문서 언어를 추가했으며,
start=time.time() metadatas = [] for index, row in passage_data.iterrows(): doc_meta = { "id": row['Id'], "language": row['Language'] } metadatas.append(doc_meta)
그게 다입니다… 이제 FAISS 지수를 구축하겠습니다.
faiss = FAISS.from_texts(passage_data['Content'].tolist(), embedding_function, metadatas) print("Time Taken --> ", time.time()-start)
이제 FAISS 인덱스를 디스크에 저장하고 다시 로드해 보겠습니다.
faiss.save_local("/Users/shyam/Python_Programs/LangChain_FAISS", "Standford") loaded_faiss = faiss.load_local("/Users/shyam/Python_Programs/LangChain_FAISS",embedding_function, "Standford")
FAISS 인덱스 구축, 저장, 로딩이 완료되었습니다. 추론 시간입니다. 몇 가지 쿼리를 검색하고 FAISS 지수를 테스트해 보겠습니다.
먼저 '무신론'과 관련된 유사 문서 상위 5개를 찾아보겠습니다.
start=time.time() loaded_faiss.similarity_search_with_score("What is atheism?",5)
글쎄요, 결과는 설득력이 있습니다. 하지만 여전히 우리는 더 많은 것을 탐구할 것입니다…
이번에는 메타 필터링을 통해 다른 언어 쿼리를 시도해 보겠습니다. 필터링 기준이 {lang: 'ru_RU'}여야 함을 명시하는 러시아어 쿼리를 요청하겠습니다.
#Что такое атеизм? - Russian loaded_faiss.similarity_search_with_score("Что такое атеизм?",5, {"language":"ru_RU"}, 10)
여기서는 벡터 저장소에서 가장 유사한 문서 10개를 가져온 다음 필터링 조건을 적용하여 쿼리에 대한 상위 5개 문서를 가져오는 것에 대해 언급했습니다.
이 기사를 마치면 벡터 스토어와 벡터 검색에 대한 확실한 이해를 얻으셨으리라 믿습니다. 우리는 또한 LangChain FAISS의 기능을 설명하기 위해 데모를 제공했습니다.
ChromaDb, Qdrant, Milvus 등과 같은 다른 벡터 스토어를 탐색해 보시기 바랍니다.
각 벡터 스토어에는 고유한 장점과 단점이 있으므로 사용 사례의 특정 요구 사항에 따라 선택하십시오.
즐겁고 유익한 학습 여정을 기원합니다!