LLM

랭체인(Langchain)을 이용한 RAG 시스템 만들기

JustJunsu 2024. 4. 20. 16:36
728x90

랭체인을 이용한 RAG 시스템

PDF 데이터를 이용한 RAG시스템의 플로우차트를 그리면 다음과 같습니다.

 

이제 순서대로 실습을 진행하겠습니다. 저는 Attention is all you need라는 논문 PDF를 이용하여 실습을 진행하였습니다.

1. Data Loader

$pip install langchain !pip install pypdf
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("attention is all you need.pdf")
docs = loader.load_and_split() #page 수 만큼 Split
print(type(docs))
print(len(docs))
print(docs[0])
print(docs[1].page_content)
print(docs[1].metadata)

 

저는 langchain에서 제공하는 PyPDFLoader를 이용하여 PDF파일을 불러왔고, Page별로 나누어졌습니다. 이를 메타 데이터를 통해 확인할 수 있습니다. 파일을 불러오는 기능은 PyPDFLoader, UnstructuredPDFLoader, PDFPlumber 등 다양한 방법이 있으며 본인의 상황에 맞게 사용해야 합니다.

2. Text Splitter

 from langchain.text_splitter import RecursiveCharacterTextSplitter
 text_splitter = RecursiveCharacterTextSplitter(Chunk_size=1000, chunck_overlap=200)
 splits = text_splitter.split_documents(docs)
 print(len(splits))
 print(splits[0].page_content)
 print(splits[0].metadata)

 

저는 가장 범용적으로 사용되는 langchain에서 제공하는 RecursiveCharacterTextSplitter를 사용했으며 Chunk 사이즈를 1000, overlap을 200으로 하여 텍스트를 분할하였습니다. 이 역시 TokenTextSplitter, SemanticChunker 등 다양한 Split 방법이 있으며 본인의 상황에 맞게 사용해야 합니다.

3. Text Embedding

$pip install openai
$pip install sentence_transformers
$pip install rapidfuzz
$pip install tiktoken
 import os
 os.environ["OPENAI_API_KEY"] = {OPENAI_API_KEY}
 from langchain_community.embeddings import OpenAIEmbeddings
 from langchain.embeddings import CacheBackedEmbeddings
 from langchain.storage import LocalFileStore
 embeddings = OpenAIEmbeddings()
 store = LocalFileStore("/cache")
 cached_embeddings = CacheBackedEmbeddings.from_bytes_store(embeddings, store, namespace = embeddings.model)

 

가장 기본적인 방법인 OEPNAI에서 제공하는 embedding 모델을 사용하였습니다. 이때 OPENAI의 API를 사용하려면 OPENAI에서 API KEY를 발급받아야 합니다.

 

https://platform.openai.com/api-keys

 

여기서 로그인 하시고 API KEY를 발급받아 사용하시면 됩니다.
사용한 양과 비례하여 과금이 되는데 이때 과금을 조금이라도 줄이기 위해 한번 임베딩한 텍스트를 로컬에 저장하여 사용하였습니다. embedding 방법 또한 여러가지 방법이 있으며, HuggingFace의 Embedding 모델이 많이 있어 사용법을 익히시면 과금없이 Embedding을 할 수 있습니다.

4. VectorStore

from langchain_community.vectorstores import FAISS
 db = FAISS.from_documents(splits, cached_embeddings)
 retriever = db.as_retriever()
 retriver.invocke("I want to know the architecture of transformer")

 

VectorStore로 저는 FAISS를 사용하였습니다. RAG시스템을 구축할 때 FAISS와 CHROMA 이 두가지를 많이 사용하는데, FAISS의 경우 대규모 데이터의 유사성 검색에 적합하게 설계되었고, META에서 개발하였기에 안정적이라고 생각했습니다. 추후 FAISS DB를 retriever로 사용하기 위해서 코드를 추가해 주었습니다. 그리고 질문("I want to know the architecture of transformer")을 통해서 질문과 유사한 chunck를 찾아보았습니다.

5. LLM(Large Language Model)

$pip install faiss-gpu
$conda install -c conda-forge faiss-gpu --yes
from langchain.chat_models import ChatOpenAI
 llm = ChatOpenAI(model_name = "gpt-3.5-turbo", temperature = 0)
 llm.invoke("Hi")

 

LLM으로 가장 기본적인 방법인 GPT3.5-turbo를 사용하였으며 추후 허깅페이스를 이용해 용도에 맞게 LLM을 파인튜닝하여 사용하신다면 과금 걱정없이 원하는 언어 생성 모델로 사용하실 수 있을 것입니다. 그리고 저는 잘 작동하는지 확인하게 위해 대화("HI")를 해보았습니다.

6. Chain

$pip install langchianhub
from langchain import hub
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
 prompt = hub.pull("rlm/rag-prompt")
 chain = {"context" : retriever,"question": RunnablePassthrough()} \
                     | prompt \
                     | llm \
                     | StrOutputParser()
chain.invoke({"question":"I want to know the architecture of transformer"})

 

Retriever를 이용해 질문과 연관된 Context를 찾고, 이를 prompt에 함께 사용해 llm에 넣어주어 답변을 받을 수 있도록 과정을 이어주는 chain을 만들었습니다. prompt는 langchain hub에서 rag시스템에 흔히 사용되는 prompt를 가져다 사용하였고, 용도에 맞게 커스텀하여 사용할 수도 있습니다. 그리고 최종 질문을 통해 답을 확인하였습니다. 

이를 통해 간단한 LangChain 라이브러리를 이용하여 간단한 RAG시스템을 구축해 보았습니다. 앞으로는 각 부분에서 RAG 시스템을 고도화 하기 위해 노력해 봐야겠습니다.

 

Reference

https://python.langchain.com/docs/get_started/quickstart/

 

Quickstart | 🦜️🔗 LangChain

In this quickstart we'll show you how to:

python.langchain.com

https://www.youtube.com/watch?v=NfQrRQmDrcc

https://www.youtube.com/watch?v=tIU2tw3PMUE

https://www.youtube.com/watch?v=127lV0wcDmc

https://www.youtube.com/watch?v=qH69XGQZHDg

https://www.youtube.com/watch?v=fE4SH2vEsdk

728x90