- 가상환경 설정 및 MVP 구현
- Dataset과 Vector DB 구현
- Embedding & Searching 구현
- Generation 구현
이전 Intro에 이어 RAG를 위한 가상환경과 RAG의 MVP(Most Viable Product) 선정하여 구현을 진행 했다. MVP 형태의 RAG를 구현한 다음 고도화를 할 수 있는 부분들을 선정하기 위해서였다. 그리고 사실 이단계에서는 RAG에 대한 이해가 높지 않기에 바로 의도한 RAG를 만들 수 없다고 생각했다.
그래서 현재 형태의 RAG는 아래의 사진과 같다.
가상환경의 경우 일반적인 Python 가상 환경으로 진행하였으나 Google Colab을 사용하였기에 문법이 조금은 다르다.
가상환경 설정
!apt install python3.10-venv
!python3.10 -m venv rag_prac_env
!source /content/rag_prac_env/bin/activate
MVP에서의 핵심은 RAG의 기본적인 구조를 갖추면서도 작동하는 최소단위라고 판단했다.
그래서 Dataset, Vector Database, Embedding Model 그리고 LLM을 먼저 선정했고 그와 관련된 Package를 설치했다.
Packages Installation
# Langchain LLM application framework
!rag_prac_env/bin/pip install langchain
!rag_prac_env/bin/pip install -U langchain-community
# LLM
!rag_prac_env/bin/pip install openai
# Vector DB and Embedding
!rag_prac_env/bin/pip install chromadb
!rag_prac_env/bin/pip install unstructured
!rag_prac_env/bin/pip install sentence-transformers
Loading & Embedding
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import SentenceTransformerEmbeddings
from langchain.vectorstores import Chroma
def chunking_dcos(documents, chunk_size=1000, chunk_overlap=20):
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
docs = text_splitter.split_documents(documents)
return docs
# Loading
directory_path = '/content/drive/MyDrive/RAG_DATA'
if not os.path.exists(directory_path):
os.makedirs(directory_path)
given_text = os.path.join(directory_path, 'seongbuk.txt')
documents = TextLoader(given_text).load()
# Chunking
chunked_docs = chunking_dcos(documents=documents)
# Embedding & Storing
embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
db = Chroma.from_documents(chunked_docs, embeddings)
Vector DB와 Embedding에 있어서 어떻게 구성하는지에 따라 차이가 있겠으나 지금 현재의 MVP단계에서는 테스트용으로 한페이지 정도의 Data를 선정하여 Vector DB에 넣었다. 그리고 Data를 Vector DB에 넣기위해 chunking을 진행했다. Chunking은 하나의 큰 데이터 혹은 Dataset을 잘게 쪼갠다음 의미 단위로 분류하는 행위로 데이터에 대한 이해도를 높일 수 있다.
RecursiveCharacterTextSplitter()를 사용한 이유는 큰 문단에서 부터 작은 단위로 작아진다는 방식이 가장 기본적인 형태라 생각 되어 선정하게 됐다.
그리고 Embedding Model과 함께 Vector DB를 만들었다.
Retrieval & Generation
from langchain.chat_models import ChatOpenAI
from langchain.chains.question_answering import load_qa_chain
os.environ['OPENAI_API_KEY'] = userdata.get('openAI')
# LLM Model
model_name = "gpt-3.5-turbo"
llm = ChatOpenAI(model_name=model_name)
# Using Q&A Chain to get answer
chain = load_qa_chain(llm, chain_type="stuff", verbose=True)
query = "성북구의 장점"
# Retreiving and Generating
matching_docs = db.similarity_search(query)
answer = chain.run(input_documents=matching_docs, question=query)
answer
그 다음의 Retrieval과 Generation을 진행하였는 Retrieval에서의 Query에 대한 Embedding이 Vector DB에서 진행돼서 구분되어 보이지는 않는다. MVP의 최소 기능이기에 현재 사용한 모든 모델들이 기본형이다.
여기서 load_qa_chain은 Langchain에서 제공하는 모듈이다. 질문과 대답의 형태의 LLM 서비스를 만들 때 관련 된 특징들이 모듈화 돼있다고 생각하면 된다.
결과
기본적인 MVP RAG를 만들고 나서 기본적인 RAG 작동 구조에 대해서 좀 더 구체적으로 알게 됐다.
특히, 생각지 못했던 DB와 Dataset의 중요성이 부가됐다. 그리고 LLM Application 개발에 있어 Langchain이라는 Framework의 존재 이유에 대해서 확실히 채감 됐다. 특히 기본적으로 Langchain을 구성하는 주요모듈에 대해서 한번 확인해 볼 필요가 생겼다. 그래서 이번 MVP 개발을 하면서 가장 부각 됐던 DB와 Vector DB구성을 구현된 MVP RAG에 추가할 예정이다.
먼저 데이터셋을 확보하고 그 다음 Vector DB를 구현하기로 결정했다.
'AI > Gen AI' 카테고리의 다른 글
RAG 구현 Step-by-Step Vector DB 구현 - 2: Faiss with LangChain (3) | 2024.09.17 |
---|---|
RAG 구현 Step-by-Step Vector DB 구현 - 1: Implementation Outline (1) | 2024.09.16 |
RAG 구현 Step-by-Step Dataset 확보: Selenium을 활용한 Crawler (3) | 2024.09.02 |
RAG 구현 Step-by-Step Dataset 확보 (1) | 2024.08.28 |
RAG 구현 Step-by-Step: Intro (0) | 2024.08.19 |