beppeinthesky commited on
Commit
6927fd1
·
1 Parent(s): e78c81c

fix: write results to /tmp to avoid permission denied on HF mounted storage

Browse files
README.md CHANGED
@@ -7,17 +7,182 @@ sdk: docker
7
  pinned: false
8
  ---
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  # 🚀 Deploy su Hugging Face Spaces: PNRR Data Processor
11
 
12
  Questa guida descrive i passaggi necessari per configurare, pubblicare e aggiornare l'applicazione "PNRR Data Processor" su [Hugging Face Spaces](https://huggingface.co/spaces).
13
 
14
  ## 💻 Risorse di Sistema Necessarie
 
15
  L'applicazione utilizza modelli di embedding (`sentence-transformers`), indici vettoriali (`faiss-cpu`) e librerie di manipolazione dati (`pandas`, `scikit-learn`). Per funzionare correttamente senza errori di memoria (OOM), l'ambiente di hosting richiede:
16
 
17
- * **RAM:** Minimo 4 GB (Consigliati 16 GB per elaborazioni fluide di cluster numerosi).
18
- * **CPU:** Almeno 2 vCPU.
19
- * **Storage:** Archiviazione persistente per salvare i risultati generati nella cartella `/app/results`.
20
- * **Porta esposta:** Il container Docker deve obbligatoriamente esporre la porta **7860** (già configurata nel `Dockerfile`).
21
 
22
  Il piano gratuito **"CPU Basic"** di Hugging Face Spaces (16 GB RAM, 2 vCPU) è perfettamente in grado di far girare l'applicazione.
23
 
@@ -26,30 +191,30 @@ Il piano gratuito **"CPU Basic"** di Hugging Face Spaces (16 GB RAM, 2 vCPU) è
26
  ## 🛠️ Fase 1: Creazione e Configurazione dello Space
27
 
28
  ### 1. Creazione Account e Space
 
29
  1. Crea un account gratuito su [Hugging Face](https://huggingface.co/).
30
  2. Vai in alto a destra (sulla tua immagine profilo) e seleziona **"New Space"**.
31
  3. Compila il modulo:
32
- * **Space name:** `pnrr-data-processor` (o un nome a tua scelta).
33
- * **License:** Seleziona *MIT* o lascia vuoto.
34
- * **Select the Space SDK:** Scegli **Docker** e poi il template **Blank**.
35
- * **Space Hardware:** Lascia il piano gratuito di default.
36
- * **Visibility:** Imposta su **Public** (necessario per condividere l'app con i clienti tramite link senza richiedere il login ad HF).
37
  4. Clicca su **Create Space**.
38
 
39
  ### 2. Configurazione Credenziali (Secrets)
 
40
  L'applicazione è protetta da una schermata di login. Le password non sono nel codice sorgente e devono essere configurate nel cloud.
 
41
  1. Nella pagina del tuo Space, vai sulla tab **Settings**.
42
  2. Scorri fino a **Variables and secrets** e clicca su **New secret**.
43
  3. Aggiungi i seguenti segreti:
44
- * `LOGIN_USER1` ➔ Valore: `nomeutente:password_scelta` (es. `admin:12345`)
45
- * `OPENAI_API_KEY` ➔ Valore: `sk-...` (Inserisci la tua chiave API di OpenAI, se usata dai moduli dell'app).
 
 
46
 
47
- ### 3. Configurazione Storage Persistente (Gratuito)
48
- Per evitare che i file CSV ed Excel generati vadano persi quando l'app va in standby:
49
- 1. Sempre in **Settings**, scorri fino alla sezione **Storage**.
50
- 2. Clicca su **Attach a storage bucket** (potrebbe chiederti di crearne uno nuovo, accetta).
51
- 3. Alla voce **Mount path**, inserisci esattamente: `/app/results`.
52
- 4. Salva. Ora l'app salverà i file in modo permanente.
53
 
54
  ---
55
 
@@ -58,12 +223,14 @@ Per evitare che i file CSV ed Excel generati vadano persi quando l'app va in sta
58
  Per inviare il codice dal tuo computer a Hugging Face senza sovrascrivere la tua repository principale (es. Bitbucket), configureremo HF come destinazione remota secondaria.
59
 
60
  ### 1. Generare un Access Token
 
61
  1. Vai su Hugging Face ➔ **Settings** ➔ **Access Tokens**.
62
  2. Clicca su **New token**.
63
  3. Nominalo `Deploy-App` e imposta il Type su **Write**.
64
  4. Copia il token generato (`hf_...`). **Attenzione:** non inserire MAI questo token nel codice sorgente.
65
 
66
  ### 2. Collegare il repository locale
 
67
  Apri il terminale nella cartella del progetto locale e aggiungi Hugging Face come `remote` (chiamato `hf`).
68
  Sostituisci `TUO_NOME_UTENTE`, `TUO_TOKEN` e `NOME_SPACE` con i tuoi dati reali:
69
 
@@ -78,21 +245,25 @@ git remote add hf [https://TUO_NOME_UTENTE:TUO_TOKEN@huggingface.co/spaces/TUO_N
78
  Ogni volta che fai una modifica al codice sul tuo computer e vuoi pubblicare l'aggiornamento sull'app in produzione, segui questi 3 passaggi nel terminale:
79
 
80
  **1. Registra le modifiche (Commit):**
 
81
  ```bash
82
  git add .
83
  git commit -m "Descrizione dell'aggiornamento"
84
  ```
85
 
86
  **2. Invia alla tua repository principale (es. Bitbucket):**
 
87
  ```bash
88
  git push origin main
89
  ```
90
 
91
  **3. Invia a Hugging Face per avviare il deploy:**
 
92
  ```bash
93
  git push hf main
94
  ```
95
- *(Nota: se il tuo branch locale principale si chiama `master`, usa il comando `git push hf master:main`).*
 
96
 
97
  Non appena eseguito il comando `push hf`, Hugging Face rileverà il nuovo codice e inizierà automaticamente la ricostruzione del container Docker. L'app sarà online in circa 2-3 minuti.
98
 
@@ -100,6 +271,6 @@ Non appena eseguito il comando `push hf`, Hugging Face rileverà il nuovo codice
100
 
101
  ## ⚠️ Note Importanti e Limitazioni
102
 
103
- * **Sleep Mode:** Poiché l'app è ospitata sul piano gratuito, se non riceve traffico web per 48 ore consecutive, il server andrà in pausa ("Sleep"). Al primo accesso successivo, l'utente vedrà una schermata di caricamento per circa 1-2 minuti mentre il container si riavvia. Dopodiché, l'app tornerà fluida e responsiva.
104
- * **Link Diretto per Demo:** Per inviare l'app a un cliente offrendo un'esperienza a tutto schermo (nascondendo l'interfaccia di Hugging Face), usa l'URL diretto. Clicca sui tre puntini `...` in alto a destra sull'app in esecuzione ➔ **Embed this Space** ➔ Copia il **Direct URL**.
105
- * **Gestione Segreti:** Non committare mai token di Hugging Face, password in chiaro o chiavi API nei file di codice o nei Notebook Jupyter (`.ipynb`). Il sistema di sicurezza di HF bloccherà automaticamente il caricamento del codice in caso di leak.
 
7
  pinned: false
8
  ---
9
 
10
+ ## Setup ed Esecuzione (Docker)
11
+
12
+ ### Prerequisiti
13
+
14
+ - Docker e Docker Compose installati
15
+ - File Excel con i dati dei progetti PNRR
16
+
17
+ ### Configurazione Ambiente
18
+
19
+ 1. **Crea il file di configurazione ambiente:**
20
+
21
+ ```bash
22
+ cp .env.example .env
23
+ ```
24
+
25
+ 2. **Configura la chiave API OpenAI nel file `.env`:**
26
+
27
+ ```
28
+ OPENAI_API_KEY='sk-xxxxxxxxxxxxxxxxxxxxxxx'
29
+ ```
30
+
31
+ Per ottenere una chiave API OpenAI:
32
+ - Registrati o accedi a [OpenAI Platform](https://platform.openai.com)
33
+ - Vai nella sezione "API Keys" nel tuo profilo
34
+ - Crea una nuova chiave API
35
+ - Copia la chiave e inseriscila nel file `.env`
36
+
37
+ ### Avvio dell'Applicazione
38
+
39
+ ```bash
40
+ docker compose -f docker/compose.base.yaml up --build
41
+ ```
42
+
43
+ L'applicazione sarà disponibile su: **http://localhost:8501**
44
+
45
+ ### Monitoraggio
46
+
47
+ Per visualizzare i log del container:
48
+
49
+ ```bash
50
+ docker container logs -f semantic_filter
51
+ ```
52
+
53
+ ## 🎯 Funzionalità dell'Applicazione
54
+
55
+ ### 🔍 Filtro Semantico
56
+
57
+ **Scopo**: Identificare automaticamente progetti PNRR rilevanti basandosi su query in linguaggio naturale.
58
+
59
+ **Come funziona**:
60
+
61
+ - Utilizza modelli di AI per comprendere il significato semantico delle descrizioni dei progetti
62
+ - Confronta la query dell'utente con il contenuto dei progetti per trovare corrispondenze concettuali
63
+ - Assegna un punteggio di confidenza a ogni progetto basato sulla rilevanza
64
+
65
+ **Come usarlo**:
66
+
67
+ 1. Carica il file Excel contenente i progetti PNRR
68
+ 2. Imposta la soglia di confidenza (0.0-1.0) per filtrare i risultati
69
+ 3. Scrivi una query descrittiva in linguaggio naturale (es. "progetti di digitalizzazione nelle scuole", "infrastrutture sostenibili", "riqualificazione urbana")
70
+ 4. Scegli se aggiungere i risultati come nuova colonna o creare un nuovo file
71
+ 5. Avvia la ricerca e scarica i risultati
72
+
73
+ **Output**: File Excel con i progetti filtrati e punteggi di rilevanza
74
+
75
+ ### 🎯 Analisi Cluster
76
+
77
+ **Scopo**: Raggruppare automaticamente progetti simili in cluster tematici per identificare pattern ricorrenti e aree di investimento comuni.
78
+
79
+ **Come funziona**:
80
+
81
+ - Analizza il contenuto testuale delle colonne selezionate usando tecniche di machine learning
82
+ - Applica preprocessing intelligente rimuovendo stopwords italiane, termini PNRR comuni e parole personalizzate dall'utente
83
+ - Raggruppa progetti con caratteristiche simili in cluster tematici usando embeddings semantici
84
+ - Genera automaticamente titoli, descrizioni e parole chiave per ogni cluster tramite AI
85
+ - Calcola statistiche di distribuzione dei progetti
86
+
87
+ **Come usarlo**:
88
+
89
+ 1. Carica il file Excel contenente i progetti PNRR
90
+ 2. Seleziona le colonne testuali da utilizzare per il clustering (es. titolo progetto, descrizione, sintesi)
91
+ 3. Configura i parametri:
92
+ - **Automatico**: L'algoritmo determina il numero ottimale di cluster
93
+ - **Manuale**: Specifica un numero fisso di cluster
94
+ 4. **Personalizza la blacklist** (opzionale):
95
+ - Aggiungi parole specifiche da escludere dall'analisi
96
+ - Inserisci termini troppo generici o irrilevanti per il tuo contesto
97
+ - Le parole possono essere inserite separate da virgole o una per riga
98
+ - Esempi: nomi di enti frequenti, termini tecnici comuni, location ricorrenti
99
+ 5. Avvia l'analisi e attendi il completamento
100
+ 6. Esplora i risultati nei cluster generati
101
+ 7. **🆕 Visualizza il plot PCA**: Analizza la distribuzione spaziale dei cluster nel grafico interattivo
102
+ 8. Scarica i risultati:
103
+ - **Sommario Cluster**: File con titoli, descrizioni e statistiche
104
+ - **Dati con Cluster ID**: File originale con aggiunta dell'identificativo cluster
105
+
106
+ **Output**:
107
+
108
+ - Sommario dei cluster con titoli, descrizioni, parole chiave e progetti campione
109
+ - Dataset originale arricchito con l'ID del cluster di appartenenza
110
+ - Visualizzazioni della distribuzione dei progetti per cluster
111
+ - **🆕 Plot PCA interattivo**: Visualizzazione bidimensionale dei cluster nello spazio degli embeddings
112
+
113
+ ### 📊 Visualizzazione PCA dei Cluster
114
+
115
+ **Caratteristiche**:
116
+
117
+ - **Riduzione dimensionale**: I complessi embeddings multidimensionali vengono ridotti a 2 dimensioni tramite PCA (Principal Component Analysis)
118
+ - **Plot interattivo**: Visualizzazione Plotly con zoom, pan e informazioni al passaggio del mouse
119
+ - **Codifica colori**: Ogni cluster ha un colore distintivo per facilitare l'identificazione
120
+ - **Informazioni dettagliate**: Hover con titolo cluster, descrizione e numero di progetti
121
+ - **Varianza spiegata**: Mostra quanto della variabilità originale è preservata nelle due componenti principali
122
+
123
+ **Interpretazione**:
124
+
125
+ - Punti vicini rappresentano progetti semanticamente simili
126
+ - Gruppi di punti dello stesso colore mostrano la coesione del cluster
127
+ - La distanza tra cluster indica quanto sono diversi tematicamente
128
+ - La percentuale di varianza spiegata indica l'affidabilità della rappresentazione 2D
129
+
130
+ ### 🎯 Blacklist Personalizzata
131
+
132
+ **Scopo**: Migliorare la qualità dei cluster escludendo parole irrilevanti specifiche del tuo dataset.
133
+
134
+ **Benefici**:
135
+
136
+ - **Cluster più precisi**: Rimuovendo parole generiche, i cluster si basano su termini realmente distintivi
137
+ - **Controllo granulare**: Personalizza l'analisi in base al tuo contesto specifico
138
+ - **Flessibilità**: Testa diverse configurazioni per ottimizzare i risultati
139
+
140
+ **Esempi di parole da escludere**:
141
+
142
+ - Termini troppo frequenti: "progetto", "attività", "servizio"
143
+ - Nomi di enti ricorrenti: "comune", "regione", "asl"
144
+ - Parole tecniche generiche: "sistema", "gestione", "sviluppo"
145
+ - Location comuni nel dataset: "milano", "roma", "italia"
146
+
147
+ ## 📋 Formato File
148
+
149
+ L'applicazione è **completamente flessibile** riguardo al formato del file Excel:
150
+
151
+ ### ✅ Requisiti Minimi
152
+
153
+ - File in formato Excel (.xlsx)
154
+ - Almeno una colonna contenente testo descrittivo
155
+
156
+ ### 🎯 Adattabilità
157
+
158
+ - **Nomi colonne**: Possono essere qualsiasi, l'interfaccia mostrerà tutte le colonne disponibili
159
+ - **Struttura dati**: Qualsiasi struttura è supportata
160
+ - **Selezione dinamica**: L'utente sceglie quali colonne utilizzare per l'analisi
161
+
162
+ ### 🏆 Colonne Consigliate (Opzionali)
163
+
164
+ Per progetti PNRR, colonne come queste migliorano la qualità dell'analisi:
165
+
166
+ - **Titolo/Nome Progetto**: Identificazione del progetto
167
+ - **Descrizione/Sintesi**: Contenuto descrittivo dettagliato
168
+ - **Settore/Ambito**: Area tematica del progetto
169
+ - **Soggetto/Ente**: Organizzazione responsabile
170
+ - **Località**: Informazioni geografiche
171
+
172
+ > **💡 Suggerimento**: Più contenuto testuale descrittivo è disponibile, migliore sarà la qualità dell'analisi semantica e del clustering, indipendentemente dai nomi delle colonne.
173
+
174
  # 🚀 Deploy su Hugging Face Spaces: PNRR Data Processor
175
 
176
  Questa guida descrive i passaggi necessari per configurare, pubblicare e aggiornare l'applicazione "PNRR Data Processor" su [Hugging Face Spaces](https://huggingface.co/spaces).
177
 
178
  ## 💻 Risorse di Sistema Necessarie
179
+
180
  L'applicazione utilizza modelli di embedding (`sentence-transformers`), indici vettoriali (`faiss-cpu`) e librerie di manipolazione dati (`pandas`, `scikit-learn`). Per funzionare correttamente senza errori di memoria (OOM), l'ambiente di hosting richiede:
181
 
182
+ - **RAM:** Minimo 4 GB (Consigliati 16 GB per elaborazioni fluide di cluster numerosi).
183
+ - **CPU:** Almeno 2 vCPU.
184
+ - **Storage:** Non è necessario storage persistente — i file generati vengono scritti in `/tmp` e scaricati direttamente dall'interfaccia.
185
+ - **Porta esposta:** Il container Docker deve obbligatoriamente esporre la porta **7860** (già configurata nel `Dockerfile`).
186
 
187
  Il piano gratuito **"CPU Basic"** di Hugging Face Spaces (16 GB RAM, 2 vCPU) è perfettamente in grado di far girare l'applicazione.
188
 
 
191
  ## 🛠️ Fase 1: Creazione e Configurazione dello Space
192
 
193
  ### 1. Creazione Account e Space
194
+
195
  1. Crea un account gratuito su [Hugging Face](https://huggingface.co/).
196
  2. Vai in alto a destra (sulla tua immagine profilo) e seleziona **"New Space"**.
197
  3. Compila il modulo:
198
+ - **Space name:** `pnrr-data-processor` (o un nome a tua scelta).
199
+ - **License:** Seleziona _MIT_ o lascia vuoto.
200
+ - **Select the Space SDK:** Scegli **Docker** e poi il template **Blank**.
201
+ - **Space Hardware:** Lascia il piano gratuito di default.
202
+ - **Visibility:** Imposta su **Public** (necessario per condividere l'app con i clienti tramite link senza richiedere il login ad HF).
203
  4. Clicca su **Create Space**.
204
 
205
  ### 2. Configurazione Credenziali (Secrets)
206
+
207
  L'applicazione è protetta da una schermata di login. Le password non sono nel codice sorgente e devono essere configurate nel cloud.
208
+
209
  1. Nella pagina del tuo Space, vai sulla tab **Settings**.
210
  2. Scorri fino a **Variables and secrets** e clicca su **New secret**.
211
  3. Aggiungi i seguenti segreti:
212
+ - `LOGIN_USER1` ➔ Valore: `nomeutente:password_scelta` (es. `admin:12345`)
213
+ - `OPENAI_API_KEY` ➔ Valore: `sk-...` (Inserisci la tua chiave API di OpenAI, se usata dai moduli dell'app).
214
+
215
+ ### 3. Storage
216
 
217
+ Non è necessario (né consigliato) attaccare uno storage persistente di HF Spaces. I file generati vengono scritti in `/tmp/results` all'interno del container e sono scaricabili direttamente tramite i pulsanti di download nell'interfaccia. Montare un bucket su `/app/results` causerebbe errori di permesso (Permission denied) perché il volume sovrascrive i permessi impostati nel Dockerfile.
 
 
 
 
 
218
 
219
  ---
220
 
 
223
  Per inviare il codice dal tuo computer a Hugging Face senza sovrascrivere la tua repository principale (es. Bitbucket), configureremo HF come destinazione remota secondaria.
224
 
225
  ### 1. Generare un Access Token
226
+
227
  1. Vai su Hugging Face ➔ **Settings** ➔ **Access Tokens**.
228
  2. Clicca su **New token**.
229
  3. Nominalo `Deploy-App` e imposta il Type su **Write**.
230
  4. Copia il token generato (`hf_...`). **Attenzione:** non inserire MAI questo token nel codice sorgente.
231
 
232
  ### 2. Collegare il repository locale
233
+
234
  Apri il terminale nella cartella del progetto locale e aggiungi Hugging Face come `remote` (chiamato `hf`).
235
  Sostituisci `TUO_NOME_UTENTE`, `TUO_TOKEN` e `NOME_SPACE` con i tuoi dati reali:
236
 
 
245
  Ogni volta che fai una modifica al codice sul tuo computer e vuoi pubblicare l'aggiornamento sull'app in produzione, segui questi 3 passaggi nel terminale:
246
 
247
  **1. Registra le modifiche (Commit):**
248
+
249
  ```bash
250
  git add .
251
  git commit -m "Descrizione dell'aggiornamento"
252
  ```
253
 
254
  **2. Invia alla tua repository principale (es. Bitbucket):**
255
+
256
  ```bash
257
  git push origin main
258
  ```
259
 
260
  **3. Invia a Hugging Face per avviare il deploy:**
261
+
262
  ```bash
263
  git push hf main
264
  ```
265
+
266
+ _(Nota: se il tuo branch locale principale si chiama `master`, usa il comando `git push hf master:main`)._
267
 
268
  Non appena eseguito il comando `push hf`, Hugging Face rileverà il nuovo codice e inizierà automaticamente la ricostruzione del container Docker. L'app sarà online in circa 2-3 minuti.
269
 
 
271
 
272
  ## ⚠️ Note Importanti e Limitazioni
273
 
274
+ - **Sleep Mode:** Poiché l'app è ospitata sul piano gratuito, se non riceve traffico web per 48 ore consecutive, il server andrà in pausa ("Sleep"). Al primo accesso successivo, l'utente vedrà una schermata di caricamento per circa 1-2 minuti mentre il container si riavvia. Dopodiché, l'app tornerà fluida e responsiva.
275
+ - **Link Diretto per Demo:** Per inviare l'app a un cliente offrendo un'esperienza a tutto schermo (nascondendo l'interfaccia di Hugging Face), usa l'URL diretto. Clicca sui tre puntini `...` in alto a destra sull'app in esecuzione ➔ **Embed this Space** ➔ Copia il **Direct URL**.
276
+ - **Gestione Segreti:** Non committare mai token di Hugging Face, password in chiaro o chiavi API nei file di codice o nei Notebook Jupyter (`.ipynb`). Il sistema di sicurezza di HF bloccherà automaticamente il caricamento del codice in caso di leak.
modules/cluster_analysis.py CHANGED
@@ -15,7 +15,7 @@ import plotly.express as px
15
  import plotly.graph_objects as go
16
 
17
 
18
- RESULTS_DIR = '/app/results'
19
  SAVE_PATH_CLUSTERS = os.path.join(RESULTS_DIR, 'cluster_results.xlsx')
20
  SAVE_PATH_ORIGINAL = os.path.join(RESULTS_DIR, 'data_with_clusters.xlsx')
21
  EMBEDDING_MODEL_NAME = 'sentence-transformers/all-MiniLM-L6-v2'
 
15
  import plotly.graph_objects as go
16
 
17
 
18
+ RESULTS_DIR = '/tmp/results'
19
  SAVE_PATH_CLUSTERS = os.path.join(RESULTS_DIR, 'cluster_results.xlsx')
20
  SAVE_PATH_ORIGINAL = os.path.join(RESULTS_DIR, 'data_with_clusters.xlsx')
21
  EMBEDDING_MODEL_NAME = 'sentence-transformers/all-MiniLM-L6-v2'
modules/semantic_filter.py CHANGED
@@ -8,7 +8,7 @@ from modules import column_query_agent
8
  from langchain_huggingface import embeddings
9
 
10
 
11
- SAVE_PATH = 'semantic_filter_results.xlsx'
12
  LLM_MODEL_NAME = 'gpt-4o-mini'
13
  EMBEDDING_MODEL_NAME = 'sentence-transformers/all-MiniLM-L6-v2'
14
 
@@ -56,7 +56,7 @@ def apply(
56
  df_reduced = chunk[relevant_columns]
57
  db = create.build_faiss(
58
  df_reduced,
59
- index_path='faiss_index',
60
  embedder=embedder
61
  )
62
  results = search.multi_column(db, chunk, query_pairs, threshold)
 
8
  from langchain_huggingface import embeddings
9
 
10
 
11
+ SAVE_PATH = '/tmp/semantic_filter_results.xlsx'
12
  LLM_MODEL_NAME = 'gpt-4o-mini'
13
  EMBEDDING_MODEL_NAME = 'sentence-transformers/all-MiniLM-L6-v2'
14
 
 
56
  df_reduced = chunk[relevant_columns]
57
  db = create.build_faiss(
58
  df_reduced,
59
+ index_path='/tmp/faiss_index',
60
  embedder=embedder
61
  )
62
  results = search.multi_column(db, chunk, query_pairs, threshold)