b8c760d004
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
163 lines
8.4 KiB
Python
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()
|