Nowy indeks podsumowań dokumentów dla systemów QA opartych na LLM

May 09 2023
W tym poście na blogu przedstawiamy zupełnie nową strukturę danych LlamaIndex: indeks podsumowania dokumentów. Opisujemy, w jaki sposób może pomóc zapewnić lepszą wydajność wyszukiwania w porównaniu z tradycyjnym wyszukiwaniem semantycznym, a także przedstawiamy przykład.

W tym poście na blogu przedstawiamy zupełnie nową strukturę danych LlamaIndex: indeks podsumowania dokumentów. Opisujemy, w jaki sposób może pomóc zapewnić lepszą wydajność wyszukiwania w porównaniu z tradycyjnym wyszukiwaniem semantycznym, a także przedstawiamy przykład.

Tło

Jednym z podstawowych przypadków użycia modeli dużych języków (LLM) jest odpowiadanie na pytania dotyczące własnych danych. Aby to zrobić, łączymy LLM z modelem „wyszukiwania”, który może wyszukiwać informacje w korpusie wiedzy i przeprowadzać syntezę odpowiedzi na pobranych tekstach za pomocą LLM. Ta ogólna struktura nazywa się Retrieval-Augmented Generation.

Większość użytkowników budujących obecnie systemy QA oparte na LLM ma tendencję do wykonywania następujących czynności:

  1. Weź dokumenty źródłowe, podziel każdy z nich na fragmenty tekstu
  2. Przechowuj fragmenty tekstu w wektorowej bazie danych
  3. W czasie wykonywania zapytania pobieraj fragmenty tekstu, osadzając filtry podobieństw i/lub słów kluczowych.
  4. Wykonaj syntezę odpowiedzi

Ograniczenia istniejących podejść

Istnieje kilka ograniczeń pobierania osadzania przy użyciu fragmentów tekstu.

  • Fragmenty tekstu nie mają kontekstu globalnego. Często pytanie wymaga kontekstu wykraczającego poza to, co jest indeksowane w określonej porcji.
  • Ostrożne dostrojenie progów wyniku najwyższego k / podobieństwa. Ustaw zbyt małą wartość, a przegapisz kontekst. Ustaw zbyt dużą wartość, a koszt/opóźnienie może wzrosnąć w przypadku bardziej nieistotnego kontekstu.
  • Osadzenia nie zawsze wybierają najbardziej odpowiedni kontekst dla pytania. Osadzenia są z natury określane niezależnie od tekstu i kontekstu.

Indeks streszczenia dokumentu

Diagram indeksu streszczenia dokumentu

Proponujemy nowy indeks w LlamaIndex , który wyodrębni/indeksuje nieustrukturyzowane podsumowanie tekstowe dla każdego dokumentu . Indeks ten może pomóc zwiększyć wydajność wyszukiwania poza istniejącymi metodami wyszukiwania. Pomaga zaindeksować więcej informacji niż pojedynczy fragment tekstu i ma większe znaczenie semantyczne niż znaczniki słów kluczowych. Pozwala również na bardziej elastyczną formę wyszukiwania: możemy zarówno pobierać LLM, jak i pobierać na podstawie osadzania.

Jak to działa

W czasie kompilacji przetwarzamy każdy dokument i używamy LLM do wyodrębnienia podsumowania z każdego dokumentu. Podzieliliśmy również dokument na fragmenty tekstu (węzły). Zarówno podsumowanie, jak i węzły są przechowywane w naszej abstrakcji magazynu dokumentów . Utrzymujemy mapowanie z podsumowania do dokumentu/węzłów źródłowych.

W czasie zapytania pobieramy odpowiednie dokumenty do zapytania na podstawie ich podsumowań, stosując następujące podejścia:

  • Wyszukiwanie oparte na LLM: Przedstawiamy LLM zestawy streszczeń dokumentów i prosimy LLM o określenie, które dokumenty są istotne oraz ich ocenę trafności.
  • Wyszukiwanie oparte na osadzeniu: pobieramy odpowiednie dokumenty na podstawie podobieństwa osadzania streszczenia (z odcięciem górnych k).

Przechowywanie podsumowań dokumentu umożliwia również pobieranie oparte na LLM . Zamiast podawać cały dokument do LLM na początku, możemy najpierw zlecić LLM sprawdzenie zwięzłego streszczenia dokumentu, aby sprawdzić, czy w ogóle jest ono istotne dla zapytania. Wykorzystuje to możliwości rozumowania LLM, które są bardziej zaawansowane niż wyszukiwanie oparte na osadzeniu, ale pozwala uniknąć kosztów/opóźnień związanych z dostarczaniem całego dokumentu do LLM

Dodatkowe informacje

Wyszukiwanie dokumentów za pomocą podsumowań można traktować jako „środek pośredni” między wyszukiwaniem semantycznym a streszczaniem siłowym we wszystkich dokumentach. Wyszukujemy dokumenty na podstawie sumarycznej trafności z podanym zapytaniem, a następnie zwracamy wszystkie *węzły* odpowiadające pobranym dokumentom.

Dlaczego powinniśmy to robić? Ta metoda wyszukiwania daje użytkownikowi więcej kontekstu niż top-k na kawałku tekstu, poprzez pobieranie kontekstu na poziomie dokumentu. Ale jest to również bardziej elastyczne/automatyczne podejście niż modelowanie tematyczne; koniec z martwieniem się o to, czy Twój tekst ma odpowiednie znaczniki słów kluczowych!

Przykład

Przyjrzyjmy się przykładowi, który prezentuje indeks streszczenia dokumentów, ponad artykułami Wikipedii dotyczącymi różnych miast.

W pozostałej części tego przewodnika przedstawiono odpowiednie fragmenty kodu. Możesz znaleźć pełny opis przejścia tutaj (a tutaj jest link do notatnika ).

Możemy zbudować GPTDocumentSummaryIndexzestaw dokumentów i przekazać ResponseSynthesizerobiekt do syntezy podsumowań dla dokumentów.

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...

Interfejs API wysokiego poziomu

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)

Podejście do automatycznego podsumowania dowolnego fragmentu tekstu jest naprawdę ekscytujące. Cieszymy się, że możemy rozwijać rozszerzenia w dwóch obszarach:

  • Kontynuuj odkrywanie automatycznego podsumowania w różnych warstwach. Obecnie jest to na poziomie dokumentu, ale co z podsumowaniem dużego fragmentu tekstu w mniejszym? (np. jednolinijkowy).
  • Kontynuuj odkrywanie pobierania opartego na LLM, którego podsumowanie pomaga odblokować.

Przewodnik podsumowujący dokumenty

Link do notebooka