Rag code를 돌려볼까하던 와중에
Langchain 과 llamaindex가 있길래 두개 비교 정리를 해봄
LangChain | LlamaIndex |
- 사용자 인터페이스는 더 간편하고, 개발자 커뮤니티가 큼 | - 메모리 구조에 중점을 두며 쿼리 능력이 강화 됨 |
- 간단하게 시작하기 쉬우며 예제와 자료가 풍부 | - 복잡한 에이전트 구성과 유연한 메모리 구조에 더 적합 |
1.일반적인 프레임워크: LangChain은 다양한 으용 프로그램을 구축하기 위한 보다 일반적인 프레임 워크로 사용. → 프로젝트의 목표와 요구 사항을 다양하게 다룰 수 있음 |
1. 데이터 쿼리와 정보 합성: Llama Index는 데이터 쿼리와 정보 합성에 중점을 두며, LLM을 쿼리하고 관련 문서를 검색하기 위한 간단한 인터페이스를 제공 |
2. 유연성: Langchain은 사용자에게 응용 프로그램의 동작을 사용자 정의할 수 있는 유연성을 제공. → 다양한 작업을 수행하고 필요에 따라 맞춤 설정 할 수 있음 |
2. 메모리 구조 강화: 이 도구는 메모리 구조에 중점을 두고 있어, 데이터 처리에 뛰어나며 더 효율적으로 작동 |
3. 간편한 사용자 인터페이스: 사용자 인터페이스는 간편하며, 사용자들이 쉽게 응용 프로그램을 구축하고 관리할 수 있도록 도움을 줌 | 3. 벡터 임베딩 작업: Llama Index는 벡터 임베딩 작업과 인덱스 쿼리에 최적화 되어 있어, 데이터를 효과적으로 다룰 수 있음 |
4. 품부한 개발자 커뮤니티: Langchain은 큰 개발자 커뮤니티를 가지고 있어, 사용자들은 다른 개발자들과 경험을 공유하고 도움을 얻을 수 있음 | 4. 복합 에이전트 구성: LlamaIdnex는 복합 에이전트 구성과 유연한 메모리 구조를 지원하며, 특히 복잡한 메모리 관리가 필요한 경우 유용 |
→ 코딩 초보자나 프로젝트 방향을 모르는 경우 langchain을 시작하는 것이 권장됨.
→ Langchain에서 쿼리 부분이 발전 된것이 Llamaindex but, 범용성은 아직 langchin이 우수
→ llamaIndax는 고급 사용자나 명확한 프로젝트 요구사항이 있는 경우에 적합
- API KEY
- Langchain과 LlamaIndex 모두 언어모델(GPT)등의 API를 이용해서 다양한 모델들을 쉽게 사용하고 통합할 수 있지만, 랭체인은 ChatOpenAI()라이브러리를 사용하고, 라마 인덱스는 OS에서 API key를 직접 받아온다.
- 전체 적인 구성
- 모델 설정 - vector store에 저장 - 쿼리 질문 이라는 전체적인 구성은 유사
Langchain
- 모델 api 선정
- document 불러오기 ( LocalFileStore)
- file load
- 사용자가 characterTextSplitter를 사용해서 적절히 chunk단위로 parsing
- embedding을 통해서 vector store 저장
- template과 chain 방식을 선정해서 chain구성
- 쿼리 전달
→ chunk단위로 적절히 parsing하는 작업을 해야 메모리의 효율성을 보장할 수 있지만, Chain과 templete을 통해서 사용자가 원하는 방식으로 형성이 가능
Llama-index
- api key
- 데이터 문서 다운로드
- 데이터 문서 load(simpleDirectoryReader)
- model 선정
- chunk 단위로 parsing
- vector store의 vector index 정의 (VectorStoreIndex)
- QueryEbgine 빌드 및 Query 시작
→ 모델 통합이나 templete과 chain보다는 다른 부분에 집중을 하고있음, vector store에 chunk 단위의 parsing작업이 없어도 vectorStoreIndex로 적절히 잘 보관되어 인덱스의 효율성을 보관하고, 쿼리엔진으로 쿼리 자체에 집중하는 모습을 보임
- Vector Store
Langchain
# vector store - Langchain
from langchain_text_splitters import CharacterTextSplitter
# CharacterTextSplitter: 사용자가 지정한 문자를 기준으로 문서를 분할
splitter = CharacterTextSplitter.from_tiktoken_encoder(
separator='\n', # 해당 문자 기준으로 문서 분할
chunk_size=600, # 분할된 한 문서의 최대 chunk크기를 지정
chunk_overlap=100, # 문서 분할 시 앞뒤 문서의 100자를 중복으로 추가하여 생성. 문맥상 적절하지 않은 부분에서 문서 분할 문제 해결
)
# unstructedFileLoader는 text files, powerpoints, html,pdfs, images 등 여러가지 형식의 파일 지원에 편리함
loader = UnstructuredFileLoader("./files/운수 좋은날.txt")
#load_and_split: 파일 로딩과 동시에 분할 진행. splitter 파라미터로 전달하고, 분할된 문서를 반환한다.
docs = loader.load_and_split(text_splitter=splitter)
# embedding: text에 적절한 점수를 의미별로 부여하는 방식, 자연어를 vector로 변환하는 작업
# embedding 된 문서는 vectorstore에 저장 됨
# Retriever에서 쿼리와 연관성이 높은 문서들을 vectorstore로 부터 찾아오고, 문서를 LLM에 전달할 프롬프트에 포함시켜 정확도가 높은 답변을 기대
embeddings = OpenAIEmbeddings()
# Cache Memory를 사용해서 임베딩을 효율적으로 처리함
# CacheBackedEmbeddings: Embedding 객체와 캐시가 저장되어 있는 위치를 파라미터로 전달. Embedding 객체가 호출될 일이 있으면, Cached_embeddings을 사용
# 이미 캐시되어 있다면 저장된 캐시를 사용, 그렇지 않다면 embedding을 진행하여 캐시를 생성
cached_embeddings = CacheBackedEmbeddings.from_bytes_store(embeddings, cache_dir)
vectorstore = FAISS.from_documnets(docs, cached_embeddings)
retriver = vectorstore.as_retriever()
Llama-index
# Llama Index
# node index를 chunk단위로 parsing
node_parser = SimpleNodeParser.from_defaults(chunk_size=512)
nodes = node_parser.ger_nodes_from_documents(documnets)
# vectorstore의 vector index를 정의
vector_index = VectorStoreIndex(nodes)
Langchain의 프롬프트와 체인 기능
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"""
You are a helpful assistant.
Answer questions using only the following context.
If you don't know the answer just say you don't know, don't make it up:
\n\n
{context}",
"""
),
("human", "{question}"),
]
)
# Stuff: 관련 문서를 모두 prompt에 채워 넣어 전달
# Map reduce: 각 문서를 요약하고, 요약된 문서를 기반으로 최종 요약본을 만들어냄. 문서 요약에서 속도가 느림
# Refine: 문서들을 순회하며 중간 답변을 생성, 이것을 반복하면서 답변을 정제함. 양질의 답변을 만들어 낼 수 있고, 속도와 비용면에서 단점이 있지만, 결과물이 뛰어남
# Map re-rank: 각 문서에 대해 각 답변을 만들어 내고, 점수를 부여한다. 가장 높은 점수의 답변을 최종 답변으로 설정함.
#Stuff 방식으로 chain을 구성
chain = (
{
"context": retriver,
"question": RunnablePassthrough(), # 사용자의 질문이 {Question}에 그대로 들어가게 됨
}
| prompt
| llm
)
- Query
Langchain
# query - langchain
# 전달된 쿼리를 retruever에 전달하고, template의 {context}에 넣어준다.
result = chain.invoke("김첨지는 학생을 어디로 데려다 주었나?")
Llama-index
# query - Llama-index
# queryEngine을 빌드하고 Query를 시작
Query_engine = vector_index.as_query_engine()
response_vector = query_engine.query("What did the author do growing up?")
참고 :
https://hypro2.github.io/langchain-llamaindex/
https://pred0771.tistory.com/230
'Machine Learning' 카테고리의 다른 글
[pytorch] GRU 입력 텐서와 출력 텐서의 shape 이해 (0) | 2023.07.19 |
---|---|
what is Ensemble Learning? (0) | 2023.07.19 |
what is Grid search? (0) | 2023.07.19 |
[summary]what is BERT? (0) | 2023.07.05 |
Few shot Learning, Meta Learning (3) | 2022.11.29 |