Inicio
» Dominios
»
Cómo automatizar la extracción de datos de PDF utilizando modelos de IA locales sin una API en la nube
Cómo automatizar la extracción de datos de PDF utilizando modelos de IA locales sin una API en la nube
El flujo de trabajo de extracción de PDF local más fiable suele ser un pipeline, no un único prompt de IA: primero recupera texto y diseño fiables del PDF, luego pide a un modelo local que mapee ese contenido a un esquema estricto y, finalmente, valida los campos antes de guardarlos. Enviar cada página de PDF directamente a un modelo de visión puede funcionar, pero a menudo es más lento, consume más recursos de hardware y es más difícil de auditar que usar texto nativo de PDF u OCR cuando estos son suficientes.
Esta distinción es importante si tu objetivo es “sin API en la nube”. Aún puedes usar una API local en tu propia máquina, por ejemplo, el endpoint HTTP de Ollama en localhost, sin enviar el contenido de los documentos a un servicio alojado. Ollama afirma que los prompts y las respuestas no se envían de vuelta a Ollama cuando los modelos se ejecutan localmente, y proporciona un modo solo local que desactiva las funciones en la nube. Docling también mantiene los servicios remotos deshabilitados por defecto, aunque los archivos de modelos aún pueden necesitar ser descargados durante la configuración a menos que los obtengas previamente para uso sin conexión.
El stack adecuado depende del PDF. Las facturas digitales nativas con texto seleccionable requieren un enfoque diferente al de los recibos escaneados, las tablas financieras complicadas o los formularios con muchas imágenes. Esta guía compara esas opciones y ofrece un patrón de automatización de cuatro etapas que puedes adaptar a facturas, contratos, órdenes de compra, formularios de solicitud, informes y otros documentos recurrentes.
Recomendación rápida: elige el pipeline según el tipo de documento
Tipo de PDF
Pipeline local práctico
Ventaja principal
Compensación principal
PDF digital nativo con texto seleccionable limpio
PyMuPDF → LLM de texto local → validación JSON
Rápido y relativamente ligero en hardware
La extracción simple puede perder el orden de lectura o las relaciones de tabla
PDF escaneado con páginas simples
OCRmyPDF/Tesseract → PyMuPDF → LLM de texto local
Convierte imágenes de página en texto buscable antes de la extracción con IA
Los errores de OCR se convierten en errores de entrada del modelo
PDF mixto con texto, escaneos y tablas
Docling o OCRmyPDF en modo skip/redo → LLM local
Mejor control sobre contenido mixto y estructura del documento
Más dependencias y tiempo de procesamiento
Formularios con mucho diseño, tablas, diagramas o páginas visualmente significativas
Pipeline local de Docling o modelo de visión local → salida estructurada
Preserva más contexto visual/de diseño
Generalmente requiere más cómputo y una validación más robusta
No hay un ganador universal. Si tus documentos son predecibles y contienen texto incrustado, un analizador más un pequeño modelo de lenguaje local puede superar a un flujo de trabajo de visión mucho más grande en costo, velocidad y reproducibilidad. Si la posición del texto es parte del significado, por ejemplo, una tabla con celdas combinadas o un formulario donde las etiquetas y los valores están emparejados espacialmente, el procesamiento consciente del diseño se vuelve más valioso.
Paso 1: Clasifica el PDF antes de elegir OCR o IA
Comienza determinando si el documento ya contiene texto utilizable. Digital nativo significa que el PDF fue generado desde software y generalmente contiene objetos de texto que se pueden seleccionar y copiar. Un PDF escaneado puede contener solo imágenes de página, por lo que un analizador de texto normal devuelve poco o nada.
La documentación oficial de PyMuPDF muestra la extracción directa de texto con page.get_text(). Una prueba local mínima se ve así:
import pymupdf
def extract_native_text(pdf_path: str) -> str:
pages = []
with pymupdf.open(pdf_path) as doc:
for page in doc:
pages.append(page.get_text())
return "\f".join(pages)
text = extract_native_text("invoice.pdf")
print(text[:1000])
Consulta los conceptos básicos oficiales de PyMuPDF. PyMuPDF también advierte que el texto plano de PDF puede no aparecer en el orden natural de lectura y puede contener saltos de línea inesperados. Esa es una limitación del analizador, no necesariamente un problema de IA.
Mejor ajuste: facturas, extractos, informes y formularios donde la copia/pegado de texto ya funciona y los campos son fáciles de identificar a partir de etiquetas cercanas.
Cuidado con: una página puede contener una capa de texto muy pequeña más una gran imagen escaneada. Por lo tanto, simplemente comprobar si “existe algo de texto” no es un detector de escaneo perfecto. Para la automatización en producción, inspecciona documentos representativos en lugar de depender de un umbral universal de conteo de caracteres.
Acción: toma 20–50 PDFs representativos y clasifícalos en grupos de digital nativo, escaneado, mixto y con mucho diseño. Tu pipeline debe enrutar según el comportamiento del documento, no solo según la extensión del archivo.
Ilustración generada por IA de la etapa de entrada de PDF. Es una imagen conceptual del flujo de trabajo, no una captura de pantalla de una aplicación específica de PDF o un resultado de benchmark.
Paso 2: Extrae texto localmente, o usa OCR solo cuando lo necesites
Opción A: PyMuPDF para PDFs digitales limpios
Si la capa de texto es fiable, la extracción directa es normalmente la ruta más simple. Evita la latencia del OCR y evita introducir errores de caracteres de OCR en texto que ya estaba codificado correctamente. Para documentos largos, puedes preservar los separadores de página y procesar grupos de páginas o secciones lógicas en lugar de pasar todo el documento al modelo a la vez.
Compensación: el texto plano es barato y rápido, pero las tablas, las páginas de varias columnas, los encabezados, los pies de página y el orden de lectura pueden necesitar un manejo adicional. Si esas relaciones importan para los campos objetivo, pasa a una representación consciente del diseño en lugar de amontonar instrucciones de prompt sobre texto fuente pobre.
Opción B: OCRmyPDF más Tesseract para páginas escaneadas
Tesseract es un motor OCR de código abierto. Su manual de usuario actual documenta la serie 5.x y el soporte para muchos idiomas a través de archivos de datos entrenados separados. OCRmyPDF envuelve el OCR alrededor del procesamiento específico de PDF para que las páginas escaneadas puedan ganar una capa de texto buscable.
Para un documento mixto donde algunas páginas ya contienen texto, las versiones actuales de OCRmyPDF soportan un modo skip:
ocrmypdf --mode skip input.pdf searchable.pdf
La documentación avanzada oficial de OCRmyPDF explica que --mode skip deja en paz las páginas con texto existente y aplica OCR a las páginas que lo necesitan. La misma documentación describe redo para reemplazar el OCR previo detectado y force para rasterizar y aplicar OCR a todo el contenido. Usa force con precaución porque la rasterización puede descartar ventajas vectoriales y aplanar contenido interactivo.
Para la instalación de Tesseract, idiomas y comportamiento de línea de comandos, usa el manual de usuario oficial de Tesseract. El idioma del OCR importa: si tus facturas contienen inglés y alemán, por ejemplo, instala y configura los datos de idioma apropiados en lugar de asumir que el modelo de inglés predeterminado manejará ambos igualmente bien.
Opción C: Docling cuando la estructura importa
Docling está diseñado para la conversión de documentos con opciones de diseño, tablas, OCR y procesamiento local de visión-lenguaje. Su documentación de proyecto enumera la comprensión avanzada de PDF, la estructura de tablas, el OCR y las salidas sin pérdida estilo JSON/Markdown, con ejecución local destinada a flujos de trabajo sensibles y aislados (air-gapped).
Una conversión básica en Python puede ser tan pequeña como:
Consulta la guía de inicio rápido oficial de Docling. Docling también soporta pipelines VLM locales y varios backends de OCR. Sus opciones avanzadas explican que las llamadas a servicios remotos requieren una opt-in explícita, mientras que los artefactos de modelos pueden obtenerse previamente para uso sin conexión.
Mejor ajuste: tablas complejas, encabezados, informes de varias columnas, escaneos mixtos o casos donde quieras una representación de documento reutilizable en lugar de un volcado de texto plano.
Compensación: el pipeline es más pesado que un simple analizador de PDF. Úsalo porque la estructura adicional mejora tu precisión de extracción, no simplemente porque tenga más componentes.
Acción: elige el método de extracción más ligero que preserve la información que necesita tu esquema objetivo. No apliques OCR a texto incrustado limpio, y no descartes el diseño cuando el diseño determina el significado.
Ilustración generada por IA de elegir OCR para escaneos y extracción directa para PDFs digitales nativos. Representa el concepto de decisión en lugar de una interfaz real de aplicación de OCR.
Paso 3: Mapea el contenido recuperado a un esquema estricto con un modelo local
Una vez que tengas contenido fuente fiable, usa el modelo local para lo que es bueno: el mapeo semántico. En lugar de preguntar, “Extrae todo de esta factura”, define los campos que realmente necesitas.
Por ejemplo:
from pydantic import BaseModel
from typing import Optional
class LineItem(BaseModel):
description: str
quantity: Optional[float]
unit_price: Optional[float]
amount: Optional[float]
class Invoice(BaseModel):
invoice_number: Optional[str]
invoice_date: Optional[str]
vendor_name: Optional[str]
currency: Optional[str]
subtotal: Optional[float]
tax: Optional[float]
total: Optional[float]
items: list[LineItem]
La documentación actual de salidas estructuradas de Ollama soporta pasar un JSON Schema a través del campo format y validar la respuesta con Pydantic. Una llamada local puede verse así:
from ollama import chat
schema = Invoice.model_json_schema()
prompt = f"""
Extract the invoice into the supplied schema.
Rules:
- Use only information present in the source.
- Use null when a field is not found.
- Do not infer missing invoice numbers, dates, tax, or totals.
- Preserve line items individually.
SOURCE:
{text}
"""
response = chat(
model="gpt-oss",
messages=[{"role": "user", "content": prompt}],
format=schema,
options={"temperature": 0},
)
invoice = Invoice.model_validate_json(response.message.content)
El nombre del modelo anterior es un ejemplo de la propia documentación de salidas estructuradas de Ollama, no una afirmación de que sea el mejor modelo para cada trabajo de extracción. Un modelo más pequeño puede ser adecuado para facturas repetitivas con etiquetas claras; un modelo más fuerte puede ayudar con contratos ambiguos o diseños inconsistentes, pero generalmente requerirá más memoria y tiempo de procesamiento.
¿Modelo de texto o modelo de visión?
Usa un modelo de texto cuando la salida del analizador/OCR ya preserva las relaciones de campo que necesitas. Usa un modelo local con capacidad de visión cuando la posición visual es esencial o la conversión de texto pierde estructura consistentemente. La documentación oficial de Visión de Ollama soporta entradas de imagen para modelos de visión locales, y su función de salida estructurada puede combinarse con modelos con capacidad de visión.
Sin embargo, renderizar cada página a una imagen cambia la compensación:
se deben procesar más píxeles;
las páginas de alta resolución consumen más cómputo y memoria;
la agrupación de páginas se vuelve importante para PDFs largos;
los modelos visuales aún pueden inventar un campo o leer mal un número;
necesitas una forma de rastrear los valores extraídos hasta una página o región fuente.
Acción: comienza con texto de analizador/OCR más un LLM local restringido por esquema. Escala solo los tipos de página difíciles a un VLM local en lugar de pagar el costo de visión por cada página.
Ilustración generada por IA de la etapa de modelo local. No representa una pantalla real de Ollama ni implica que un modelo local pueda extraer cada campo sin validación.
Paso 4: Valida antes de escribir JSON, CSV, Excel o una base de datos
Un JSON válido según el esquema no es automáticamente correcto factualmente. Un modelo puede producir campos válidos con valores incorrectos. La última etapa debe usar por lo tanto comprobaciones deterministas donde sea posible.
Para una factura, las comprobaciones útiles incluyen:
Campos de identidad requeridos: el número de factura o el nombre del proveedor deben estar presentes si tu flujo de trabajo los necesita.
Análisis de fechas: analiza las fechas con una política fija en lugar de confiar en cadenas ambiguas como 03/04/26.
Aritmética: compara la suma de los importes de las líneas con el subtotal del documento dentro de una tolerancia definida.
Totales: verifica si el subtotal más impuestos y otros cargos es consistente con el total.
Moneda: no asumas USD porque el documento esté en inglés.
Procedencia: almacena el nombre del archivo fuente, el número de página, la marca de tiempo de extracción y opcionalmente un hash del PDF original.
Cola de revisión: enruta los casos faltantes, conflictivos o de baja confianza para revisión humana en lugar de rellenar valores silenciosamente.
Una estructura básica de lote puede separar la extracción de la validación:
from pathlib import Path
import json
for pdf_path in Path("inbox").glob("*.pdf"):
source_text = extract_native_text(str(pdf_path))
# If text is unusable, run your OCR or Docling branch here.
record = extract_with_local_model(source_text)
errors = validate_record(record)
if errors:
save_for_review(pdf_path, record, errors)
else:
output = Path("processed") / f"{pdf_path.stem}.json"
output.write_text(
json.dumps(record, ensure_ascii=False, indent=2),
encoding="utf-8"
)
Las funciones auxiliares se dejan intencionalmente específicas de la aplicación porque las reglas de validación difieren dramáticamente entre facturas, contratos, formularios de impuestos, informes de laboratorio y órdenes de compra. Un validador universal crearía una falsa confianza.
Si necesitas CSV o Excel, aplana solo los campos que realmente pertenecen a filas y columnas. Para documentos con líneas de detalle repetidas, a menudo es más limpio crear una tabla a nivel de documento y una segunda tabla de líneas de detalle vinculadas por un ID de documento en lugar de forzar cada campo en una fila de hoja de cálculo ancha.
Acción: define las reglas de validación antes de procesar miles de archivos. Prueba contra un conjunto de muestra etiquetado y registra la precisión a nivel de campo, no solo “documentos procesados con éxito”.
Ilustración generada por IA de objetivos de exportación locales como Excel, CSV y JSON. Es un punto final conceptual, no evidencia de que cada PDF pueda convertirse sin revisión.
Una arquitectura totalmente local práctica
Para muchos trabajos de automatización pequeños y medianos, esta división de responsabilidades es más fácil de mantener que un modelo todo-en-uno:
Este diseño te permite intercambiar componentes independientemente. Si la calidad del OCR es débil, mejora la capa de OCR sin reentrenar el LLM. Si el modelo local es demasiado lento, usa uno más pequeño sin cambiar el analizador de PDF. Si las facturas de un proveedor necesitan un manejo especial de tablas, enruta solo esos archivos a través de Docling o una rama de visión.
Ollama vs. llama.cpp vs. Docling VLM: ¿qué runtime local debes elegir?
Opción
Úsalo cuando
Fortaleza
Compensación
Ollama
Quieres la API de modelo local más fácil y salida restringida por esquema
API simple de localhost, JSON estructurado, soporte de visión para modelos compatibles
La abstracción te da menos control de runtime de bajo nivel que un motor de inferencia puro
llama.cpp
Quieres control directo de GGUF, despliegue por línea de comandos o un servidor local ligero
CLI/servidor local y generación restringida por gramática/esquema JSON
Más detalles de modelo/runtime son tu responsabilidad
Docling VLM
Tu principal desafío es la conversión de diseño de documentos en lugar de extracción general estilo chat
Pipeline VLM local enfocado en documentos con salidas estilo Markdown/HTML/DocTags
Mejor pensado como un componente de conversión de documentos, no un reemplazo para cada paso de extracción de reglas de negocio
No selecciones un runtime basándote solo en una tabla de clasificación de modelos. Para la extracción de PDF, las medidas prácticas son la precisión de campo, el rendimiento por documento, el uso de memoria en tu máquina, la tasa de fallos en tus diseños, la complejidad de inicio y qué tan fácilmente puedes inspeccionar resultados incorrectos.
Cómo mantener el pipeline genuinamente local
“Sin API en la nube” debe ser una propiedad de despliegue que puedas verificar, no solo una etiqueta de marketing.
Ollama
La FAQ oficial de Ollama dice que los prompts y respuestas locales no se envían de vuelta a Ollama. También documenta una configuración para deshabilitar la nube:
OLLAMA_NO_CLOUD=1
o la configuración de servidor equivalente disable_ollama_cloud. La API local de Ollama se ejecuta en http://localhost:11434 y no requiere autenticación para el acceso local, según su documentación de autenticación.
Recuerda que un servicio vinculado a localhost es diferente de uno expuesto a tu LAN. Si cambias su dirección de vinculación o lo colocas detrás de otro servidor, eres responsable del control de acceso.
Docling
Docling mantiene el uso de servicios remotos deshabilitado por defecto. Su documentación también distingue la privacidad de procesamiento de la adquisición de modelos: los modelos pueden obtenerse en el primer uso a menos que los descargues previamente. Para un sistema aislado (air-gapped), usa docling-tools models download en una máquina de preparación conectada o pre-ubica artefactos de modelos aprobados de otra manera, luego apunta al entorno sin conexión a ese directorio de artefactos local.
Acción: antes de procesar documentos sensibles, bloquea el acceso de red saliente en la capa de sistema operativo o de red y ejecuta una prueba mientras monitoreas las conexiones. La configuración de la aplicación es útil, pero los controles de red te dan una capa de verificación independiente.
Lo que la IA local no resuelve
Ejecutar localmente mejora las opciones de control de datos, pero no hace automáticamente que la extracción sea correcta, cumpla normativas o sea segura. Los archivos locales aún pueden filtrarse a través de registros de depuración, directorios temporales, copias de seguridad, carpetas compartidas, servicios demasiado permisivos o exportaciones copiadas. Un modelo local también puede alucinar valores exactamente como un modelo alojado.
No uses el modelo como el único verificador para campos de alto impacto como números de cuentas bancarias, instrucciones de pago, fechas de contrato, valores médicos o identificadores regulatorios. Para esos, compara contra el texto fuente, aplica validación determinista y requiere revisión humana cuando la confianza sea insuficiente.
Cómo probar antes de automatizar una carpeta completa
Construye un pequeño conjunto de evaluación etiquetado que contenga los casos que realmente recibes:
PDF digital limpio;
escaneo de baja resolución;
página rotada o sesgada;
factura de múltiples páginas;
tabla que abarca páginas;
campos opcionales faltantes;
diferentes formatos de fecha y número;
al menos un documento deliberadamente difícil.
Para cada campo objetivo, compara el valor extraído con la verdad fundamental (ground truth). Mide la coincidencia exacta para identificadores, tolerancia numérica para importes y precisión a nivel de fila para líneas de detalle. También registra el tiempo de procesamiento y el porcentaje de documentos enviados a revisión manual.
Si una ruta más simple de PyMuPDF más LLM alcanza tu precisión requerida, mantenla. Si los escaneos son el principal fallo, mejora el OCR. Si las relaciones de tabla son el problema, prueba Docling. Si los campos posicionados visualmente siguen siendo difíciles, enruta ese subconjunto a través de un modelo de visión local. Esta escalada por etapas generalmente te da mejor control sobre la velocidad y el uso de hardware que aplicar el modelo más pesado a cada página.
Conclusión
Un buen sistema local de extracción de PDF separa la lectura de documentos de la extracción semántica. Usa PyMuPDF cuando el PDF ya contiene buen texto; OCRmyPDF/Tesseract cuando la página está escaneada; Docling cuando la estructura y las tablas importan; y un modelo local Ollama o llama.cpp cuando necesitas un mapeo flexible a un esquema de negocio. Usa visión local solo donde el diseño visual añade información que el pipeline de texto no puede preservar de manera fiable.
El requisito final es la validación. JSON Schema puede restringir la forma de una respuesta del modelo, pero no puede probar que el importe, la fecha, el nombre o el número de cuenta coincidan con la fuente. Si diseñas el pipeline para que los documentos inciertos sean visibles y revisables, puedes automatizar una gran fracción de la extracción de datos de PDF sin entregar los documentos a una API en la nube, y sin fingir que la IA local elimina la necesidad de control de calidad.