- Extraer texto de archivos PDF es mucho más difícil de lo que parece, y el PDF es en esencia un formato de archivo basado en gráficos
- Dentro del PDF solo existe información de posición de glifos y casi no hay señales semánticas, por lo que identificar y reconstruir el texto es complicado
- Los motores de búsqueda requieren entradas limpias en formato HTML, pero las herramientas open source existentes tienen limitaciones para extraer información estructural como títulos o párrafos
- El enfoque visual basado en machine learning es el más preciso, pero tiene dificultades para aplicarse a gran escala por temas de recursos y rendimiento
- Entre las principales mejoras está la incorporación de algoritmos de identificación de títulos y párrafos basados en tamaño de fuente y estadísticas para aumentar la precisión de la extracción
El desafío de extraer texto de un PDF
- Los motores de búsqueda modernos ya cuentan con capacidad para indexar el formato de archivo PDF
- Extraer información de un PDF no es un problema sencillo, porque el PDF originalmente no es un formato de texto sino un formato gráfico
- En lugar de texto real, hay glifos colocados en coordenadas, lo que provoca rotaciones, superposiciones, desorden en el orden y ausencia de información semántica
- La información como texto que normalmente imaginamos no existe directamente dentro del archivo
- Que en un visor de PDF se pueda buscar texto con
ctrl+f es, en realidad, algo sorprendente
Lo que exigen los motores de búsqueda y los límites del enfoque básico
- La entrada que más prefieren los motores de búsqueda es HTML limpio
- Los modelos modernos de visión por computadora basados en machine learning muestran el mejor rendimiento, pero
- procesar archivos PDF de gran volumen (cientos de GB) en un solo servidor sin GPU es ineficiente
- Por suerte, este campo no es territorio completamente desconocido, así que
- se puede usar como punto de partida la clase PDFTextStripper de PDFBox
- pero casi no logra identificar estructura semántica como títulos: solo extrae cadenas de texto
Algoritmo de identificación de títulos
Principio básico para identificar títulos
- Normalmente se puede aprovechar que los títulos suelen estar aislados en tipografía semibold o más gruesa
- también son comunes los títulos sin negritas, así que este método por sí solo tiene límites
- En muchos casos, el tamaño de fuente sirve como criterio para distinguir títulos
- pero el tamaño de fuente varía totalmente entre documentos, por lo que no se puede usar un umbral global
Uso de estadísticas del tamaño de fuente
- En cada página suele existir un tamaño de fuente dominante (cuerpo del texto)
- La página 1 (portada) tiene contenido descriptivo e información de autor, por lo que su distribución de tamaños de fuente es distinta
- Como la distribución del tamaño de fuente cambia por página, es más efectivo usar estadísticas por página y no de todo el documento
- Aplicando un aumento de alrededor de 20% sobre el tamaño de fuente mediano de cada página, es posible identificar títulos con bastante precisión
El problema de unir títulos de varias líneas
- Por razones de estilo, un título puede dividirse en varias líneas
- no es sencillo decidir cuándo unir un título, y puede haber mezcla de títulos de dos o más líneas, nombres de autor o texto destacado aparte
- Regla de unión:
- funciona bastante bien combinar líneas consecutivas con el mismo tamaño de fuente y grosor
- pero hay muchas excepciones: unir sin criterio puede producir resultados equivocados
Mejoras en la identificación de párrafos
- PDFTextStripper identifica párrafos con base en espaciado entre líneas y sangría
- como usa un umbral fijo para separar líneas, tiene limitaciones cuando cada documento aplica espaciados distintos
- sobre todo en borradores de papers o preprints, también es común ver interlineado de 1.5 a 2 veces
- Si el umbral es demasiado grande, aparece el error de incluir el título dentro del cuerpo del texto
Separación de párrafos basada en estadísticas
- Igual que con el tamaño de fuente, también se puede aplicar procesamiento estadístico al espaciado entre líneas
- usando la mediana de la distancia entre líneas, se puede lograr una separación de párrafos robusta sin importar el interlineado
Conclusión
- Extraer texto de un PDF es, en el fondo, algo que inevitablemente nunca será perfecto
- porque el propio formato PDF no fue diseñado para ese propósito
- En una implementación real, hacer concesiones es indispensable, y es importante una estrategia para obtener un resultado “lo suficientemente bueno”
- Para los motores de búsqueda, es más eficiente centrarse en extraer señales significativas como títulos, resúmenes y pistas estructurales importantes
Texto de muestra de referencia
- Can Education be Standardized? Evidence from Kenya (2022) - Working Paper
: Guthrie Gray-Lobe, Anthony Keats, Michael Kremer, Isaac Mbiti, Owen W. Ozier
- The theory of ideas and Plato’s philosophy of mathematics (2019)
: Dembiński, B.
- The role of phronesis in Knowledge-Based Economy (2024)
: Anna Ceglarska, Cymbranowicz Katarzyna
1 comentarios
Opiniones de Hacker News
A veces uno cree haber encontrado algo nuevo e interesante en la vida y de pronto le vuelve vagamente el recuerdo de que antes ya se había vuelto experto en eso durante meses o años. Incluso parece que hasta los momentos en que hizo cosas muy geniales desaparecieron de la cabeza, y termina sintiendo que está empezando otra vez desde cero. Tengo un recuerdo borroso de haber hecho algo impresionante con PDF y OCR hace unos 6 o 7 años. Busqué en Google y el nombre “tesseract” me sonó familiar
Por 2006 me frustraba que en el iRex, un e-reader temprano que se podía hackear, no se pudiera copiar texto de artículos científicos en varias columnas. En ese tiempo el visor PDF usaba poppler, así que modifiqué poppler para inferir el orden de lectura en documentos multicolumna. Para eso me guié por el algoritmo de OCR de Thomas Breuel, autor de tesseract. Era una especie de hack heurístico y no encajaba bien con la API de accesibilidad. Se introdujo una función de selección multicolumna, pero costó convencer a los mantenedores. De todos modos, así fue como kpdf obtuvo la selección multicolumna. Hoy me parece mucho más razonable usar tesseract directamente para este tipo de cosas
No hay forma de recuperar las decenas de años de tiempo humano desperdiciadas por culpa del formato PDF. Me pregunto cuándo terminará esta locura
Durante un tiempo, Tesseract fue el mejor OCR open source. Pero hoy creo que docTR es superior en precisión y aceleración por GPU. docTR tiene una arquitectura de pipeline que permite combinar distintos modelos de detección y reconocimiento de texto. También se puede entrenar y ajustar en PyTorch o TensorFlow, así que puede rendir mucho mejor en dominios específicos
Así es la vida. Cada vez que termino un proyecto pienso: “Ahora sí soy experto en este tema. Pero probablemente nunca vuelva a hacer esto”. Porque la siguiente vez toca empezar desde cero con un tema completamente nuevo
Hace poco alguien me preguntó sobre C++ y dije que “nunca había trabajado seriamente con eso”. Luego recordé tarde que hace unos 20 años escribí el código cliente de un mensajero instantáneo privado hecho con Borland C++, y lo usaban miles de personas. Esto me pasa seguido
No puedo saber exactamente qué hay en tu cabeza, pero sí, probablemente de verdad era tesseract. A mí me pasó algo parecido, en mi caso hace como 12 años
Cuando HQ estaba de moda, hice un resolvedor automático de trivia de HQ con tesseract. Le tomaba captura de pantalla a la pregunta en la app, la mandaba a una API pequeña, luego buscaba el texto de la pregunta en Google y contaba cuántas veces aparecía cada respuesta para rankearlas por probabilidad. No era muy preciso y era bastante simple, pero fue muy divertido hacerlo
No es muy distinto de una hormiga de fuego que, si el viento se lleva una hoja, simplemente busca otra
Si fue hace 7 u 8 años y estabas en tus 20, todavía debería ser un recuerdo bastante fresco. Me pregunto si hay una diferencia de edad considerable. Si no, también te recomendaría hacerte un chequeo médico
Me gustaría que existiera una herramienta como las devtools del navegador (“inspeccionar elemento”) para ver a nivel de código el content stream de un PDF —el
BT…ETque rodea el texto, los operadores que definen fuentes y coordenadas, etc.— y poder compararlo y analizarlo lado a lado con el resultado renderizado. Es distinto del flujo actual donde los modelos de visión procesan el PDF “viéndolo”, pero lo que quiero es entender a fondo qué información contiene realmente un PDF por dentro. Existen algunas herramientas, pero solo muestran hasta el nivel de objetos y no profundizan dentro del content stream. Quisiera un entorno donde se pueda comparar y analizar, como en HTML, el source real del stream de un PDF de ejemplo junto con el renderizado para ver qué parte se expresa de qué maneraCreo que si renderizas el PDF al DOM usando Mozilla PDF.js, puedes conseguir una experiencia bastante parecida. Por ejemplo, operadores como Tj o TJ se convierten en
<span>o en conjuntos de ellos. Supongo que es porque necesitan mantenerse fieles al documento originalRecomiendo probar la herramienta cpdf (la hice yo). Con las opciones
-output-jsony-output-json-parse-content-streamsde cpdf puedes convertir un PDF a JSON y hacer toda clase de experimentos. También se puede volver de JSON a PDF. Eso sí, no ofrece interacción en tiempo realParece que buscas una herramienta gratis u open source, pero cuando usaba Acrobat Pro hace años ofrecía algo casi igual. Aunque en vez de inspeccionar la página, recorría el árbol de contenido, y solo mostraba hasta objetos/streams, no hasta comandos individuales
“Esa combinación entre ‘ver el PDF como lo haría una persona con un modelo de visión’ y ‘saber qué datos contiene realmente el PDF’ es lo que estamos construyendo en Tensorlake (trabajo ahí). No solo leemos texto: entendemos de verdad tablas, imágenes, fórmulas, escritura a mano, etc., para extraer datos en Markdown/JSON y aplicarlos a apps de AI, LLM y similares” https://tensorlake.ai
No llega exactamente al nivel que quieres, pero te recomiendo revisar este notebook, que ofrece un inspector para ver ‘en vivo’ varias operaciones de dibujo dentro de un PDF https://observablehq.com/@player1537/pdf-utilities
Pasé años en Apple enfocado en este problema. La clave es aceptar que “todo es geometría” y usar un algoritmo que diferencie el espaciado entre palabras y el espaciado entre caracteres mediante clustering. Funciona bien en la mayoría de los PDF, pero cuando uno mira de cerca hay tanta variedad que algunos terminan siendo decepcionantes. Si lo hiciera otra vez hoy, quitaría por completo el OCR y seguiría un enfoque basado en información geométrica, pero incorporando machine learning. Si generas PDF a partir de texto conocido y los usas para aprendizaje automático, incluso puedes automatizar la construcción del dataset. (Hay un video de una charla de Bertrand Serlet en WWDC 2009)
No es un solo problema de ‘PDF to Text’; en realidad lo dividiría en 3 categorías: (1) OCR confiable (para búsqueda, ingreso a vector DB, etc.), (2) extracción de datos estructurados (sacar solo ciertos valores), (3) automatización del pipeline documental completo (por ejemplo, automatización de hipotecas). Marginalia apunta a (1), y hoy, gracias a Gemini Flash y similares, el OCR se ha vuelto barato y más generalista. Pero (2) y (3) son más difíciles, y la automatización completa todavía requiere mucho trabajo humano: construcción de datasets, diseño del pipeline, detección de incertidumbre e intervención manual, fine-tuning, etc. El futuro va por ahí. (Dirijo una empresa de procesamiento de documentos con LLM) https://extend.ai
Yo añadiría una (4): OCR confiable y extracción semántica en documentos de muchas formas distintas, es decir, soluciones para accesibilidad. Esto es difícil porque, a diferencia de un workflow normal, no puedes predecir qué tipo de documento traerá el usuario; además de texto hay que extraer tablas, headers/footers/anotaciones/fórmulas y otros elementos; se exige minimizar errores, así que no se puede usar OCR más de lo necesario; puede haber discrepancias entre el texto embebido y lo realmente renderizado (texto oculto o combinaciones no estándar, etc.); suele correr en apps locales, así que es difícil aprovechar servidores; y también hace falta soporte de Forms para documentos pensados para imprimir. No existe hoy una solución que resuelva por completo todo eso
Aunque se diga que los VLM simplificaron el pipeline de OCR, ojo: en documentos realmente complejos sigue siendo muy difícil. Son excelentes para etiquetas simples en imágenes, y sirven en documentos muy sencillos, pero en documentos con tablas, headers, resúmenes y demás alucinan muchísimo. En la práctica, casi no sirven
He estado viviendo varios de esos problemas al convertir a Markdown, incluida la detección de headers y similares. El OCR de hoy es excelente, pero preservar la estructura completa del documento es mucho más difícil. Estoy logrando resultados más o menos decentes pasando varias veces por un LLM para extraer estructura e inyectando contexto por página
Una mejor solución sería adjuntar dentro del PDF el documento fuente editable. Con LibreOffice se puede hacer fácilmente. Por lo general no ocupa mucho espacio adicional y permite conocer con claridad el significado del texto. Además sigue siendo usable con lectores PDF existentes
Cuando el problema es extraer texto de PDF ya existentes, me pregunto qué ayuda real aporta aconsejar cómo deberían crearse los PDF. No sé en qué momento este tipo de solución empezará a tener efecto de verdad
Es cierto, pero entonces aparece el riesgo de que el documento fuente y el PDF renderizado tengan contenidos completamente distintos
Estoy de acuerdo, pero solo sirve si están alineados los intereses de quien crea el PDF y de quien lo consume. En e-Discovery, es común que el abogado de la contraparte entregue material convertido a PDF a propósito para dificultar su uso. Como resultado, los defensores públicos con menos recursos terminan invirtiendo más tiempo en procesarlo y sufren una desventaja real. Para evitarlo, creo que habría que exigir por ley que ciertos datos se entreguen en formatos estándar legibles por máquina
Si tienes acceso al documento fuente, adjuntarlo dentro del PDF es una excelente idea. El problema es que en la mayoría de los casos no tienes ese control
La mayoría de los problemas reales vienen de PDF legacy. En mi empresa también tenemos miles acumulados, y algunos son escaneos horribles. Algunos traen OCR embebido de Adobe, pero la mayoría ni siquiera eso
El PDF de abajo en realidad es un archivo
.txt. Puedes cambiarle la extensión a.pdfy abrirlo en un visor PDF, o editarlo directamente con un editor de texto para controlar lo que aparecerá en pantalla, la fuente, el tamaño de fuente, el interlineado, la cantidad de caracteres por página, el número de líneas, el tamaño del papel y muchas otras cosas. (Incluye un ejemplo de texto PDF hecho a mano)Un PDF también puede incluir streams binarios. PDF no es un formato de texto, sino un formato hecho para layout y gráficos. Como en el ejemplo, cada línea puede aparecer de una sola vez, pero en la práctica también puede representarse carácter por carácter, palabra por palabra o incluso en desorden
PDF significa “Portable Document Format”. Está codificado como un archivo ASCII de 7 bits, lo que le da una gran portabilidad entre distintos dispositivos y sistemas operativos. (Referencia: enlace a documentación oficial de Adobe)
Este ejemplo es el ‘Hello World’ de los PDF. Los PDF modernos normalmente comprimen los objetos (
obj) con deflate y además los agrupan dentro de streams, así que todo se vuelve más complicado. Por eso es muy difícil analizarlos simplemente buscando texto como "6 0 Obj"Extraer texto de un PDF, especialmente texto estructurado, no es nada fácil. De una tabla HTML normalmente puedes extraer datos con relativa facilidad, pero en un PDF algo solo “parece” tabla por las coordenadas renderizadas; en realidad el texto y los gráficos están dispersos. Yo lo hago convirtiendo el PDF a HTML con Poppler PDF utils, luego busco los headers de la tabla y uso la coordenada x de cada valor para determinar la columna y extraer los datos por fila. Se ve tosco, pero me da resultados más confiables que trabajar con txt alineado
Me frustraba no poder extraer datos de PDF como se hace con una web y BeautifulSoup, así que hice yo mismo una librería con esa interfaz. (Ejemplo estilo
page.find) Cada PDF es un infierno de casos especiales, así que estoy juntando know-how de extracción y ejemplos de PDF monstruosos dentro de la librería https://jsoma.github.io/natural-pdf/ , https://badpdfs.com/Algún día quiero extraer datos tabulares desde PDF hacia mi software de procesamiento de datos. Si alguien conoce una librería gratis o muy barata que pueda integrar con una app en C++, avise
Hay documentos (por ejemplo, de organismos públicos) en los que el texto visible para imprimir y el texto que realmente se extrae son completamente distintos. Este tipo de caso aparece seguido
PDF es esencialmente un formato de markup/XML. Un mismo PDF puede construirse de muchísimas maneras. Si lo exportas desde una herramienta gráfica, obtienes un PDF con mezcla de gráficos y texto; si lo exportas desde un procesador de texto, sale un PDF más centrado en texto. La app que lo produce influye muchísimo en cómo queda la salida PDF. Entre las utilidades off-the-shelf, varias familias de productos como cisdem sirven hasta cierto punto para sacar datos estructurados. Pero al final necesitas la herramienta adecuada para cada trabajo
Uno de mis casos favoritos es este PDF de un artículo académico (con enlace). En la primera página tiene el típico texto en dos columnas, un header en el centro, texto que se mete entre ambas columnas y elementos que cambian la longitud de línea y la sangría. Los headers de página también cambian entre páginas pares e impares, y las reglas para los headers de sección no son uniformes. Los párrafos tampoco siempre llevan sangría y el espaciado entre líneas varía. Es un compendio de muchos problemas distintos
Cuando hice mi propio parser sencillo de PDF, me sorprendió la manera en que está hecho el formato. Desde entonces siempre me ha parecido raro que se use tanto para cosas centradas en texto. Por ejemplo, para una factura, un sistema digital debería poder extraer los datos con facilidad y al mismo tiempo presentar un formato cómodo para humanos. Me gustaría que el mundo técnico migrara poco a poco a formatos mejores
Extraer ‘información útil’ de PDF es justamente el trabajo de Tensorlake (https://tensorlake.ai). Un PDF no contiene solo texto, sino también tablas, imágenes, fórmulas, escritura a mano, tachados y más; como desarrolladores, no basta con “leer” texto, también tenemos que “entenderlo”. (Aclara que trabaja ahí)