Pinecone 벡터 스토어 - 하이브리드 검색

Pinecone 벡터 스토어 - 하이브리드 검색

Pinecone을 사용해 희소 벡터(sparse vector)와 밀집 벡터(dense vector)를 함께 활용하는 하이브리드 검색을 구현하는 방법을 보여드릴게요. add_sparse_vector=True 옵션을 켜면 각 문서의 희소 벡터까지 자동으로 계산해서 저장합니다. 검색 품질을 더 올리고 싶다면 커스텀 희소 임베딩 모델로 교체할 수도 있어요.

출처: 문서

본문

Colab에서 노트북을 여신다면 LlamaIndex 🦙를 설치해야 할 수 있어요.

%pip install llama-index-vector-stores-pinecone "transformers[torch]"

Pinecone 인덱스 만들기

from pinecone import Pinecone, ServerlessSpec
import os


os.environ["PINECONE_API_KEY"] = "..."
os.environ["OPENAI_API_KEY"] = "sk-..."


api_key = os.environ["PINECONE_API_KEY"]


pc = Pinecone(api_key=api_key)
# 필요하면 삭제
pc.delete_index("quickstart")
# 차원은 text-embedding-ada-002 용
# 참고: 하이브리드 검색에는 dotproduct 메트릭이 필요해요


pc.create_index(
    name="quickstart",
    dimension=1536,
    metric="dotproduct",
    spec=ServerlessSpec(cloud="aws", region="us-east-1"),
)


# Pod 기반 Pinecone 인덱스가 필요하다면 이렇게도 만들 수 있어요:
#
# from pinecone import Pinecone, PodSpec
#
# pc = Pinecone(api_key='xxx')
#
# pc.create_index(
#    name='my-index',
#    dimension=1536,
#    metric='cosine',
#    spec=PodSpec(
#      environment='us-east1-gcp',
#      pod_type='p1.x1',
#      pods=1
#    )
# )
#
pinecone_index = pc.Index("quickstart")

데이터 다운로드

!mkdir -p 'data/paul_graham/'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'

문서를 불러와 PineconeVectorStore 만들기

add_sparse_vector=True로 설정하면 PineconeVectorStore가 각 문서에 대해 희소 벡터를 계산해요.

기본적으로는 희소 벡터를 만들 때 단순한 토큰 빈도(token frequency)를 사용하지만, 커스텀 희소 임베딩 모델을 지정할 수도 있어요.

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.vector_stores.pinecone import PineconeVectorStore
from IPython.display import Markdown, display
# 문서 로드
documents = SimpleDirectoryReader("./data/paul_graham/").load_data()
# upsert 시 희소 벡터를 계산하려면 add_sparse_vector=True 지정
from llama_index.core import StorageContext


if "OPENAI_API_KEY" not in os.environ:
    raise EnvironmentError(f"Environment variable OPENAI_API_KEY is not set")


vector_store = PineconeVectorStore(
    pinecone_index=pinecone_index,
    add_sparse_vector=True,
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
    documents, storage_context=storage_context
)
huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...
To disable this warning, you can either:
  - Avoid using `tokenizers` before the fork if possible
  - Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)




Upserted vectors:   0%|          | 0/22 [00:00<?, ?it/s]

인덱스 질의하기 (Query Index)

인덱스가 준비되기까지 1~2분 정도 기다려야 할 수 있어요

# 더 자세한 출력을 보려면 Logging을 DEBUG로 설정
query_engine = index.as_query_engine(vector_store_query_mode="hybrid")
response = query_engine.query("What happened at Viaweb?")
display(Markdown(f"<b>{response}</b>"))

Paul Graham이 돈이 필요해서 Viaweb을 시작했다는 답변이 나옵니다. 회사가 성장하면서 큰 회사를 운영하고 싶지 않다는 걸 깨달았고, 비전의 일부를 오픈소스 프로젝트로 만들기로 했습니다. 결국 1998년 여름 Viaweb을 Yahoo에 매각했고, 이는 Paul Graham에게 큰 안도였다는 내용이네요.

희소 임베딩 모델 바꾸기

%pip install llama-index-sparse-embeddings-fastembed
# 벡터 스토어 비우기
vector_store.clear()
from llama_index.sparse_embeddings.fastembed import FastEmbedSparseEmbedding


sparse_embedding_model = FastEmbedSparseEmbedding(
    model_name="prithivida/Splade_PP_en_v1"
)


vector_store = PineconeVectorStore(
    pinecone_index=pinecone_index,
    add_sparse_vector=True,
    sparse_embedding_model=sparse_embedding_model,
)
Fetching 5 files:   0%|          | 0/5 [00:00<?, ?it/s]
index = VectorStoreIndex.from_documents(
    documents, storage_context=storage_context
)
Upserted vectors:   0%|          | 0/22 [00:00<?, ?it/s]

업로드가 끝날 때까지 잠시 기다려 주세요.

response = query_engine.query("What happened at Viaweb?")
display(Markdown(f"<b>{response}</b>"))

Paul Graham이 돈이 필요해서 Viaweb을 시작했다는 답변이 나옵니다. 그는 팀을 모아 애플리케이션 빌더와 네트워크 인프라 구축에 집중하는 소프트웨어·서비스 개발에 매진했습니다. 그런데 여름이 반쯤 지났을 무렵 큰 회사를 운영하고 싶지 않다는 걸 깨달았고, 프로젝트의 일부를 오픈소스로 만들기로 방향을 틀었습니다. 그 결과 Arc라는 새로운 Lisp 계열 언어 개발로 이어졌고, 결국 1998년 여름 Viaweb을 Yahoo에 매각해 안도하며 인생의 새 국면으로 전환하게 됐습니다.

더 알아보기 (Learn more)