# Anexo A. Código fuente y datos analizados {.unnumbered} ## A.1 Repositorio del Proyecto El código fuente completo y los datos utilizados en este trabajo están disponibles en el siguiente repositorio: **URL del repositorio:** https://github.com/seryus/MastersThesis El repositorio incluye: - **Servicios OCR dockerizados**: PaddleOCR, DocTR, EasyOCR con soporte GPU - **Scripts de evaluación**: Herramientas para evaluar y comparar modelos OCR - **Scripts de ajuste**: Ray Tune con Optuna para optimización de hiperparámetros - **Dataset**: Imágenes y textos de referencia utilizados - **Resultados**: Archivos CSV con los resultados de los 64 trials por servicio ## A.2 Estructura del Repositorio ```mermaid --- title: "Estructura del repositorio MastersThesis" config: theme: base themeVariables: primaryColor: "#E6F4F9" primaryTextColor: "#404040" primaryBorderColor: "#0098CD" lineColor: "#0098CD" --- flowchart TB subgraph root["MastersThesis/"] direction TB subgraph docs["docs/ - Capítulos TFM"] d0["00-07 chapters (.md)"] subgraph metrics["metrics/"] m1["metrics_paddle.md"] m2["metrics_doctr.md"] m3["metrics_easyocr.md"] end end subgraph src["src/ - Código fuente"] subgraph paddle["paddle_ocr/"] p1["paddle_ocr_tuning_rest.py"] p2["Dockerfile.gpu/cpu"] end subgraph doctr["doctr_service/"] dt1["doctr_tuning_rest.py"] end subgraph easy["easyocr_service/"] e1["easyocr_tuning_rest.py"] end subgraph ray["raytune/"] r1["raytune_ocr.py"] r2["run_tuning.py"] end results["results/*.csv"] dataset["dataset/"] end subgraph thesis["thesis_output/"] htm["plantilla_individual.htm"] figs["figures/figura_1-11.png"] end subgraph inst["instructions/"] i1["instrucciones.pdf"] i2["plantilla_individual.htm"] end scripts["apply_content.py
generate_mermaid_figures.py"] config["claude.md
README.md"] end ``` **Tabla A5.** *Descripción de directorios principales.* | Directorio | Contenido | |------------|-----------| | `docs/` | Capítulos del TFM en Markdown (estructura UNIR) | | `docs/metrics/` | Métricas de rendimiento por servicio OCR | | `src/paddle_ocr/` | Servicio PaddleOCR dockerizado | | `src/doctr_service/` | Servicio DocTR dockerizado | | `src/easyocr_service/` | Servicio EasyOCR dockerizado | | `src/raytune/` | Scripts de optimización Ray Tune | | `src/results/` | CSVs con resultados de 64 trials por servicio | | `thesis_output/` | Documento TFM generado + figuras PNG | | `instructions/` | Plantilla e instrucciones UNIR oficiales | *Fuente: Elaboración propia.* ## A.3 Requisitos de Software ### Sistema de Desarrollo **Tabla A1.** *Especificaciones del sistema de desarrollo.* | Componente | Especificación | |------------|----------------| | Sistema Operativo | Ubuntu 24.04.3 LTS | | CPU | AMD Ryzen 7 5800H | | RAM | 16 GB DDR4 | | GPU | NVIDIA RTX 3060 Laptop (5.66 GB VRAM) | | CUDA | 12.4 | *Fuente: Elaboración propia.* ### Dependencias **Tabla A2.** *Dependencias del proyecto.* | Componente | Versión | |------------|---------| | Python | 3.12.3 | | Docker | 29.1.5 | | NVIDIA Container Toolkit | Requerido para GPU | | Ray | 2.52.1 | | Optuna | 4.7.0 | *Fuente: Elaboración propia.* ## A.4 Instrucciones de Ejecución de Servicios OCR ### PaddleOCR (Puerto 8002) **Imágenes Docker:** - GPU: [`seryus.ddns.net/unir/paddle-ocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-gpu/latest) - CPU: [`seryus.ddns.net/unir/paddle-ocr-cpu`](https://seryus.ddns.net/unir/-/packages/container/paddle-ocr-cpu/latest) ```bash cd src/paddle_ocr # GPU (recomendado) docker compose up -d # CPU (más lento, 82x) docker compose -f docker-compose.cpu-registry.yml up -d ``` ### DocTR (Puerto 8003) **Imagen Docker:** [`seryus.ddns.net/unir/doctr-gpu`](https://seryus.ddns.net/unir/-/packages/container/doctr-gpu/latest) ```bash cd src/doctr_service # GPU docker compose up -d ``` ### EasyOCR (Puerto 8002) > **Nota:** EasyOCR utiliza el mismo puerto (8002) que PaddleOCR. No se pueden ejecutar simultáneamente. Por esta razón, existe un archivo docker-compose separado para EasyOCR. **Imagen Docker:** [`seryus.ddns.net/unir/easyocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/easyocr-gpu/latest) ```bash cd src/easyocr_service # GPU (usar archivo separado para evitar conflicto de puerto) docker compose up -d ``` ### Verificar Estado del Servicio ```bash # Verificar salud del servicio curl http://localhost:8002/health # Respuesta esperada: # {"status": "ok", "model_loaded": true, "gpu_name": "NVIDIA GeForce RTX 3060"} ``` ## A.5 Uso de la API OCR ### Evaluar Dataset Completo ```bash # PaddleOCR - Evaluación completa curl -X POST http://localhost:8002/evaluate_full \ -H "Content-Type: application/json" \ -d '{ "pdf_folder": "/app/dataset", "save_output": true }' ``` ### Evaluar con Hiperparámetros Optimizados ```bash # PaddleOCR con configuración óptima curl -X POST http://localhost:8002/evaluate_full \ -H "Content-Type: application/json" \ -d '{ "pdf_folder": "/app/dataset", "use_doc_orientation_classify": true, "use_doc_unwarping": false, "textline_orientation": true, "text_det_thresh": 0.0462, "text_det_box_thresh": 0.4862, "text_det_unclip_ratio": 0.0, "text_rec_score_thresh": 0.5658, "save_output": true }' ``` ## A.6 Ajuste de Hiperparámetros con Ray Tune ### Ejecutar Ajuste ```bash cd src # Activar entorno virtual source ../.venv/bin/activate # PaddleOCR (64 muestras) python -c " from raytune_ocr import * ports = [8002] check_workers(ports, 'PaddleOCR') trainable = create_trainable(ports, paddle_ocr_payload) results = run_tuner(trainable, PADDLE_OCR_SEARCH_SPACE, num_samples=64) analyze_results(results, prefix='raytune_paddle', config_keys=PADDLE_OCR_CONFIG_KEYS) " ``` ### Servicios y Puertos **Tabla A3.** *Servicios Docker y puertos.* | Servicio | Puerto | Script de Ajuste | Nota | |----------|--------|------------------|------| | PaddleOCR | 8002 | `paddle_ocr_payload` | - | | DocTR | 8003 | `doctr_payload` | - | | EasyOCR | 8002 | `easyocr_payload` | Conflicto con PaddleOCR | *Fuente: Elaboración propia.* > **Nota:** Debido a limitaciones de recursos GPU (VRAM insuficiente para ejecutar múltiples modelos OCR simultáneamente), solo se ejecuta un servicio a la vez. PaddleOCR y EasyOCR comparten el puerto 8002. Para cambiar de servicio, detener el actual con `docker compose down`. ## A.7 Métricas de Rendimiento Los resultados detallados de las evaluaciones y ajustes de hiperparámetros se encuentran en: - [Métricas Generales](metrics/metrics.md) - Comparativa de los tres servicios - [PaddleOCR](metrics/metrics_paddle.md) - Mejor precisión (8.85% CER baseline, **7.72% optimizado**, **0.79% mejor trial**) - [DocTR](metrics/metrics_doctr.md) - Más rápido (0.50s/página) - [EasyOCR](metrics/metrics_easyocr.md) - Balance intermedio ### Resumen de Resultados **Tabla A4.** *Resumen de resultados del benchmark por servicio.* | Servicio | CER Base | CER Ajustado | Mejora | |----------|----------|--------------|--------| | **PaddleOCR** | 8.85% | **7.72%** | 12.8% | | DocTR | 12.06% | 12.07% | 0% | | EasyOCR | 11.23% | 11.14% | 0.8% | *Fuente: Elaboración propia.* ## A.8 Licencia El código se distribuye bajo licencia MIT.