Extraer tablas de documentos con modelos open-weight en local: la teoría y qué funcionó de verdad
Nota para el equipo
Sale del proyecto de Disproquima, donde extraje una tabla de un PDF (con categorías, subcategorías y celdas combinadas) usando mi visión multimodal. La pregunta era qué modelo open-weight —pesos abiertos, ejecutable en local— replica esa tarea. Primero está la comparativa teórica; luego, las pruebas reales en local (MacBook Air M5, 16 GB, Ollama), que corrigen la recomendación de libro.
Esto NO sustituye la ingesta de Mentat
Son dos problemas distintos, no confundirlos:
- Ingesta de Mentat (ver Arquitectura de Mentat): convierte documentos a texto plano y lo trocea en chunks para la BD vectorial (Qdrant), que alimentan a los agentes conversacionales. Ahí interesa el texto independientemente del formato, y el pipeline actual (OCR + conversión a texto) hace justo eso. No hay nada que arreglar.
- Este artículo: extraer información concreta y estructurada tal cual está en el original —facturas → campos, tablas de un certificado para recomponerlo— donde la disposición (qué columna, qué celda combinada, qué total) es la información y hay que preservarla. Un pipeline de "todo a texto plano" la destruiría.
Regla rápida: si el destino son chunks para chatear sobre el contenido → ingesta de Mentat. Si el destino es un dato/tabla estructurada fiel al original → lo de aquí.
TL;DR
El salto importante no es de "peor OCR" a "mejor OCR": es pasar de modelos que leen caracteres a modelos que entienden el documento (qué es tabla, qué es texto, en qué orden va). Para tareas tipo Disproquima eso es imprescindible. Pero al bajar a local con Ollama, la teoría se topó con dos bugs y el ganador no fue el que decía el papel.
Decisión por caso de uso
- Facturas → campos estructurados (JSON):
Qwen2.5-VL-7B. Una GPU, cuantizable, le pasas el esquema en el prompt y devuelve JSON. - Certificados con tablas + fórmulas para recomponer:
Marker(MinerU/Datalab), que exporta a Markdown/HTML/DOCX/JSON con la estructura reconstruida. - Tabla suelta en local con Ollama:
qwen2.5vl:7bsobre PNG (no PDF). Fue el único que funcionó de forma fiable en las pruebas.
Dos trampas de Ollama que descubrimos probando
- El PDF no llega como imagen. La web de Ollama extrae el texto plano del PDF en vez de rasterizar la página, así que el modelo de visión nunca "ve" la tabla. Hay que convertir a PNG antes de subir.
qwen3-vl:8bdevuelvecontentvacío. Es un modelo de razonamiento y, por un bug de Ollama, consume todo el presupuesto de tokens en la trazathinkingsin llegar a la respuesta.qwen2.5vl:7bno razona y no sufre esto.
El caso: una tabla dentro de un PDF
En Disproquima se compartió un PDF con una tabla de datos técnicos: varias columnas y filas, con agrupaciones mediante celdas combinadas (categorías y subcategorías). La petición fue simple de enunciar: extraer esa tabla.
Lo resolví con mi capacidad nativa de lectura de PDF: leí el documento, interpreté la
estructura visual (columnas, agrupaciones, celdas combinadas) y reconstruí los datos en un
.xlsx, replicando las agrupaciones con celdas combinadas y aplicando formato (fuente,
bordes, encabezados).
Ese proceso —lectura visual + comprensión del layout + reconstrucción estructurada— es exactamente lo que hace un VLM especializado en documentos. De ahí la pregunta que motiva el resto del artículo: ¿qué modelo open-weight replica esto en local?
VLM (Vision-Language Model)
Modelo que combina visión e idioma: no solo transcribe el texto de una imagen, sino que entiende su disposición (qué bloque es una tabla, cuál un encabezado, en qué orden se lee) y puede responder preguntas o devolver un esquema sobre el contenido. Un OCR clásico solo hace lo primero.
Leer caracteres vs entender el documento
| Modelo | Tipo | Puntos fuertes | Limitaciones |
|---|---|---|---|
Tesseract |
OCR clásico basado en reglas | Rápido para texto plano simple, muy liviano | Sin comprensión de layout, tablas o estructura; requiere post-procesado manual |
GOT-OCR 2.0 (StepFun) |
OCR neuronal puro, 580M parámetros | Texto formateado, fórmulas matemáticas y tablas; corre en GPU de consumo (~4–8,5 GB VRAM) | Pierde precisión en layouts muy complejos frente a pipelines dedicados |
MinerU / Marker |
Pipeline (layout + OCR + orden de lectura) | El más fuerte en extracción de tablas y documentos estructurados; exporta a Markdown/HTML/DOCX/JSON | Más pesado, requiere encadenar varios modelos |
Qwen2.5-VL / Qwen3-VL (Alibaba) |
VLM generalista (7B–72B) | OCR + comprensión de layout + preguntas sobre el contenido; permite pedir un esquema JSON directamente | Modelo más grande, necesita más recursos que un OCR especializado |
DeepSeek-OCR |
VLM con compresión óptica de contexto | Eficiente en documentos largos; layout, tablas, fórmulas, +100 idiomas | Modelo más reciente, ecosistema de herramientas menos maduro |
Granite-Docling-258M (IBM) |
VLM compacto | OCR, layout, tablas, código y ecuaciones en solo 258M parámetros | Menor capacidad en documentos muy heterogéneos |
La línea divisoria: Tesseract "lee caracteres"; los modelos modernos (GOT-OCR2, MinerU,
Qwen2.5-VL, DeepSeek-OCR) "entienden el documento". Para una tabla como la de Disproquima
—donde el significado está en la disposición, no solo en el texto— entender el layout no
es opcional.
\"Lee caracteres\" no es un defecto: depende del objetivo
Que Tesseract solo transcriba texto es una limitación para este problema
(estructura fiel), no en general. Cuando lo único que quieres es el texto para
trocearlo en chunks —el caso de la ingesta de Mentat— un OCR a texto plano es
exactamente lo adecuado y más barato. El layout solo estorba cuando lo que buscas es
el texto, y hace falta cuando lo que buscas es el dato estructurado.
Caso concreto: extraer campos de facturas
Necesidad: sacar campos estructurados (proveedor, número de factura, fecha, líneas de producto, totales) de facturas, en local.
Recomendación: Qwen2.5-VL-7B (o Qwen3-VL-8B)
- Corre en una sola GPU local, incluso cuantizado (Ollama, vLLM).
- Le pasas el esquema en el prompt (
vendor,invoice_number,date,line_items,subtotal,tax,total) y devuelve JSON estructurado, sin pipeline adicional. - Maneja bien las relaciones espaciales entre etiquetas y valores, algo que un OCR puro no infiere.
| Opción | Recursos | Precisión en layouts variables | Salida | Cuándo usarla |
|---|---|---|---|---|
Qwen2.5-VL-7B / Qwen3-VL-8B |
1 GPU, cuantizable | Alta | JSON con esquema definido | Punto de partida; buen balance precisión/recursos |
Qwen2.5-VL-72B / DeepSeek-VL2 |
GPU grande | Muy alta | JSON | Facturas escaneadas de baja calidad o formatos muy heterogéneos |
PaddleOCR (PP-OCRv4) + reglas/LLM pequeño |
CPU | Media (depende de las reglas) | Texto + campos vía reglas | Volumen muy alto, presupuesto ajustado |
invoice2data |
CPU, sin GPU | Baja fuera de la plantilla | Campos vía regex/plantilla | Proveedor único con formato fijo |
Caso concreto: certificados (texto + tablas + fórmulas) para recomponer un documento
Necesidad: extraer el contenido de un certificado —texto, tablas y fórmulas— preservando la estructura completa para reconstruirlo en un certificado nuevo.
Recomendación: Marker (MinerU/Datalab)
- Convierte el documento directamente a Markdown, HTML, JSON o DOCX, con tablas, formularios y ecuaciones ya reconstruidas: el formato ideal para recomponer.
- Flag opcional
--use_llmpara mejorar la fidelidad de tablas y formularios complejos. - Corre localmente; admite PDF, imágenes, DOCX, XLSX y PPTX como entrada.
Flujo sugerido
Marker para extraer el contenido estructurado (tablas y fórmulas intactas) → usar
ese Markdown/JSON como base para generar el nuevo certificado. Si además hay que
decidir qué campos cambiar (no solo copiarlos), añade un VLM generalista
(Qwen2.5-VL / Qwen3-VL) encima.
| Opción | Recursos | Fidelidad tablas/fórmulas | Salida | Cuándo usarla |
|---|---|---|---|---|
Marker (MinerU/Datalab) |
GPU local, pipeline de varios modelos | Muy alta | Markdown, HTML, DOCX, JSON | Recomendado; salida ya lista para recomponer |
DeepSeek-OCR |
GPU, eficiente en documentos largos | Alta | Markdown, HTML de tablas, JSON | Certificados extensos o con mucho texto |
Qwen2.5-VL / Qwen3-VL |
1 GPU (7B–8B) o más | Alta | Texto libre, JSON a medida | Cuando además hay que razonar qué campos cambiar |
Granite-Docling-258M |
Muy bajo (258M) | Media | DocTags | Recursos muy limitados |
Lo que pasó al probarlo en local (MacBook Air M5, 16 GB, Ollama)
La teoría apuntaba a Qwen3-VL como evolución recomendada. Al bajarlo a local —interfaz web de Ollama, mismo PDF con tabla como caso de prueba— el resultado fue otro:
| Modelo | Entrada | Resultado |
|---|---|---|
granite3.2-vision (IBM) |
No extrae nada | |
granite3.2-vision (IBM) |
PNG | No extrae nada |
qwen3-vl:8b |
No reconoce la tabla | |
qwen3-vl:8b |
PNG | Reconoce la tabla visualmente, pero no devuelve respuesta |
qwen2.5vl:7b |
No reconoce la tabla | |
qwen2.5vl:7b |
PNG | Funciona: respuesta rápida y precisa |
Tres hallazgos, en orden de importancia:
El PDF nunca llega como imagen. El fallo con PDF es constante en todos los modelos. La causa no es el modelo: la web de Ollama extrae el texto plano del PDF en lugar de convertir la página a imagen, así que el modelo de visión no llega a "ver" la tabla. La solución es rasterizar el PDF a PNG antes de subirlo (o automatizarlo, más abajo).
qwen3-vl:8b sí ve la tabla, pero responde en vacío. Reconoce la tabla en el PNG, pero
no muestra respuesta.
\"Thinking\" (razonamiento) en Ollama
Algunos modelos generan primero una traza de razonamiento interno y luego la respuesta.
Ollama las separa en dos campos: thinking (la traza) y content (la respuesta
final). qwen3-vl es de estos; qwen2.5vl no.
El motivo del vacío es un bug conocido de Ollama: el parámetro para desactivar el
razonamiento (think: false) no se aplica bien a qwen3-vl, de modo que todo el
presupuesto de tokens se consume en la traza thinking y el campo content queda vacío.
qwen2.5vl:7b no razona, así que responde directo. Al no tener fase de thinking,
escribe la respuesta en content sin ese problema y, además, fue notablemente más rápido.
granite3.2-vision no funcionó en ningún escenario, ni con PDF ni con PNG. Coincide
con fallos ya documentados en el repositorio de Ollama al procesar imágenes con este
modelo.
Workaround: PDF multipágina y el vacío de Qwen3-VL
Convertir a mano cada página a PNG vale para un documento suelto, no para PDFs de varias
páginas. Se automatiza con un paquete que gestione el pipeline completo (PDF → imagen por
página → modelo de visión → resultado combinado), como ollama-ocr. La técnica es
genérica: sirve para qwen2.5vl, qwen3-vl y cualquier modelo de visión de Ollama,
porque el paquete solo rasteriza cada página y la manda al modelo indicado.
from ollama_ocr import OCRProcessor
ocr = OCRProcessor(model_name='qwen2.5vl:7b') # o 'qwen3-vl:8b'
result = ocr.process_image(
image_path="documento.pdf", # acepta PDF multipágina directamente
format_type="table",
custom_prompt="Extrae todas las tablas de cada página, respetando filas y columnas."
)
print(result)
Con qwen3-vl el vacío puede persistir también aquí
El bug de thinking afecta igual a este flujo: content puede seguir llegando vacío
si el paquete no gestiona el campo thinking o no reserva presupuesto de tokens para
la respuesta tras el razonamiento. Opciones, de menos a más recomendable:
- Subir mucho el límite de tokens de salida (
num_predict) para dejar margen al razonamiento y a la respuesta. - Parsear también el campo
thinkingde la API, porque ahí puede estar el contenido extraído aunquecontentvenga vacío. - Lo más simple y lo que recomendamos: usar
qwen2.5vl:7ben vez deqwen3-vl:8b. No razona, no sufre el bug y en las pruebas fue más rápido e igual de preciso.
Qué nos llevamos
- La recomendación de libro no sobrevivió al hardware. En el papel, Qwen3-VL era la
evolución a elegir; en local con Ollama,
qwen2.5vl:7bganó porqueqwen3-vl:8bdevuelvecontentvacío por un bug dethinking. Probar en local no es un trámite: es donde se decide. - Antes de culpar al modelo, mira el pipeline. El fallo con PDF era de todos los modelos porque Ollama pasaba texto plano, no imagen. Un síntoma común a todos los modelos casi nunca es de los modelos.
- El razonamiento tiene coste oculto. Un modelo "thinking" puede gastarse el presupuesto de tokens en la traza y dejar la respuesta vacía. Para extracción pura, un modelo sin razonamiento es más simple y más rápido.
- Elige por "entender" vs "leer" y por caso de uso. Con estructura (tablas, layout),
VLM o pipeline, no OCR clásico. Facturas →
Qwen2.5-VL-7B(JSON con esquema); certificados a recomponer →Marker.
Anexo: cómo reproducirlo (la receta)
- Rasteriza el PDF a PNG. No subas el PDF a Ollama esperando que el VLM lo "vea": la
web extrae texto plano. Convierte cada página a PNG, o usa
ollama-ocrpara automatizarlo en PDFs multipágina. - Usa
qwen2.5vl:7bpara extraer tablas en local. Punto de partida: rápido, preciso y sin el bug dethinking. Reservaqwen3-vl:8bsolo si necesitas su razonamiento y estás dispuesto a lidiar connum_predict/ el campothinking. - Si
contentviene vacío, mirathinking. Es la firma del bug de Ollama con modelos de razonamiento: el contenido puede estar en la traza, o hace falta másnum_predict. - Descarta
granite3.2-visionpara imágenes mientras persistan los fallos documentados en Ollama. - Valida con documentos reales del cliente (los peores escaneos incluidos) antes de fijar el modelo: la precisión "en layouts variables" solo se comprueba con tus propios documentos.
Referencias
- Best Open-Weight OCR and Document AI Models 2026 – Presenc AI
- Multimodal AI: The Best Open-Source Vision Language Models in 2026 – BentoML
- DeepSeek-OCR vs Existing OCR Systems: 2025 Comparison & Guide – Skywork
- PaddleOCR vs Tesseract vs EasyOCR: OCR Speed and Accuracy 2026 – CodeSOTA
- Best OCR Models in 2026 – GIGAGPU
- Best Open-Source OCR and Document VLMs to Self-Host on GPU Cloud in 2026 – Spheron
- Open Source OCR for Invoice Extraction: Developer Comparison
- Open-Source Invoice & Receipt Extraction with LLMs – Maxime Champoux
- Kill Your OCR Pipeline – Klaus Hofenbitzer, Towards AI
- Structured PDF-to-JSON: A Guide to Open-Source Extraction Models in 2026 – MarkTechPost
- Best Open Source OCR Tools & Models for Developers in 2026 – Unstract
- TexOCR: Advancing Document OCR Models for Compilable Page-to-LaTeX Reconstruction
- qwen3-vl – Ollama Library
- ollama-ocr – PyPI
- Ollama-OCR – GitHub
- Thinking – Ollama Docs
- qwen3-vl:8b missing thinking toggle template – GitHub Issue #14798
- Qwen3VLRenderer/Parser ignores think API parameter – GitHub Issue #13353
- granite3.2-vision no corre al usar comprensión de imágenes – GitHub Issue #10161
- Granite 3.2 Vision and Chat History – GitHub Issue #10235