Utilizzo del modello Clip di OpenAI per supportare la ricerca in linguaggio naturale su una raccolta di 70.000 copertine di libri
In un messaggio precedente Ho fatto un piccolo PoC per vedere se potevo usare il modello Clip di OpenAI per creare una ricerca semantica di libri. Ha funzionato sorprendentemente bene, secondo me, ma non ho potuto fare a meno di chiedermi se sarebbe stato meglio con più dati. La versione precedente utilizzava solo circa 3,5mila libri, ma nella versione ce ne sono milioni Set di dati OpenLibrarye ho pensato che valesse la pena provare ad aggiungere più opzioni allo spazio di ricerca.
Tuttavia, il set di dati completo è di circa 40 GB e provare a gestire così tanti dati sul mio piccolo laptop, o anche su un notebook Colab, era un po’ eccessivo, quindi ho dovuto trovare una pipeline in grado di gestire il filtraggio e l’incorporamento di un set di dati più grande .
TLDR; Ha migliorato la ricerca? Penso di sì! Abbiamo moltiplicato i dati per 15 volte, il che dà alla ricerca molto più su cui lavorare. Non è perfetto, ma ho pensato che i risultati fossero abbastanza interessanti; anche se non ho effettuato una misura di precisione formale.
Questo è stato un esempio che non sono riuscito a mettere al lavoro, non importa come l’ho espresso nell’ultima iterazione, ma funziona abbastanza bene nella versione con più dati.
Se sei curioso puoi provarlo al!
Nel complesso, è stato un viaggio tecnico interessante, con molti ostacoli e opportunità di apprendimento lungo il percorso. Lo stack tecnologico include ancora il modello OpenAI Clip, ma questa volta utilizzo Apache Spark e AWS EMR per eseguire la pipeline di incorporamento.
Ci è sembrata una buona opportunità per utilizzare Spark, poiché ci consente di parallelizzare il calcolo dell’incorporamento.
Ho deciso di eseguire la pipeline in EMR Serverless, un’offerta AWS abbastanza nuova che fornisce un ambiente serverless per EMR e gestisce automaticamente il ridimensionamento delle risorse. Ho pensato che avrebbe funzionato bene per questo caso d’uso, invece di avviare un EMR su un cluster EC2, perché si tratta di un progetto abbastanza ad hoc, sono paranoico sui costi del cluster e inizialmente non ero sicuro di quali risorse il lavoro richiederebbe. EMR Serverless semplifica la sperimentazione dei parametri del lavoro.
Di seguito è riportato l’intero processo che ho seguito per rendere tutto attivo e funzionante. Immagino che ci siano modi migliori per gestire determinati passaggi, questo è proprio quello che ha funzionato per me, quindi se hai pensieri o opinioni, per favore condividili!
Creazione di un processo di incorporamento della pipeline con Spark
Il passaggio iniziale è stato scrivere i processi Spark. L’intera pipeline è suddivisa in due fasi, la prima accoglie il set di dati iniziale e filtra la narrativa recente (negli ultimi 10 anni). Ciò ha prodotto circa 250.000 libri e circa 70.000 con immagini di copertina disponibili per il download e l’incorporamento nella seconda fase.
Per prima cosa estraiamo le colonne rilevanti dal file di dati grezzi.
Quindi esegui una trasformazione generale dei dati sui tipi di dati e filtra tutto tranne la narrativa inglese con più di 100 pagine.
La seconda fase acquisisce il set di dati di output della prima fase ed esegue le immagini attraverso il modello Clip, scaricato da Hugging Face. Il passaggio importante qui è trasformare le varie funzioni che dobbiamo applicare ai dati in Spark UDF. Quello di principale interesse è get_image_embedding, che accetta l’immagine e restituisce l’incorporamento
Lo registriamo come UDF:
E chiama quella UDF sul set di dati:
Impostazione del database vettoriale
Come ultimo passaggio facoltativo nel codice, possiamo impostare un database vettoriale, in questo caso Milvus, da caricare ed eseguire query. Tieni presente che non l’ho fatto come parte del lavoro cloud per questo progetto, poiché ho selezionato i miei incorporamenti da utilizzare senza dover mantenere un cluster attivo e funzionante a tempo indeterminato. Tuttavia, è abbastanza semplice configurare Milvus e caricare uno Spark Dataframe in una raccolta.
Innanzitutto, crea una raccolta con un indice nella colonna di incorporamento delle immagini che il database può utilizzare per la ricerca.
Quindi possiamo accedere alla raccolta nello script Spark e caricarvi gli incorporamenti dal Dataframe finale.
Infine, possiamo semplicemente incorporare il testo di ricerca con lo stesso metodo utilizzato nella UDF sopra e colpire il database con gli incorporamenti. Il database fa il lavoro pesante per individuare le migliori corrispondenze
Configurazione della pipeline in AWS
Prerequisiti
Ora è necessario eseguire alcune operazioni di configurazione per eseguire questi lavori su EMR Serverless.
Come prerequisiti abbiamo bisogno di:
- Un bucket S3 per script di lavoro, input e output e altri artefatti necessari al lavoro
- Un ruolo IAM con autorizzazioni di lettura, elenco e scrittura per S3, nonché di lettura e scrittura per Glue.
- Una policy di attendibilità che consente ai lavori EMR di accedere ad altri servizi AWS.
Sono disponibili descrizioni dettagliate dei ruoli e delle policy di autorizzazione, nonché una descrizione generale di come iniziare a utilizzare EMR Serverless nella documentazione AWS qui: Iniziare con Amazon EMR Serverless
Successivamente dobbiamo configurare un EMR Studio: Crea uno studio EMR
Accesso al Web tramite un gateway Internet
Un’altra impostazione specifica per questo particolare lavoro è che dobbiamo consentire al lavoro di raggiungere Internet, cosa che l’applicazione EMR non è in grado di fare per impostazione predefinita. Come abbiamo visto nello script, il lavoro deve accedere sia alle immagini da incorporare, sia a Hugging Face per scaricare le configurazioni e i pesi del modello.
Nota: esistono probabilmente modi più efficienti per gestire il modello piuttosto che scaricarlo per ciascun lavoratore (trasmettendolo, archiviandolo da qualche parte localmente nel sistema, ecc.), ma in questo caso, per una singola esecuzione dei dati, ciò è sufficiente.
In ogni caso, per consentire alla macchina su cui è in esecuzione il processo Spark di raggiungere Internet è necessario un VPC con sottoreti private dotate di gateway NAT. Tutta questa configurazione inizia con l’accesso all’interfaccia AWS VPC -> Crea VPC -> selezionando VPC e altro -> selezionando l’opzione almeno sul gateway NAT -> facendo clic su Crea VPC.
La configurazione del VPC richiede alcuni minuti. Una volta fatto ciò, dobbiamo anche creare un gruppo di sicurezza nell’interfaccia del gruppo di sicurezza e collegare il VPC che abbiamo appena creato.
Creazione dell’applicazione EMR Serverless
Ora passiamo all’applicazione EMR Serverless che invierà il lavoro! La creazione e l’avvio di uno studio EMR dovrebbe aprire un’interfaccia utente che offre alcune opzioni tra cui la creazione di un’applicazione. Nell’interfaccia utente dell’applicazione creata, seleziona Utilizza impostazioni personalizzate -> Impostazioni di rete. È qui che entrano in gioco il VPC, le due sottoreti private e il gruppo di sicurezza.
Costruire un ambiente virtuale
Infine, l’ambiente non viene fornito con molte librerie, quindi per aggiungere ulteriori dipendenze Python possiamo utilizzare Python nativo o creare e pacchettizzare un ambiente virtuale: Utilizzo delle librerie Python con EMR Serverless.
Ho seguito la seconda strada e il modo più semplice per farlo è con Docker, poiché ci consente di creare l’ambiente virtuale all’interno della distribuzione Amazon Linux che esegue i processi EMR (farlo in qualsiasi altra distribuzione o sistema operativo può diventare incredibilmente complicato) .
Un altro avvertimento: fai attenzione a scegliere la versione di EMR che corrisponde alla versione di Python che stai utilizzando e scegli di conseguenza anche le versioni del pacchetto.
Il processo Docker restituisce l’ambiente virtuale compresso come pyspark_dependencies.tar.gz, che poi viene inserito nel bucket S3 insieme agli script di lavoro.
Possiamo quindi inviare questo ambiente compresso insieme al resto delle configurazioni del lavoro Spark
Carino! Abbiamo lo script del lavoro, le dipendenze ambientali, i gateway e un’applicazione EMR, possiamo inviare il lavoro! Non così in fretta! Ora arriva il vero divertimento, l’accordatura Spark.
Come accennato in precedenza, EMR Serverless si ridimensiona automaticamente per gestire il nostro carico di lavoro, il che in genere sarebbe ottimo, ma ho scoperto (ovvio col senno di poi) che non era utile per questo particolare caso d’uso.
Alcune decine di migliaia di record non sono affatto “big data”; Spark vuole che vengano elaborati terabyte di dati e stavo semplicemente inviando essenzialmente poche migliaia di URL di immagini (nemmeno le immagini stesse). Lasciato ai propri dispositivi, EMR Serverless invierà il lavoro a un nodo per farlo funzionare su un singolo thread, vanificando completamente lo scopo della parallelizzazione.
Inoltre, sebbene i processi di incorporamento assorbano una quantità relativamente piccola di dati, li espandono in modo significativo, poiché gli incorporamenti sono piuttosto grandi (512 nel caso di Clip). Anche se lasci quel nodo a sfornare per alcuni giorni, esaurirà la memoria molto prima che finisca di elaborare l’intero set di dati.
Per farlo funzionare, ho sperimentato alcune proprietà Spark in modo da poter utilizzare macchine di grandi dimensioni nel cluster, ma dividere i dati in partizioni molto piccole in modo che ogni core avesse solo un po’ di lavoro e output:
- spark.executor.memory: quantità di memoria da utilizzare per processo dell’esecutore
- spark.sql.files.maxPartitionBytes: il numero massimo di byte da comprimere in una singola partizione durante la lettura dei file.
- spark.executor.cores: il numero di core da utilizzare su ciascun esecutore.
Dovrai modificarli a seconda della natura particolare dei tuoi dati e l’incorporamento non è ancora un processo rapido, ma è stato in grado di elaborare i miei dati.
Conclusione
Come con il mio messaggio precedente i risultati certamente non sono perfetti e non sostituiscono in alcun modo i solidi consigli sui libri di altri esseri umani! Ma detto questo, c’erano delle risposte precise a molte delle mie ricerche, il che pensavo fosse piuttosto interessante.
Se vuoi giocare tu stesso con l’app, è dentro aled è presente il codice completo per la pipeline Github!
Fonte: towardsdatascience.com