Files
2026-05-04 23:44:11 +02:00

163 lines
8.4 KiB
Python

"""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()