Spaces:
Paused
Paused
| import streamlit as st | |
| from ragpipeline import (RAGPipeline,Retriever,OllamaChatbot) | |
| import tempfile | |
| import pandas as pd | |
| from textutils import ParagraphDocumentProcessor, SmallFragmentDocumentProcessor,WholeTextDocumentProcessor | |
| from HFChatbot import HFBot | |
| import os | |
| def main(): | |
| if "faiss_builder" not in st.session_state: | |
| ragpipeline = RAGPipeline(numero_frammenti=10) | |
| st.session_state["faiss_builder"] = ragpipeline | |
| else: | |
| ragpipeline = st.session_state["faiss_builder"] | |
| if "storico_domande" not in st.session_state: | |
| st.session_state["storico_domande"] = [] | |
| if "indice_creato" not in st.session_state: | |
| st.session_state["indice_creato"] = False | |
| modelliVelvet = [ | |
| 'Almawave/Velvet-2B', | |
| 'Almawave/Velvet-14B', | |
| ] | |
| modelliLLM = [ | |
| 'Almawave/Velvet-2B', | |
| 'Almawave/Velvet-14B', | |
| 'mistralai/Mistral-7B-Instruct-v0.1', | |
| 'Qwen/Qwen2.5-1.5B', | |
| ] | |
| modelliOllama = [ | |
| 'Almawave/Velvet:2B', | |
| 'Almawave/Velvet:14b', | |
| 'llama3.1:8b-instruct-q4_K_M', | |
| 'qwen3:14b', | |
| 'qwen3:30b-a3b', | |
| 'gpt-oss:20b' | |
| ] | |
| ## indica se sono sullo spaces di HF (deve essere inserita uan variabile I_AM_ON_HF) | |
| sono_su_hf =os.environ.get('I_AM_ON_HF', False) | |
| ## se sono su Hugginh Face non uso ollama | |
| if not sono_su_hf: | |
| modelliLLM.append("----- USARE SOLO CON OLLAMA -----") | |
| for mollama in modelliOllama: | |
| modelliLLM.append(mollama) | |
| UPLOAD_DIR="/tmp/" | |
| if "indice_creato" not in st.session_state: | |
| st.session_state["indice_creato"] = False | |
| if "faiss_builder" not in st.session_state: | |
| ragpipeline = RAGPipeline( ) | |
| codice_tabella = f"<table><tr><td>💡AURA:</td><td> AI-Utilizzata per la Regolarità Amministrativa</td></tr></table>" | |
| st.markdown(codice_tabella, unsafe_allow_html=True) | |
| st.title("Cosa è AURA?") | |
| st.write(""" | |
| Questo strumento, attualmente in fase sperimentale, è stato sviluppato per eseguire controlli di | |
| regolarità amministrativa ai sensi dell’art. 147-bis del D.Lgs. 267/2000, | |
| con riferimento agli atti relativi al PNRR. | |
| È in continua evoluzione. Per testarne il funzionamento, è sufficiente caricare un file PDF contenente | |
| una determinazione dirigenziale. | |
| <p> | |
| AURA è un sistema RAG <em>Retrieval Augmented Generation</em> che dato un atto amministrativo ed eventuali allegati | |
| ed una o più domande ricerca nei documenti | |
| i frammenti rilevanti per la domanda; questi assieme ad alcune istruzioni (<em>In-context learning</em>) | |
| vengono inviati ad un LLM <em>Large Language Model</em> | |
| al fine di generare una risposta corretta e coerente con i frammenti rilevanti. | |
| </p> | |
| <p> | |
| Questa versione di AURA utilizza Velvet di Almawave, rilasciato sotto | |
| <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a> come LLM. | |
| </p> | |
| """ , unsafe_allow_html=True) | |
| st.warning("Attenzione questo tool è sperimentale. AURA può sbagliare") | |
| if not sono_su_hf: | |
| modello_scelto = st.selectbox("Seleziona un modello:", modelliLLM, index=0) | |
| else: | |
| modello_scelto = st.selectbox("Seleziona un modello:", modelliVelvet, index=0) | |
| st.write(f"Hai selezionato: {modello_scelto}") | |
| if not sono_su_hf: | |
| st.title("Generazione testo") | |
| generatoriLLM = { | |
| 'Hugging Face Transformers': "HF", | |
| 'Ollama in locale' :"OLLAMA" | |
| } | |
| selected_generator= st.selectbox("Scegli lo strumento per interagire con LLM", generatoriLLM.keys()) | |
| chiave_LLM=generatoriLLM[selected_generator] | |
| st.write(f"Hai selezionato {selected_generator}") | |
| else: | |
| chiave_LLM="HF" | |
| st.title("Suddivisione in paragrafi") | |
| docprocessor_options = { | |
| "Small Fragments (più veloce ma poco preciso)": SmallFragmentDocumentProcessor(), | |
| "ParagraphDocumentProcessor (più lento e leggermente più preciso)": ParagraphDocumentProcessor(), | |
| "WholeText (viene generato un solo grande frammento, può confondere gli LLM)": WholeTextDocumentProcessor(), | |
| } | |
| selected_docprocessor = st.selectbox("Divisione in paragrafi", docprocessor_options.keys()) | |
| ragpipeline.docprocessor = docprocessor_options[selected_docprocessor] | |
| st.write(f"Hai selezionato: **{selected_docprocessor}**") | |
| if not st.session_state["indice_creato"]: | |
| st.subheader("Carica eventuali Allegati PDF multipli") | |
| other_pdfs = st.file_uploader("Carica allegati (puoi caricare più PDF)", | |
| type=["pdf"], | |
| accept_multiple_files=True, | |
| key="allegati_pdf") | |
| if st.button("Crea indice FAISS"): | |
| if other_pdfs: | |
| nfile=1 | |
| for uploaded_file in other_pdfs: | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf", dir=UPLOAD_DIR) as tmp_file: | |
| tmp_file.write(uploaded_file.read()) | |
| tmp_path = tmp_file.name | |
| ragpipeline.aggiungi_file_pdf(tmp_path) | |
| st.write(f"Caricato file N {nfile}") | |
| nfile = nfile+1 | |
| st.success("Allegati caricati con successo!") | |
| else: | |
| st.error("Nessun allegato caricato.") | |
| ragpipeline.crea_indice() | |
| st.success("Indice FAISS generato e caricato.") | |
| st.session_state["indice_creato"] = True | |
| frammenti_recuperati =ragpipeline.attributi_frammenti | |
| for frammento_recuperato in frammenti_recuperati: | |
| RAGPipeline.dump_excel(dizionario=frammento_recuperato, filename="frammentiChatbot.xlsx") | |
| if st.session_state["indice_creato"]: | |
| with st.form(key="domanda_form"): | |
| domanda = st.text_area("Inserisci la domanda", key="domanda_input") | |
| istruzione = st.text_area("Inserisci le istruzioni", key="istruzione_input") | |
| submit_button = st.form_submit_button("Analizza atto") | |
| if submit_button: | |
| if domanda.strip().upper() == "FINE": | |
| st.stop() | |
| if chiave_LLM == "HF": | |
| LLM=HFBot(model_name=modello_scelto) | |
| elif chiave_LLM == "OLLAMA": | |
| LLM=OllamaChatbot(model_name="flaollama",model_orig=modello_scelto) | |
| else: | |
| LLM=HFBot(model_name=modello_scelto) | |
| ret = Retriever( | |
| indice=ragpipeline.indice, | |
| sentence_transformer_model=ragpipeline.sentence_transformer_model, | |
| query=domanda + istruzione, | |
| documenti=ragpipeline.documenti, | |
| frammenti_indicizzati=ragpipeline.frammenti_indicizzati, | |
| attributi_frammenti=ragpipeline.attributi_frammenti | |
| ) | |
| ret.esegui_query(top_k=3) | |
| risposta = LLM.generate( | |
| query=domanda, | |
| relevant_docs=ret.passaggi_rilevanti, | |
| attributi_frammenti_rilevanti=ret.attributi_rilevanti, | |
| istruzioni=istruzione | |
| ) | |
| st.session_state.storico_domande.append((modello_scelto, domanda, istruzione, risposta)) | |
| st.markdown( | |
| f"<p><strong>Domanda:</strong> {domanda} <br/>" | |
| f"<strong>Istruzioni:</strong> <em>{istruzione}</em><br/><br/>" | |
| f"<strong>Risposta:</strong><em> {risposta}</em></p>", | |
| unsafe_allow_html=True | |
| ) | |
| id_frammenti_recuperati = ":".join(sorted(set(elemento['id'] for elemento in ret.attributi_rilevanti))) | |
| dump = { | |
| 'timestamp': ragpipeline.timestamp, | |
| "modello": modello_scelto, | |
| "documenti": st.session_state.get("main_pdf_nome", "non disponibile"), | |
| "file_recuperati": "", | |
| "file_gold": "", | |
| "frammenti_recuperati":id_frammenti_recuperati, | |
| "frammenti_gold": "", | |
| "domanda":domanda, | |
| "istruzioni":istruzione, | |
| "risposta_gold": " ", | |
| "risposta":LLM.pulisci_risposta(risposta)} | |
| RAGPipeline.dump_excel(dizionario=dump,filename="dumpChatbot.xlsx") | |
| if st.session_state.storico_domande: | |
| st.markdown("---") | |
| st.subheader("Storico delle domande analizzate") | |
| for idx, (mymod, q, inst, resp) in enumerate(st.session_state.storico_domande, 1): | |
| st.markdown( | |
| f""" | |
| **{idx}. Domanda:** {q}<br/> | |
| <em>Modello: </em>{mymod}<br/> | |
| <em>Istruzioni:</em> {inst}<br/><br/> | |
| <strong>Risposta:</strong> {resp}<br/> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| if __name__ == "__main__": | |
| main() | |