Un nuovo indice di riepilogo dei documenti per i sistemi di controllo qualità basati su LLM

May 09 2023
In questo post del blog, introduciamo una nuovissima struttura di dati LlamaIndex: un indice di riepilogo dei documenti. Descriviamo come può aiutare a offrire prestazioni di recupero migliori rispetto alla ricerca semantica tradizionale e passiamo anche attraverso un esempio.

In questo post del blog, introduciamo una nuovissima struttura di dati LlamaIndex: un indice di riepilogo dei documenti. Descriviamo come può aiutare a offrire prestazioni di recupero migliori rispetto alla ricerca semantica tradizionale e passiamo anche attraverso un esempio.

Sfondo

Uno dei casi d'uso principali dei Large Language Models (LLM) è rispondere a domande sui propri dati. Per fare ciò, abbiniamo il LLM a un modello di "recupero" che può eseguire il recupero delle informazioni su un corpus di conoscenza ed eseguire la sintesi della risposta sui testi recuperati utilizzando il LLM. Questo quadro generale è chiamato Retrieval-Augmented Generation.

La maggior parte degli utenti che oggi costruiscono sistemi di QA basati su LLM tende a eseguire una delle seguenti operazioni:

  1. Prendi i documenti di origine, dividili ciascuno in blocchi di testo
  2. Memorizza blocchi di testo in un vettore db
  3. Durante la fase di query, recupera blocchi di testo incorporando somiglianze e/o filtri per parole chiave.
  4. Eseguire la sintesi della risposta

Limitazioni degli approcci esistenti

Ci sono alcune limitazioni nell'incorporamento del recupero usando blocchi di testo.

  • I blocchi di testo mancano di contesto globale. Spesso la domanda richiede un contesto al di là di ciò che è indicizzato in un blocco specifico.
  • Attenta messa a punto delle soglie del punteggio top-k/somiglianza. Rendi il valore troppo piccolo e perderai il contesto. Rendi il valore troppo grande e il costo/latenza potrebbe aumentare con un contesto più irrilevante.
  • Gli incorporamenti non sempre selezionano il contesto più pertinente per una domanda. Gli incorporamenti sono intrinsecamente determinati separatamente tra il testo e il contesto.

Indice di riepilogo del documento

Un diagramma per l'indice di riepilogo del documento

Proponiamo un nuovo indice in LlamaIndex che estrarrà/indicizzerà un sommario di testo non strutturato per ogni documento . Questo indice può aiutare a migliorare le prestazioni di recupero oltre gli approcci di recupero esistenti. Aiuta a indicizzare più informazioni rispetto a un singolo blocco di testo e ha un significato semantico maggiore rispetto ai tag delle parole chiave. Consente inoltre una forma di recupero più flessibile: possiamo eseguire sia il recupero LLM che il recupero basato sull'incorporamento.

Come funziona

Durante la fase di compilazione, ingeriamo ogni documento e utilizziamo un LLM per estrarre un riepilogo da ogni documento. Abbiamo anche suddiviso il documento in blocchi di testo (nodi). Sia il riepilogo che i nodi sono archiviati all'interno della nostra astrazione dell'archivio documenti . Manteniamo una mappatura dal riepilogo al documento/nodi di origine.

Durante la fase della query, recuperiamo i documenti pertinenti alla query in base ai relativi riepiloghi, utilizzando i seguenti approcci:

  • Recupero basato su LLM: presentiamo serie di riepiloghi di documenti al LLM e chiediamo al LLM di determinare quali documenti sono rilevanti + il loro punteggio di pertinenza.
  • Recupero basato sull'incorporamento: recuperiamo i documenti pertinenti in base alla somiglianza dell'incorporamento riepilogativo (con un limite massimo-k).

La memorizzazione di riepiloghi per un documento consente anche il recupero basato su LLM . Invece di fornire l'intero documento all'LLM all'inizio, possiamo prima fare in modo che l'LLM ispezioni il riepilogo conciso del documento per vedere se è pertinente alla query. Ciò sfrutta le capacità di ragionamento di LLM che sono più avanzate della ricerca basata sull'incorporamento, ma evita il costo/la latenza di alimentare l'intero documento al LLM

Approfondimenti aggiuntivi

Il recupero di documenti con riepiloghi può essere considerato una "via di mezzo" tra la ricerca semantica e il riepilogo a forza bruta in tutti i documenti. Cerchiamo i documenti in base alla pertinenza riassuntiva con la query data, quindi restituiamo tutti i *nodi* corrispondenti ai documenti recuperati.

Perché dovremmo farlo? Questo metodo di recupero offre all'utente più contesto rispetto a top-k su una porzione di testo, recuperando il contesto a livello di documento. Ma è anche un approccio più flessibile/automatico rispetto alla modellazione degli argomenti; non dovrai più preoccuparti se il tuo testo ha i tag parole chiave giusti!

Esempio

Esaminiamo un esempio che mette in mostra l'indice di riepilogo del documento, su articoli di Wikipedia su diverse città.

Il resto di questa guida mostra i frammenti di codice pertinenti. Puoi trovare la procedura dettagliata completa qui (e qui c'è il collegamento al taccuino ).

Possiamo costruire GPTDocumentSummaryIndexsu una serie di documenti e passare un ResponseSynthesizeroggetto per sintetizzare i riassunti per i documenti.

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 di alto livello

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)

L'approccio del riepilogo automatico su qualsiasi parte di testo è davvero entusiasmante. Siamo entusiasti di sviluppare estensioni in due aree:

  • Continua a esplorare il riepilogo automatico in diversi livelli. Attualmente è a livello di documento, ma che ne dici di riassumere un grosso pezzo di testo in uno più piccolo? (ad esempio una riga).
  • Continua a esplorare il recupero basato su LLM, che il riepilogo aiuta a sbloccare.

Guida riassuntiva del documento

Collegamento taccuino