Facebook AI Similarity Search (FAISS) 설정하기
안녕하세요, 기술 애호가 여러분! 오늘 우리는 인공지능 분야에서 큰 반향을 일으키고 있는 도구인 Facebook의 AI 유사도 검색(FAISS)을 탐험하는 여정을 시작합니다. Spotify가 여러분이 좋아하는 곡과 섬뜩할 정도로 비슷하게 들리는 노래를 어떻게 찾아내는지, 또는 Google Photos가 같은 사람의 사진을 어떻게 그룹화하는지 궁금해하신 적이 있다면, 이제 그 미스터리를 밝혀낼 차례입니다.
유사도 검색, 또는 최근접 이웃 검색은 많은 AI 및 머신러닝 애플리케이션의 핵심적인 측면입니다. 이는 주어진 쿼리 포인트와 가장 유사한 데이터 포인트를 찾는 것에 관한 모든 것입니다. 예를 들어, Spotify에서 노래를 검색하면 시스템은 검색 쿼리와 가장 “유사한” 노래를 찾아야 합니다. 따라서 유사도 검색이라고 합니다.
이 효율적인 유사도 검색이 인상적으로 들리지만, 한 가지 문제가 있습니다. 기존의 유사도 검색 방법은 대량의 데이터에서는 끔찍할 정도로 느려질 수 있습니다. 바로 여기서 FAISS가 등장해 기존 쿼리 검색 엔진의 한계를 해결합니다. FAISS는 Facebook AI가 개발한 효율적인 유사도 검색을 위한 라이브러리로, 특히 대규모 데이터를 다룰 때 유사도 검색 문제에 대한 신뢰할 수 있는 솔루션을 제공합니다.
하지만 잡담은 여기까지! 이 블로그 글에서는 FAISS를 설정하고, 실행시키고, 샘플 유사도 검색 프로그램을 통해 그 강력함을 보여주는 과정을 안내합니다. 그러니 안전벨트를 매세요. 이제 FAISS를 활용한 효율적인 유사도 검색의 매혹적인 세계로 깊이 들어가 볼 예정입니다. 재미있는 여정이 될 거예요!
FAISS (Facebook AI Similarity Search) 이해하기
이제 간단한 소개로 흥미를 돋웠으니, FAISS에 대해 더 깊이 파고들어 보겠습니다. FAISS, 즉 Facebook AI Similarity Search는 벡터 유사도 검색과 밀집 벡터 클러스터링을 위한 알고리즘 라이브러리입니다. 이는 대규모 데이터베이스를 효율적으로 처리하도록 설계한 Facebook의 AI 팀이 만들어낸 결과물입니다.
FAISS는 주로 “벡터 유사도”라는 개념을 기반으로 작동합니다. 쉽게 말해, 벡터는 본질적으로 숫자의 목록이며, 유사도는 두 벡터가 얼마나 닮았는지를 의미합니다. 현재 가장 좋아하는 곡의 분위기와 어울리는 노래를 찾으려 한다고 상상해 보세요. 벡터는 두 곡을 모두 표현할 수 있으며, 유사한 벡터의 서로 다른 요소는 노래의 서로 다른 특징을 나타냅니다. 고차원 공간에서 벡터 간의 거리를 비교함으로써 이 노래들 사이의 “유사도”를 비교할 수 있습니다. 유클리드 거리는 벡터 간의 이러한 유사도를 측정하는 데 중요한 역할을 합니다.
여기서 FAISS가 진가를 발휘합니다. FAISS는 수백만 개, 심지어 수십억 개의 이러한 벡터를 빠르고 정확하게 비교할 수 있는 방법을 제공합니다. 이는 거대한 음악 라이브러리를 순식간에 훑어보고, 여러분이 가장 좋아하는 곡과 가장 유사한 노래를 정확히 찾아내는 초강력 검색 엔진을 가진 것과 같습니다. 인덱싱된 벡터는 이 과정에서 필수적입니다. 시스템이 주어진 쿼리 벡터와 가장 가까운 일치 항목을 효율적으로 검색할 수 있게 해주기 때문입니다.
하지만 FAISS의 마법은 음악 추천에서 멈추지 않습니다. 이미지 인식과 텍스트 검색부터 클러스터링 및 데이터 분석에 이르기까지 많은 애플리케이션이 FAISS를 사용합니다. 많은 양의 데이터가 있고 유사한 항목을 빠르게 찾아야 할 때마다 FAISS는 여러분이 선택할 수 있는 유용한 도구가 될 수 있습니다.
FAISS 설정하기
이 섹션에서는 Linux 시스템에서 FAISS를 설정하는 방법을 안내합니다.
Conda 설치하기
FAISS를 설치하기 전에 시스템에 Conda가 설치되어 있어야 합니다. Conda는 Windows, macOS, Linux에서 실행되는 오픈 소스 패키지 및 환경 관리 시스템입니다.
Linux 시스템에 Conda를 설치하려면 다음 단계를 따르세요:
공식 웹사이트에서 Linux용 Miniconda 설치 프로그램을 다운로드하세요.
설치 프로그램 해시를 확인하세요.
터미널 창을 열고 다음 명령을 실행하여 설치를 시작하세요:
bash Miniconda3-latest-Linux-x86_64.sh
설치 프로그램이 시작되면 몇 가지 질문을 합니다. 확실하지 않은 항목이 있으면 기본 옵션을 선택하세요. 나중에 언제든지 변경할 수 있습니다.
설치가 완료되면 터미널 창을 닫았다가 다시 여세요. 이렇게 하면 변경한 내용이 활성화됩니다.
이제 모든 것이 제대로 설치되었는지 확인해야 합니다. 이를 위해 터미널 창 또는 Anaconda Prompt에 conda list를 입력하고 Enter를 누르세요. 모든 것이 제대로 작동하면 설치된 패키지 목록이 표시됩니다.
FAISS 설치
Conda를 통해 FAISS를 설치할 수 있습니다. FAISS 패키지에는 CPU 전용 버전(faiss-cpu)과 CPU 및 GPU 인덱스를 모두 포함하는 버전(faiss-gpu)의 두 가지 버전이 있습니다. 필요에 따라 이 중 하나를 설치할 수 있습니다.
FAISS를 설치하는 권장 방법은 PyTorch Conda 채널을 통하는 것입니다. 다음은 FAISS의 최신 안정 릴리스를 설치하는 명령입니다.
CPU 버전의 경우:
conda install -c pytorch faiss-cpu
GPU 버전의 경우:
conda install -c pytorch faiss-gpu
또한 FAISS는 Conda를 위한 커뮤니티 주도 패키징 생태계인 conda-forge에 의해 패키징됩니다. 다음 명령을 사용하여 conda-forge에서 FAISS를 설치할 수 있습니다. CPU 전용 버전의 경우:
conda install -c conda-forge faiss-cpu
GPU 버전의 경우:
conda install -c conda-forge faiss-gpu
SQuAD를 사용한 샘플 코드 설명
conda list 명령을 사용하여 Conda 패키지가 어느 채널에서 왔는지 확인할 수 있습니다.
이 데모에서는 Stanford Question Answering Dataset(SQuAD)을 사용해 보겠습니다. SQuAD는 자연어 처리(NLP)를 위한 인기 있는 데이터셋이며 FAISS가 어떻게 작동하는지 보여주기에 좋은 방법입니다. 이 데이터셋에는 질문-답변 쌍이 포함되어 있으며, 각 질문에 대한 답변은 해당 읽기 지문의 텍스트 구간, 즉 “span”입니다. 검색 과정에서는 쿼리 벡터를 사용하여 데이터셋과 비교함으로써 가장 관련성 높은 답변을 찾습니다.
코드로 들어가기 전에 먼저 SQuAD 데이터셋을 다운로드하고 준비해 보겠습니다:
SQuAD 데이터셋 다운로드: 데이터셋은 SQuAD 웹사이트에서 다운로드할 수 있습니다. 간단히 하기 위해 SQuAD 1.1을 사용하겠습니다. 다음 링크를 사용하여 데이터셋을 다운로드할 수 있습니다: SQuAD 1.1 Train. JSON 파일(train-v1.1.json)을 다운로드하여 작업 디렉터리에 저장하세요.
JSON 파일 읽기: 이제 Python JSON 라이브러리를 사용하여 데이터를 로드할 수 있습니다:
with open('train-v1.1.json', 'r') as file: squad_data = json.load(file)
수치 벡터는 IndexFlatL2 내에서 효율적인 거리 측정과 쿼리를 가능하게 하므로 FAISS 인덱스에서 필수적입니다.
필요한 라이브러리 가져오기
첫 번째 단계는 필요한 모든 라이브러리를 가져오는 것입니다. 수치 연산을 위해 numpy, 벡터 유사도 검색을 위해 Faiss, 데이터셋 로드를 위해 JSON, 텍스트 토큰화를 위해 nltk가 필요합니다.
import numpy as np
import faiss
import json
from nltk.tokenize import word_tokenize
데이터 로드 및 전처리
SQuAD 데이터셋을 로드해 보겠습니다. JSON 파일이므로 JSON 모듈의 load 함수를 사용할 수 있습니다.
with open('train-v1.1.json', 'r') as file:
squad_data = json.load(file)
JSON 객체가 data 키와 딕셔너리 목록을 포함하는 딕셔너리라고 가정하겠습니다. 목록의 각 딕셔너리는 paragraph 키와 단락 목록을 포함하는 문서를 나타냅니다.
이제 데이터를 전처리해 보겠습니다. nltk의 word_tokenize 함수를 사용하여 각 단락을 토큰화할 것입니다. 이 함수는 문장을 개별 단어로 분할합니다. 그런 다음 각 단어를 원-핫 인코딩 벡터로 표현하겠습니다.
vocabulary = set(word for article in squad_data['data'] for paragraph in article['paragraphs'] for word in word_tokenize(paragraph['context']))
word_to_index = {word: index for index, word in enumerate(vocabulary)}
def convert_text_to_vector(text):
words = word_tokenize(text)
bow_vector = np.zeros(len(vocabulary))
for word in words:
word in word_to_index:
bow_vector[word_to_index[word]] = 1
return bow_vector
paragraph_vectors = [convert_text_to_vector(paragraph['context']) for article in squad_data['data'] for paragraph in article['paragraphs']]
인덱스 구축하기
이제 데이터가 올바른 형식으로 준비되었으므로 FAISS 인덱스를 구축할 수 있습니다. 기본적인 L2 거리 인덱스인 IndexFlatL2 인덱스 유형을 사용할 것입니다.
dimension = len(vocabulary)
index = faiss.IndexFlatL2(dimension)
# NumPy 배열 리스트를 하나의 2D 배열로 변환
paragraph_vectors = np.stack(paragraph_vectors).astype('float32')
index.add(paragraph_vectors)
IndexFlatL2 유형은 데이터의 차원을 지정해야 합니다. 각 벡터가 원-핫 인코딩되어 있으므로 차원은 어휘의 크기입니다.
그런 다음 2D NumPy 배열을 필요로 하는 add 메서드를 사용하여 데이터를 인덱스에 추가합니다.
FAISS 벡터 검색 수행하기
인덱스 설정이 모두 완료되었으므로 이제 탐정 놀이를 하며 데이터셋에서 검색 쿼리와 가장 잘 일치하는 단락을 찾을 수 있습니다.
검색 함수는 다음과 같습니다.
def search_for_paragraphs(search_term, num_results):
search_vector = convert_text_to_vector(search_term)
search_vector = np.array([search_vector]).astype('float32')
distances, indexes = index.search(search_vector, num_results)
for i, (distance, index) in enumerate(zip(distances[0], indexes[0])):
print(f"Result {i+1}, Distance: {distance}")
print(squad_data['data'][index]['paragraphs'][0]['context'])
print()
검색어는 "What is the capital of France?"이고 5개의 결과를 찾고자 합니다.
search_term = "What is the capital of France?"
search_for_paragraphs(search_term, 5)
search_for_paragraphs()는 먼저 검색어를 인코딩된 벡터로 변환합니다. 그런 다음 이 벡터 표현을 인덱스에서 검색 메서드로 사용합니다. 여기에는 2D 배열이 필요하므로 검색 벡터에 추가 차원을 더합니다.
유사도 검색 메서드에는 원하는 결과 수를 지정해야 합니다(그것이 num_results의 역할입니다). search 메서드는 두 개의 2D 배열을 제공합니다. 하나는 가장 가까운 결과들의 거리이고, 다른 하나는 그 인덱스입니다. 이 인덱스를 사용하여 데이터셋에서 실제 단락을 찾을 수 있습니다. 그런 다음 각 결과의 순위, 유사도 거리, 단락 텍스트를 출력합니다.
이렇게 끝입니다! 이것은 FAISS를 사용하여 유사한 텍스트 데이터를 찾는 기본 예제입니다. 물론 FAISS는 고차원 벡터 공간에서 검색하는 것처럼 훨씬 더 복잡한 작업도 할 수 있습니다. 하지만 이 예제가 FAISS 사용을 시작하는 데 좋은 출발점이 될 것입니다.
모범 사례와 팁
데이터가 있나요? 데이터를 파악하세요: FAISS를 사용하기 전에 잠시 시간을 내어 데이터를 파악하세요. 다음과 같은 질문을 해보세요. 큰 숫자로 채워져 있나요? 빈틈이 많나요, 아니면 정보로 빽빽한가요? 데이터를 이해하면 올바른 FAISS 인덱스 유형을 선택하고 데이터를 준비하는 최선의 방법을 결정하는 데 도움이 됩니다.
전처리가 핵심입니다: 데이터를 어떻게 준비하느냐는 FAISS가 얼마나 잘 작동하는지에 큰 영향을 줄 수 있습니다. 텍스트 데이터의 경우 단순한 원-핫 인코딩 대신 TF-IDF나 Word2Vec처럼 단어를 숫자로 변환하는 더 스마트한 방법을 사용하는 것을 고려하세요. 이미지의 경우 convolutional neural network(CNN)에서 추출한 특징을 사용해 보세요.
자신에게 가장 적합한 인덱스를 선택하세요: FAISS에는 다양한 인덱스 유형이 있으며, 각각 특별한 강점이 있습니다. 어떤 것은 차원이 많은 데이터를 처리하는 데 뛰어나고, 어떤 것은 이진 벡터에 완벽하며, 또 어떤 것은 매우 큰 데이터를 처리하도록 만들어졌습니다. 따라서 자신의 요구 사항에 가장 잘 맞는 것을 선택해야 합니다.
쿼리를 배치 처리하세요: 인덱스에 대해 실행할 쿼리가 너무 많다면, 이를 함께 묶어 한 번에 실행하는 것이 더 효율적입니다. FAISS는 배치 처리에 최적화되어 있습니다.
매개변수를 조정하세요: FAISS에는 인덱싱 단계의 클러스터 수와 벡터 유사도 검색 단계의 프로브 수처럼 조정 가능한 매개변수가 여러 개 있습니다. 기본값에만 머무르지 말고, 다양한 설정을 실험해 데이터에 가장 잘 맞는 것이 무엇인지 확인하세요.
벡터 데이터베이스 vs FAISS
FAISS는 ANN 검색을 위한 훌륭한 솔루션입니다. 또한 FAISS는 밀집 벡터의 유사도 검색 및 클러스터링과 관련된 평가 및 매개변수 조정을 위한 추가 기능을 제공하는 지원 코드를 제공합니다. 하지만 저장 및 검색을 위해 수천만 개의 벡터를 보유하면서 동시에 실시간 응답이나 고급 쿼리 벡터 관련 기능이 필요한 경우에는 몇 가지 한계가 있습니다.
FAISS와 비교할 때, Milvus 및 Zilliz Cloud와 같은 목적 특화 벡터 데이터베이스는 위에서 언급한 과제를 해결할 수 있으며 다음 영역에서 더 고급 기능을 제공합니다:
CRUD 지원, 데이터 일관성, 필터 검색과 같은 기본 기능
강력한 데이터 지속성과 더 나은 재해 복구를 갖춘 시스템 가용성
로드 밸런싱 지원, 컴퓨팅과 스토리지를 분리하는 분산 아키텍처, 더 나은 사용성을 갖춘 시스템 확장성
멀티테넌트 지원, 다양한 프로그래밍 언어의 SDK, restful API, 모니터링 시스템을 갖춘 RBAC.
Milvus는 수십억 규모의 유사도 검색 및 AI 애플리케이션을 위한 세계 최초이자 가장 인기 있는 오픈 소스 벡터 데이터베이스입니다. Milvus는 심층 신경망 및 기타 머신 러닝(ML) 모델에서 생성된 10억 개 이상의 벡터 임베딩을 저장, 인덱싱 및 관리할 수 있습니다. 벡터 데이터베이스를 모든 개발자와 조직이 이용할 수 있도록 하기 위해, Zilliz는 Milvus를 인큐베이션 단계 프로젝트로 LF AI & Data Foundation에 기여했으며, 2021년 6월에 졸업했습니다.
Milvus Lite는 Python 애플리케이션 내에서 로컬로 실행되는 Milvus의 경량 버전입니다. 인기 있는 오픈 소스 Milvus 벡터 데이터베이스를 기반으로, Milvus Lite는 벡터 인덱싱 및 쿼리 파싱을 위한 핵심 구성 요소를 재사용하면서 분산 시스템에서 높은 확장성을 위해 설계된 요소는 제거했습니다. 이 설계는 노트북, Jupyter Notebooks, 모바일 또는 엣지 디바이스와 같이 컴퓨팅 리소스가 제한된 환경에 이상적인 작고 효율적인 솔루션을 만듭니다.
Zilliz Cloud는 Milvus 기반의 완전 관리형 벡터 데이터베이스 서비스입니다. Zilliz Cloud를 사용하면 벡터 검색이 10배 더 빠르고, 벡터 검색 애플리케이션의 배포 및 확장이 그 어느 때보다 쉬워집니다. Zilliz Cloud는 또한 무료 티어를 제공하여, 모든 개발자가 금전적 부담 없이 이 최첨단 기술에 접근할 수 있도록 합니다.
결론
이제 다 살펴보았습니다! 우리는 함께 Facebook AI Similarity Search, 즉 FAISS의 흥미로운 세계를 탐험했습니다. 그것이 무엇이며 어떻게 작동하는지 이해하는 것부터 시스템에 설정하는 방법, SQuAD 데이터셋을 사용한 샘플 코드 살펴보기, 그리고 목적 특화 벡터 데이터베이스와 어떻게 다른지까지, 많은 내용을 다루었습니다.
FAISS는 방대한 양의 데이터를 검색하는 일을 가능하게 할 뿐만 아니라 효율적으로 만들도록 설계된 믿을 수 없을 만큼 강력한 도구라는 점을 기억하세요. 다양한 데이터 유형과 크기를 수용하는 그 다재다능함은 그 설계를 잘 보여 줍니다.
이 지식을 갖추고 앞으로 나아갈 때, 우리가 논의한 모범 사례와 팁을 기억하세요. 데이터를 이해하고, 적절한 인덱스를 선택하고, 데이터를 효과적으로 전처리하고, 쿼리를 배치 처리하고, 매개변수를 튜닝하는 것—이 모든 단계는 결과를 크게 향상시킬 수 있습니다.
하지만 여기서 멈추지 마세요. 계속 탐색하고, 실험하고, 배우세요. FAISS가 제공하는 다양한 인덱스 유형을 더 깊이 파고들든, 더 복잡한 데이터 전처리 기법을 탐색하든, 더 정교한 사용 사례를 실험하든, 배울 것은 언제나 더 있습니다.
이 글은 고도로 숙련되고 열정적인 보안 엔지니어인 Keshav Malik이 작성했습니다. Keshav는 자동화, 해킹, 다양한 도구와 기술 탐구에 열정을 가지고 있습니다. 그는 복잡한 문제에 대한 혁신적인 해결책을 찾는 것을 좋아하며, 전문가로서 성장하고 발전할 새로운 기회를 끊임없이 찾고 있습니다. 그는 앞서 나가기 위해 헌신하고 있으며, 항상 최신이자 최고의 도구와 기술을 찾고 있습니다.
계속 읽기

Build Multimodal Search for 3D Assets with Tripo and Zilliz Cloud
Generate 3D assets with Tripo, then search them by text, image, and metadata with multimodal embeddings and Zilliz Cloud.

Our Journey to 35K+ GitHub Stars: The Real Story of Building Milvus from Scratch
Join us in celebrating Milvus, the vector database that hit 35.5K stars on GitHub. Discover our story and how we’re making AI solutions easier for developers.

Creating Collections in Zilliz Cloud Just Got Way Easier
We've enhanced the entire collection creation experience to bring advanced capabilities directly into the interface, making it faster and easier to build production-ready schemas without switching tools.



