¿Por qué seguimos luchando con documentos en 2025?
En cualquier organización basada en datos, y encontrará una gran cantidad de PDF, archivos de palabras, PowerPoints, imágenes a medias, notas escritas a mano y el CSV sorpresa ocasional al acecho en una carpeta de SharePoint. Los analistas de negocios y datos desperdician horas convirtiendo, dividiendo y engatusando esos formatos en algo que sus tuberías de Python aceptarán. Incluso las últimas pilas generativas de AI pueden ahogarse cuando el texto subyacente se envuelve dentro de los gráficos o se rocía a través de cuadrículas de mesa irregulares.
Docling nació para resolver exactamente ese dolor. Lanzado como un proyecto de código abierto por IBM Research Zurich y ahora alojado bajo la Fundación Linux AI & Data Foundation, la Biblioteca abstracta el análisis, la comprensión de diseño, el OCR, la reconstrucción de la tabla, la exportación multimodal e incluso la transcripción de audio detrás de un comando API y CLI razonablemente directo.
Aunque DoCling admite el procesamiento de HTML, los archivos de formato de MS Office, formatos de imagen y otros, veremos principalmente usarlo para procesar los archivos PDF.
Como científico de datos o ingeniero de ML, ¿por qué debería preocuparme por Docling?
A menudo, el verdadero cuello de botella no está construyendo el modelo, lo está alimentando. Pasamos un gran porcentaje de nuestro tiempo en la disputa de datos, y nada mata la productividad más rápido que recibir un conjunto de datos crítico bloqueado dentro de un PDF de 100 páginas. Este es precisamente el problema que el DoCling resuelve, actuando como un puente desde el mundo de los documentos no estructurados directamente a la cordura estructurada de Markdown, JSON o un Pandas DataFrame.
Pero su poder se extiende más allá de la extracción de datos, directamente en el área del desarrollo moderno y asistido por AI. Imagínese apuntando alojado en una página HTML de especificaciones API; Traduce sin esfuerzo ese diseño web complejo en una reducción limpia y estructurada, el contexto perfecto para alimentarse directamente en asistentes de codificación de IA como cursor, chatgpt o claude.
De donde vino
El proyecto se originó en el equipo de búsqueda profunda de IBM, que estaba desarrollando tuberías de generación de recuperación (RAG) de generación (RAG) para largos PDF de patentes. De origen abierto el núcleo bajo una licencia del MIT a fines de 2024 y han estado enviando lanzamientos semanales desde entonces. Una comunidad vibrante se formó rápidamente alrededor de su unificado Documento Modelo, un objeto pydantic que mantiene texto, imágenes, tablas, fórmulas y metadatos de diseño juntos para que las herramientas aguas abajo como Langchain, Llamaindex o Haystack no tengan que adivinar el orden de lectura de una página.
Hoy, DoCling integra modelos de idioma visual (VLMS), como Smoldocling, Para el subtítulo de figuras. También es compatible con Tesseract, Easyocr y Rapidocr para la extracción de texto y las recetas de naves para fragmentos, serialización e ingestión de tiendas vectoriales. En otras palabras: lo señala en una carpeta, y obtienes Markdown, HTML, CSV, PNGS, JSON o simplemente un objeto Python listo para inclinar, no se requiere código de andamio adicional.
Que haremos
Para mostrar el contenido, primero lo instalaremos y luego lo usaremos con tres ejemplos diferentes que demuestran su versatilidad y utilidad como un analizador y procesador de documentos. Tenga en cuenta que el uso de catalografías es bastante intensivo computacionalmente, por lo que será útil si tiene acceso a una GPU en su sistema.
Sin embargo, antes de comenzar a codificar, necesitamos configurar un entorno de desarrollo.
Configurar un entorno de desarrollo
He comenzado a usar el Administrador de paquetes UV para esto ahora, pero no dude en usar las herramientas con las que se sienta más cómodo. Tenga en cuenta también que trabajaré en WSL2 Ubuntu para Windows y ejecutar mi código usando un cuaderno Jupyter.
Tenga en cuenta que incluso usando UV, el siguiente código tardó un par de minutos en completarse en mi sistema, ya que es un conjunto bastante considerable de instalaciones de biblioteca.
$ uv init docling
Initialized project `docling` at `/home/tom/docling`
$ cd docling
$ uv venv
Using CPython 3.11.10 interpreter at: /home/tom/miniconda3/bin/python
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
$ source .venv/bin/activate
(docling) $ uv pip install docling pandas jupyter
Ahora escriba el comando,
(docling) $ jupyter notebook
Y debería ver un cuaderno abierto en su navegador. Si eso no sucede automáticamente, es probable que vea una pantalla de información después de ejecutar el Cuaderno de jupyter dominio. Cerca de la parte inferior, encontrará una URL para copiar y pegar en su navegador para iniciar el cuaderno Jupyter.
Su URL será diferente a la mía, pero debería verse algo así:-
http://127.0.0.1:8888/tree?token=3b9f7bd07b6966b41b68e2350721b2d0b6f388d248cc69d
Ejemplo 1: Convierta cualquier PDF o DOCX a Markdown o JSON
El caso de uso más simple también es el que utilizará un gran porcentaje de la hora:- Convierta el texto de un documento en Markdown
Para la mayoría de nuestros ejemplos, nuestro PDF de entrada será uno que he usado varias veces antes para diferentes pruebas. Es una copia del documento de presentación de 10-Q de Tesla desde septiembre de 2023. Tiene aproximadamente cincuenta páginas y consiste principalmente en información financiera relacionada con Tesla. El documento completo está disponible públicamente en el sitio web de la Comisión de Valores y Valores (SEC) y se puede ver/descargar utilizando este enlace.
Aquí hay una imagen de la primera página de ese documento para su referencia.
Revisemos el código de contenido que necesitamos convertir en Markdown. Establece la ruta del archivo para el PDF de entrada, ejecuta la función de Converver de documentos y luego exporta el resultado analizado en el formato de Markdown para que el contenido se pueda leer, editar o analizar más fácilmente.
from docling.document_converter import DocumentConverter
import time
from pathlib import Path
inpath = "/mnt/d//tesla"
infile = "tesla_q10_sept_23.pdf"
data_folder = Path(inpath)
doc_path = data_folder / infile
converter = DocumentConverter()
result = converter.convert(doc_path) # → DoclingResult
# Markdown export still works
markdown_text = result.document.export_to_markdown()
Esta es la salida que obtenemos al ejecutar el código anterior (solo la primera página).
## UNITED STATES SECURITIES AND EXCHANGE COMMISSION
Washington, D.C. 20549 FORM 10-Q
(Mark One)
- x QUARTERLY REPORT PURSUANT TO SECTION 13 OR 15(d) OF THE SECURITIES EXCHANGE ACT OF 1934
For the quarterly period ended September 30, 2023
OR
- o TRANSITION REPORT PURSUANT TO SECTION 13 OR 15(d) OF THE SECURITIES EXCHANGE ACT OF 1934
For the transition period from \_\_\_\_\_\_\_\_\_ to \_\_\_\_\_\_\_\_\_
Commission File Number: 001-34756
## Tesla, Inc.
(Exact name of registrant as specified in its charter)
Delaware
(State or other jurisdiction of incorporation or organization)
1 Tesla Road Austin, Texas
(Address of principal executive offices)
## (512) 516-8177
(Registrant's telephone number, including area code)
## Securities registered pursuant to Section 12(b) of the Act:
| Title of each class | Trading Symbol(s) | Name of each exchange on which registered |
|-----------------------|---------------------|---------------------------------------------|
| Common stock | TSLA | The Nasdaq Global Select Market |
Indicate by check mark whether the registrant (1) has filed all reports required to be filed by Section 13 or 15(d) of the Securities Exchange Act of 1934 ('Exchange Act') during the preceding 12 months (or for such shorter period that the registrant was required to file such reports), and (2) has been subject to such filing requirements for the past 90 days. Yes x No o
Indicate by check mark whether the registrant has submitted electronically every Interactive Data File required to be submitted pursuant to Rule 405 of Regulation S-T (§232.405 of this chapter) during the preceding 12 months (or for such shorter period that the registrant was required to submit such files). Yes x No o
Indicate by check mark whether the registrant is a large accelerated filer, an accelerated filer, a non-accelerated filer, a smaller reporting company, or an emerging growth company. See the definitions of 'large accelerated filer,' 'accelerated filer,' 'smaller reporting company' and 'emerging growth company' in Rule 12b-2 of the Exchange Act:
Large accelerated filer
x
Accelerated filer
Non-accelerated filer
o
Smaller reporting company
Emerging growth company
o
If an emerging growth company, indicate by check mark if the registrant has elected not to use the extended transition period for complying with any new or revised financial accounting standards provided pursuant to Section 13(a) of the Exchange Act. o
Indicate by check mark whether the registrant is a shell company (as defined in Rule 12b-2 of the Exchange Act). Yes o No x
As of October 16, 2023, there were 3,178,921,391 shares of the registrant's common stock outstanding.
Con el aumento de los editores de código de IA y el uso de LLM en general, esta técnica se ha vuelto significativamente más valiosa y relevante. La eficacia de LLM y editores de código puede mejorarse significativamente proporcionándoles un contexto apropiado. A menudo, esto implicará proporcionarles la representación textual de una herramienta o ejemplos de documentación, API y codificación de una herramienta o marco en particular.
La conversión de la salida del formato PDF a JSON también es sencillo. Simplemente agregue estas dos líneas de código. Puede encontrar limitaciones con el tamaño de la salida JSON, así que ajuste la instrucción de impresión en consecuencia.
json_blob = result.document.model_dump_json(indent=2)
print(json_blob[10000], "…")
Ejemplo 2: Extraer tablas complejas de un PDF
Muchos PDF a menudo almacenan tablas como trozos de texto aislados o, peor aún, como imágenes aplanadas. El modelo de estructura de tabla de DoCling vuelve a ensamblar filas, columnas y células que abarcan, lo que le brinda un marco de datos PANDAS o un CSV listo para salvar. Nuestro PDF de entrada de prueba tiene muchas tablas. Mira, por ejemplo, en la página 11 del PDF, y podemos ver la tabla a continuación,
Veamos si podemos extraer esos datos. Es un código un poco más complejo que en nuestro primer ejemplo, pero está haciendo más trabajo. El PDF se convierte nuevamente utilizando la función DocumentConverter de DoCling, produciendo una representación de documentos estructurada. Luego, para cada tabla detectada, transforma la tabla en un marco de datos Pandas y también recupera el número de página de la tabla de los metadatos de procedencia del documento. Si la tabla proviene de la página 11, la imprime en formato de Markdown y luego rompe el bucle (por lo que solo se muestra la primera tabla coincidente).
import pandas as pd
from docling.document_converter import DocumentConverter
from time import time
from pathlib import Path
inpath = "/mnt/d//tesla"
infile = "tesla_q10_sept_23.pdf"
data_folder = Path(inpath)
input_doc_path = data_folder / infile
doc_converter = DocumentConverter()
start_time = time()
conv_res = doc_converter.convert(input_doc_path)
# Export table from page 11
for table_ix, table in enumerate(conv_res.document.tables):
page_number = table.prov[0].page_no if table.prov else "Unknown"
if page_number == 11:
table_df: pd.DataFrame = table.export_to_dataframe()
print(f"## Table {table_ix} (Page {page_number})")
print(table_df.to_markdown())
break
end_time = time() - start_time
print(f"Document converted and tables exported in {end_time:.2f} seconds.")
Y la salida no es demasiado mal.
## Table 10 (Page 11)
| | | Three Months Ended September 30,.2023 | Three Months Ended September 30,.2022 | Nine Months Ended September 30,.2023 | Nine Months Ended September 30,.2022 |
|---:|:---------------------------------------|:----------------------------------------|:----------------------------------------|:---------------------------------------|:---------------------------------------|
| 0 | Automotive sales | $ 18,582 | $ 17,785 | $ 57,879 | $ 46,969 |
| 1 | Automotive regulatory credits | 554 | 286 | 1,357 | 1,309 |
| 2 | Energy generation and storage sales | 1,416 | 966 | 4,188 | 2,186 |
| 3 | Services and other | 2,166 | 1,645 | 6,153 | 4,390 |
| 4 | Total revenues from sales and services | 22,718 | 20,682 | 69,577 | 54,854 |
| 5 | Automotive leasing | 489 | 621 | 1,620 | 1,877 |
| 6 | Energy generation and storage leasing | 143 | 151 | 409 | 413 |
| 7 | Total revenues | $ 23,350 | $ 21,454 | $ 71,606 | $ 57,144 |
Document converted and tables exported in 33.43 seconds.
Para recuperar todas las tablas de un PDF, necesitaría omitir el Si page_number = … línea desde mi código.
Una cosa que he notado con el contalmonado es que no es rápido. Como se muestra arriba, tardó casi 34 segundos en extraer esa tabla individual de un PDF de 50 páginas.
Ejemplo 3: Realice OCR en una imagen.
Para este ejemplo, escaneé una página aleatoria del Tesla 10-Q PDF y la guardé como un archivo PNG. Veamos cómo elaborado hace frente a leer esa imagen y convertir lo que encuentra en Markdown. Aquí está mi imagen escaneada.
Y nuestro código. Usamos Tesseract como nuestro motor OCR (otros están disponibles)
from pathlib import Path
import time
import pandas as pd
from docling.document_converter import DocumentConverter, ImageFormatOption
from docling.models.tesseract_ocr_cli_model import TesseractCliOcrOptions
def main():
inpath = "/mnt/d//tesla"
infile = "10q-image.png"
input_doc_path = Path(inpath) / infile
# Configure OCR for image input
image_options = ImageFormatOption(
ocr_options=TesseractCliOcrOptions(force_full_page_ocr=True),
do_table_structure=True,
table_structure_options={"do_cell_matching": True},
)
converter = DocumentConverter(
format_options={"image": image_options}
)
start_time = time.time()
conv_res = converter.convert(input_doc_path).document
# Print all tables as Markdown
for table_ix, table in enumerate(conv_res.tables):
table_df: pd.DataFrame = table.export_to_dataframe(doc=conv_res)
page_number = table.prov[0].page_no if table.prov else "Unknown"
print(f"\n--- Table {table_ix+1} (Page {page_number}) ---")
print(table_df.to_markdown(index=False))
# Print full document text as Markdown
print("\n--- Full Document (Markdown) ---")
print(conv_res.export_to_markdown())
elapsed = time.time() - start_time
print(f"\nProcessing completed in {elapsed:.2f} seconds")
if __name__ == "__main__":
main()
Aquí está nuestro resultado.
--- Table 1 (Page 1) ---
| | Three Months Ended September J0,. | Three Months Ended September J0,.2022 | Nine Months Ended September J0,.2023 | Nine Months Ended September J0,.2022 |
|:-------------------------|------------------------------------:|:----------------------------------------|:---------------------------------------|:---------------------------------------|
| Cost ol revenves | 181 | 150 | 554 | 424 |
| Research an0 developrent | 189 | 124 | 491 | 389 |
| | 95 | | 2B3 | 328 |
| Total | 465 | 362 | 1,328 | 1,141 |
--- Full Document (Markdown) ---
## Note 8 Equity Incentive Plans
## Other Pertormance-Based Grants
("RSUs") und stock optlons unrecognized stock-based compensatian
## Summary Stock-Based Compensation Information
| | Three Months Ended September J0, | Three Months Ended September J0, | Nine Months Ended September J0, | Nine Months Ended September J0, |
|--------------------------|------------------------------------|------------------------------------|-----------------------------------|-----------------------------------|
| | | 2022 | 2023 | 2022 |
| Cost ol revenves | 181 | 150 | 554 | 424 |
| Research an0 developrent | 189 | 124 | 491 | 389 |
| | 95 | | 2B3 | 328 |
| Total | 465 | 362 | 1,328 | 1,141 |
## Note 9 Commitments and Contingencies
## Operating Lease Arrangements In Buffalo, New York and Shanghai, China
## Legal Proceedings
Between september 1 which 2021 pald has
Processing completed in 7.64 seconds
Si compara esta salida con la imagen original, los resultados son decepcionantes. Gran parte del texto en la imagen fue perdido o confuso. Aquí es donde un producto como AWS Textract entra en sí, ya que sobresale en extraer texto de una amplia gama de fuentes.
Sin embargo, DoCling proporciona varias opciones para OCR, por lo que si recibe malos resultados de un sistema, siempre puede cambiar a otro.
Intenté la misma tarea usando Easyocr, pero los resultados no fueron significativamente diferentes de los obtenidos con Tesseract. Si desea probarlo, aquí está el código.
from pathlib import Path
import time
import pandas as pd
from docling.document_converter import DocumentConverter, ImageFormatOption
from docling.models.easyocr_model import EasyOcrOptions # Import EasyOCR options
def main():
inpath = "/mnt/d//tesla"
infile = "10q-image.png"
input_doc_path = Path(inpath) / infile
# Configure image pipeline with EasyOCR
image_options = ImageFormatOption(
ocr_options=EasyOcrOptions(force_full_page_ocr=True), # use EasyOCR
do_table_structure=True,
table_structure_options={"do_cell_matching": True},
)
converter = DocumentConverter(
format_options={"image": image_options}
)
start_time = time.time()
conv_res = converter.convert(input_doc_path).document
# Print all tables as Markdown
for table_ix, table in enumerate(conv_res.tables):
table_df: pd.DataFrame = table.export_to_dataframe(doc=conv_res)
page_number = table.prov[0].page_no if table.prov else "Unknown"
print(f"\n--- Table {table_ix+1} (Page {page_number}) ---")
print(table_df.to_markdown(index=False))
# Print full document text as Markdown
print("\n--- Full Document (Markdown) ---")
print(conv_res.export_to_markdown())
elapsed = time.time() - start_time
print(f"\nProcessing completed in {elapsed:.2f} seconds")
if __name__ == "__main__":
main()
Resumen
El boom generativo-AI volvió a encender una vieja verdad: basura, basura fuera. Los LLM pueden alucinar menos cuando ingieren la entrada semántica y espacialmente coherente. DoCling proporciona coherencia (la mayor parte del tiempo) en múltiples formatos de origen que sus partes interesadas pueden presentar, y lo hace de manera local y reproducible.
Sin embargo, Docling tiene sus usos más allá del mundo de la IA. Considere la gran cantidad de documentos almacenados en ubicaciones como bóvedas bancarias, oficinas de abogados y compañías de seguros en todo el mundo. Si se van a digitalizar, Dormo puede proporcionar algunas de las soluciones para eso.
Su mayor debilidad es probablemente el reconocimiento de caracteres ópticos del texto dentro de las imágenes. Intenté usar Tesseract y Easyocr, y los resultados de ambos fueron decepcionantes. Probablemente necesite usar un producto comercial como AWS Textract si desea reproducir de manera confiable el texto de ese tipo de fuentes.
También puede ser lento. Tengo una PC de escritorio de alta especificación con una GPU, y tomó un tiempo en la mayoría de las tareas que la configuré. Sin embargo, si sus documentos de entrada son principalmente PDFS, Docling podría ser una adición valiosa a su caja de herramientas de procesamiento de texto.
Solo he arañado la superficie de lo que es capaz de hacer, y le animo a que visite su página de inicio, a la que se puede acceder utilizando lo siguiente enlace para aprender más.