728x90
Llama-Index with Pinecone
์ด ๋
ธํธ๋ถ์์๋ semantic-search๋ฅผ ์ํด Pinecone๊ณผ llama-index
(์ด์ ์ GPT-index) ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋ค. ์ด ๋
ธํธ๋ถ์ llama-index
์ ์์์ด๋ฉฐ ํฅํ ๋ฆด๋ฆฌ์ค์์๋ Pinecone ์์ ์ ์ฅ์์์ ์ฐพ์ ์ ์์ต๋๋ค.
1) install packages
!pip install -qU llama-index datasets pinecone-client openai transformers
2) SQuAD dataset Load
- Wikipedia(context-title)
from datasets import load_dataset
data = load_dataset('squad', split='train')
data = data.to_pandas()[['id', 'context', 'title']]
data.drop_duplicates(subset='context', keep='first', inplace=True)
data.head()
len(data)
- DataFram์ llama_index๋ก ์ธ๋ฑ์ฑ
- ๊ฐ ๋ฌธ์์ ํ ์คํธ ๊ตฌ์ , ๊ณ ์ ID, ๋ฌธ์ ์ ๋ชฉ ์ถ๊ฐ
from llama_index import Document
docs = []
for i, row in data.iterrows():
docs.append(Document(
text=row['context'],
doc_id=row['id'],
extra_info={'title': row['title']}
))
docs[0]
print(f"document counts: {len(docs)}")
3) OpenAI API key ์ค์ , SimpleNodeParser
์ด๊ธฐํ
- m1 mac์์๋ SimpleNodeParser๋ฅผ default๋ก ์ฌ์ฉ
import os
os.environ['OPENAI_API_KEY'] = 'OPENAI_API_KEY' # platform.openai.com
from llama_index.node_parser import SimpleNodeParser
# parser = SimpleNodeParser()
parser = SimpleNodeParser.from_defaults()
nodes = parser.get_nodes_from_documents(docs)
nodes[0]
len(nodes)
4) Indexing in Pinecone
- Pinecone: ML Application์ ์ํด ๋์์ธ๋ vector database manage service
- ์ฃผ๋ก llm(large language model)์์ ์์ฑ๋ embedding vector๋ค์ ์ ์ฅํ๊ณ semantic sililarity-based ๊ฒ์์ ์ํด ์ฌ์ฉํ๋ค.
- ์ฝ์์์ free๋ก ์ป์ ์ ์๋ ๊ด๋ จ API ํค์ ํ๊ฒฝ(https://app.pinecone.io/)์ผ๋ก Pinecone์ ์ด๊ธฐํํ ๋ค์ ์ ์ธ๋ฑ์ค๋ฅผ ์์ฑ
- ์ธ๋ฑ์ค์ dim์ 1536์ด๋ฉฐ, ์ฝ์ฌ์ธ ์ ์ฌ๋(cosine similarity)๋ฅผ ์ฌ์ฉ, ์ฃผ๋ก embedding vector๋
text-embedding-ada-002
๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ ๋ ดํ๊ณ ๋น ๋ฅธ embedding model์ด๋ค.
- PINECONE_API_KEY: Pinecone API key
- index_name : pinecone์ ์ ์ฅ์ ์ด๋ฆ
- PINECONE_ENVIRONMENT: pinecone์ ์๋ฒ ํ๊ฒฝ ์ด๋ฆ
import pinecone
# find API key in console at app.pinecone.io
os.environ['PINECONE_API_KEY'] = 'PINECONE_API_KEY'
# environment is found next to API key in the console
os.environ['PINECONE_ENVIRONMENT'] = 'PINECONE_ENVIRONMENT'
# initialize connection to pinecone
pinecone.init(
api_key=os.environ['PINECONE_API_KEY'],
environment=os.environ['PINECONE_ENVIRONMENT']
)
# create the index if it does not exist already
index_name = 'llama-index-intro'
if index_name not in pinecone.list_indexes():
pinecone.create_index(
index_name,
dimension=1536,
metric='cosine'
)
# connect to the index
pinecone_index = pinecone.Index(index_name)
- Pinecone ์ธ๋ฑ์ค๋ก
PineconeVectorStore
๋ฅผ ์ด๊ธฐํ PineconeVectorStore
๋ Pinecone์ vector database์์ document embedding์ ์ํ ์ ์ฅ ๋ฐ ๊ฒ์ ์ธํฐํ์ด์ค ์ญํ ์ ์ ๊ณต
from llama_index.vector_stores import PineconeVectorStore
# we can select a namespace (acts as a partition in an index)
namespace = 'test' # default namespace
vector_store = PineconeVectorStore(pinecone_index=pinecone_index)
PineconeVectorStore
๋ฅผ storage๋ก,OpenAIEmbedding
์ embedding,GPTVectorStoreIndex
๋ฅผDocument
๊ฐ์ฒด ๋ชฉ๋ก์ผ๋ก ์ด๊ธฐํStorageContext
๋ storage ์ค์ ์ ๊ตฌ์ฑํ๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ,ServiceContext
๋ embedding ๋ชจ๋ธ์ ์ค์ GPTVectorStoreIndex
๋ ์ ๊ณต๋ storage์ service_context๋ฅผ ํ์ฉํด ์ธ๋ฑ์ฑ ๋ฐ ์ฟผ๋ฆฌ ํ๋ก์ธ์ค๋ฅผ ์ฒ๋ฆฌ
from llama_index import GPTVectorStoreIndex, StorageContext, ServiceContext
from llama_index.embeddings.openai import OpenAIEmbedding
# setup our storage (vector db)
storage_context = StorageContext.from_defaults(
vector_store=vector_store
)
# setup the index/query process, ie the embedding model (and completion if used)
embed_model = OpenAIEmbedding(model='text-embedding-ada-002', embed_batch_size=100)
service_context = ServiceContext.from_defaults(embed_model=embed_model)
index = GPTVectorStoreIndex.from_documents(
docs, storage_context=storage_context,
service_context=service_context
)
- index query engine์ ํตํด QA๋ฅผ
query_engine = index.as_query_engine()
res = query_engine.query("์ด์์ ์ฅ๊ตฐ์ ๋ํด ์ค๋ช
ํด ์ฃผ์ธ์.")
print(res)
# ์ด์์ ์ฅ๊ตฐ์ ํ๊ตญ์ ์ ๋ช
ํ ์ฅ๊ตฐ์ผ๋ก ์๋ ค์ ธ ์์ต๋๋ค.
# ๊ทธ๋ ์กฐ์ ์๋์ ํ์ฝํ ์ฅ๊ตฐ์ผ๋ก, ์กฐ์ ์์กฐ ์๋์ ๋ง์ ์ ์์์ ์ฑ๊ณผ๋ฅผ ๋ด์์ต๋๋ค.
# ์ด์์ ์ฅ๊ตฐ์ ์กฐ์ ์ ํด์ ์๋ณด๋ฅผ ๊ฐํํ๊ธฐ ์ํด ์กฐ์ ์ต์ด์ ๊ฐํ๋๋ฅผ ๊ฑด์คํ๊ณ , ์กฐ์ ์ ํด์ ์ ๋ต์ ๊ฐ๋ฐํ์ต๋๋ค.
# ๊ทธ๋ ์ผ๋ณธ์ ์นจ๋ต์ ๋ง๊ธฐ ์ํด ๋ง์ ์ ํฌ์์ ์น๋ฆฌ๋ฅผ ๊ฑฐ๋์์ผ๋ฉฐ, ํนํ ๋ช
๋ํด์ ์์์ ์น๋ฆฌ๋ก ์ ๋ช
ํฉ๋๋ค.
# ์ด์์ ์ฅ๊ตฐ์ ์กฐ์ ์ ๊ตฐ์ฌ ์ ๋ต๊ณผ ๋ฐ์ด๋ ์งํ๋ ฅ์ผ๋ก ๋ง์ ์ฌ๋๋ค์๊ฒ ์กด๊ฒฝ๋ฐ๋ ์ธ๋ฌผ์
๋๋ค.
- vector db์ ์๋ ์ง๋ฌธ
query_engine = index.as_query_engine()
res = query_engine.query("์ด์์ ์ฅ๊ตฐ์ด ์ฌ์ฉํ ์์์ ๋ํด ์ค๋ช
ํด์ฃผ์ธ์")
print(res)
# ์ด์์ ์ฅ๊ตฐ์ด ์ฌ์ฉํ ์์์ ๋ํด๋ ์ ๊ณต๋ ๋ฌธ๋งฅ ์ ๋ณด๊ฐ ์์ต๋๋ค.
- ์๋ฏธ ์๋ index๊ฐ vectordb์ ์ถ๊ฐ ๋ ๊ฒฝ์ฐ
index_name
์ผ๋ก ์ญ์
pinecone.delete_index(index_name)
๋ฐ์ํ