Machine Learning

Langchain vs Llama Index

뚜둔뚜둔 2025. 2. 19. 17:35

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를 직접 받아온다.

 

 

# langchain

from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(temperature=0.1) # api_key 삽입 가능

# LlamaIndex
import os

# openAI API key
os.environ['OPENAI_API_KEY'] = 'YOUR OPENAI API KEY'

 

 

- 전체 적인 구성

- 모델 설정 - vector store에 저장 - 쿼리 질문 이라는 전체적인 구성은 유사

Langchain 

  1. 모델 api 선정
  2. document 불러오기 ( LocalFileStore)
  3. file load
  4. 사용자가 characterTextSplitter를 사용해서 적절히 chunk단위로 parsing
  5. embedding을 통해서 vector store 저장
  6. template과 chain 방식을 선정해서 chain구성
  7. 쿼리 전달

→ chunk단위로 적절히 parsing하는 작업을 해야 메모리의 효율성을 보장할 수 있지만, Chain과 templete을 통해서 사용자가 원하는 방식으로 형성이 가능

 

 

Llama-index 

  1. api key
  2. 데이터 문서 다운로드
  3. 데이터 문서 load(simpleDirectoryReader)
  4. model 선정
  5. chunk 단위로 parsing 
  6. vector store의 vector index 정의 (VectorStoreIndex)
  7. 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