Crea un percorso RAG con l’indice LLama

Crea un percorso RAG con l'indice LLama - Guida alla bellezza e alla moda

Introduzione

Una delle applicazioni più popolari dei modelli linguistici di grandi dimensioni (LLM) è quella di rispondere a domande su set di dati personalizzati. LLM come ChatGPT e Bard sono eccellenti comunicatori. Possono rispondere a quasi tutto su cui sono stati addestrati. Questo è anche uno dei principali ostacoli per gli LLM. Possono rispondere solo alle domande che hanno visto durante l’addestramento del modello. I modelli linguistici hanno un limite di conoscenza sul mondo. Ad esempio, ChatGPT è stato addestrato su dati disponibili fino al 2021. Inoltre, non c’è modo che GPT possa apprendere dai tuoi file privati. Quindi, come possiamo rendere il modello consapevole della conoscenza che non possiede ancora? La risposta è una pipeline di generazione arricchita da recupero. In questo articolo, impareremo sulla pipeline RAG (Retrieval Augmented Generation) e ne costruiremo una usando l’indice LLama.

Obiettivi di apprendimento

  • Esplorare cosa sia la Generazione Arricchita da Recupero (RAG) e quando dovremmo utilizzarla.
  • Comprendere brevemente i diversi componenti di RAG.
  • Imparare sull’indice LLama e come utilizzarlo per costruire una semplice pipeline RAG per PDF.
  • Comprendere cosa siano le incapsulature e i database di vettori e come utilizzare i moduli integrati nell’indice LLama per costruire basi di conoscenza da PDF.
  • Scoprire le applicazioni basate su RAG nel mondo reale.

Questo articolo è stato pubblicato come parte del Data Science Blogathon.

Cos’è RAG?

Gli LLM sono i modelli NLP più efficienti e potenti fino ad oggi. Abbiamo visto il potenziale degli LLM nella traduzione, nella scrittura di saggi e nella risposta a domande generali. Ma quando si tratta di rispondere a domande specifiche di un dominio, soffrono di allucinazioni. Inoltre, in un’app per domande specifiche di un dominio, solo alcuni documenti contengono un contesto rilevante per ogni query. Quindi, abbiamo bisogno di un sistema unificato che semplifichi l’estrazione del documento per la generazione della risposta e tutti i processi intermedi. Questo processo è chiamato Generazione Arricchita da Recupero.

Per saperne di più: Generazione Arricchita da Recupero (RAG) in AI

Quindi, cerchiamo di capire perché RAG è molto efficace per la costruzione di app di domande specifiche di un dominio nel mondo reale.

Perché Dovrebbe Essere Utilizzato RAG?

Ci sono tre modi in cui un LLM può apprendere nuovi dati.

  • Addestramento: Una grande rete neurale viene addestrata su trilioni di token con miliardi di parametri per creare modelli linguistici di grandi dimensioni. I parametri di un modello di deep learning sono i coefficienti o i pesi che contengono tutte le informazioni relative al modello specifico. Addestrare un modello come GPT-4 costa centinaia di milioni di dollari. Questo metodo va oltre le capacità di chiunque. Non possiamo riaddestrare un modello così enorme su nuovi dati. Questo non è fattibile.
  • Raffinamento: Un’altra opzione è il raffinamento di un modello sui dati esistenti. Il raffinamento comporta l’utilizzo di un modello pre-addestrato come punto di partenza durante l’addestramento. Utilizziamo le conoscenze del modello pre-addestrato per addestrare un nuovo modello su diversi set di dati. Sebbene sia molto potente, è costoso in termini di tempo e denaro. A meno che non ci sia una specifica esigenza, il raffinamento non ha senso.
  • Prompting: Il prompting è il metodo in cui inseriamo nuove informazioni all’interno della finestra di contesto di un LLM e lo facciamo rispondere alle query a partire dalle informazioni fornite nella traccia. Potrebbe non essere efficace come la conoscenza appresa durante l’addestramento o il raffinamento, ma è sufficiente per molti casi d’uso reali, come le domande e risposte sui documenti.

Richiedere risposte dai documenti di testo è efficace, ma tali documenti sono spesso molto più grandi delle finestre di contesto dei modelli linguistici di grandi dimensioni (LLM), il che rappresenta una sfida. Le pipeline di Generazione potenziata da recupero (RAG) affrontano questo problema elaborando, archiviando e recuperando sezioni di documenti pertinenti, consentendo ai LLM di rispondere alle query in modo efficiente. Quindi, discutiamo i componenti cruciali di una pipeline di RAG.

Quali sono i componenti di RAG?

In un tipico processo RAG, abbiamo alcuni componenti.

  • Text Splitter: Suddivide i documenti per adattarsi alle finestre di contesto dei LLM.
  • Embedding Model: Il modello di apprendimento profondo utilizzato per ottenere le incorporazioni dei documenti.
  • Vector Stores: I database in cui vengono memorizzate e interrogate le incorporazioni dei documenti insieme ai loro metadati.
  • LLM: Il Large Language Model responsabile della generazione di risposte alle query.
  • Funzioni di utilità: Questo include funzioni di utilità aggiuntive come Webretriver e parser di documenti che aiutano nella ricerca e nella pre-elaborazione dei file.

L’immagine sopra è di un tipico processo RAG. Abbiamo documenti (PDF, pagine web, documenti), uno strumento per suddividere il testo lungo in blocchi più piccoli, modelli di incorporamento per ottenere una rappresentazione vettoriale dei blocchi di testo, il DataBase di vettori come base di conoscenza e un LLM per ottenere risposte dai blocchi di testo.

Cos’è il Llama Index?

Il Llama Index (GPTIndex) è un framework scritto in Python per la creazione di applicazioni LLM. È un framework dati semplice e flessibile che collega le fonti di dati personalizzate ai grandi modelli linguistici. Fornisce strumenti appropriati per supportare il recupero dei dati da varie fonti, database vettoriali per l’indicizzazione dei dati e interfacce di interrogazione per interrogare i grandi documenti. In breve, Llama Index è un punto di riferimento unico per la creazione di applicazioni di generazione potenziata dal recupero. Consente un’integrazione facile con altre applicazioni come Langchain, Flask, Docker, ecc. Consulta il repository ufficiale di GitHub per maggiori informazioni: https://github.com/run-llama/llama_index.

Leggi anche: Come utilizzare LlamaIndex

Adesso che sappiamo di RAG e Llama Index. Quindi, costruiamo la nostra pipeline di RAG per elaborare documenti PDF e discutiamo i singoli concetti man mano che procediamo.

Configurazione dell’ambiente di sviluppo

La prima regola per la creazione di qualsiasi progetto Python è creare un ambiente virtuale. Una volta fatto ciò, installa le seguenti librerie.

llama-indexopenaitiktoken

Ora, importa le seguenti funzioni.

import osfrom llama_index import ServiceContext, LLMPredictor, OpenAIEmbedding, PromptHelperfrom llama_index.llms import OpenAIfrom llama_index.text_splitter import TokenTextSplitterfrom llama_index.node_parser import SimpleNodeParserfrom llama_index import VectorStoreIndex, SimpleDirectoryReaderfrom llama_index import set_global_service_context

Ora, imposta la chiave API di Open AI.

import osos.environ['OPENAI_API_KEY'] = "LA TUA CHIAVE API"

Carica i documenti

Come sappiamo, i LLM non possiedono una conoscenza aggiornata del mondo né conoscenza dei tuoi documenti interni. Per aiutare i LLM, dobbiamo fornirgli informazioni pertinenti da fonti di conoscenza. Queste fonti di conoscenza possono essere dati strutturati come CSV, fogli di calcolo o tabelle SQL, dati non strutturati come testi, documenti Word, documenti di Google, PDF o PPT e dati semi-strutturati come Notion, Slack, Salesforce, ecc.

In questo articolo, useremo PDF. Llama Index include una classe SimpleDirectoryReader che può leggere i documenti salvati da una directory specificata. Seleziona automaticamente un parser in base all’estensione del file.

documents = SimpleDirectoryReader(input_dir='dati').load_data()

Puoi avere una tua implementazione personalizzata di un lettore PDF utilizzando pacchetti come PyMuPDF o PyPDF2.

Creazione di blocchi di testo

Spesso, i dati estratti dalle fonti di conoscenza sono estesi e superano la finestra di contesto dei LLM. Se inviamo testi più lunghi della finestra di contesto, l’API Chatgpt accorcerà i dati, tralasciando informazioni cruciali. Un modo per risolvere questo problema è la suddivisione dei testi. Nella suddivisione dei testi, i testi più lunghi vengono divisi in blocchi più piccoli in base ai separatori.

Il chunking del testo ha altri vantaggi oltre a consentire di adattare i testi alla finestra di contesto di un grande modello di linguaggio.

  • I chunk di testo più piccoli producono una maggiore precisione di incorporamento, migliorando di conseguenza l’accuratezza del recupero.
  • Contesto preciso: Ridurre le informazioni aiuta a ottenere informazioni migliori.

L’indice Llama dispone di strumenti integrati per suddividere i testi in chunk. Ecco come possiamo farlo.

text_splitter = TokenTextSplitter(  separator=" ",  chunk_size=1024,  chunk_overlap=20,  backup_separators=["\n"],  tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode)node_parser = SimpleNodeParser.from_defaults(  text_splitter = TokenTextSplitter ))

SimpleNodeParser crea nodi dai chunk di testo, e i chunk di testo vengono creati utilizzando il TokenTextSplitter di Llama Index. Possiamo utilizzare anche un SentenceSplitter.

text_splitter = SentenceSplitter(  separator=" ",  chunk_size=1024,  chunk_overlap=20,  paragraph_separator="\n\n\n",  secondary_chunking_regex="[^,.;。]+[,.;。]?",  tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode)

Creazione di basi di conoscenza

I testi estratti dalle fonti di conoscenza devono essere memorizzati da qualche parte. Ma nelle applicazioni basate su RAG, abbiamo bisogno degli incorporamenti dei dati. Questi incorporamenti sono numeri decimali che rappresentano i dati in uno spazio vettoriale ad alta dimensione. Per memorizzarli e operare su di essi, abbiamo bisogno di basi di dati vettoriali. Le basi di dati vettoriali sono archivi dati appositamente progettati per memorizzare e interrogare vettori.

In questa sezione, comprenderemo gli incorporamenti e le basi di dati vettoriali e li implementeremo utilizzando Llama Index per il nostro pipeline RAG.

Incorporamenti

Possiamo comprendere gli incorporamenti attraverso un semplice esempio di supermercato. In un supermercato, troverai sempre mele e arance nella stessa sezione. Per trovare un sapone, dovrai spostarti più lontano dalla sezione delle frutta verso la sezione dell’abbigliamento quotidiano, ma troverai facilmente profumi nella stessa sezione a pochi passi di distanza.

Ecco come funzionano gli incorporamenti. Due testi semanticamente correlati saranno vicini nello spazio vettoriale, mentre i testi dissimili saranno lontani. Gli incorporamenti hanno una straordinaria capacità di mappare analogie tra diversi punti di dati. Qui c’è un’illustrazione semplice dello stesso.

Allora, perché abbiamo bisogno di incorporamenti?

Gli incorporamenti generati da modelli di deep-learning capaci possono catturare efficientemente il significato semantico dei chunk di testo. Quando un utente invia una query di testo, la convertiamo in incorporamenti utilizzando lo stesso modello, confrontiamo le distanze degli incorporamenti di testo memorizzati nel database vettoriale e recuperiamo i chunk di testo “n” più vicini semanticamente. Questi chunk sono i chunk più semanticamente simili al testo interrogato.

Per i modelli di incorporamento, non dobbiamo fare nulla di speciale. Llama Index ha una implementazione personalizzata di modelli di incorporamento popolari, come Ada di OpenAI, Cohere, Sentence transformers, ecc.

Per personalizzare il modello di incorporamento, dobbiamo utilizzare ServiceContext e PromptHelper.

llm = OpenAI(model='gpt-3.5-turbo', temperature=0, max_tokens=256)embed_model = OpenAIEmbedding()prompt_helper = PromptHelper(  context_window=4096,   num_output=256,   chunk_overlap_ratio=0.1,   chunk_size_limit=None)service_context = ServiceContext.from_defaults(  llm=llm,  embed_model=embed_model,  node_parser=node_parser,  prompt_helper=prompt_helper)

Database vettoriale

I database vettoriali sono appositamente progettati per memorizzare e organizzare incorporamenti e metadati associati per fornire la massima efficienza di interrogazione. Forniscono il recupero semantico dei dati, che aiuta ad arricchire i LLM con nuove informazioni. Ecco come funziona.

Ora, potresti chiederti, perché non possiamo utilizzare i database tradizionali? Tecnicamente, possiamo utilizzare un database come SQLite o MySQL per memorizzare vettori e confrontare linearmente gli incorporamenti del testo di query con tutti gli altri. Ma il problema è, come avrai immaginato, la ricerca lineare con complessità temporale O(n). Mentre una macchina con GPU può gestire perfettamente alcuni migliaia di punti dati, fallirebbe miseramente nel processo di centinaia di milioni di incorporamenti in qualsiasi applicazione del mondo reale.

Allora, come risolviamo questo problema? La risposta è l’indicizzazione degli incorporamenti utilizzando diversi algoritmi ANN come HNSW. L’HNSW è un algoritmo basato su grafi che può gestire efficientemente miliardi di incorporamenti. La complessità media delle query di HNSW è O(log n).

Oltre a HNSW, ci sono alcune altre tecniche di indicizzazione, come la quantizzazione del prodotto, la quantizzazione scalare e l’indicizzazione a file invertiti. Tuttavia, HNSW viene utilizzato come algoritmo di indicizzazione predefinito per la maggior parte dei database vettoriali.

Abbiamo appreso le embed e i vector store. Ora, li implementeremo nel nostro codice. Utilizzeremo il vector store predefinito di Llama Index. È un database vettoriale in memoria. È possibile utilizzare altri vector store come Chroma, Weaviate, Qdrant, Milvus, ecc.

index = VectorStoreIndex.from_documents(documents, service_context=service_context)

Viene creato un indice utilizzando i documenti dalla nostra directory e le impostazioni predefinite dal contesto del servizio definito in precedenza.

Query Index

Il passo finale è effettuare una query sull’indice e ottenere una risposta dalla LLM. Llama Index fornisce un motore di query per effettuare query e un motore di chat per una conversazione simile a una chat. La differenza tra i due è che il motore di chat conserva la cronologia della conversazione, mentre il motore di query no.

query_engine = index.as_query_engine(service_context=service_context)
response = query_engine.query("Cos'è HNSW?")
print(response)

Repository GitHub per immagini e codice: sunilkumardash9/llama_rag

Codice completo:

from llama_index import ServiceContext, LLMPredictor, OpenAIEmbedding, PromptHelperfrom llama_index.llms import OpenAIfrom llama_index.text_splitter import TokenTextSplitterfrom llama_index.node_parser import SimpleNodeParserimport tiktokenllm = OpenAI(model='gpt-3.5-turbo', temperature=0, max_tokens=256)embed_model = OpenAIEmbedding()text_splitter = TokenTextSplitter(separator=" ", chunk_size=1024, chunk_overlap=20, backup_separators=["\n"], tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode)node_parser = SimpleNodeParser.from_defaults(text_splitter=text_splitter)prompt_helper = PromptHelper(context_window=4096, num_output=256, chunk_overlap_ratio=0.1, chunk_size_limit=None)service_context = ServiceContext.from_defaults(llm=llm, embed_model=embed_model, node_parser=node_parser, prompt_helper=prompt_helper)documents = SimpleDirectoryReader(input_dir='data').load_data()index = VectorStoreIndex.from_documents(documents, service_context=service_context)index.storage_context.persist()query_engine = index.as_query_engine(service_context=service_context)response = query_engine.query("Cos'è HNSW?")
print(response)

Casi d’uso reali

Un’applicazione basata su RAG può essere utile in molti casi d’uso reali.

  1. Ricerca accademica: I ricercatori spesso si occupano di numerosi articoli e paper di ricerca in formato PDF. Una pipeline RAG potrebbe aiutarli ad estrarre informazioni rilevanti, creare bibliografie e organizzare le proprie referenze in modo efficiente.
  2. Studi legali: Gli studi legali spesso si occupano di numerosi documenti legali. Un chatbot Q&A abilitato da RAG può semplificare il processo di recupero dei documenti. Ciò risparmierà molto tempo dalla perdita.
  3. Istituti educativi: Gli insegnanti e gli educatori possono estrarre contenuti da risorse educative per creare materiali didattici personalizzati o preparare contenuti per i corsi. Gli studenti possono estrarre informazioni pertinenti da grandi PDF in una frazione di tempo.
  4. Amministrazione: I dipartimenti amministrativi governativi e privati spesso si occupano di grandi quantità di documenti, domande e rapporti. L’utilizzo di un chatbot RAG può semplificare i processi di recupero dei documenti noiosi.
  5. Assistenza clienti: Un chatbot Q&A abilitato da RAG con una base di conoscenza esistente può essere utilizzato per rispondere alle domande del cliente.

Conclusion

Come abbiamo visto, RAG semplifica il recupero delle generazioni. Aiuta a selezionare il contesto giusto da un mucchio di documenti in una frazione di secondo. I LLM vengono quindi inseriti con il contesto corretto della query per generare risposte. I contesti aggiuntivi ancorano essenzialmente i LLM per mantenere le risposte solo nel contesto. Ciò impedisce ai LLM di allucinare, mantenendo al contempo la loro superiore capacità di espressione e scrittura.

Ecco quindi i punti principali dell’articolo.

Punti principali

  • Il modo ideale per far apprendere ai LLM i documenti personali e ridurre le allucinazioni è di completare i LLM con documenti recuperati da basi di conoscenza.
  • RAG sta per Retrieval Augmented Generation. RAG viene utilizzato per completare LLM con informazioni da basi di conoscenza e documenti personali.
  • Gli embedding sono rappresentazioni numeriche di dati testuali in uno spazio vettoriale ad alta dimensione. Gli embedding catturano il significato semantico dei testi.
  • Gli utenti utilizzano i database di vettori come basi di conoscenza, utilizzando vari algoritmi di indicizzazione per organizzare vettori ad alta dimensione, consentendo un’abilità di interrogazione veloce e robusta.
  • Llama Index fornisce strumenti e metodi integrati per sviluppare applicazioni RAG di livello produttivo.

Domande frequenti

I media mostrati in questo articolo non sono di proprietà di Analytics Vidhya e sono utilizzati a discrezione dell’autore.