5단 분석법
순서 | 분석 | 단어 | 내용 |
1 | 일반 명사 | - | - |
2 | 고유 명사 | FAISS | 개발자가 서로 유사한 멀티미디어 문서의 임베딩을 빠르게 검색할 수 있는, 페이스북에서 개발한 라이브러리 |
3 | 사용 이유 | FAISS | 해시 기반 검색에 최적화된 기존 쿼리 검색 엔진의 한계를 해결하고 확장 가능한 유사성 검색 기능을 제공하기 때문에 |
4 | 사용 방법 | FAISS | FAISS 라이브러리를 사용해 벡터 데이터를 인덱싱하고 검색 쿼리를 수행 |
5 | 다른 기술과의 비교 | FAISS | - |
정의
고유 명사
FAISS | 개발자가 서로 유사한 멀티미디어 문서(파일)의 임베딩을 빠르게 검색할 수 있는, 페이스북에서 개발한 라이브러리 |
Facebook AI Similarity Search(이하 FAISS)는 개발자가 서로 유사한 멀티미디어 문서의 임베딩을 빠르게 검색할 수 있는, 페이스북에서 개발한 라이브러리 입니다.
주로 머신 러닝, 추천 시스템, 정보 검색 등에서 대규모 데이터의 유사성을 빠르고 정확하게 찾기 위해 사용합니다.
멀티미디어 문서가 뭔가요?
텍스트, 이미지, 오디오, 비디오 등의 다양한 형태의 데이터를 포함하는 문서
•
예시
◦
텍스트: 뉴스 기사, 블로그 포스트, 이메일 등
◦
이미지: 사진, 그림, 그래프 등
◦
오디오: 팟캐스트, 음악 파일, 음성 녹음 등
◦
비디오: 영화, 유튜브 동영상, 강의 녹화 등
사용 이유
FAISS | 해시 기반 검색에 최적화된 기존 쿼리 검색 엔진의 한계를 해결하고 확장 가능한 유사성 검색 기능을 제공하기 때문에 (평탄화 +유사성을 만들기 위해서) |
FAISS는 해시 기반 검색에 최적화된 기존 쿼리 검색 엔진의 한계를 해결하고 확장 가능한 유사성 검색 기능을 제공하기 때문에 사용합니다.
이유 | 설명 |
빠른 검색 속도 | 대규모 데이터셋에서도 빠른 검색을 가능하게 합니다. |
유연한 자원 사용 | 메모리와 컴퓨팅 자원을 유연하게 사용하여 대규모 벡터 데이터 검색을 수행합니다. |
다양한 인덱싱 방법 | 여러 가지 인덱싱 방법을 제공하여 다양한 검색 요구를 충족시킵니다. |
확장성 | 단일 노드뿐만 아니라 분산 환경에서도 사용할 수 있습니다. |
오픈소스 | 자유롭게 사용할 수 있는 오픈소스 라이브러리입니다. |
해시 기반 검색에 최적화된 기존 쿼리 검색 엔진의 한계를 어떻게 해결했나요?
FAISS는 벡터 기반 접근, 근사 최근접 이웃 검색 등의 방법을 통해 기존 쿼리 검색 엔진의 한계를 해결했습니다.
•
벡터 기반 접근
◦
FAISS는 해시 기반이 아닌 벡터 기반 접근 방식을 사용합니다.
◦
이는 데이터를 고차원 벡터 공간에 매핑하여 의미적 유사성을 더 잘 포착할 수 있게 합니다.
•
근사 최근접 이웃 (Approximate Nearest Neighbor, ANN) 검색
◦
정확한 최근접 이웃을 찾는 대신, 근사치를 빠르게 찾는 알고리즘을 사용합니다.
◦
이를 통해 대규모 데이터셋에서도 빠른 검색이 가능해집니다.
•
다양한 인덱싱 방법
◦
FAISS는 여러 인덱싱 방법(예: 플랫 인덱스, IVF, HNSW 등)을 제공하여 데이터의 특성과 요구사항에 따라 최적의 검색 방법을 선택할 수 있게 합니다.
확장 가능한 유사성 검색 기능은 어떻게 제공하나요?
FAISS는 GPU 가속, 클러스터링 및 양자화, 다차원 인덱싱, 분산 처리 지원 등의 방식으로 유사성 검색 기능을 제공합니다.
•
GPU 가속
◦
FAISS는 GPU를 활용한 병렬 처리를 지원하여 대규모 데이터셋에서도 빠른 검색이 가능합니다.
•
클러스터링 및 양자화
◦
데이터를 클러스터링하고 양자화하여 메모리 사용량을 줄이고 검색 속도를 높입니다.
▪
양자화: 모델의 파라미터를 더 작은 비트로 표현하여 모델 크기를 줄이고 추론 속도를 높이는 기법
•
다차원 인덱싱
◦
고차원 벡터를 빠르고 정확하게 인덱싱하고 검색할 수 있는 알고리즘을 제공합니다.
•
분산 처리 지원
◦
여러 머신에 걸쳐 인덱스를 분산시키고 병렬로 검색을 수행할 수 있어, 대규모 데이터셋에서도 확장성을 유지할 수 있습니다.
클러스터링이란?
데이터 포인트들을 유사성에 기반해 그룹화 하는 과정
•
대량의 데이터를 더 작고 관리하기 쉬운 하위 집합으로 나누어, 검색 속도를 높이고 메모리 사용을 최적화 함
사용 방법
FAISS | FAISS 라이브러리를 사용해 벡터 데이터를 인덱싱하고 검색 쿼리를 수행계의 세심하고 자세한 설명은 다음과 같습니다: |
1. 라이브러리 설치 및 데이터셋 생성
원래는 대규모 벡터 데이터베이스에서 검색을 수행해야 하지만, 예제이므로 간단히 4개의 벡터를 생성하여 검색을 수행하겠습니다.
!pip install faiss-cpu
JSON
복사
# OpenAI API 키 설정 (환경 변수로 설정)
import os
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
Bash
복사
•
os: 환경 변수를 설정하기 위한 표준 라이브러리입니다.
•
os.environ: 환경 변수를 설정하는 방법입니다. "OPENAI_API_KEY"는 OpenAI API 키를 저장하는 환경 변수입니다.
•
"your-openai-api-key": OpenAI API 키로, 실제 OpenAI 계정에서 발급받은 API 키로 대체해야 합니다.
import numpy as np
import faiss
Python
복사
•
import numpy as np: NumPy 라이브러리를 np로 임포트합니다.
•
import faiss: FAISS 라이브러리를 임포트합니다.
d = 128
Python
복사
•
d: 각 벡터의 차원 수를 128로 설정합니다.
◦
쉽게 말해, 벡터는 1행 n열의 배열이다. 즉, 128 차원수라는 것은 1행 128열이다.
nb = 10000
Python
복사
•
nb: 데이터셋의 벡터 개수를 10,000개로 설정합니다.
◦
단어 임베딩에서는 ‘단어’ 하나가 벡터 1개를 의미
▪
apple은 300차원의 벡터
◦
문서 임베딩에서는 ‘문서’ 하나가 벡터 1개를 의미
▪
여러 문장을 포함한 문서가 512차원의 백터
np.random.seed(1234)
Python
복사
•
np.random.seed(1234): 난수 생성을 위한 시드를 1234로 설정하여, 동일한 랜덤 데이터셋을 재생성할 수 있게 합니다.
data = np.random.random((nb, d)).astype('float32')
Python
복사
•
data: 10000개의 128차원 벡터를 랜덤으로 생성하고, 데이터 타입을 float32로 변환합니다.
◦
쉽게 말해 10,000행X128열의 배열을 만드는 것입니다.
2. FAISS 인덱스 생성 및 훈련
index = faiss.IndexFlatL2(d) # index는 결국 메모리의 시작 위치
print(index) # 결과값 <faiss.swigfaiss_avx2.IndexFlatL2; proxy of <Swig Object of type 'faiss::IndexFlatL2 *' at 0x7ad8422935a0> >
# 이 래퍼 객체가 메모리에 저장된 위치를 보여줍니다. 데이터의 위치를 동적으로 저장하여서 문서를 빠르게 찾기 위해서 메모리 위치를 변수에 할당해놓습니다.
Python
복사
•
index = faiss.IndexFlatL2(d): 벡터 간의 거리를 계산할 때 L2 거리(유클리드 거리)를 사용하는 인덱스를 생성합니다.
◦
매개변수 d: 벡터의 차원 수를 나타냅니다.
예를 들어, 벡터가 128차원이라면 d는 128로 설정됩니다.
유클리드 거리가 뭔가요?
유클리드 거리(Euclidean Distance)는 n차원 공간에서 두 점 사이의 직선 거리를 계산하는 방법입니다. 이 거리는 피타고라스의 정리를 확장하여 계산됩니다.
예 (1,1), (3.3)
index.add(data) # float타입의 10,000행X128열의 배열
Python
복사
•
index.add(data): 생성한 10,000개의 벡터 데이터를 인덱스에 추가합니다.
3. 쿼리 벡터 생성
실제로는 쿼리 입력을 받아서 벡터로 변환해야하지만, 예제이다보니 가상의 쿼리 벡터를 만들도록 하겠습니다.
nq = 5 # 사용자가 입력한 쿼리가 5개.
Python
복사
•
nq: 검색할 쿼리 벡터의 개수를 5개로 설정합니다.
queries = np.random.random((nq, d)).astype('float32')
Python
복사
•
queries: 5개의 128차원 쿼리 벡터를 랜덤으로 생성하고, 데이터 타입을 float32로 변환합니다.
4. 검색 수행
원래는 대규모 벡터 데이터베이스에서 검색을 수행해야 하지만, 예제이므로 간단히 4개의 벡터를 생성하여 검색을 수행하겠습니다.
k = 4
Python
복사
•
k: 각 쿼리 벡터에 대해 가장 가까운 4개의 이웃을 검색합니다.
Distances, Indices = index.search(queries, k)
Python
복사
•
D, I = index.search(queries, k): 인덱스에서 각 쿼리 벡터에 대해 k개의 가장 가까운 이웃을 검색하고, 거리(Distances)와 인덱스(Indicesndices)를 반환합니다.
print('Indices')
print(Indices)
Python
복사
•
print(I): 가장 가까운 이웃의 인덱스를 출력합니다.
print('Distances')
print(Distances)
Python
복사
•
print(D): 가장 가까운 이웃과의 거리를 출력합니다.
결과 (예시)
Indices
[[7548 5874 4044 1573]
[8619 2762 2862 417]
[6059 5596 1617 106]
[7167 6353 8302 4062]
[5531 9262 2933 5512]]
Distances
[[14.120588 14.428286 14.519493 14.67854 ]
[14.769968 15.277808 15.82649 15.894089]
[14.996596 15.646384 15.67143 15.70339 ]
[13.788441 13.872476 14.549911 14.625786]
[13.655877 13.713434 13.981209 14.274239]]
JavaScript
복사
Indices 7548의 의미가 무엇을 말하나요?
인덱스(I)는 원본 데이터셋에서 검색된 벡터의 위치를 나타내는 정수입니다. 각 인덱스는 원본 데이터 배열에서 벡터의 위치를 가리킵니다.
•
정수인 이유: 인덱스는 데이터셋 내에서 벡터의 위치를 나타내므로, 이는 자연스럽게 정수 값입니다. 예를 들어, 7548은 데이터셋에서 7548번째 벡터를 의미합니다.
Distances 14.120588 의미가 무엇을 말하나요?
거리는 검색된 쿼리 벡터와 데이터셋 내의 각 벡터 간의 유사성을 나타내는 값입니다. 여기서 거리는 유클리드 거리로 계산되며, 실수로 표현됩니다.
•
실수인 이유: 거리는 벡터 간의 실제 거리(유클리드 거리)를 나타내므로, 이는 연속적인 값을 가지며, 실수 값으로 표현됩니다. 예를 들어, 14.120588은 쿼리 벡터와 해당 벡터 간의 유클리드 거리입니다.