Ein neuer Dokumentzusammenfassungsindex für LLM-gestützte QA-Systeme

May 09 2023
In diesem Blogbeitrag stellen wir eine brandneue LlamaIndex-Datenstruktur vor: einen Document Summary Index. Wir beschreiben, wie es dazu beitragen kann, eine bessere Abrufleistung im Vergleich zur herkömmlichen semantischen Suche zu bieten, und gehen auch durch ein Beispiel.

In diesem Blogbeitrag stellen wir eine brandneue LlamaIndex-Datenstruktur vor: einen Document Summary Index. Wir beschreiben, wie es dazu beitragen kann, eine bessere Abrufleistung im Vergleich zur herkömmlichen semantischen Suche zu bieten, und gehen auch durch ein Beispiel.

Hintergrund

Einer der wichtigsten Anwendungsfälle von Large Language Models (LLMs) ist die Beantwortung von Fragen zu Ihren eigenen Daten. Dazu koppeln wir das LLM mit einem „Abruf“-Modell, das den Informationsabruf über einen Wissenskorpus durchführen kann, und führen mithilfe des LLM eine Antwortsynthese über die abgerufenen Texte durch. Dieses allgemeine Framework wird als Retrieval-Augmented Generation bezeichnet.

Die meisten Benutzer, die heute LLM-gestützte QA-Systeme erstellen, neigen dazu, in irgendeiner Form Folgendes zu tun:

  1. Nehmen Sie Quelldokumente und teilen Sie sie jeweils in Textblöcke auf
  2. Speichern Sie Textblöcke in einer Vektordatenbank
  3. Rufen Sie während der Abfrage Textblöcke ab, indem Sie Ähnlichkeits- und/oder Schlüsselwortfilter einbetten.
  4. Response-Synthese durchführen

Einschränkungen bestehender Ansätze

Es gibt einige Einschränkungen beim Einbetten des Abrufs mithilfe von Textblöcken.

  • Textblöcken fehlt der globale Kontext. Oft erfordert die Frage Kontext, der über das hinausgeht, was in einem bestimmten Chunk indiziert ist.
  • Sorgfältige Abstimmung der Top-k-/Ähnlichkeits-Score-Schwellenwerte. Wenn Sie den Wert zu klein machen, wird Ihnen der Kontext entgehen. Wenn Sie den Wert zu groß machen, können sich Kosten/Latenz mit irrelevanterem Kontext erhöhen.
  • Einbettungen wählen nicht immer den relevantesten Kontext für eine Frage aus. Einbettungen werden grundsätzlich getrennt zwischen Text und Kontext festgelegt.

Dokumentenzusammenfassungsindex

Ein Diagramm für den Document Summary Index

Wir schlagen einen neuen Index in LlamaIndex vor, der eine unstrukturierte Textzusammenfassung für jedes Dokument extrahiert/indiziert . Dieser Index kann dazu beitragen, die Abrufleistung über bestehende Abrufansätze hinaus zu verbessern. Es hilft, mehr Informationen zu indizieren als ein einzelner Textblock, und trägt mehr semantische Bedeutung als Schlüsselwort-Tags. Es ermöglicht auch eine flexiblere Form des Abrufs: Wir können sowohl den LLM-Abruf als auch den einbettungsbasierten Abruf durchführen.

Wie es funktioniert

Während der Erstellungszeit nehmen wir jedes Dokument auf und verwenden ein LLM, um eine Zusammenfassung aus jedem Dokument zu extrahieren. Wir teilen das Dokument auch in Textblöcke (Knoten) auf. Sowohl die Zusammenfassung als auch die Knoten werden in unserer Document Store- Abstraktion gespeichert . Wir pflegen eine Zuordnung von der Zusammenfassung zu den Quelldokumenten/Knoten.

Während der Abfragezeit rufen wir relevante Dokumente für die Abfrage auf der Grundlage ihrer Zusammenfassungen ab, indem wir die folgenden Ansätze verwenden:

  • LLM-basierter Abruf: Wir legen dem LLM eine Reihe von Dokumentenzusammenfassungen vor und bitten das LLM, zu bestimmen, welche Dokumente relevant sind + ihre Relevanzbewertung.
  • Embedding-based Retrieval: Wir rufen relevante Dokumente basierend auf der summarischen Embedding-Ähnlichkeit (mit einem Top-k-Cutoff) ab.

Das Speichern von Zusammenfassungen für ein Dokument ermöglicht auch einen LLM-basierten Abruf . Anstatt das gesamte Dokument am Anfang dem LLM zuzuführen, können wir das LLM zuerst die prägnante Dokumentzusammenfassung prüfen lassen, um festzustellen, ob sie für die Abfrage überhaupt relevant ist. Dies nutzt die Argumentationsfähigkeiten von LLMs, die fortgeschrittener sind als die auf Einbettung basierende Suche, vermeidet jedoch die Kosten/Latenzzeit für die Zuführung des gesamten Dokuments zum LLM

Zusätzliche Einblicke

Das Abrufen von Dokumenten mit Zusammenfassungen kann als „Mittelweg“ zwischen semantischer Suche und Brute-Force-Zusammenfassung über alle Dokumente hinweg betrachtet werden. Wir suchen Dokumente basierend auf der Zusammenfassungsrelevanz mit der angegebenen Abfrage und geben dann alle *Knoten* zurück, die den abgerufenen Dokumenten entsprechen.

Warum sollten wir das tun? Diese Abrufmethode gibt dem Benutzer mehr Kontext als Top-k über einen Textblock, indem der Kontext auf Dokumentebene abgerufen wird. Aber es ist auch ein flexiblerer/automatischerer Ansatz als die Themenmodellierung; Machen Sie sich keine Gedanken mehr darüber, ob Ihr Text die richtigen Keyword-Tags hat!

Beispiel

Lassen Sie uns ein Beispiel durchgehen, das den Dokumentzusammenfassungsindex über Wikipedia-Artikeln zu verschiedenen Städten zeigt.

Der Rest dieses Leitfadens zeigt die relevanten Codeausschnitte. Die vollständige exemplarische Vorgehensweise finden Sie hier (und hier ist der Notizbuch-Link ).

Wir können das GPTDocumentSummaryIndexüber eine Reihe von Dokumenten erstellen und ein Objekt übergeben, ResponseSynthesizerum Zusammenfassungen für die Dokumente zu synthetisieren.

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

High-Level-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)

Der Ansatz der automatischen Zusammenfassung über beliebige Textstücke ist wirklich spannend. Wir freuen uns, Erweiterungen in zwei Bereichen zu entwickeln:

  • Erkunden Sie die automatische Zusammenfassung in verschiedenen Ebenen weiter. Derzeit befindet es sich auf Dokumentebene, aber wie wäre es, wenn Sie einen großen Textabschnitt in einen kleineren zusammenfassen? (z. B. ein Einzeiler).
  • Erkunden Sie weiterhin den LLM-basierten Abruf, dessen Zusammenfassung beim Entsperren hilft.

Leitfaden für Dokumentzusammenfassungen

Notebook-Link