"""Benchmark v2 — GLiNER2 (Apache 2.0, NER+RE joint) vs stack actual. Genera benchmark_v2.json con resultados sobre 4 corpora: - es_corporate_short (notebook 02 baseline) - es_corporate_long (extension a ~30 frases) - es_osint (castellano, ciberseguridad — NUEVO) - en_corporate (control idioma) Para cada corpus, corre GLiNER2 con el schema joint y registra: ents, rels, time, calidad manual a posteriori. """ from __future__ import annotations import json import os import sys import time import warnings from pathlib import Path warnings.filterwarnings("ignore") os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1") HERE = Path(__file__).resolve().parent _pf = "/home/lucas/fn_registry/python/functions" sys.path = [p for p in sys.path if not p.startswith(_pf + "/")] if _pf not in sys.path: sys.path.insert(0, _pf) from gliner2 import GLiNER2 CORPUS = { "es_corporate_short": ( "Pablo Isla, expresidente de Inditex, ha sido nombrado consejero de Telefonica. " "La operacion fue anunciada por el presidente Jose Maria Alvarez-Pallete en Madrid el pasado lunes. " "Inditex factura mas de 30.000 millones anuales y tiene su sede en Arteixo, A Coruna. " "En paralelo, Iberdrola y Endesa firmaron un acuerdo de colaboracion en proyectos eolicos en Galicia. " "El presidente de Iberdrola, Ignacio Galan, se reunio con la CEO de Endesa, Marina Serrano, en Bilbao. " "El acuerdo movilizara 2.000 millones de euros en cinco anos. " "El BBVA, presidido por Carlos Torres, mostro interes en participar en la financiacion del proyecto. " "Su sede central esta en Bilbao." ), "es_corporate_long": ( # 30 frases — generadas para test de chunking y memoria "Pablo Isla, expresidente de Inditex, ha sido nombrado consejero de Telefonica. " "La operacion fue anunciada por el presidente Jose Maria Alvarez-Pallete en Madrid el pasado lunes. " "Inditex factura mas de 30.000 millones anuales y tiene su sede en Arteixo, A Coruna. " "Amancio Ortega, fundador de Inditex, sigue siendo el principal accionista. " "Su hija Marta Ortega ha asumido la presidencia ejecutiva del grupo en 2022. " "Zara, marca emblema de Inditex, opera en mas de 90 paises. " "Telefonica anuncio una alianza estrategica con Microsoft para servicios cloud. " "Satya Nadella, CEO de Microsoft, visito la sede de Telefonica en Distrito Telefonica. " "BBVA, presidido por Carlos Torres, ha completado la integracion de Sabadell tras la fusion. " "Onur Genc, consejero delegado del banco, lideró el proceso desde Bilbao. " "Banco Santander, dirigido por Ana Botin, sigue siendo el primer banco espanol por capitalizacion. " "Hector Grisi es el CEO global de Santander desde enero de 2023. " "CaixaBank tiene su sede operativa en Valencia desde 2017, presidida por Jose Ignacio Goirigolzarri. " "Iberdrola, liderada por Ignacio Galan, opera en EEUU a traves de Avangrid. " "Endesa, filial de la italiana Enel, tiene como CEO a Marina Serrano. " "El acuerdo entre Iberdrola y Endesa movilizara 2.000 millones de euros en proyectos eolicos en Galicia. " "Repsol, dirigida por Josu Jon Imaz, ha vendido su filial de Mexico a la australiana Macquarie. " "Antonio Brufau preside el consejo de administracion de Repsol desde hace mas de una decada. " "Acciona, presidida por Jose Manuel Entrecanales, ha cerrado un contrato en Australia por 600 millones. " "Ferrovial, presidida por Rafael del Pino, traslado su sede a Holanda en 2022. " "ACS, presidida por Florentino Perez, sigue siendo lider mundial en construccion de infraestructuras. " "Naturgy, antes Gas Natural, esta presidida por Francisco Reynes desde Madrid. " "Indra ha nombrado a Marc Murtra como nuevo presidente tras la salida de Fernando Abril-Martorell. " "Telefonica anuncio el cierre de su division de medios y la venta de Telxius a American Tower. " "El Banco de Espana, gobernado por Pablo Hernandez de Cos, advirtio sobre los riesgos de inflacion. " "Luis de Guindos, vicepresidente del BCE, fue ministro de Economia en el gobierno de Mariano Rajoy. " "Calvin Souther Fuller, fundador de SunPower, vendio la empresa al grupo TotalEnergies. " "Patrick Pouyanne, CEO de TotalEnergies, anuncio inversiones en renovables en Espana. " "Iberdrola firma con Amazon un PPA de 15 anos para suministrar energia eolica. " "Andy Jassy, CEO de Amazon, agradecio el acuerdo en una nota publica desde Seattle." ), "es_osint": ( # OSINT en castellano — ciberseguridad "El 15 de agosto de 2024, el grupo APT-29 (atribuido a Rusia) lanzo una campana de phishing contra empresas energeticas espanolas. " "El servidor de comando y control 185.220.101.45 conectaba con sistemas internos de Iberdrola via TLS. " "El malware utilizado, identificado como CozyBear, exploto la vulnerabilidad CVE-2024-21412 en Microsoft Defender. " "El operador @phantomzero reivindico el ataque en un foro de la dark web alojado en hxxps://malwareops[.]biz/control. " "El analista Carlos Garcia, del CCN-CERT, publico un informe tecnico con el hash SHA-256 a3f5e8c9b1d2e3f4a5b6c7d8e9f0a1b2 del binario malicioso. " "Telefonica Tech alerto a sus clientes sobre indicadores de compromiso adicionales en el dominio cloudfront-cdn[.]net." ), "en_corporate_short": ( "Pablo Isla, the former chairman of Inditex, has been appointed as a director of Telefonica. " "The announcement was made by Jose Maria Alvarez-Pallete, the chairman of Telefonica, in Madrid last Monday. " "Inditex has its headquarters in Arteixo, A Coruna. " "BBVA, chaired by Carlos Torres, has its headquarters in Bilbao." ), } ENTITY_LABELS = { "general": ["person", "organization", "location"], "osint_es": ["persona", "organizacion", "ubicacion", "ip_address", "dominio", "url", "username", "vulnerabilidad", "malware", "hash"], "osint_en": ["person", "organization", "location", "ip_address", "domain", "url", "username", "vulnerability", "malware", "hash"], } RELATION_LABELS = { "corporate": ["works_at", "located_in", "appointed_as", "ceo_of", "president_of", "headquartered_in", "subsidiary_of", "parent_company", "founded_by", "agreement_with", "acquired", "succeeded_by"], "osint_es": ["targets", "controlled_by", "hosted_at", "exploits", "uses", "attributed_to", "communicates_with", "indicator_of"], "osint_en": ["targets", "controlled_by", "hosted_at", "exploits", "uses", "attributed_to", "communicates_with", "indicator_of"], } def run_corpus(model: GLiNER2, corpus_key: str, text: str) -> dict: if "osint" in corpus_key: ent_lbl = ENTITY_LABELS["osint_es"] if "es_" in corpus_key else ENTITY_LABELS["osint_en"] rel_lbl = RELATION_LABELS["osint_es"] if "es_" in corpus_key else RELATION_LABELS["osint_en"] else: ent_lbl = ENTITY_LABELS["general"] rel_lbl = RELATION_LABELS["corporate"] schema = ( model.create_schema() .entities(ent_lbl) .relations(rel_lbl) ) t0 = time.time() result = model.extract(text, schema=schema) elapsed = time.time() - t0 n_ents = sum(len(v) for v in result.get("entities", {}).values()) n_rels = sum(len(v) for v in result.get("relation_extraction", {}).values()) return { "n_chars": len(text), "n_words": len(text.split()), "elapsed_s": round(elapsed, 3), "n_entities": n_ents, "n_relations": n_rels, "entities": result.get("entities", {}), "relations": result.get("relation_extraction", {}), "ent_labels": ent_lbl, "rel_labels": rel_lbl, } def main(): print("[load] GLiNER2 large...") t0 = time.time() m = GLiNER2.from_pretrained("fastino/gliner2-large-v1") print(f"[load] {time.time()-t0:.1f}s\n") results = {} for k, text in CORPUS.items(): print(f"[corpus] {k} ({len(text)} chars, {len(text.split())} words)") r = run_corpus(m, k, text) results[k] = r print(f" → {r['n_entities']} ents, {r['n_relations']} rels, {r['elapsed_s']}s\n") out = HERE / "benchmark_v2.json" out.write_text(json.dumps(results, indent=2, ensure_ascii=False)) print(f"[saved] {out}") return results if __name__ == "__main__": main()