Files
gliner_glirel_tuning/analysis.md
T
2026-05-04 23:44:11 +02:00

6.9 KiB
Raw Blame History

name, lang, domain, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url
name lang domain description tags uses_functions uses_types framework entry_point dir_path repo_url
gliner_glirel_tuning py datascience Estudio empirico de GLiNER y GLiREL: distribucion de scores, sensibilidad a threshold/top_k/labels/idioma, calibracion de thresholds para extract_graph_hybrid
nlp
gliner
glirel
thresholds
jupyterlab notebooks/main.ipynb projects/osint_graph/analysis/gliner_glirel_tuning

Notas

Estudio empirico de GLiNER y GLiREL: distribucion de scores, sensibilidad a threshold/top_k/labels/idioma, calibracion de thresholds para extract_graph_hybrid.

Tras varias jornadas el alcance se amplio: ahora cubre 6 modelos (GLiNER, GLiREL, mREBEL, REBEL, GLiNER2, NuExtract 2.0-2B) + OpenIE schema-less ES con spaCy + reglas de dependencia. La conclusion ganadora vive en el vault osint_nlp_models.

Notebooks (orden cronologico — ejecutados con outputs guardados)

# Notebook Hallazgo clave
01 notebooks/01_gliner_glirel_tuning.ipynb Calibracion thresholds GLiNER+GLiREL. Multilingue: labels EN funcionan sobre texto ES. snake_case verbal labels >> natural_long en GLiREL.
02 notebooks/02_e2e_spanish_graph.ipynb E2E ES + grafo. Descubrimiento: GLiREL emite 51 falsos positivos en es_corporate_short a t=0.15; a t=0.30 solo 1 relacion (tambien falsa). No hay sweet spot en castellano.
03 notebooks/03_mrebel_vs_glirel.ipynb mREBEL frase-a-frase: 8 tripletas crudas, 5 alineables, 4 inequivocamente correctas. Cero falsos absurdos. PERO licencia CC BY-NC-SA 4.0 (no comercial).
04 notebooks/04_gliner2_winner.ipynb GLiNER2 fastino/gliner2-large-v1 (Apache 2.0, 340M, NER+RE joint). 6/8 correctas vs 4/5 mREBEL, 20× mas rapido. Funciona en OSINT castellano. Modelo elegido.
05 notebooks/05_long_text_and_pdf.ipynb Pipeline PDF E2E sobre politica_proteccion_datos.pdf (BBVA, 89.882 chars). 67 chunks, 378 entidades, 54 relaciones, 97.9s total.
06 notebooks/06_improvements.ipynb Mejoras GLiNER2: threshold 0.3 (vs 0.5 default) → +187% relaciones (71→204). Coref normalize+substring → 18% aislados (389→318). Descripciones por relacion sin efecto. batch_extract 25% mas lento en CPU.
07 notebooks/07_nuextract_vs_gliner2.ipynb NuExtract 2.0-2B GPU sobre RTX 3070: load 7.1s, T1 2.88s vs CPU 25s (8.7×). PDF entero extrapolado 5.2 min vs GLiNER2 CPU 2.2 min — 2.6× mas lento incluso con GPU. Calidad similar. Descartado por velocidad.
08 notebooks/08_improving_gliner2.ipynb Label naming: snake_case verbal >> camelCase >> espacios. include_confidence=True permite threshold por relacion. Post-filter typed gratis y decisivo. GLiREL+allowed_head/tail post-hoc revive el modelo como complemento.
09 notebooks/09_spacy_es_openie.ipynb spaCy ES es_core_news_md + reglas de dependencia: OpenIE schema-less en castellano. (Enmanuel, querer, Ashlly) con verbo del texto, 5ms/frase. Reglas pendientes V2: pasiva refleja, copulares, coref pronombres.

Hallazgos operativos consolidados

Stack final recomendado para graph_explorer

Capa 1 (NER + RE schema-driven):
  GLiNER2 (Apache 2.0)
    + threshold=0.3 (vs default 0.5)
    + snake_case verbal labels
    + include_confidence=True (para tuning fino)

Capa 2 (post-procesado puro, gratis):
  filter_relations_by_entity_types  ← descarta absurdos (Madrid president_of Persona)
  merge_entity_aliases              ← BBVA ⊂ Banco Bilbao Vizcaya...
  aggregate_extraction_results       ← dedupe + counter sobre N chunks

Capa 3 (chunking para texto largo):
  chunk_with_overlap (max_chars=1500, overlap_sentences=2)

Capa 4 opcional (OpenIE schema-less complementaria):
  spaCy es_core_news_md + extract_triples_spacy_es

Todo el stack esta como funciones del registry tras esta sesion (10 funciones en core/datascience/pipelines).

Decisiones registradas en el vault

vaults/osint_nlp_models/decisions/:

  • 2026-05-04-mrebel-over-glirel.md — primera decision (mañana): mREBEL gana a GLiREL pero caveat licencia.
  • 2026-05-04-gliner2-over-mrebel.md — decision final (tarde): GLiNER2 reemplaza a todos por velocidad + Apache 2.0 + multilingue ES nativo.
  • 2026-05-04-license-constraint.md — plan de contingencia si en algun momento se necesita comercial sin Apache 2.0.

Modelos descartados y por que

Modelo Razon
GLiREL jackboyla/glirel-large-v0 51 falsos positivos en ES corporate, sin sweet spot. Util quiza en EN tecnico (no probado).
mREBEL large/base CC BY-NC-SA 4.0 (bloqueante comercial) + 25× mas lento que GLiNER2. Queda como fallback.
REBEL EN-only Apache 2.0 pero requiere traducir ES→EN, +500ms-1s + riesgo nombres propios.
NuExtract 2.0-2B 2.6× mas lento que GLiNER2 incluso con GPU. Mejor para "ficha rica" por entidad pero excesivo para grafo.
triplet-extract EN-only Pierdes verbos del texto castellano al traducir; (quiere, loves) no es lo mismo.

Pendientes (tracked en issues)

  • dev/issues/0050-jupyter-exec-collab-client-failure.md — bug jupyter_exec con cliente colaborativo.
  • projects/osint_graph/apps/graph_explorer/issues/0041-split-confidence-thresholds.md — split confidence_threshold en entity_threshold + relation_threshold.
  • projects/osint_graph/apps/graph_explorer/issues/0042-gliner2-unified-extractor.md — sustituir GLiREL por GLiNER2 en extract_graph_hybrid del panel paste_extract.
  • dev/issues/0051-extraction-pipeline-followups.md — funciones aun por construir (NuExtract loader, extract_graph_from_pdf, spaCy ES V2 rules, kernel startup fix). Ver issue.

Como reproducir cualquier experimento

Cada notebook tiene su build_notebook_*.py y, cuando es pesado, su run_*.py que vuelca a JSON:

cd projects/osint_graph/analysis/gliner_glirel_tuning
./.venv/bin/python3 -u run_benchmark_v2.py            # genera benchmark_v2.json
./.venv/bin/python3 build_notebook_gliner2.py         # genera notebooks/04_gliner2_winner.ipynb
IPYTHONDIR=$(pwd)/.ipython ./.venv/bin/jupyter nbconvert \
    --to notebook --execute notebooks/04_gliner2_winner.ipynb \
    --output 04_gliner2_winner.ipynb --ExecutePreprocessor.timeout=600

JSONs de resultados (todos en la raiz del analysis):

  • benchmark_v2.json — GLiNER2 sobre 4 corpora.
  • improvements.json — 5 configs A-E sobre el PDF + coref.
  • nuextract_results.json — NuExtract CPU baseline + GPU.
  • nuextract_full.json — NuExtract GPU sobre PDF entero (179 chunks parsed OK).
  • mrebel_results.json — mREBEL sobre es_corporate_short.
  • openie_results.json — comparativa 3 paradigmas (triplet-extract EN, spaCy ES, GLiNER2).

Playground

projects/osint_graph/analysis/gliner_glirel_tuning/playground/ — server FastAPI + frontend Sigma.js sirviendo en localhost:7878. Aplica todo el stack de capas 1-3 sobre cualquier texto que pegues. Ver playground/server.py y playground/index.html.