# Optimización de Hiperparámetros OCR con Ray Tune para Documentos Académicos en Español **Trabajo Fin de Máster (TFM) – Máster Universitario en Inteligencia Artificial** **Líneas:** Percepción computacional · Aprendizaje automático **Autor:** Sergio Jiménez Jiménez · **UNIR** · **Año:** 2025 > Optimización sistemática de hiperparámetros de **PaddleOCR (PP-OCRv5)** mediante **Ray Tune** con **Optuna** para mejorar el reconocimiento óptico de caracteres en documentos académicos en español. --- ## Objetivo Optimizar el rendimiento de PaddleOCR para documentos académicos en español mediante ajuste de hiperparámetros, alcanzando un **CER inferior al 2%** sin requerir fine-tuning del modelo ni recursos GPU dedicados. **Resultado alcanzado:** CER = **1.49%** (objetivo cumplido) --- ## Resultados Principales **Tabla.** *Comparación de métricas OCR entre configuración baseline y optimizada.* | Modelo | CER | Precisión Caracteres | WER | Precisión Palabras | |--------|-----|---------------------|-----|-------------------| | PaddleOCR (Baseline) | 7.78% | 92.22% | 14.94% | 85.06% | | **PaddleOCR-HyperAdjust** | **1.49%** | **98.51%** | **7.62%** | **92.38%** | *Fuente: Elaboración propia.* **Mejora obtenida:** Reducción del CER en un **80.9%** ### Configuración Óptima Encontrada ```python config_optimizada = { "textline_orientation": True, # CRÍTICO - reduce CER ~70% "use_doc_orientation_classify": False, "use_doc_unwarping": False, "text_det_thresh": 0.4690, # Correlación -0.52 con CER "text_det_box_thresh": 0.5412, "text_det_unclip_ratio": 0.0, "text_rec_score_thresh": 0.6350, } ``` --- ## Metodología ### Pipeline de Trabajo ``` PDF (académico UNIR) └─► Conversión a imagen (PyMuPDF, 300 DPI) └─► Extracción de ground truth └─► OCR con PaddleOCR (PP-OCRv5) └─► Evaluación (CER, WER con jiwer) └─► Optimización (Ray Tune + Optuna) ``` ### Experimento de Optimización **Tabla.** *Parámetros de configuración del experimento Ray Tune.* | Parámetro | Valor | |-----------|-------| | Número de trials | 64 | | Algoritmo de búsqueda | OptunaSearch (TPE) | | Métrica objetivo | CER (minimizar) | | Trials concurrentes | 2 | | Tiempo total | ~6 horas (CPU) | *Fuente: Elaboración propia.* --- ## Estructura del Repositorio ``` MastersThesis/ ├── docs/ # Capítulos del TFM en Markdown (estructura UNIR) │ ├── 00_resumen.md # Resumen + Abstract + Keywords │ ├── 01_introduccion.md # Cap. 1: Introducción (1.1-1.3) │ ├── 02_contexto_estado_arte.md # Cap. 2: Contexto y estado del arte (2.1-2.3) │ ├── 03_objetivos_metodologia.md # Cap. 3: Objetivos y metodología (3.1-3.4) │ ├── 04_desarrollo_especifico.md # Cap. 4: Desarrollo específico (4.1-4.3) │ ├── 05_conclusiones_trabajo_futuro.md # Cap. 5: Conclusiones (5.1-5.2) │ ├── 06_referencias_bibliograficas.md # Referencias bibliográficas (APA) │ └── 07_anexo_a.md # Anexo A: Código fuente y datos ├── thesis_output/ # Documento final generado │ ├── plantilla_individual.htm # TFM completo (abrir en Word) │ └── figures/ # Figuras generadas desde Mermaid │ ├── figura_1.png ... figura_7.png │ └── figures_manifest.json ├── src/ │ ├── paddle_ocr_fine_tune_unir_raytune.ipynb # Experimento principal │ ├── paddle_ocr_tuning.py # Script de evaluación CLI │ ├── dataset_manager.py # Clase ImageTextDataset │ ├── prepare_dataset.ipynb # Preparación del dataset │ └── raytune_paddle_subproc_results_*.csv # Resultados de 64 trials ├── results/ # Resultados de benchmarks ├── instructions/ # Plantilla e instrucciones UNIR │ ├── instrucciones.pdf │ ├── plantilla_individual.pdf │ └── plantilla_individual.htm ├── apply_content.py # Genera documento TFM desde docs/ + plantilla ├── generate_mermaid_figures.py # Convierte diagramas Mermaid a PNG ├── ocr_benchmark_notebook.ipynb # Benchmark comparativo inicial └── README.md ``` --- ## Hallazgos Clave 1. **`textline_orientation=True` es crítico**: Reduce el CER en un 69.7%. Para documentos con layouts mixtos (tablas, encabezados), la clasificación de orientación de línea es esencial. 2. **Umbral `text_det_thresh` importante**: Correlación -0.52 con CER. Valores óptimos entre 0.4-0.5. Valores < 0.1 causan fallos catastróficos (CER >40%). 3. **Componentes innecesarios para PDFs digitales**: `use_doc_orientation_classify` y `use_doc_unwarping` no mejoran el rendimiento en documentos académicos digitales. --- ## Rendimiento GPU Se realizó una validación adicional con aceleración GPU para evaluar la viabilidad práctica del enfoque en escenarios de producción. **Tabla.** *Comparación de rendimiento CPU vs GPU.* | Métrica | CPU | GPU (RTX 3060) | Aceleración | |---------|-----|----------------|-------------| | Tiempo/Página | 69.4s | 0.55s | **126x** | | Dataset completo (45 páginas) | ~52 min | ~25 seg | **126x** | *Fuente: Elaboración propia.* ### Recomendación de Modelos **Tabla.** *Comparación de modelos PaddleOCR en RTX 3060.* | Modelo | VRAM | Recomendación | |--------|------|---------------| | **PP-OCRv5 Mobile** | 0.06 GB | ✓ Recomendado | | PP-OCRv5 Server | 5.3 GB | ✗ Causa OOM en RTX 3060 | *Fuente: Elaboración propia.* **Conclusión:** Para hardware con VRAM limitada (≤6 GB), los modelos Mobile ofrecen el mejor balance entre precisión y recursos. La aceleración GPU hace viable el procesamiento en tiempo real. --- ## Requisitos **Tabla.** *Dependencias principales del proyecto y versiones utilizadas.* | Componente | Versión | |------------|---------| | Python | 3.12.3 | | PaddlePaddle | 3.2.2 | | PaddleOCR | 3.3.2 | | Ray | 2.52.1 | | Optuna | 4.7.0 | | jiwer | (para métricas CER/WER) | | PyMuPDF | (para conversión PDF) | *Fuente: Elaboración propia.* --- ## Uso ### Preparar dataset ```bash # Ejecutar prepare_dataset.ipynb para convertir PDF a imágenes y extraer ground truth jupyter notebook src/prepare_dataset.ipynb ``` ### Ejecutar optimización ```bash # Ejecutar el notebook principal de Ray Tune jupyter notebook src/paddle_ocr_fine_tune_unir_raytune.ipynb ``` ### Evaluación individual ```bash python src/paddle_ocr_tuning.py \ --pdf-folder ./dataset \ --textline-orientation True \ --text-det-thresh 0.469 \ --text-det-box-thresh 0.541 \ --text-rec-score-thresh 0.635 ``` --- ## Fuentes de Datos - **Dataset**: 2 documentos UNIR (45 páginas total): Instrucciones TFE (24 pág.) + Plantilla TFE (21 pág.) - **Resultados Ray Tune (PRINCIPAL)**: `src/raytune_paddle_subproc_results_20251207_192320.csv` - 64 trials de optimización con todas las métricas y configuraciones --- ## Generación del Documento TFM ### Prerrequisitos ```bash # Instalar dependencias de Python pip install beautifulsoup4 # Instalar mermaid-cli para generación de figuras npm install @mermaid-js/mermaid-cli ``` ### Flujo de Generación del Documento El documento TFM se genera en **3 pasos** que deben ejecutarse en orden: ``` ┌─────────────────────────────────────────────────────────────────────┐ │ PASO 1: generate_mermaid_figures.py │ │ ────────────────────────────────────────────────────────────────── │ │ • Lee diagramas Mermaid de docs/*.md │ │ • Genera thesis_output/figures/figura_*.png │ │ • Crea figures_manifest.json con títulos │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ PASO 2: apply_content.py │ │ ────────────────────────────────────────────────────────────────── │ │ • Lee plantilla desde instructions/plantilla_individual.htm │ │ • Inserta contenido de docs/*.md en cada capítulo │ │ • Genera tablas con formato APA y figuras con referencias │ │ • Guarda en thesis_output/plantilla_individual.htm │ └─────────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────────┐ │ PASO 3: Abrir en Microsoft Word │ │ ────────────────────────────────────────────────────────────────── │ │ • Abrir thesis_output/plantilla_individual.htm │ │ • Ctrl+A → F9 para actualizar índices (contenidos/figuras/tablas) │ │ • Guardar como TFM_Sergio_Jimenez.docx │ └─────────────────────────────────────────────────────────────────────┘ ``` ### Comandos de Generación ```bash # Desde el directorio raíz del proyecto: # PASO 1: Generar figuras PNG desde diagramas Mermaid python3 generate_mermaid_figures.py # Output: thesis_output/figures/figura_1.png ... figura_8.png # PASO 2: Aplicar contenido de docs/ a la plantilla UNIR python3 apply_content.py # Output: thesis_output/plantilla_individual.htm # PASO 3: Abrir en Word y finalizar documento # - Abrir thesis_output/plantilla_individual.htm en Microsoft Word # - Ctrl+A → F9 para actualizar todos los índices # - IMPORTANTE: Ajustar manualmente el tamaño de las imágenes para legibilidad # (seleccionar imagen → clic derecho → Tamaño y posición → ajustar al ancho de página) # - Guardar como .docx ``` ### Notas Importantes para Edición en Word 1. **Ajuste de imágenes**: Las figuras Mermaid pueden requerir ajuste manual de tamaño para ser legibles. Seleccionar cada imagen y ajustar al ancho de texto (~16cm). 2. **Actualización de índices**: Después de cualquier cambio, usar Ctrl+A → F9 para regenerar índices. 3. **Formato de código**: Los bloques de código usan Consolas 9pt. Verificar que no se corten líneas largas. ### Archivos de Entrada y Salida **Tabla.** *Relación de scripts de generación con sus archivos de entrada y salida.* | Script | Entrada | Salida | |--------|---------|--------| | `generate_mermaid_figures.py` | `docs/*.md` (bloques ```mermaid```) | `thesis_output/figures/figura_*.png`, `figures_manifest.json` | | `apply_content.py` | `instructions/plantilla_individual.htm`, `docs/*.md`, `thesis_output/figures/*.png` | `thesis_output/plantilla_individual.htm` | *Fuente: Elaboración propia.* ### Contenido Generado Automáticamente - **30 tablas** con formato APA (Tabla X. *Título* + Fuente: ...) - **8 figuras** desde Mermaid (Figura X. *Título* + Fuente: Elaboración propia) - **25 referencias** en formato APA con sangría francesa - **Resumen/Abstract** con palabras clave - **Índices** actualizables (contenidos, figuras, tablas) - Eliminación automática de textos de instrucción de la plantilla --- ## Trabajo Pendiente para Completar el TFM ### Contexto: Hardware Este trabajo adoptó la estrategia de **optimización de hiperparámetros** en lugar de **fine-tuning** debido a que el fine-tuning de modelos OCR requiere datasets etiquetados extensos y tiempos de entrenamiento prohibitivos. **Hardware utilizado:** - **Optimización (CPU)**: Los 64 trials de Ray Tune se ejecutaron en CPU (~69s/página) - **Validación (GPU)**: Se validó con RTX 3060 logrando 126x de aceleración (0.55s/página) La optimización de hiperparámetros demostró ser una **alternativa efectiva** al fine-tuning, logrando una reducción del 80.9% en el CER sin reentrenar el modelo. ### Tareas Pendientes #### Obligatorias para Entrega - [ ] **Revisión final del documento**: Abrir en Word, actualizar índices (Ctrl+A → F9), ajustar figuras, guardar como .docx - [ ] **Crear presentación**: Preparar slides para la defensa del TFM #### Opcionales (Mejoras Futuras) - [ ] **Validación cruzada**: Evaluar configuración en otros documentos (facturas, formularios) - [ ] **Explorar `text_det_unclip_ratio`**: Parámetro fijado en 0.0, podría mejorar resultados - [ ] **Comparativa con fine-tuning**: Cuantificar brecha vs fine-tuning real - [ ] **Herramienta de configuración automática**: Auto-detectar configuración óptima por documento - [ ] **Benchmark público para español**: Facilitar comparación de soluciones OCR #### Completadas - [x] **Estructura docs/ según plantilla UNIR** - [x] **Diagramas Mermaid**: 8 figuras generadas - [x] **Documento TFM unificado**: Script `apply_content.py` - [x] **Evaluación con GPU**: RTX 3060 - 126x más rápido (0.55s/página) ### Dataset El dataset contiene **45 páginas** de 2 documentos UNIR: - `src/dataset/0/`: Instrucciones TFE (24 páginas) - `src/dataset/1/`: Plantilla TFE (21 páginas) #### Formato Hugging Face El dataset está disponible en formato Hugging Face en `src/dataset_hf/`: ``` src/dataset_hf/ ├── README.md # Dataset card ├── metadata.jsonl # Metadata (image_path, text, doc_id, page_num) └── data/ # 45 imágenes PNG ``` #### Generar/Regenerar Dataset ```bash # Convertir de formato original a HF source .venv/bin/activate python src/dataset_formatting/convert_to_hf_dataset.py # Upload a Gitea packages (requiere GITEA_TOKEN) ./src/dataset_formatting/upload-dataset.sh $GITEA_TOKEN ``` #### Descargar Dataset ```bash # Desde Gitea packages curl -O https://seryus.ddns.net/api/packages/unir/generic/ocr-dataset-spanish/1.0.0/dataset-1.0.0.tar.gz tar -xzf dataset-1.0.0.tar.gz -C src/dataset_hf/ ``` --- ## Licencia Este proyecto es parte de un Trabajo Fin de Máster académico. --- ## Referencias - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) - [Ray Tune](https://docs.ray.io/en/latest/tune/index.html) - [Optuna](https://optuna.org/) - [jiwer](https://github.com/jitsi/jiwer)