LLM 기반 QA 시스템을 위한 새로운 문서 요약 색인
이 블로그 게시물에서는 완전히 새로운 LlamaIndex 데이터 구조인 문서 요약 인덱스를 소개합니다. 전통적인 시맨틱 검색에 비해 더 나은 검색 성능을 제공하는 데 어떻게 도움이 되는지 설명하고 예제를 살펴봅니다.
배경
대규모 언어 모델(LLM)의 핵심 사용 사례 중 하나는 자신의 데이터에 대한 질문 답변입니다. 이를 위해 LLM을 지식 코퍼스에 대한 정보 검색을 수행할 수 있는 "검색" 모델과 페어링하고 LLM을 사용하여 검색된 텍스트에 대한 응답 합성을 수행합니다. 이 전체 프레임워크를 Retrieval-Augmented Generation이라고 합니다.
오늘날 LLM 기반 QA 시스템을 구축하는 대부분의 사용자는 다음과 같은 형식을 수행하는 경향이 있습니다.
- 소스 문서를 가져 와서 각각을 텍스트 덩어리로 나눕니다.
- 벡터 db에 텍스트 청크 저장
- 쿼리 시간 동안 유사성 및/또는 키워드 필터를 포함하여 텍스트 청크를 검색합니다.
- 응답 합성 수행
기존 접근법의 한계
텍스트 청크를 사용하여 임베딩 검색에는 몇 가지 제한 사항이 있습니다.
- 텍스트 청크에는 전역 컨텍스트가 없습니다. 종종 질문에는 특정 청크에 인덱싱된 것 이상의 컨텍스트가 필요합니다.
- top-k/유사성 점수 임계값을 신중하게 조정합니다. 값을 너무 작게 설정하면 컨텍스트를 놓치게 됩니다. 값을 너무 크게 설정하면 관련 없는 컨텍스트로 인해 비용/대기 시간이 증가할 수 있습니다.
- 임베딩이 항상 질문에 대해 가장 관련성이 높은 컨텍스트를 선택하는 것은 아닙니다. 임베딩은 본질적으로 텍스트와 컨텍스트 간에 별도로 결정됩니다.
문서 요약 색인
우리는 LlamaIndex 에서 각 문서에 대한 구조화되지 않은 텍스트 요약을 추출/인덱싱할 새 인덱스를 제안합니다 . 이 인덱스는 기존 검색 접근 방식을 넘어 검색 성능을 향상시키는 데 도움이 될 수 있습니다. 단일 텍스트 청크보다 더 많은 정보를 인덱싱하는 데 도움이 되며 키워드 태그보다 더 많은 의미론적 의미를 전달합니다. 또한 보다 유연한 형태의 검색이 가능합니다. LLM 검색과 임베딩 기반 검색을 모두 수행할 수 있습니다.
작동 방식
빌드 시간 동안 각 문서를 수집하고 LLM을 사용하여 각 문서에서 요약을 추출합니다. 또한 문서를 텍스트 청크(노드)로 분할합니다. 요약과 노드는 모두 문서 저장소 추상화 내에 저장됩니다. 요약에서 소스 문서/노드로의 매핑을 유지합니다.
쿼리 시간 동안 다음 접근 방식을 사용하여 요약을 기반으로 쿼리에 대한 관련 문서를 검색합니다.
- LLM 기반 검색: LLM에 문서 요약 세트를 제공하고 LLM에 어떤 문서가 관련성이 있는지 + 해당 관련성 점수를 결정하도록 요청합니다.
- 임베딩 기반 검색: 요약 임베딩 유사성(top-k 컷오프 포함)을 기반으로 관련 문서를 검색합니다.
문서 요약을 저장하면 LLM 기반 검색 도 가능합니다 . 처음에 전체 문서를 LLM에 공급하는 대신 먼저 LLM이 간결한 문서 요약을 검사하여 쿼리와 관련이 있는지 확인할 수 있습니다. 이는 임베딩 기반 조회보다 더 발전된 LLM의 추론 기능을 활용하지만 전체 문서를 LLM에 공급하는 비용/지연 시간을 방지합니다.
추가 통찰력
요약을 사용한 문서 검색은 모든 문서에서 시맨틱 검색과 무차별 대입 요약 사이의 "중간 지점"으로 생각할 수 있습니다. 주어진 쿼리로 요약 관련성을 기반으로 문서를 조회한 다음 검색된 문서에 해당하는 모든 *노드*를 반환합니다.
왜 우리가 이것을 해야 합니까? 이 검색 방법은 문서 수준에서 컨텍스트를 검색하여 사용자에게 텍스트 청크에 대한 top-k보다 더 많은 컨텍스트를 제공합니다. 그러나 주제 모델링보다 더 유연하고 자동적인 접근 방식이기도 합니다. 텍스트에 올바른 키워드 태그가 있는지 더 이상 걱정할 필요가 없습니다!
예
여러 도시에 대한 Wikipedia 기사에 대한 문서 요약 색인을 보여주는 예를 살펴보겠습니다.
이 가이드의 나머지 부분에서는 관련 코드 스니펫을 보여줍니다. 여기에서 전체 연습을 찾을 수 있습니다 (여기에 노트북 링크가 있습니다 ).
GPTDocumentSummaryIndex
우리는 일련의 문서를 작성 하고 ResponseSynthesizer
개체를 전달하여 문서에 대한 요약을 합성할 수 있습니다.
from llama_index import (
SimpleDirectoryReader,
LLMPredictor,
ServiceContext,
ResponseSynthesizer
)
from llama_index.indices.document_summary import GPTDocumentSummaryIndex
from langchain.chat_models import ChatOpenAI
# load docs, define service context
...
# build the index
response_synthesizer = ResponseSynthesizer.from_args(response_mode="tree_summarize", use_async=True)
doc_summary_index = GPTDocumentSummaryIndex.from_documents(
city_docs,
service_context=service_context,
response_synthesizer=response_synthesizer
)
summary = doc_summary_index.get_document_summary("Boston")
from llama_index.indices.document_summary import DocumentSummaryIndexRetriever
retriever = DocumentSummaryIndexRetriever(
doc_summary_index,
# choice_select_prompt=choice_select_prompt,
# choice_batch_size=choice_batch_size,
# format_node_batch_fn=format_node_batch_fn,
# parse_choice_select_answer_fn=parse_choice_select_answer_fn,
# service_context=service_context
)
retrieved_nodes = retriever.retrieve("What are the sports teams in Toronto?")
print(retrieved_nodes[0].score)
print(retrieved_nodes[0].node.get_text())The retriever will retrieve a set of relevant nodes for a given index.
8.0
Toronto ( (listen) tə-RON-toh; locally [təˈɹɒɾ̃ə] or [ˈtɹɒɾ̃ə]) is the capital city of the Canadian province of Ontario. With a recorded population of 2,794,356 in 2021, it is the most populous city in Canada...
높은 수준의 API
query_engine = doc_summary_index.as_query_engine(
response_mode="tree_summarize", use_async=True
)
response = query_engine.query("What are the sports teams in Toronto?")
print(response)
# use retriever as part of a query engine
from llama_index.query_engine import RetrieverQueryEngine
# configure response synthesizer
response_synthesizer = ResponseSynthesizer.from_args()
# assemble query engine
query_engine = RetrieverQueryEngine(
retriever=retriever,
response_synthesizer=response_synthesizer,
)
# query
response = query_engine.query("What are the sports teams in Toronto?")
print(response)
모든 텍스트에 대한 자동 요약 접근 방식은 정말 흥미진진합니다. 다음 두 가지 영역에서 확장 기능을 개발하게 되어 기쁩니다.
- 다른 계층에서 자동 요약을 계속 탐색합니다. 현재는 문서 수준이지만 큰 텍스트 덩어리를 작은 덩어리로 요약하는 것은 어떻습니까? (예: 한 줄짜리).
- 요약이 잠금을 해제하는 데 도움이 되는 LLM 기반 검색을 계속 탐색하십시오.
문서 요약 가이드
노트북 링크