Spaces:
Running
Running
| #Questo documento incapsula la logica per l'estrazione delle NE e del testo strutturato | |
| from gliner import GLiNER | |
| import torch | |
| import logging | |
| from processingPdf.loader import get_layout_extractor, load_pdf_from_bytes | |
| from processingPdf.logicSections import extract_logical_sections | |
| logger = logging.getLogger(__name__) | |
| class PDFExtractor: | |
| def __init__(self): | |
| self.layout_extractor = get_layout_extractor() | |
| def extract_sections(self, file_path: str): | |
| # Legge il file in bytes per spaCyLayout | |
| with open(file_path, "rb") as f: | |
| pdf_bytes = f.read() | |
| # Carica il documento ed estrae il layout | |
| doc = load_pdf_from_bytes(pdf_bytes, self.layout_extractor) | |
| # Suddivide in sezioni logiche | |
| if doc: | |
| return extract_logical_sections(doc) | |
| return {} | |
| class EntityExtractor: | |
| _model = None | |
| def get_model(): | |
| if EntityExtractor._model is None: | |
| logger.info("Caricamento del modello GLiNER...") | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| EntityExtractor._model = GLiNER.from_pretrained("urchade/gliner_medium-v2.1").to(device) | |
| return EntityExtractor._model | |
| def extract_ne(text: str): | |
| model = EntityExtractor.get_model() | |
| labels = [ | |
| # --- GENERAL & IDENTIFIERS --- | |
| "Person", "Organization", "Location", "Date", "Time", | |
| "Product", "Event", "Nationality", "Language", | |
| # --- BUROCRATICO, NORMATIVO & BANDI --- | |
| "Normative Reference", # Articoli di legge, decreti, commi | |
| "Public Body", # Enti pubblici (es. Ministero, Commissione Europea) | |
| "Deadline", # Scadenze per bandi, domande o pagamenti | |
| "Requirement", # Requisiti di partecipazione o criteri di accesso | |
| "Amount", # Cifre monetarie, borse di studio, tasse | |
| "Evaluation Criteria", # Criteri di punteggio o valutazione | |
| "Document Type", # Es. ISEE, Marca da bollo, Certificato di laurea | |
| # --- TECNICO & MANUALE DI ISTRUZIONI --- | |
| "Component", # Parti di macchinari o componenti hardware | |
| "Technical Specification", # Es. 220V, 50Hz, risoluzione 4K, velocità rotazione | |
| "Error Code", # Codici errore (es. E04, 404, Fault-01) | |
| "Safety Instruction", # Avvertenze di sicurezza o pericoli | |
| "Tool", # Strumenti necessari (es. chiave inglese, cacciavite) | |
| "Operation Mode", # Modalità operative (es. Standby, Manuale, Eco) | |
| # --- SCIENTIFICO, CHIMICO & FISICO --- | |
| "Scientific Term", # Termini tecnici generali | |
| "Chemical Compound", # Formule e nomi di sostanze (es. H2O, Glucosio) | |
| "Theory/Law", # Leggi fisiche o teorie (es. Legge di Ohm, Relatività) | |
| "Measurement Unit", # Unità di misura (es. Joule, Watt, Nanometri) | |
| "Phenomenon", # Fenomeni naturali o reazioni (es. Ossidazione, Gravità) | |
| # --- MEDICO & CLINICO --- | |
| "Clinical Condition", # Malattie, patologie o sintomi | |
| "Medical Parameter", # Es. Glicemia, Pressione Arteriosa, Frequenza Cardiaca | |
| "Anatomical Structure", # Organi, ossa, muscoli o tessuti | |
| "Drug/Medication", # Nomi di farmaci o principi attivi | |
| "Diagnostic Test", # Es. Risonanza Magnetica, Analisi del sangue | |
| # --- ACCADEMICO & SCOLASTICO --- | |
| "Academic Subject", # Materie (es. Storia Moderna, Fisica Quantistica) | |
| "Exam/Test Name", # Titoli di esami o test (es. Test TOLC, Prova Scritta) | |
| "Degree Course", # Corsi di laurea o diplomi | |
| "Bibliographic Source", # Citazioni, autori o titoli di testi universitari | |
| # --- STORICO & NARRATIVO (FANTASCIENZA) --- | |
| "Historical Period", # Ere, secoli o movimenti (es. Illuminismo, Paleolitico) | |
| "Fictional Species", # Es. Androidi, Alieni, Specie di fantasia | |
| "Technological Concept", # Tecnologie immaginarie o concetti futuristici | |
| # --- QUANTITATIVO --- | |
| "Percentage", # Percentuali e tassi | |
| "Quantity", # Quantità generiche non monetarie | |
| "Distance" # Distanze e lunghezze | |
| ] | |
| entities_found = model.predict_entities(text, labels, threshold=0.5) | |
| entities = [] | |
| seen = set() # Per tracciare i duplicati nello stesso chunk | |
| for ent in entities_found: | |
| text_clean = ent["text"].strip().lower() | |
| label_clean = ent["label"].upper().replace(" ", "_") | |
| # Creiamo una chiave univoca per il set | |
| entity_key = (text_clean, label_clean) | |
| if entity_key not in seen: | |
| entities.append({ | |
| "text": text_clean, | |
| "label": label_clean | |
| }) | |
| seen.add(entity_key) | |
| return entities |