[LangChain for LLM Application Development] 랭체인 QA

본 게시물은 Deeplearning.ai 코스를 수강 후 요약 및 정리한 내용입니다.


 

우리가 자연어 처리 모델을 주로 쓸 때, 특히 대규모 언어 모델을 통해 주로 하고 싶은 것. 

바로 QnA task 이다.

 

QA 파트에서는 다음과 같은 내용들을 정리하였다.

  • 주어진 문서 및 자료 질문에 답변하기
  • pdf, 웹페이지, 인트라넷 내부 문서 등
  • 훈련되지 않은 문서에 처음으로 접하게 되는 것
  • LLM이 필요에 따라 유동적으로 적용된 다는 것을 의미함
  • 언어 모델, 프롬프트, Output Parser 등을 넘어서서 LangChain의 임베딩 모델, 벡터 저장소 등

혹시 글을 읽다가 모르는 내용들이 나오게 된다면 이전 게시글들을 참조하자.

 

셋 다 너무 너무 중요한 내용들이다!!

 

2023.12.15 - [LLM/LangChain] - [LangChain for LLM Application Development] 랭체인 Models, Prompts and Parsers

 

[LangChain for LLM Application Development] 랭체인 Models, Prompts and Parsers

본 게시물은 Deeplearning.ai 코스를 수강 후 요약 및 정리한 내용입니다. 랭체인..!! LLM...!!! 너무 재밌다! 같이 공부할사람! 🙋‍♀️ 먼저 LangChain이 뭔지 모르시는 분들을 위해 LangChain이란 LLM(Large L

zero-ai.tistory.com

2023.12.15 - [LLM/LangChain] - [LangChain for LLM Application Development] 랭체인 Memory

 

[LangChain for LLM Application Development] 랭체인 Memory

본 게시물은 Deeplearning.ai 코스를 수강 후 요약 및 정리한 내용입니다. LLM task에서 중요한 부분 또 한가지! 대규모 언어모델을 통해 챗봇을 만들고 이를 기반으로 사용자와 모델 간 대화를 하기 위

zero-ai.tistory.com

2023.12.20 - [LLM/LangChain] - [LangChain for LLM Application Development] 랭체인 Chains

 

[LangChain for LLM Application Development] 랭체인 Chains

본 게시물은 Deeplearning.ai 코스를 수강 후 요약 및 정리한 내용입니다. LangChain에서 지원하는 다양한 모듈 중 하나인 Chain 이 체인은 LLM과 프롬프트를 결합하며 다양한 요소를 한 번에 묶어 텍스트

zero-ai.tistory.com


 

아래 공식 문서를 참고하는 것이 더 도움이 될 수도 있다. ^^..

https://python.langchain.com/docs/modules/data_connection/

 

Library Import 하기

 

먼저 체인을 만드는데 도움되는 모듈들을 import 해 준다.

여기서 사용한 것은 Retrival QA 로, Retrieval QA 를 이용하면 주어진 문서에 대한 검색을 할 수 있다.

Chat model 은 이전 게시물들과 마찬가지로 OpenAI Chat model을 이용해 주었고 위의 docs 를 참고한대로 CSVLoader를 import 해 왔다.

 

모듈 불러온것만 확인해도 앞에서 배울 내용들이 무엇일지 확인이 된다^^..

 

본 실습에서 사용한 벡터 저장소는 DocArrayInMemorySearch 이다.

 

벡터 저장소 생성하기

DocArrayInMemorySearch

  • 인메모리 벡터 저장소로, 따로 외부 데이터 베이스에 연결할 필요 없이 시작하기 쉽다.
  • 주피터에서 정보를 표시하는데 사용될 Display, Markdown 등을 import 한다.

 

그럼 벡터 저장소를 생성해보자.

 

from langchain.indexes import VectorstoreIndexCreator
index = VectorstoreIndexCreator(
	vectorstore_cls = DocArrayInMemorySearch
    ).from_loaders([loader])

 

vector query

 

질문을 하고 이렇게 Markdown 을 통해 쿼리들을 받으면

데이터를 기반으로 햇빛 차당 기능이 있는 셔츠 군 제품의 이름과, 설명이 쓰여있는 Markdown 표를 받게 된다.

 

 

Q. LLM 이 어떻게 문서를 통해서 정확히 이런 결과를 도출시키는 것일까?

먼저, 우리는 언어 모델을 우리의 문서와 결합하고 싶다.

하지만 언어 모델은 한번에 Thousand words 정도만 검색이 가능하다. 따라서 짧은 context의 문서와는 연결이 용이할 수 있으나 context 량이 많은 문서의 경우 언어 모델이 문서에 매칭하기가 어려워진다. 따라서 언어 모델을 문서에 결합하고 싶다면, 어떻게 언어 모델을 사용해야 문서의 모든 것을 불러올 수 있을까?

 

문서의 모든 것을 불러오기 위해서는 임베딩, 벡터 저장소가 중요한 역할을 한다!

 

Vector Embedding

출처 : Deeplearning.AI

 

  • 임베딩은 주어진 텍스트를 숫자로 표현한다. (정확히 표현하자면, 하나의 벡터 값을 갖게 된다.)
  • 임베딩 벡터는 텍스트의 내용과 의미를 담고 있다. 또한 비슷한 의미를 가진 텍스트들은 비슷한 벡터를 가지게 된다.

출처 : Deeplearning.AI

예를 들어, 위 그림과 같은 세 문장이 있을 때, 애완동물에 대한 문장들을 비교할 때 비슷한 숫자들을 각각 가지게 되는 것을 확인할 수 있다. 이를 통해 단어의 임베딩 벡터 값을 비교하여 어떤 텍스트들이 서로 비슷한 지 알 수 있으며, 언어 모델을 사용하기 전에 어떤 텍스트 조각을 포함해야 하는 지 알 수 있다.

 

 

Vector Database 

출처 : Deepleaning.AI

  • 임베딩을 통해 만들어진 벡터 값을 저장하기 위해 사용한다.
  • 벡터 데이터 베이스를 만드는 방법은 먼저 들어오는 문서들의 텍스트 조각들로 채우는 것이다.
  • 보다 큰 문서를 사용해야 한다면 문서를 작은 조각들로 나누어 원래 문서보다 작은 텍스트 조각들을 이용한다.
  • 작은 조각들 중 관련성이 가장 높은 것들을 선별하여 언어 모델에 넘겨준다.
  • 최종적으로 작은 조각들의 벡터 임베딩을 생성하고 이를 벡터 데이터베이스에 저장한다.

 

쉽게 말하면, 임베딩을 통해 얻은 벡터 값들을 저장하는 저장소라고 생각하면 좋을 것 같다.

 

 

벡터 데이터베이스에 저장되는 순서는 아래와 같다.

  • 인덱스에서 런타임동안 가장 관련성이 높은 텍스트 조각들을 쿼리에 비교하여 찾는다.
  • 쿼리가 들어올 때 먼저 그 쿼리에 대한 임베딩을 생성한다.
  • 그 다음 임베딩을 벡터 데이터베이스의 모든 벡터들과 비교하고, 가장 유사한 n개를 선택한다.

출처 : Deepleanring.AI

 

이 값들이 반환되면 프롬프트와 언어 모델에 전달되어 최종 답변을 받을 수 있다.

LangChain을 이용하면 이를 한 줄의 코드로 작성하여 도출할 수도 있고 여러개의 작은 조각들로 나누어진 코드들로 나누어 결과를 도출할 수도 있다.

 

이렇게 나누어진 작은 덩어리, 조각들을 = Chunck 라고 한다. 

 

 

Q. 같은 질문을 다양한 유형의 청크들에 수행하고 싶으면?

그렇다면, 같은 질문을 다양한 유형의 청크들에 수행하고 싶다면 어떻게 하면 좋을까?

 

3가지 대표적인 방법이 있다. 

  • Map_reduce
  • Refine
  • Map_rerank

 

Map_reduce

출처 : Deeplearning.AI

Map reduce 방법에서는 모든 청크(Chunk)들을 언어 모델에 전달하고, 받은 여러가지의 답변들을 다른 언어 모델을 불러 요약시켜 하나의 최종 답변으로 만들어내는 방법으로 진행된다.

주어진 문서의 양에 제한 받지 않는다는 장점이 있으며, 모든 청크들을 언어 모델에 한번에 전달하기 때문에 개별 질문들을 여러 문서에 병렬로 처리할 수 있다. 하지만 문서들을 개별의 독립적으로 취급해 항상 선호되는 방법은 아니다.

 

Refine

출처 : Deeplearning.AI

 

Refine 방법은 map reduce 방법과는 달리 반복적으로 문서들을 사용한다. 따라서 답변을 이전의 문서에서 도출했던 답변을 기반으로 구축해나간다. 정보를 결합하거나 오랜 시간을 거쳐 답변을 구축하는데 유용하다는 장점이 있으며 때문에 대체로 답변이 긴 편이다.

Refine의 경우 답변이 도출되는 과정도 느린 편인데, 그 이유는 호출이 독립적이지 않기 때문이다.

이전의 호출이 끝나야 다음 호출이 시작된다는 특징이 있다.

 

Map_rerank

출처 : Deeplearning.AI

마지막 방법은 각 chunck에 점수를 매기는 방법이다.

언어 모델을 각 문서에 호출해서 문서에 점수를 부여하도록 요청한 뒤, 가장 높은 점수를 채택하는 방법이다.

언어 모델이 점수를 어떻게 부여할 지 알아야 하기 때문에 모델에게 "이 문서와 관련이 있다면 높은 점수를 부여한다"와 같은 지시를 명확하게 내려주어야 한다. 

Map rerank 방법은 Map reduce 방법과 유사하게 모든 호출이 독립적으로 작동한다. 따라서 일괄처리를 할 수 있기 때문에 QA query에 있어 빠른편이지만, 언어 모델 호출을 많이 하게 되어 비용이 좀 더 발생하는 편이다.

 

 

Stuff method

출처 : Deeplearning.AI

 

추가로, Stuff method가 있다. 

stuff method 같은 경우에는 하나의 Prompt 가 모든 입력값을 수집하여 언어 모델에 전달하고 하나의 응답(Final Answer)을 받는다.

간단하고 모델의 이해가 쉽다는 장점이 있으며, 비용도 저렴하고 작동도 잘 되는 편이다.

 

 

실제로 실무에서 가장 널리 쓰이는 방법은 바로 위에서 설명한 Stuff method라고 한다.

위의 method들은 질문 응답 외에도 다른 체인들과 사용할 수 있으며, 특히 map_reduce의 흔한 사용 사례는 '요약' task 이다.

 

위의 방법들은 매우 긴 문서 내에서 정보를 재귀적으로 요약하고 싶을 때 유용하게 사용할 수 있다.

 

더 자세한건 역시나 공식 문서를 활용하자 ㅎㅎ

https://js.langchain.com/docs/modules/chains/document/map_reduce

 

Map reduce | 🦜️🔗 Langchain

The map reduce documents chain first applies an LLM chain to each document individually (the Map step), treating the chain output as a new document. It then passes all the new documents to a separate combine documents chain to get a single output (the Redu

js.langchain.com