Caso de estudio
Cómo se construyó, midió y valoró el sistema, en una sola página. Las tablas largas están plegadas; cada cifra conserva su fuente.
El problema
Rellenar cualquier esquema JSON a partir de un texto en español y devolver null para lo que el texto no dice.
Extracción guiada por esquema en español
Una instancia de la tarea es una terna: un texto fuente en español, una instrucción en lenguaje natural y un esquema JSON que define qué extraer. El esquema solo se conoce en el momento de la inferencia, de modo que un sistema no puede memorizar tipos de entidad: tiene que leer los nombres, tipos y descripciones de los campos y actuar en consecuencia.
Una salida válida debe cumplir dos restricciones a la vez:
- Validez estructural: la salida es un objeto JSON que se ajusta al esquema.
- Fidelidad a la fuente: todo valor no nulo está respaldado por el texto, y todo campo que el texto no respalda se devuelve como
null.
A continuación se muestra una instancia ilustrativa escrita para esta página, en el formato del corpus sintético (esquema abreviado); no es un registro del corpus. Fíjate en que el caudal medio no aparece en el texto, así que la respuesta correcta para ese campo es null.
{
"input_text": "El río Arga es uno de los principales ríos de Navarra. Nace en el área de Quinto Real, en los Pirineos navarros, y atraviesa Pamplona y Puente la Reina antes de desembocar en el río Aragón. Tiene una longitud de 145 km.",
"instruction": "Extrae el perfil estructurado del río descrito: su nombre, el río en el que desemboca, su longitud en kilómetros, la zona donde nace, las localidades que atraviesa y su caudal medio.",
"target_schema": "RiverProfile: name, tributary_of, length_km (integer), source_range, passes_through (array), avg_flow_m3s (number or null)",
"output": {
"name": "Arga",
"tributary_of": "Aragón",
"length_km": 145,
"source_range": "Quinto Real",
"passes_through": ["Pamplona", "Puente la Reina"],
"avg_flow_m3s": null
}
}
Null-traps
A los campos que el texto no responde se les llama null-traps. Un modelo que inventa un valor verosímil para ellos está alucinando, y la evaluación lo penaliza. Esto convierte la tarea en una prueba de contención tanto como de extracción.
La tarea compartida GenSIE 2026
GenSIE (General-purpose Schema-guided Information Extraction) fue una tarea compartida de IberLEF 2026. Dos reglas condicionaron el trabajo:
- Política de No-Training. Estaba prohibido modificar los pesos del modelo (LoRA, QLoRA, fine-tuning completo). Solo se permitían técnicas en tiempo de inferencia: prompting, recuperación, decodificación restringida y ejemplos few-shot.
- Varios modelos abiertos pequeños. Los sistemas se evaluaban sobre varios modelos de pesos abiertos de menos de 14B parámetros de familias distintas, algunos de ellos ocultos hasta los resultados, lo que desincentivaba ajustar un pipeline a un único modelo.
Aproximadamente la mitad de los esquemas del test privado eran completamente nuevos.
La métrica
La métrica principal es el Flattened Schema Scoring: las salidas de referencia y del sistema se aplanan en conjuntos clave–valor, cada clave compartida recibe una puntuación de similitud entre 0 y 1 (coincidencia exacta para tipos rígidos como enumeraciones y números, una mezcla de embeddings y similitud léxica para texto libre), y la puntuación final es un Micro-F1:
F1 = 2 · TPS / (|G| + |S|), donde TPS es la suma de las similitudes de las claves compartidas, y |G| y |S| son los tamaños de los conjuntos de claves de referencia y del sistema.
El leaderboard de GenSIE agrega los resultados como la fracción de la distancia entre el baseline y la perfección que cada sistema cierra, promediada sobre los modelos de evaluación. Este sitio reporta el Micro-F1 bruto por modelo.
Enfoque
Un único corpus sintético alimenta dos ramas: un pipeline zero-shot con los pesos congelados y una rama de fine-tuning.
El trabajo no enfrenta fine-tuning contra no fine-tuning. Resuelve un único problema y explora varias técnicas, con y sin entrenamiento, sobre los mismos tres modelos abiertos pequeños. Un único corpus sintético alimenta ambas ramas.
| Bloque | Qué hace |
|---|---|
| Generación de datos sintéticos | Produce un corpus en español guiado por esquema con un pipeline de cinco etapas adaptado de GuideX |
| Rama zero-shot | Mantiene los pesos congelados y combina prompting, ejemplos few-shot recuperados, decodificación restringida y posprocesado |
| Rama de fine-tuning | Actualiza los pesos con LoRA y con fine-tuning completo sobre el mismo corpus |
Generación de datos sintéticos
El corpus sigue la idea de GuideX (generación sintética guiada para extracción de información zero-shot), adaptada al español y al formato de registro de GenSIE.
| Etapa | Qué ocurre |
|---|---|
| 0 | Preparar un corpus heterogéneo en español (sobre todo pasajes de la Wikipedia en español), segmentarlo en pasajes autocontenidos y etiquetar el dominio |
| 1 | Un LLM profesor escribe un resumen estructurado de cada pasaje y lista candidatos a null-trap, preguntas que el pasaje no responde |
| 2 | Sintetizar un esquema JSON y una instrucción únicos para cada pasaje |
| 3 | Extraer una instancia JSON conforme al esquema, reintentando con la realimentación del validador si no lo es |
| 4–5 | Control de calidad sin LLM (violaciones de esquema, registros degenerados o poco especificados) y empaquetado en el formato de registro de GenSIE |
La principal diferencia respecto a GuideX es que cada pasaje recibe su propio esquema, de modo que un modelo al que se le da el corpus como prompt o como datos de entrenamiento tiene que leer el esquema en la inferencia en lugar de memorizar una ontología fija.
Rama zero-shot
Una cascada de generar y verificar en torno a una única llamada al LLM. Ningún nombre de campo ni ejemplo del conjunto de desarrollo está fijado en el código.
- Construcción del prompt. Un prompt de sistema fija el papel de extractor estructurado. El mensaje del usuario contiene el esquema, el texto y unas pocas demostraciones few-shot recuperadas de la biblioteca sintética por similitud de esquema, con embeddings multilingües de frases. Una guía de campos opcional reformula en lenguaje llano la descripción, la enumeración y la nulabilidad de cada campo.
- Decodificación restringida. El esquema JSON se compila en una gramática que enmascara los logits de tokens del modelo, de modo que la validez estructural se cumple por construcción y el esfuerzo del modelo se dedica a la corrección semántica.
- Posprocesado consciente del esquema. Una pasada determinista con cinco capas conservadoras: anclaje a la fuente, normalización léxica, canonicalización guiada por el esquema, ajuste literal y un filtro de alucinaciones que sustituye por
nulllos valores sin respaldo de campos anulables.
Rama de fine-tuning
Fine-tuning supervisado sobre ejemplos en formato de chat del mismo corpus, con la pérdida de entropía cruzada habitual sobre el JSON de referencia y sin aprendizaje por refuerzo. Dos regímenes se ejecutan en paralelo con los mismos datos y objetivo:
- LoRA: congela los pesos base y entrena adaptadores de bajo rango que pueden fusionarse de nuevo en un checkpoint estándar.
- Fine-tuning completo: actualiza todos los parámetros, repartidos entre varias GPUs para los modelos más grandes.
Se prueban tres modos de prompt en entrenamiento, incluido el in-context tuning, donde unas pocas demostraciones se colocan dentro del propio prompt de entrenamiento.
Experimentos
Cuatro experimentos organizados en fases, cada uno responde a una pregunta sobre los mismos tres modelos.
El estudio se organiza en fases, cada una responde a una sola pregunta y pasa su mejor configuración a la siguiente.
Datos
| Conjunto | Tamaño | Uso |
|---|---|---|
| Conjunto starter | 40 instancias | Cribado inicial de familias de técnicas en tiempo de inferencia |
| Conjunto de desarrollo | 149 tareas | Todos los experimentos posteriores y las comparaciones de este sitio |
| Corpus sintético | 3.948 pares | Biblioteca de recuperación few-shot y datos de fine-tuning supervisado |
| Reserva de eval-loss | 197 ejemplos | Partición interna de validación usada como métrica auxiliar durante la búsqueda de LoRA (la versión limpia del corpus tiene una reserva de 200 ejemplos) |
El corpus sintético tiene 3.748 pares de entrenamiento y una reserva de 200 ejemplos. El test oficial de GenSIE se evalúa en el artículo publicado; los resultados de este sitio son sobre el conjunto de desarrollo.
Modelos
| Modelo | Checkpoint | Notas |
|---|---|---|
| Qwen3-14B | Qwen/Qwen3-14B |
El más grande de los tres |
| Salamandra-7B | BSC-LT/salamandra-7b-instruct |
Orientado al español, entrenado en el Barcelona Supercomputing Center |
| Llama-3.2-3B | meta-llama/Llama-3.2-3B-Instruct |
El más pequeño de los tres |
Los mismos tres modelos se usan en todos los experimentos, de modo que las comparaciones entre modelos son interpretables. El artículo publicado también reporta resultados zero-shot con Gemma-4-E4B.
Los cuatro experimentos
- Familias de técnicas en tiempo de inferencia. Baseline, chain-of-thought, razonamiento consciente del esquema y recuperación few-shot se criban sobre el conjunto starter; la mejor familia se refina después sobre el conjunto de desarrollo con decodificación restringida, una guía de campos y capas de posprocesado.
- Búsqueda de hiperparámetros de LoRA. Tres fases sobre la reserva de eval-loss: rango y dropout, luego scheduler, luego modo de prompt. Cada fase pasa su mejor ajuste a la siguiente.
- Efecto del fine-tuning en el F1. Para cada modelo, cuatro celdas sobre el conjunto de desarrollo: baseline sin entrenar, sin entrenar con el mejor pipeline zero-shot, LoRA y fine-tuning completo.
- Efecto del fine-tuning en los errores. Cada error se clasifica en una de cinco categorías, y la tasa de null-trap se mide aparte como sonda de fabricación.
Protocolo de evaluación
- Métrica: Micro-F1 de Flattened Schema Scoring, tal como la define la tarea (ver el problema).
- Todas las ejecuciones usan una sola semilla. Los entrenamientos usan parada temprana con una paciencia de 2 evaluaciones.
- El coste de cómputo de un pipeline de inferencia se estima a partir del número de tokens y del número de parámetros.
Hardware y software
El entrenamiento se ejecuta en el supercomputador MareNostrum 5 del Barcelona Supercomputing Center, sobre GPUs NVIDIA H100, planificado con SLURM. Cada ejecución de LoRA tarda entre 3 y 6 horas de GPU. El stack de software se detalla en tecnologías.
Resultados
El mejor pipeline zero-shot alcanzó el F1 más alto; el entrenamiento redujo sobre todo la alucinación.
Solo números y observaciones; la interpretación está en Lo que aprendí. Todos los resultados son sobre el conjunto de desarrollo de GenSIE (149 tareas), con una sola semilla.
Mejor pipeline zero-shot: progresión en Qwen3-14B
Tabla de datos
| Paso | F1 | Δ |
|---|---|---|
| Baseline (zero-shot) | 0,6577 | |
| E021 · 1-shot | 0,6994 | +0,0417 |
| E025 · 3-shot por similitud de esquema | 0,7155 | +0,0161 |
| E211 · + posprocesado de anclaje | 0,7426 | +0,0271 |
| E222 · + filtro de alucinaciones | 0,7840 | +0,0414 |
| E225 · selector enriquecido + biblioteca sintética | 0,7910 | +0,0070 |
| E226 · + guía de campos + limpieza de la fuente | 0,7999 | +0,0089 |
| Pipeline | F1 |
|---|---|
| Baseline (zero-shot) | 0,6577 |
| E021 (1-shot) | 0,6994 |
| E025 (3-shot, similitud de esquema) | 0,7155 |
| E211 (E025 + posprocesado de anclaje) | 0,7426 |
| E222 (E025 + posprocesado completo, incluido el filtro de alucinaciones) | 0,7840 |
| E225 (selector enriquecido, biblioteca sintética, adendas de comportamiento) | 0,7910 |
| E226 (E225 + guía de campos + limpieza de la fuente) | 0,7999 |
En toda la pila de posprocesado, el recuento de errores de alucinación bajó de 84 (E025, sin posprocesado) a 21 (E222). Una variante de E226 con un prompt un 40 % más corto (E227) obtuvo 0,7895.
Mejor resultado por régimen y modelo
| Modelo | Baseline sin entrenar | Mejor zero-shot | Mejor LoRA | Mejor fine-tuning completo |
|---|---|---|---|---|
| Qwen3-14B | 0,6577 | 0,7999 | 0,6977 | 0,7054 |
| Llama-3.2-3B | 0,6703 | 0,7459 | 0,7449 | 0,7481 |
| Salamandra-7B | 0,4843 | 0,6276 | 0,6406 | 0,6193 |
Mejor valor por modelo en negrita. Los modelos entrenados Qwen y Llama se evaluaron solo con los prompts baseline y 1-shot: los pipelines más ricos (E225, E226) no se ejecutaron sobre ellos, y la ejecución de Qwen con LoRA y E226 se abandonó por la longitud del prompt y la latencia. La tabla no muestra, por tanto, cuánto añade el entrenamiento sobre el mejor pipeline en esos dos modelos. El F1 más alto de todas las configuraciones es el de Qwen3-14B zero-shot (0,7999). En Llama el mejor pipeline zero-shot (0,7459) y el fine-tuning completo (0,7481) están prácticamente empatados. En Salamandra el mejor resultado es LoRA combinado con un prompt few-shot enriquecido.
Alucinación en campos anulables
Tasas sobre las 505 oportunidades de campos anulables del conjunto de desarrollo, con el prompt baseline simple (sin ejemplos few-shot ni posprocesado).
| Modelo | Tasa de null-trap sin entrenar | Mejor variante entrenada |
|---|---|---|
| Qwen3-14B | 14,65 % | 12,08 % (fine-tuning completo; LoRA 12,48 %) |
| Salamandra-7B | 24,55 % | 7,33 % (fine-tuning completo; LoRA 14,26 %) |
| Llama-3.2-3B | 25,15 % | 6,34 % (LoRA; fine-tuning completo 12,67 %) |
La tasa bajó en todos los modelos con el entrenamiento. Todas las tasas se midieron con el prompt baseline simple, no con los mejores pipelines.
Búsqueda de LoRA
La búsqueda convergió en la misma configuración para los tres modelos: rango 64, alpha 128, dropout 0,10, learning rate 5e-5. Pasar del rango 64 al 128 redujo el eval-loss como máximo en 0,003 mientras la brecha entre entrenamiento y evaluación seguía creciendo. El in-context tuning dio el menor eval-loss en todos los modelos:
| Modelo | Eval-loss con prompt por defecto | Eval-loss con in-context tuning |
|---|---|---|
| Qwen3-14B | 0,5698 | 0,3569 |
| Salamandra-7B | 0,5078 | 0,3829 |
| Llama-3.2-3B | 0,671 | 0,4248 |
Bajo el capó
Cómo se trazan de principio a fin el entrenamiento y la inferencia: MLflow para los entrenamientos y Langfuse para la inferencia.
GenSIE_Llama3.2-3B_Phase1- lora_r / alpha / dropout
- 64 / 128 / 0.1
- learning_rate
- 5e-05
- scheduler
- cosine
- epochs · early stopping
- 6 · True
- batch × grad. accum.
- 1 × 8
- max_length
- 4096
- duración
- 46 min
OpenAI-generationgensie.eval.task- tokens de salida
- 75
- claves gold
- 10
- tokens de prompt
- 1243
- claves del sistema
- 8
- tokens totales
- 1318
- TPS (puntuación de aciertos)
- 8
Exportado en solo lectura y saneado: sin prompts, salidas, rutas ni claves.
Lo que aprendí
El entrenamiento parece ayudar menos cuanto mejor es el pipeline de inferencia, y aporta más a la contención que al F1 bruto.
Interpretación de los resultados. Se apoya en tres modelos, una tarea y ejecuciones de una sola semilla, así que cada afirmación se formula con cautela.
El fine-tuning parece ayudar menos cuanto mejor es el pipeline
En Qwen3-14B el mejor pipeline zero-shot (0,7999) supera tanto a LoRA como al fine-tuning completo. En Llama los dos están prácticamente empatados. Solo en Salamandra, el modelo más débil sin entrenar, LoRA suma algo sobre el mejor pipeline de prompting. La comparación tiene un límite: los modelos entrenados Qwen y Llama no se evaluaron con los pipelines más ricos, así que no está probado si el entrenamiento aporta algo sobre ellos. Una lectura plausible es que el fine-tuning enseña al modelo un comportamiento de manejo de esquemas que las capas de posprocesado y los ejemplos recuperados ya aportan en inferencia: cuando esas capas faltan, el entrenamiento compensa; cuando están, tiene menos que añadir.
El entrenamiento importa en otro eje: la alucinación
El F1 global oculta un efecto consistente. Con el prompt baseline simple, la tasa de null-trap bajó en todos los modelos con el entrenamiento, con fuerza en Salamandra y Llama y solo ligeramente en Qwen. Esto sugiere que, frente a un modelo sin entrenar con el mismo prompt, el entrenamiento hace al modelo más dispuesto a abstenerse. No demuestra que el entrenamiento supere al mejor pipeline de prompting en este eje: en el análisis de origen, un pipeline bien diseñado sigue siendo competitivo con LoRA en anclaje a la fuente.
El óptimo fue estable entre tamaños de modelo
La misma configuración de LoRA (rango 64, alpha 128, dropout 0,10) resultó la mejor para los modelos de 3B, 7B y 14B, y el in-context tuning ayudó a los tres. Junto con la ganancia plana entre el rango 64 y el 128, esto parece indicar que la dificultad de la tarea reside en razonar sobre el esquema, y que las palancas que actúan sobre ese razonamiento se comportan de forma parecida en este rango de tamaños.
Lo que no funcionó
La ejecución E229 añadió una segunda pasada dirigida del LLM para las 34 tareas de desarrollo con objetos anidados, sobre E226 con Llama-3.2-3B. El subconjunto objetivo mejoró en 0,0037, pero el F1 global bajó de 0,7459 a 0,7432 y el coste estimado creció hasta unas 1,23 veces el de E226. Además, 20 de las 115 tareas sin objetos anidados cambiaron entre dos ejecuciones de una primera pasada sin modificar, lo que apunta a no determinismo en el stack de serving y no al método. La rama se descartó.
Límites
- Tres modelos, una tarea, ejecuciones de una sola semilla: la interpretación no es una prueba entre familias de modelos.
- El pipeline más rico desborda la ventana de contexto de 8k de Salamandra en 14 de las 149 tareas de desarrollo, así que su mejor pipeline reportado es uno más ligero.
- El corpus sintético está dominado por texto de dominio general derivado de Wikipedia, así que la transferencia a dominios especializados no se prueba aquí.
Reproducibilidad
Dónde está el código y cómo se traza cada cifra del sitio hasta un fichero.
El trabajo se reparte en dos repositorios, más el repositorio de este sitio. Los repositorios son privados por ahora, así que aquí solo se nombran, sin enlaces; se enlazarán cuando se abran. El artículo publicado está enlazado en la página de Reconocimiento.
| Repositorio | Contenido |
|---|---|
gensie-solution |
La solución de la competición: baselines, variantes de prompting, agentes few-shot, decodificación restringida por gramática, posprocesado, registro de experimentos y ficheros de resultados |
gensie-dataset |
El pipeline de datos sintéticos, el código de LoRA y de fine-tuning completo, los scripts SLURM para MareNostrum 5 y los scripts de evaluación |
gensie-portfolio |
El código fuente de este sitio |
El repositorio de la solución partió del starter kit oficial de GenSIE, de donde proceden la descripción de la tarea, la métrica y los formatos de datos.
Cómo se trazan las cifras de este sitio
Cada cifra del código fuente en markdown de este sitio va precedida de un comentario HTML <!-- source: ... --> con el fichero del que se leyó. Las cifras citan ficheros de las copias de trabajo del autor de estos repositorios; los artefactos generados de gran tamaño, como el dataset sintético, no están todos subidos, y algunas notas de análisis viven fuera de main. Una batería de tests del repositorio del sitio hace fallar la compilación si una métrica decimal o un porcentaje no tiene comentario de fuente, si un enlace apunta a algo distinto de la rama main o si la estructura o las cifras difieren entre los dos idiomas. También comprueba que los ficheros fuente citados existen cuando se ejecuta en una máquina que tiene los repositorios del proyecto.
Tecnologías
Solo herramientas usadas en los dos repositorios del proyecto.
Entrenamiento y fine-tuning
- PyTorch, Hugging Face Transformers, PEFT y TRL para LoRA y fine-tuning supervisado (
SFTTrainer). - Fully Sharded Data Parallel para el fine-tuning completo de los modelos más grandes.
- Trabajos SLURM en el supercomputador MareNostrum 5 (NVIDIA H100).
Inferencia y salida estructurada
- vLLM para servir los modelos base y los afinados.
- Outlines y xgrammar para la decodificación JSON restringida por gramática.
- Pydantic y jsonschema para el manejo de esquemas y la validación de salidas.
Recuperación y evaluación
- Sentence-Transformers (MiniLM multilingüe) para la recuperación few-shot por similitud de esquema, además de una variante TF-IDF.
- fastembed, rapidfuzz y scikit-learn para la métrica Flattened Schema Scoring y los scripts de análisis.
- Variantes de agentes para chain-of-thought, descomposición de esquema, autocorrección y posprocesado multiagente.
Seguimiento de experimentos
- MLflow y Langfuse para el seguimiento y el trazado de ejecuciones, con un servidor MLflow autoalojado que se ejecuta con Docker Compose.
Generación de datos
- Un pipeline de datos sintéticos de cinco etapas adaptado de GuideX, con validación mediante
jsonschemay llamadas a LLM a través de una API compatible con OpenAI.
La recuperación en este proyecto es una selección few-shot aumentada por recuperación sobre una biblioteca de ejemplos sintéticos; no usa una base de datos vectorial.