Crea un assistente di chat potente per PDF e articoli senza la chiave OpenAI

Crea un potente assistente di chat per PDF e articoli senza bisogno della chiave OpenAI

Introduzione

Il mondo dell’Elaborazione del Linguaggio Naturale sta espandendosi enormemente, specialmente con la nascita dei grandi modelli linguistici, che hanno rivoluzionato questo campo e reso accessibile a tutti. In questo articolo, esploreremo e implementeremo alcune tecniche di NLP per creare un potente assistente di chat in grado di rispondere alle tue domande basandosi su un articolo (o PDF) dato utilizzando librerie open-source, tutto senza richiedere una chiave API OpenAI.

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

Flusso di lavoro

Il flusso di lavoro dell’applicazione è il seguente:

Dove l’utente fornisce un file PDF o un URL a un articolo, fa una domanda e l’applicazione cercherà di risponderla in base alla fonte fornita.

Estrarremo il contenuto utilizzando la libreria PYPDF2 (nel caso di un file PDF) o BeautifulSoup (nel caso di un URL di un articolo). Poi, lo divideremo in pezzi utilizzando il CharacterTextSplitter della libreria langchain.

Per ogni pezzo, calcoleremo il suo vettore di embedding delle parole corrispondente utilizzando il modello all-MiniLM-L6-v2, che mappa frasi e paragrafi in uno spazio vettoriale denso a 384 dimensioni (l’embedding delle parole è solo una tecnica per rappresentare una parola/frase come un vettore), e la stessa tecnica viene applicata alla domanda dell’utente.

I vettori vengono dati in input alla funzione di ricerca semantica fornita da sentence_transformers, che è un framework Python per l’embedding di frasi, testi e immagini di ultima generazione.

Questa funzione ritornerà il pezzo di testo che potrebbe contenere la risposta, e il modello di domanda e risposta genererà la risposta finale in base all’output della ricerca semantica + domanda dell’utente.

Nota

  • Tutti i modelli menzionati sono accessibili tramite API, utilizzando solo richieste HTTP.
  • Il codice sarà scritto utilizzando Python.
  • FAQ-QN è una parola chiave che indica che dovresti dare un’occhiata alla sezione FAQ, nello specifico alla domanda numero N, per ulteriori dettagli.

Implementazione

In questa sezione, mi concentrerò solo sull’implementazione, mentre i dettagli saranno forniti nella sezione FAQ.

Dipendenze

Iniziamo scaricando le dipendenze e quindi importandole.

pip install -r requirements.txt

import torchimport numpy as npfrom sentence_transformers import utilfrom langchain.text_splitter import CharacterTextSplitterfrom bs4 import BeautifulSoupimport requests
  • torch : molto utile quando si lavora con tensori (libreria Pytorch).
  • requests : per inviare richieste HTTP.

Estrazione del Contenuto

Nel caso di un PDF

try:    pdf=PdfReader(path_pdf_file)    result=''    for i in range(len(pdf.pages)):        result+=pdf.pages[i].extract_text()except:    print('Il file PDF non esiste'))    exit(0)

Nel caso di un articolo, cerchiamo di trovare il contenuto tra i tag HTML come h1, p, li, h2, ecc. (Questi tag funzionano bene per siti web come VoAGI e possono differire in altri)

try:        request=requests.get(URL_LINK)        request=BeautifulSoup(request.text,'html.parser')        request=request.find_all(['h1','p','li','h2'])except:        print('Link URL non valido')        exit(0)result=[element.text for element in request]result=''.join(result)

Dividi in Chunks

Ogni chunk conterrà 1000 token, con 200 token sovrapposti per mantenere i chunk correlati e prevenire la separazione. (FAQ-Q2)

text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
      )
chunks = text_splitter.split_text(result)

Word Embedding

Puoi scaricare il modello all-MiniLM-L6-v2 da huggingface, oppure puoi accedervi tramite richieste HTTP in quanto è disponibile come un API. (FAQ-Q1)

Nota: Per accedere alle API di huggingface, devi registrarti (è gratuito) per ottenere il tuo token.

hf_token='Inserisci qui il tuo token di accesso huggingface'
api_url= """https://api-inference.huggingface.co/pipeline/feature-extraction/sentence-transformers/all-MiniLM-L6-v2"""
headers = {"Authorization": f"Bearer {hf_token}"}

def query(texts):
  response = requests.post(api_url, headers=headers, json={"inputs": texts, "options":{"wait_for_model":True}})
  return response.json()

user_question = 'Inserisci qui la tua domanda'
question = query([user_question])
query_embeddings = torch.FloatTensor(question)
output = query(chunks)
output = torch.from_numpy(np.array(output)).to(torch.float)

La funzione di query restituisce il vettore denso di dimensione 384 e la trasformazione in ‘torch.Float’ e FloatTensor è necessaria per la funzione semantic_search.

Il risultato conterrà 2 chunk di testo che potrebbero includere la risposta (ho impostato top_k=2, per aumentare la probabilità di ottenere la risposta corretta dal modello di domande e risposte). (FAQ-Q4)

result = util.semantic_search(query_embeddings, output, top_k=2)
final = [chunks[result[0][i]['corpus_id']] for i in range(len(result[0]))]

Modello Domanda-Risposta

Dato che hai il contesto (i chunk di testo) e la domanda, puoi utilizzare qualsiasi modello desideri (puoi dare un’occhiata veloce ai modelli di domanda e risposta di huggingface per farti un’idea). Ho scelto il modello AI21studio Question Answer, puoi registrarti gratuitamente per ottenere un token di accesso.

AI21_api_key = 'Chiave API AI21studio'
url = "https://api.ai21.com/studio/v1/answer"

payload = {
  "context":' '.join(final),
  "question":user_question
}

headers = {
  "accept": "application/json",
  "content-type": "application/json",
  "Authorization": f"Bearer {AI21_api_key}"
}

response = requests.post(url, json=payload, headers=headers)

if response.json()['answerInContext']:
  print(response.json()['answer'])
else:
  print('La risposta non è presente nel documento ⚠️, per favore riformula la tua domanda.')

Il modello permette di verificare se la risposta è presente nel contesto o meno (nel caso dell’utilizzo di modelli linguistici complessi, potresti avere il problema di ricevere una risposta non correlata al contesto fornito). (FAQ-Q3)****

Conclusioni

Puoi estendere questo progetto a varie fonti di input (file PowerPoint, video/audio di YouTube, slide, audiolibri) a un costo relativamente basso, quindi sentiti libero di adattarlo ai tuoi casi d’uso. Inoltre, puoi creare un’interfaccia utente semplice per questa applicazione e ospitarla.

Streamlit come ho fatto (il repository GitHub può essere trovato qui, non dimenticare di premere il pulsante di stella.

In questo articolo, abbiamo costruito un potente assistente di chat per i tuoi file/articoli PDF.

  • Abbiamo utilizzato tecniche di web scraping per estrarre il testo dalla fonte.
  • Il testo è stato diviso in più chunk.
  • Abbiamo calcolato il vettore word embedding per ogni chunk e per la domanda dell’utente.
  • Abbiamo applicato la funzione semantic_search per individuare il chunk di testo più rilevante.
  • La risposta finale è stata fornita dal modello Question Answer.

Grazie per il tuo tempo e la tua attenzione. Per ulteriori assistenza:

LinkedIn: SAMY GHEBACHE

Email: [email protected].

Domande frequenti

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