Notice
Recent Posts
Today
Total
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
관리 메뉴

나름개발블로그

LangChain #3 본문

A/ML

LangChain #3

성남개발자 2024. 5. 24. 18:00

오늘은 간단하게 RAG를 구성해 볼 예정이다. 여기에 나온 소스를 조금만 응용하면 다양한 것들을 만들 수 있다. 물론 llm 성능이 중요하긴 하지만 말이다.

RAG(Retrieval-Augmented Generation)는 대규모 언어 모델의 출력을 최적화하여 응답을 생성하기 전에 학습 데이터 소스 외부의 신뢰할 수 있는 지식 베이스를 참조하도록 하는 프로세스입니다. 대규모 언어 모델(LLM)은 방대한 양의 데이터를 기반으로 학습되며 수십억 개의 매개 변수를 사용하여 질문에 대한 답변, 언어 번역, 문장 완성과 같은 작업에 대한 독창적인 결과를 생성합니다. RAG는 이미 강력한 LLM의 기능을 특정 도메인이나 조직의 내부 지식 기반으로 확장하므로 모델을 다시 교육할 필요가 없습니다. 이는 LLM 결과를 개선하여 다양한 상황에서 관련성, 정확성 및 유용성을 유지하기 위한 비용 효율적인 접근 방식입니다.

구성

간단하게 구성할 RAG는 llm은 llama3:7b , vector db는 fassi를 사용한다. 몇 개의 문서(텍스트)를 백터 db에 집어넣고, 해당 문서에서 답을 잘 찾는지 확인하는 방식으로 진행할 것이다.

llm

ollam를 llm으로 가져간다. 어떤 llm을 사용하던 하는 방식은 크게 다르지 않을 것이다. 
llm 선언

from langchain_community.llms import Ollama

llm = Ollama(temperature=0, model="llama3")

 

여기서 temperature 0에 가까워질수록 모델은 토큰을 생성할 때 가능성이 높은 토큰만 선택하는 경향이 커진다. 즉 이 값이 낮을수록 정형화된 답변을, 높을수록 새로운 답변을 만들어 낸다. 정확도가 높은 답변이 필요한 상황에서는 Temperature를 높여서 사용하고, 창의적인 답변이 필요한 상황에서는 높여서 사용하면 된다.

다른 파라미터로 모델은 llama3을 사용한다.

embedding

임베딩 모델은 아무거나 사용해도 상관이 없다. 현재 상황에 최적화 된걸 사용하면된다. 나같은경우 포스트를 작성하면 ollama를  사용하고있어서 그냥 임베딩도 가져가 사용한다. 조금 찾아보니 검색에 최적화 된 모델을 사용하는 것이 좋다고 한다.

from langchain_community.embeddings import OllamaEmbeddings

embeddings = OllamaEmbeddings(model="llama3")

vector db

벡터 디비는 그냥 가장 유명한? FAISS를 사용한다. 다양한 벡터 디비가 존재하긴 하는데 그냥 고르다 보니 FAISS를 선택하게 됐다. 메모리에 올려서 사용하고 gpu를 이용해 빠르게 검색도 가능하다.
https://github.com/facebookresearch/faiss 

 

GitHub - facebookresearch/faiss: A library for efficient similarity search and clustering of dense vectors.

A library for efficient similarity search and clustering of dense vectors. - facebookresearch/faiss

github.com

 

간단하게 영어로 2개의 텍스트 문장을 집어넣었다. 실제로는 더 길고 복잡한 내용을 집어넣는다.

from langchain_community.vectorstores import FAISS

vdb = FAISS.from_texts(
    [
        "Kim is running , he's wearing Adidas clothes and Nike shoes.",
        "Choi is wearing Adidas shoes and Nike clothes.",
    ],
    embeddings,
)

retriever = vdb.as_retriever()

 

vector db로 선언된 vdb를 retriever 변환해서 사용한다.

Prompt

prompt는 심플하게 hub에 있는 것을 사용했다. 아마 공식 문서에서 사용되고 있었던 것 같다. 어디서 퍼왔는지 기억이 안 난다. 

from langchain import hub

prompt = hub.pull("rlm/rag-prompt")

chain

위에서 하나씩 선언한 것들을 chain으로 만들어서 사용한다.

from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

 

RunnablePassthrough은 그대로 입력값을 내보내는 역할을 한다.
StrOutputParser은 llm 출력을 string 형식으로 바꿔주는 역활을 한다.

 

Parser , runnables에 대한 설명은 추가로 포스트를 작성하겠다.

확인

response = chain.invoke("Who did wear Adidas clothes?")
print(response)

 

실행을 하면 응답으로는 아래처럼 나온다.
"According to the context, Kim wore Adidas clothes."

 

한국어로 여러 번 시도를 해봤는데 제대로 하지 못해서 영어로 수정해서 진행했다. 조금 복잡하거나 어려운 질문을 할 경우에는 작은 모델의 한계가 분명하게 존재한다. 한글로 된 같은 질문을 chatGPT에게 물어보니 역시 잘된다.ㅎㅎ

 

간단하게 rag를 구성해 보았다. langchain을 이용하면 쉽게 만들 수 있고 이를 이용하면 다양하게 응용할 수 있다. 이직하고 나서 직접 RAG를 구성해본 적이 있는데, ( langchain을 인용해서), 그냥 langchain 쓰면 편하다^^.

나보다 똑똑하고 진심인 사람들이 만들어 놓은걸 잘 활용하자!

'A > ML' 카테고리의 다른 글

LangChain #4  (1) 2024.06.10
LangChain #2  (2) 2024.05.21
임베딩 / 벡터 db  (0) 2024.05.15
LangChain #1  (0) 2024.05.14
LLM - intro  (0) 2024.05.13
Comments