links regeneration
Some checks failed
build_docker / essential (push) Successful in 0s
build_docker / build_paddle_ocr (push) Successful in 5m9s
build_docker / build_easyocr_gpu (push) Has been cancelled
build_docker / build_doctr (push) Has been cancelled
build_docker / build_doctr_gpu (push) Has been cancelled
build_docker / build_raytune (push) Has been cancelled
build_docker / build_paddle_ocr_gpu (push) Has been cancelled
build_docker / build_easyocr (push) Has been cancelled
Some checks failed
build_docker / essential (push) Successful in 0s
build_docker / build_paddle_ocr (push) Successful in 5m9s
build_docker / build_easyocr_gpu (push) Has been cancelled
build_docker / build_doctr (push) Has been cancelled
build_docker / build_doctr_gpu (push) Has been cancelled
build_docker / build_raytune (push) Has been cancelled
build_docker / build_paddle_ocr_gpu (push) Has been cancelled
build_docker / build_easyocr (push) Has been cancelled
This commit is contained in:
@@ -16,6 +16,8 @@ DOCS_DIR = os.path.join(BASE_DIR, 'docs')
|
|||||||
# Global counters for tables and figures
|
# Global counters for tables and figures
|
||||||
table_counter = 0
|
table_counter = 0
|
||||||
figure_counter = 0
|
figure_counter = 0
|
||||||
|
anexo_table_counter = 0
|
||||||
|
anexo_figure_counter = 0
|
||||||
|
|
||||||
def read_file(path):
|
def read_file(path):
|
||||||
try:
|
try:
|
||||||
@@ -99,7 +101,7 @@ def extract_figure_title_from_mermaid(lines, current_index):
|
|||||||
|
|
||||||
def parse_md_to_html_blocks(md_content, is_anexo=False):
|
def parse_md_to_html_blocks(md_content, is_anexo=False):
|
||||||
"""Convert markdown content to HTML blocks with template styles."""
|
"""Convert markdown content to HTML blocks with template styles."""
|
||||||
global table_counter, figure_counter
|
global table_counter, figure_counter, anexo_table_counter, anexo_figure_counter
|
||||||
|
|
||||||
html_blocks = []
|
html_blocks = []
|
||||||
lines = md_content.split('\n')
|
lines = md_content.split('\n')
|
||||||
@@ -115,7 +117,13 @@ def parse_md_to_html_blocks(md_content, is_anexo=False):
|
|||||||
|
|
||||||
# Mermaid diagram - convert to figure with actual image
|
# Mermaid diagram - convert to figure with actual image
|
||||||
if line.strip().startswith('```mermaid'):
|
if line.strip().startswith('```mermaid'):
|
||||||
figure_counter += 1
|
# Use Anexo-specific counter with "A" prefix, or global counter
|
||||||
|
if is_anexo:
|
||||||
|
anexo_figure_counter += 1
|
||||||
|
fig_num = f"A{anexo_figure_counter}"
|
||||||
|
else:
|
||||||
|
figure_counter += 1
|
||||||
|
fig_num = str(figure_counter)
|
||||||
mermaid_lines = []
|
mermaid_lines = []
|
||||||
i += 1
|
i += 1
|
||||||
while i < len(lines) and not lines[i].strip() == '```':
|
while i < len(lines) and not lines[i].strip() == '```':
|
||||||
@@ -132,18 +140,19 @@ def parse_md_to_html_blocks(md_content, is_anexo=False):
|
|||||||
if title_match:
|
if title_match:
|
||||||
fig_title = title_match.group(1).strip()
|
fig_title = title_match.group(1).strip()
|
||||||
else:
|
else:
|
||||||
fig_title = f"Diagrama {figure_counter}"
|
fig_title = f"Diagrama {fig_num}"
|
||||||
|
|
||||||
# Check if the generated PNG exists
|
# Check if the generated PNG exists
|
||||||
fig_file = f'figures/figura_{figure_counter}.png'
|
# For Anexo figures, use the anexo counter for the actual file (A1 -> figura_A1.png)
|
||||||
|
fig_file = f'figures/figura_{fig_num}.png'
|
||||||
fig_path = os.path.join(BASE_DIR, 'thesis_output', fig_file)
|
fig_path = os.path.join(BASE_DIR, 'thesis_output', fig_file)
|
||||||
|
|
||||||
# Create figure with MsoCaption class and proper Word SEQ field for cross-reference
|
# Create figure with MsoCaption class and proper Word SEQ field for cross-reference
|
||||||
# Format: "Figura X." in bold, title in italic (per UNIR guidelines)
|
# Format: "Figura X." in bold, title in italic (per UNIR guidelines)
|
||||||
# Word TOC looks for text with Caption style - anchor must be outside main caption text
|
# Word TOC looks for text with Caption style - anchor must be outside main caption text
|
||||||
bookmark_id = f"_Ref_Fig{figure_counter}"
|
bookmark_id = f"_Ref_Fig{fig_num}"
|
||||||
# mso-pagination:keep-with-next ensures caption stays with figure image (correct MSO property)
|
# mso-pagination:keep-with-next ensures caption stays with figure image (correct MSO property)
|
||||||
html_blocks.append(f'''<a name="{bookmark_id}"></a><p class=MsoCaption style="text-align:center;mso-pagination:keep-with-next"><b><span lang=ES style="font-size:12.0pt;line-height:150%">Figura <!--[if supportFields]><span style='mso-element:field-begin'></span> SEQ Figura \\* ARABIC <span style='mso-element:field-separator'></span><![endif]-->{figure_counter}<!--[if supportFields]><span style='mso-element:field-end'></span><![endif]-->.</span></b><span lang=ES style="font-size:12.0pt;line-height:150%"> </span><i><span lang=ES style="font-size:12.0pt;line-height:150%">{fig_title}</span></i></p>''')
|
html_blocks.append(f'''<a name="{bookmark_id}"></a><p class=MsoCaption style="text-align:center;mso-pagination:keep-with-next"><b><span lang=ES style="font-size:12.0pt;line-height:150%">Figura <!--[if supportFields]><span style='mso-element:field-begin'></span> SEQ Figura \\* ARABIC <span style='mso-element:field-separator'></span><![endif]-->{fig_num}<!--[if supportFields]><span style='mso-element:field-end'></span><![endif]-->.</span></b><span lang=ES style="font-size:12.0pt;line-height:150%"> </span><i><span lang=ES style="font-size:12.0pt;line-height:150%">{fig_title}</span></i></p>''')
|
||||||
|
|
||||||
if os.path.exists(fig_path):
|
if os.path.exists(fig_path):
|
||||||
# Read actual image dimensions and scale to fit page width
|
# Read actual image dimensions and scale to fit page width
|
||||||
@@ -216,7 +225,8 @@ def parse_md_to_html_blocks(md_content, is_anexo=False):
|
|||||||
# Headers - ## becomes h2, ### becomes h3
|
# Headers - ## becomes h2, ### becomes h3
|
||||||
if line.startswith('####'):
|
if line.startswith('####'):
|
||||||
text = line.lstrip('#').strip()
|
text = line.lstrip('#').strip()
|
||||||
html_blocks.append(f'<h4><span lang=ES>{text}</span></h4>')
|
# Apply consistent styling like h2/h3, disable numbering for h4
|
||||||
|
html_blocks.append(f'<h4 style="mso-list:none"><span lang=ES style="text-transform:none">{text}</span></h4>')
|
||||||
i += 1
|
i += 1
|
||||||
continue
|
continue
|
||||||
elif line.startswith('###'):
|
elif line.startswith('###'):
|
||||||
@@ -246,7 +256,13 @@ def parse_md_to_html_blocks(md_content, is_anexo=False):
|
|||||||
|
|
||||||
# Table - check for table title pattern first
|
# Table - check for table title pattern first
|
||||||
if '|' in line and i + 1 < len(lines) and '---' in lines[i + 1]:
|
if '|' in line and i + 1 < len(lines) and '---' in lines[i + 1]:
|
||||||
table_counter += 1
|
# Use Anexo-specific counter with "A" prefix, or global counter
|
||||||
|
if is_anexo:
|
||||||
|
anexo_table_counter += 1
|
||||||
|
table_num = f"A{anexo_table_counter}"
|
||||||
|
else:
|
||||||
|
table_counter += 1
|
||||||
|
table_num = str(table_counter)
|
||||||
|
|
||||||
# Check if previous line has table title (e.g., **Tabla 1.** *Title*)
|
# Check if previous line has table title (e.g., **Tabla 1.** *Title*)
|
||||||
table_title = None
|
table_title = None
|
||||||
@@ -281,7 +297,7 @@ def parse_md_to_html_blocks(md_content, is_anexo=False):
|
|||||||
# Add table title with MsoCaption class and proper Word SEQ field for cross-reference
|
# Add table title with MsoCaption class and proper Word SEQ field for cross-reference
|
||||||
# Format: "Tabla X." in bold, title in italic (per UNIR guidelines)
|
# Format: "Tabla X." in bold, title in italic (per UNIR guidelines)
|
||||||
# Word TOC looks for text with Caption style - anchor must be outside main caption text
|
# Word TOC looks for text with Caption style - anchor must be outside main caption text
|
||||||
bookmark_id = f"_Ref_Tab{table_counter}"
|
bookmark_id = f"_Ref_Tab{table_num}"
|
||||||
if table_title:
|
if table_title:
|
||||||
# Remove any "Tabla X." or "Tabla AX." pattern from the title
|
# Remove any "Tabla X." or "Tabla AX." pattern from the title
|
||||||
clean_title = re.sub(r'^Tabla\s+[A-Z]?\d+\.\s*', '', table_title).strip()
|
clean_title = re.sub(r'^Tabla\s+[A-Z]?\d+\.\s*', '', table_title).strip()
|
||||||
@@ -291,7 +307,7 @@ def parse_md_to_html_blocks(md_content, is_anexo=False):
|
|||||||
else:
|
else:
|
||||||
clean_title = "Tabla de datos."
|
clean_title = "Tabla de datos."
|
||||||
# mso-pagination:keep-with-next ensures caption stays with table (correct MSO property)
|
# mso-pagination:keep-with-next ensures caption stays with table (correct MSO property)
|
||||||
html_blocks.append(f'''<a name="{bookmark_id}"></a><p class=MsoCaption style="mso-pagination:keep-with-next"><b><span lang=ES style="font-size:12.0pt;line-height:150%">Tabla <!--[if supportFields]><span style='mso-element:field-begin'></span> SEQ Tabla \\* ARABIC <span style='mso-element:field-separator'></span><![endif]-->{table_counter}<!--[if supportFields]><span style='mso-element:field-end'></span><![endif]-->.</span></b><span lang=ES style="font-size:12.0pt;line-height:150%"> </span><i><span lang=ES style="font-size:12.0pt;line-height:150%">{clean_title}</span></i></p>''')
|
html_blocks.append(f'''<a name="{bookmark_id}"></a><p class=MsoCaption style="mso-pagination:keep-with-next"><b><span lang=ES style="font-size:12.0pt;line-height:150%">Tabla <!--[if supportFields]><span style='mso-element:field-begin'></span> SEQ Tabla \\* ARABIC <span style='mso-element:field-separator'></span><![endif]-->{table_num}<!--[if supportFields]><span style='mso-element:field-end'></span><![endif]-->.</span></b><span lang=ES style="font-size:12.0pt;line-height:150%"> </span><i><span lang=ES style="font-size:12.0pt;line-height:150%">{clean_title}</span></i></p>''')
|
||||||
|
|
||||||
# Build table HTML with APA style (horizontal lines only, no vertical)
|
# Build table HTML with APA style (horizontal lines only, no vertical)
|
||||||
table_html = '<div align="center"><table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 align="center" style="border-collapse:collapse;margin-left:auto;margin-right:auto;mso-table-style-name:\'Plain Table 1\'">'
|
table_html = '<div align="center"><table class=MsoTableGrid border=1 cellspacing=0 cellpadding=0 align="center" style="border-collapse:collapse;margin-left:auto;margin-right:auto;mso-table-style-name:\'Plain Table 1\'">'
|
||||||
@@ -445,25 +461,25 @@ def extract_resumen_parts(resumen_content):
|
|||||||
spanish_keywords = ''
|
spanish_keywords = ''
|
||||||
if '**Palabras clave:**' in spanish_part:
|
if '**Palabras clave:**' in spanish_part:
|
||||||
text_part, kw_part = spanish_part.split('**Palabras clave:**')
|
text_part, kw_part = spanish_part.split('**Palabras clave:**')
|
||||||
spanish_text = text_part.replace('# Resumen', '').strip()
|
spanish_text = md_to_html_para(text_part.replace('# Resumen', '').strip())
|
||||||
spanish_keywords = kw_part.strip()
|
spanish_keywords = md_to_html_para(kw_part.strip())
|
||||||
else:
|
else:
|
||||||
spanish_text = spanish_part.replace('# Resumen', '').strip()
|
spanish_text = md_to_html_para(spanish_part.replace('# Resumen', '').strip())
|
||||||
|
|
||||||
# Extract English content
|
# Extract English content
|
||||||
english_text = ''
|
english_text = ''
|
||||||
english_keywords = ''
|
english_keywords = ''
|
||||||
if '**Keywords:**' in english_part:
|
if '**Keywords:**' in english_part:
|
||||||
text_part, kw_part = english_part.split('**Keywords:**')
|
text_part, kw_part = english_part.split('**Keywords:**')
|
||||||
english_text = text_part.replace('# Abstract', '').strip()
|
english_text = md_to_html_para(text_part.replace('# Abstract', '').strip())
|
||||||
english_keywords = kw_part.strip()
|
english_keywords = md_to_html_para(kw_part.strip())
|
||||||
else:
|
else:
|
||||||
english_text = english_part.replace('# Abstract', '').strip()
|
english_text = md_to_html_para(english_part.replace('# Abstract', '').strip())
|
||||||
|
|
||||||
return spanish_text, spanish_keywords, english_text, english_keywords
|
return spanish_text, spanish_keywords, english_text, english_keywords
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global table_counter, figure_counter
|
global table_counter, figure_counter, anexo_table_counter, anexo_figure_counter
|
||||||
|
|
||||||
print("Reading template...")
|
print("Reading template...")
|
||||||
html_content = read_file(TEMPLATE_INPUT)
|
html_content = read_file(TEMPLATE_INPUT)
|
||||||
@@ -692,7 +708,7 @@ def main():
|
|||||||
insert_point.insert_after(new_elem)
|
insert_point.insert_after(new_elem)
|
||||||
print(f" ✓ Replaced content")
|
print(f" ✓ Replaced content")
|
||||||
|
|
||||||
print(f"\nSummary: {table_counter} tables, {figure_counter} figures processed")
|
print(f"\nSummary: {table_counter} tables + {anexo_table_counter} Anexo tables, {figure_counter} figures + {anexo_figure_counter} Anexo figures processed")
|
||||||
|
|
||||||
print("Saving modified template...")
|
print("Saving modified template...")
|
||||||
output_html = str(soup)
|
output_html = str(soup)
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ Se realizó un estudio comparativo de tres soluciones OCR de código abierto: Ea
|
|||||||
|
|
||||||
Los resultados demuestran que la optimización de hiperparámetros logró mejoras significativas: el mejor trial individual alcanzó un CER de 0.79% (precisión del 99.21%), cumpliendo el objetivo de CER < 2%. Al validar la configuración optimizada sobre el dataset completo de 45 páginas, se obtuvo una mejora del 12.8% en CER (de 8.85% a 7.72%). El hallazgo más relevante fue que el parámetro `textline_orientation` (clasificación de orientación de línea de texto) tiene un impacto crítico en el rendimiento. Adicionalmente, se identificó que el umbral de detección (`text_det_thresh`) presenta una correlación positiva moderada (0.43) con el error, lo que indica que valores más bajos tienden a mejorar el rendimiento.
|
Los resultados demuestran que la optimización de hiperparámetros logró mejoras significativas: el mejor trial individual alcanzó un CER de 0.79% (precisión del 99.21%), cumpliendo el objetivo de CER < 2%. Al validar la configuración optimizada sobre el dataset completo de 45 páginas, se obtuvo una mejora del 12.8% en CER (de 8.85% a 7.72%). El hallazgo más relevante fue que el parámetro `textline_orientation` (clasificación de orientación de línea de texto) tiene un impacto crítico en el rendimiento. Adicionalmente, se identificó que el umbral de detección (`text_det_thresh`) presenta una correlación positiva moderada (0.43) con el error, lo que indica que valores más bajos tienden a mejorar el rendimiento.
|
||||||
|
|
||||||
Fuente: [`docs/metrics/metrics_paddle.md`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/docs/metrics/metrics_paddle.md), [`src/results/correlations/paddle_correlations.csv`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/results/correlations/paddle_correlations.csv).
|
|
||||||
|
|
||||||
Este trabajo demuestra que la optimización de hiperparámetros es una alternativa viable al fine-tuning, especialmente útil cuando se dispone de modelos preentrenados para el idioma objetivo. La infraestructura dockerizada desarrollada permite reproducir los experimentos y facilita la evaluación sistemática de configuraciones OCR.
|
Este trabajo demuestra que la optimización de hiperparámetros es una alternativa viable al fine-tuning, especialmente útil cuando se dispone de modelos preentrenados para el idioma objetivo. La infraestructura dockerizada desarrollada permite reproducir los experimentos y facilita la evaluación sistemática de configuraciones OCR.
|
||||||
|
|
||||||
**Palabras clave:** OCR, Reconocimiento Óptico de Caracteres, PaddleOCR, Optimización de Hiperparámetros, Ray Tune, Procesamiento de Documentos, Inteligencia Artificial
|
**Palabras clave:** OCR, Reconocimiento Óptico de Caracteres, PaddleOCR, Optimización de Hiperparámetros, Ray Tune, Procesamiento de Documentos, Inteligencia Artificial
|
||||||
@@ -22,8 +20,6 @@ A comparative study of three open-source OCR solutions was conducted with EasyOC
|
|||||||
|
|
||||||
Results demonstrate that hyperparameter optimization achieved significant improvements. The best individual trial reached a CER of 0.79% (99.21% accuracy), meeting the CER < 2% objective. When validating the optimized configuration on the full 45-page dataset, a 12.8% CER improvement was obtained (from 8.85% to 7.72%). The most relevant finding was that the `textline_orientation` parameter (text line orientation classification) has a critical impact on performance. Additionally, the detection threshold (`text_det_thresh`) showed a moderate positive correlation (0.43) with error, indicating that lower values tend to improve performance.
|
Results demonstrate that hyperparameter optimization achieved significant improvements. The best individual trial reached a CER of 0.79% (99.21% accuracy), meeting the CER < 2% objective. When validating the optimized configuration on the full 45-page dataset, a 12.8% CER improvement was obtained (from 8.85% to 7.72%). The most relevant finding was that the `textline_orientation` parameter (text line orientation classification) has a critical impact on performance. Additionally, the detection threshold (`text_det_thresh`) showed a moderate positive correlation (0.43) with error, indicating that lower values tend to improve performance.
|
||||||
|
|
||||||
Sources: [`docs/metrics/metrics_paddle.md`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/docs/metrics/metrics_paddle.md), [`src/results/correlations/paddle_correlations.csv`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/results/correlations/paddle_correlations.csv).
|
|
||||||
|
|
||||||
This work demonstrates that hyperparameter optimization is a viable alternative to fine-tuning, especially useful when pre-trained models for the target language are available. The dockerized infrastructure developed enables experiment reproducibility and facilitates systematic evaluation of OCR configurations.
|
This work demonstrates that hyperparameter optimization is a viable alternative to fine-tuning, especially useful when pre-trained models for the target language are available. The dockerized infrastructure developed enables experiment reproducibility and facilitates systematic evaluation of OCR configurations.
|
||||||
|
|
||||||
**Keywords:** OCR, Optical Character Recognition, PaddleOCR, Hyperparameter Optimization, Ray Tune, Document Processing, Artificial Intelligence
|
**Keywords:** OCR, Optical Character Recognition, PaddleOCR, Hyperparameter Optimization, Ray Tune, Document Processing, Artificial Intelligence
|
||||||
|
|||||||
@@ -579,9 +579,7 @@ Fuente: Elaboración propia.
|
|||||||
|
|
||||||
La optimización de hiperparámetros para documentos académicos en español representa una contribución original de este trabajo, abordando un nicho no explorado en la literatura.
|
La optimización de hiperparámetros para documentos académicos en español representa una contribución original de este trabajo, abordando un nicho no explorado en la literatura.
|
||||||
|
|
||||||
## Conclusiones del capítulo
|
En síntesis, la revisión del estado del arte revela un panorama en el que las herramientas técnicas están maduras, pero su aplicación óptima para dominios específicos permanece poco explorada. Los sistemas OCR modernos, como PaddleOCR, EasyOCR y DocTR, ofrecen arquitecturas sofisticadas basadas en aprendizaje profundo que alcanzan resultados impresionantes en benchmarks estándar. Sin embargo, estos resultados no siempre se trasladan a documentos del mundo real, especialmente en idiomas con menos recursos como el español.
|
||||||
|
|
||||||
La revisión del estado del arte revela un panorama en el que las herramientas técnicas están maduras, pero su aplicación óptima para dominios específicos permanece poco explorada. Los sistemas OCR modernos, como PaddleOCR, EasyOCR y DocTR, ofrecen arquitecturas sofisticadas basadas en aprendizaje profundo que alcanzan resultados impresionantes en benchmarks estándar. Sin embargo, estos resultados no siempre se trasladan a documentos del mundo real, especialmente en idiomas con menos recursos como el español.
|
|
||||||
|
|
||||||
La evolución desde los sistemas de plantillas de los años 50 hasta los Transformers actuales ha sido espectacular, pero ha generado sistemas con decenas de hiperparámetros configurables cuyos valores por defecto representan compromisos generales, no configuraciones óptimas para dominios específicos. La literatura abunda en trabajos sobre entrenamiento y fine-tuning de modelos OCR, pero dedica poca atención a la optimización sistemática de los parámetros de inferencia, como umbrales de detección, opciones de preprocesamiento y filtros de confianza, que pueden marcar la diferencia entre un sistema usable y uno que requiere corrección manual extensiva.
|
La evolución desde los sistemas de plantillas de los años 50 hasta los Transformers actuales ha sido espectacular, pero ha generado sistemas con decenas de hiperparámetros configurables cuyos valores por defecto representan compromisos generales, no configuraciones óptimas para dominios específicos. La literatura abunda en trabajos sobre entrenamiento y fine-tuning de modelos OCR, pero dedica poca atención a la optimización sistemática de los parámetros de inferencia, como umbrales de detección, opciones de preprocesamiento y filtros de confianza, que pueden marcar la diferencia entre un sistema usable y uno que requiere corrección manual extensiva.
|
||||||
|
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ flowchart LR
|
|||||||
A -.->|"Health check /health"| B
|
A -.->|"Health check /health"| B
|
||||||
```
|
```
|
||||||
|
|
||||||
La arquitectura containerizada [`src/docker-compose.tuning.paddle.yml)`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.paddle.yml))))), [`src/docker-compose.tuning.doctr.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.doctr.yml), [`src/docker-compose.tuning.easyocr.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.easyocr.yml), [`src/docker-compose.tuning.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.yml)ofrece:
|
La arquitectura containerizada [`src/docker-compose.tuning.paddle.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.paddle.yml), [`src/docker-compose.tuning.doctr.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.doctr.yml), [`src/docker-compose.tuning.easyocr.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.easyocr.yml), [`src/docker-compose.tuning.yml`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/docker-compose.tuning.yml) ofrece:
|
||||||
1. Aislamiento de dependencias entre Ray Tune y los motores OCR
|
1. Aislamiento de dependencias entre Ray Tune y los motores OCR
|
||||||
2. Health checks automáticos para asegurar disponibilidad del servicio
|
2. Health checks automáticos para asegurar disponibilidad del servicio
|
||||||
3. Comunicación via API REST (endpoints `/health` y `/evaluate`)
|
3. Comunicación via API REST (endpoints `/health` y `/evaluate`)
|
||||||
@@ -1239,16 +1239,4 @@ Fuente: [`docs/metrics/metrics.md`](https://seryus.ddns.net/unir/MastersThesis/s
|
|||||||
|
|
||||||
Los modelos Server, a pesar de ofrecer potencialmente mayor precisión, resultan inviables en hardware con VRAM limitada (≤6 GB) debido a errores de memoria (Out of Memory). Los modelos Mobile, con un consumo de memoria 88 veces menor, funcionan de manera estable y ofrecen rendimiento suficiente para el caso de uso evaluado.
|
Los modelos Server, a pesar de ofrecer potencialmente mayor precisión, resultan inviables en hardware con VRAM limitada (≤6 GB) debido a errores de memoria (Out of Memory). Los modelos Mobile, con un consumo de memoria 88 veces menor, funcionan de manera estable y ofrecen rendimiento suficiente para el caso de uso evaluado.
|
||||||
|
|
||||||
#### Conclusiones de la Validación GPU
|
La validación con aceleración GPU demuestra que la configuración optimizada mediante Ray Tune mejora la precisión (CER: 8.85% → 7.72% en dataset completo, 0.79% en mejor trial individual) y, combinada con la aceleración de 82× proporcionada por GPU, resulta prácticamente aplicable en escenarios de producción real. Las conclusiones derivadas de esta validación se presentan en el Capítulo 5.
|
||||||
|
|
||||||
La validación con aceleración GPU permite extraer las siguientes conclusiones:
|
|
||||||
|
|
||||||
1. **Aceleración significativa**: La GPU proporciona una aceleración de 82× sobre CPU, haciendo viable el procesamiento en tiempo real para aplicaciones interactivas.
|
|
||||||
|
|
||||||
2. **Modelos Mobile recomendados**: Para hardware con VRAM limitada (≤6 GB), los modelos Mobile de PP-OCRv5 ofrecen el mejor balance entre precisión y recursos, funcionando de manera estable sin errores de memoria.
|
|
||||||
|
|
||||||
3. **Viabilidad práctica**: Con GPU, el procesamiento de un documento completo (45 páginas) toma ~38 segundos, validando la aplicabilidad en entornos de producción donde el tiempo de respuesta es crítico.
|
|
||||||
|
|
||||||
4. **Escalabilidad**: La arquitectura de microservicios dockerizados utilizada para la validación GPU facilita el despliegue horizontal, permitiendo escalar el procesamiento según demanda.
|
|
||||||
|
|
||||||
Esta validación demuestra que la configuración optimizada mediante Ray Tune mejora la precisión (CER: 8.85% → 7.72% en dataset completo, 0.79% en mejor trial individual) y, combinada con aceleración GPU, resulta prácticamente aplicable en escenarios de producción real.
|
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ Otro hallazgo relevante es la innecesariedad de ciertos módulos para documentos
|
|||||||
|
|
||||||
Finalmente, los resultados demuestran que es posible mejorar modelos preentrenados mediante ajuste exclusivo de hiperparámetros de inferencia, sin necesidad de reentrenamiento. Sin embargo, esta aproximación requiere validación cuidadosa, ya que las configuraciones optimizadas sobre subconjuntos pequeños pueden no generalizar a conjuntos de datos más amplios o diversos.
|
Finalmente, los resultados demuestran que es posible mejorar modelos preentrenados mediante ajuste exclusivo de hiperparámetros de inferencia, sin necesidad de reentrenamiento. Sin embargo, esta aproximación requiere validación cuidadosa, ya que las configuraciones optimizadas sobre subconjuntos pequeños pueden no generalizar a conjuntos de datos más amplios o diversos.
|
||||||
|
|
||||||
|
Respecto a la validación con aceleración GPU, la GPU proporciona una aceleración de 82× sobre CPU, haciendo viable el procesamiento en tiempo real para aplicaciones interactivas. Con GPU, el procesamiento de un documento completo (45 páginas) toma aproximadamente 38 segundos, validando la aplicabilidad en entornos de producción donde el tiempo de respuesta es crítico. Para hardware con VRAM limitada (≤6 GB), los modelos Mobile de PP-OCRv5 ofrecen el mejor balance entre precisión y recursos, funcionando de manera estable sin errores de memoria, mientras que los modelos Server resultan inviables debido a errores Out of Memory. Además, la arquitectura de microservicios dockerizados utilizada facilita el despliegue horizontal, permitiendo escalar el procesamiento según demanda.
|
||||||
|
|
||||||
|
Fuente: [`docs/metrics/metrics.md`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/docs/metrics/metrics.md).
|
||||||
|
|
||||||
### Contribuciones del Trabajo
|
### Contribuciones del Trabajo
|
||||||
|
|
||||||
La principal contribución de este trabajo es una metodología reproducible para la optimización de hiperparámetros OCR. El proceso completo, desde la preparación del conjunto de datos hasta la validación de la configuración óptima, queda documentado y es replicable mediante las herramientas Ray Tune y Optuna.
|
La principal contribución de este trabajo es una metodología reproducible para la optimización de hiperparámetros OCR. El proceso completo, desde la preparación del conjunto de datos hasta la validación de la configuración óptima, queda documentado y es replicable mediante las herramientas Ray Tune y Optuna.
|
||||||
|
|||||||
@@ -46,27 +46,11 @@ flowchart TB
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
**Tabla A1.** *Descripción de directorios principales.*
|
|
||||||
|
|
||||||
| Directorio | Contenido |
|
|
||||||
|------------|-----------|
|
|
||||||
| [`docs/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/docs/)| Capítulos del TFM en Markdown (estructura UNIR) |
|
|
||||||
| [`docs/metrics/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/docs/metrics/)| Métricas de rendimiento por servicio OCR |
|
|
||||||
| [`src/paddle_ocr/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/paddle_ocr/)| Servicio PaddleOCR dockerizado |
|
|
||||||
| [`src/doctr_service/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/doctr_service/)| Servicio DocTR dockerizado |
|
|
||||||
| [`src/easyocr_service/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/easyocr_service/)| Servicio EasyOCR dockerizado |
|
|
||||||
| [`src/raytune/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/raytune/)| Scripts de optimización Ray Tune |
|
|
||||||
| [`src/results/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/results/)| CSVs con resultados de 64 trials por servicio |
|
|
||||||
| [`src/results/correlations/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/src/results/correlations/)| Correlaciones de hiperparámetros por servicio |
|
|
||||||
| [`thesis_output/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/thesis_output/)| Documento TFM generado + figuras PNG |
|
|
||||||
| [`instructions/`](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/instructions/)| Plantilla e instrucciones UNIR oficiales |
|
|
||||||
Fuente: [Repositorio del proyecto](https://seryus.ddns.net/unir/MastersThesis/src/branch/main/).
|
|
||||||
|
|
||||||
## A.3 Requisitos de Software
|
## A.3 Requisitos de Software
|
||||||
|
|
||||||
### Sistema de Desarrollo
|
### Sistema de Desarrollo
|
||||||
|
|
||||||
**Tabla A2.** *Especificaciones del sistema de desarrollo.*
|
**Tabla A1.** *Especificaciones del sistema de desarrollo.*
|
||||||
|
|
||||||
| Componente | Especificación |
|
| Componente | Especificación |
|
||||||
|------------|----------------|
|
|------------|----------------|
|
||||||
@@ -79,9 +63,7 @@ Fuente: [`docs/metrics/metrics.md`](https://seryus.ddns.net/unir/MastersThesis/s
|
|||||||
|
|
||||||
### Dependencias
|
### Dependencias
|
||||||
|
|
||||||
### Dependencias
|
**Tabla A2.** *Dependencias del proyecto.*
|
||||||
|
|
||||||
**Tabla A3.** *Dependencias del proyecto.*
|
|
||||||
|
|
||||||
| Componente | Versión |
|
| Componente | Versión |
|
||||||
|------------|---------|
|
|------------|---------|
|
||||||
@@ -97,8 +79,6 @@ Fuente: [`src/paddle_ocr/requirements.txt`](https://seryus.ddns.net/unir/Masters
|
|||||||
|
|
||||||
## A.4 Instrucciones de Ejecución de Servicios OCR
|
## A.4 Instrucciones de Ejecución de Servicios OCR
|
||||||
|
|
||||||
## A.4 Instrucciones de Ejecución de Servicios OCR
|
|
||||||
|
|
||||||
### PaddleOCR (Puerto 8002)
|
### PaddleOCR (Puerto 8002)
|
||||||
|
|
||||||
**Imágenes Docker:**
|
**Imágenes Docker:**
|
||||||
@@ -117,7 +97,7 @@ docker compose -f docker-compose.cpu-registry.yml up -d
|
|||||||
|
|
||||||
### DocTR (Puerto 8003)
|
### DocTR (Puerto 8003)
|
||||||
|
|
||||||
**Imagen Docker:** `seryus.ddns.net/unir/doctr-gpu`(https://seryus.ddns.net/unir/-/packages/container/doctr-gpu/latest)
|
**Imagen Docker:** [`seryus.ddns.net/unir/doctr-gpu`](https://seryus.ddns.net/unir/-/packages/container/doctr-gpu/latest)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/doctr_service
|
cd src/doctr_service
|
||||||
@@ -130,7 +110,7 @@ docker compose up -d
|
|||||||
|
|
||||||
> **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.
|
> **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)
|
**Imagen Docker:** [`seryus.ddns.net/unir/easyocr-gpu`](https://seryus.ddns.net/unir/-/packages/container/easyocr-gpu/latest)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/easyocr_service
|
cd src/easyocr_service
|
||||||
@@ -206,7 +186,7 @@ analyze_results(results, prefix='raytune_paddle', config_keys=PADDLE_OCR_CONFIG_
|
|||||||
|
|
||||||
### Servicios y Puertos
|
### Servicios y Puertos
|
||||||
|
|
||||||
**Tabla A4.** *Servicios Docker y puertos.*
|
**Tabla A3.** *Servicios Docker y puertos.*
|
||||||
|
|
||||||
| Servicio | Puerto | Script de Ajuste | Nota |
|
| Servicio | Puerto | Script de Ajuste | Nota |
|
||||||
|----------|--------|------------------|------|
|
|----------|--------|------------------|------|
|
||||||
@@ -223,7 +203,7 @@ Esta sección presenta los resultados completos de las evaluaciones comparativas
|
|||||||
|
|
||||||
### Comparativa General de Servicios
|
### Comparativa General de Servicios
|
||||||
|
|
||||||
**Tabla A5.** *Comparativa de servicios OCR en dataset de 45 páginas (GPU RTX 3060).*
|
**Tabla A4.** *Comparativa de servicios OCR en dataset de 45 páginas (GPU RTX 3060).*
|
||||||
|
|
||||||
| Servicio | CER | WER | Tiempo/Página | Tiempo Total | VRAM |
|
| Servicio | CER | WER | Tiempo/Página | Tiempo Total | VRAM |
|
||||||
|----------|-----|-----|---------------|--------------|------|
|
|----------|-----|-----|---------------|--------------|------|
|
||||||
@@ -238,7 +218,7 @@ Fuente: [`docs/metrics/metrics_paddle.md`](https://seryus.ddns.net/unir/MastersT
|
|||||||
|
|
||||||
Se ejecutaron 64 trials por servicio utilizando Ray Tune con Optuna sobre las páginas 5-10 del primer documento.
|
Se ejecutaron 64 trials por servicio utilizando Ray Tune con Optuna sobre las páginas 5-10 del primer documento.
|
||||||
|
|
||||||
**Tabla A6.** *Resultados del ajuste de hiperparámetros por servicio.*
|
**Tabla A5.** *Resultados del ajuste de hiperparámetros por servicio.*
|
||||||
|
|
||||||
| Servicio | CER Base | CER Ajustado | Mejora | Mejor Trial (5 páginas) |
|
| Servicio | CER Base | CER Ajustado | Mejora | Mejor Trial (5 páginas) |
|
||||||
|----------|----------|--------------|--------|-------------------------|
|
|----------|----------|--------------|--------|-------------------------|
|
||||||
@@ -251,7 +231,7 @@ Fuente: [`docs/metrics/metrics_paddle.md`](https://seryus.ddns.net/unir/MastersT
|
|||||||
|
|
||||||
### Distribución de trials por rango de CER (PaddleOCR)
|
### Distribución de trials por rango de CER (PaddleOCR)
|
||||||
|
|
||||||
**Tabla A7.** *Distribución de trials por rango de CER.*
|
**Tabla A6.** *Distribución de trials por rango de CER.*
|
||||||
|
|
||||||
| Rango CER | Número de trials | Porcentaje |
|
| Rango CER | Número de trials | Porcentaje |
|
||||||
|-----------|------------------|------------|
|
|-----------|------------------|------------|
|
||||||
@@ -307,7 +287,7 @@ La siguiente configuración logró el mejor rendimiento en el ajuste de hiperpar
|
|||||||
|
|
||||||
### Rendimiento CPU vs GPU
|
### Rendimiento CPU vs GPU
|
||||||
|
|
||||||
**Tabla A8.** *Comparación de rendimiento CPU vs GPU (PaddleOCR).*
|
**Tabla A7.** *Comparación de rendimiento CPU vs GPU (PaddleOCR).*
|
||||||
|
|
||||||
| Métrica | CPU | GPU (RTX 3060) | Aceleración |
|
| Métrica | CPU | GPU (RTX 3060) | Aceleración |
|
||||||
|---------|-----|----------------|-------------|
|
|---------|-----|----------------|-------------|
|
||||||
@@ -340,7 +320,7 @@ Fuente: [`src/raytune_paddle_subproc_results_20251207_192320.csv`](https://seryu
|
|||||||
|
|
||||||
### Análisis de Errores por Servicio
|
### Análisis de Errores por Servicio
|
||||||
|
|
||||||
**Tabla A9.** *Tipos de errores identificados por servicio OCR.*
|
**Tabla A8.** *Tipos de errores identificados por servicio OCR.*
|
||||||
|
|
||||||
| Servicio | Fortalezas | Debilidades | ¿Fine-tuning recomendado? |
|
| Servicio | Fortalezas | Debilidades | ¿Fine-tuning recomendado? |
|
||||||
|----------|------------|-------------|---------------------------|
|
|----------|------------|-------------|---------------------------|
|
||||||
@@ -353,7 +333,7 @@ Fuente: Análisis manual del debugset. Elaboración propia.
|
|||||||
|
|
||||||
Los resultados crudos de los 64 trials por servicio están disponibles en el repositorio:
|
Los resultados crudos de los 64 trials por servicio están disponibles en el repositorio:
|
||||||
|
|
||||||
**Tabla A10.** *Ubicación de archivos de resultados.*
|
**Tabla A9.** *Ubicación de archivos de resultados.*
|
||||||
|
|
||||||
| Servicio | Archivo CSV |
|
| Servicio | Archivo CSV |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user