Overglitch's picture
Update app.py
0a6178e verified
import gradio as gr
from modules.extractive import TFIDFSummarizer, TextRankSummarizer, CombinedSummarizer, BERTSummarizer
from modules.abstractive import load_summarizers, abstractive_summary
from modules.preprocessing import Preprocessor, PDFProcessor
from modules.utils import handle_long_text
# Cargar modelos abstractivos finetuneados
summarizers = load_summarizers()
# Ejemplo de texto
EXAMPLE_TEXT = """
La inteligencia artificial (IA) ha revolucionado múltiples industrias, desde la medicina hasta el transporte.
Los avances en modelos de lenguaje, como T5, BART y PEGASUS, permiten aplicaciones innovadoras como la generación automática de resúmenes, lo cual facilita el acceso a información clave en documentos extensos.
"""
# Función para procesar el archivo cargado
def process_file(file):
"""
Procesa un archivo cargado y extrae texto si es un PDF válido.
Args:
file (UploadedFile): Archivo subido por el usuario.
Returns:
str: Texto extraído del archivo o mensaje de error.
"""
if file is not None:
pdf_processor = PDFProcessor()
input_text = pdf_processor.pdf_to_text(file.name)
if input_text.strip():
return input_text
return "El archivo no contiene texto procesable."
return "Por favor, cargue un archivo válido."
# Función para cargar un ejemplo de texto
def load_example_text():
"""
Devuelve un ejemplo de texto predefinido.
Returns:
str: Texto de ejemplo.
"""
return EXAMPLE_TEXT
# Función para cargar y limpiar el contenido de un archivo
def process_uploaded_file(file):
"""
Procesa un archivo, lo limpia y devuelve su contenido en texto.
Args:
file (UploadedFile): Archivo subido.
Returns:
str: Texto limpio extraído del archivo.
"""
raw_text = process_file(file)
if "El archivo no contiene" not in raw_text and "Por favor" not in raw_text:
preprocessor = Preprocessor()
return preprocessor.clean_text(raw_text)
return raw_text
#
def summarize(input_text, file, summary_type, method, num_sentences, model_name, max_length, num_beams):
"""
Genera un resumen basado en el texto de entrada o archivo cargado.
Args:
input_text (str): Texto ingresado por el usuario.
file (UploadedFile): Archivo subido por el usuario.
summary_type (str): Tipo de resumen: Extractivo, Abstractivo o Combinado.
method (str): Método de resumen extractivo.
num_sentences (int): Número de oraciones para el resumen extractivo.
model_name (str): Nombre del modelo para resumen abstractivo.
max_length (int): Longitud máxima del resumen generado.
num_beams (int): Número de haces para búsqueda en el modelo.
Returns:
str: Resumen generado o mensaje de error.
"""
preprocessor = Preprocessor()
# Procesar archivo si se sube uno
if file is not None:
input_text = process_file(file)
# Validar que haya texto para resumir
if not input_text.strip():
return "Por favor, ingrese texto o cargue un archivo válido."
cleaned_text = preprocessor.clean_text(input_text)
# Procesar según el tipo de resumen seleccionado
if summary_type == "Extractivo":
if method == "TF-IDF":
summarizer = TFIDFSummarizer()
elif method == "TextRank":
summarizer = TextRankSummarizer()
elif method == "BERT":
summarizer = BERTSummarizer()
elif method == "TF-IDF + TextRank":
summarizer = CombinedSummarizer()
else:
return "Método no válido para resumen extractivo."
return summarizer.summarize(
preprocessor.split_into_sentences(cleaned_text),
preprocessor.clean_sentences(preprocessor.split_into_sentences(cleaned_text)),
num_sentences,
)
elif summary_type == "Abstractivo":
if model_name not in summarizers:
return "Modelo no disponible para resumen abstractivo."
return handle_long_text(
cleaned_text,
summarizers[model_name][0],
summarizers[model_name][1],
max_length=max_length,
stride=128,
)
elif summary_type == "Combinado":
if model_name not in summarizers:
return "Modelo no disponible para resumen abstractivo."
extractive_summary = TFIDFSummarizer().summarize(
preprocessor.split_into_sentences(cleaned_text),
preprocessor.clean_sentences(preprocessor.split_into_sentences(cleaned_text)),
num_sentences,
)
return handle_long_text(
extractive_summary,
summarizers[model_name][0],
summarizers[model_name][1],
max_length=max_length,
stride=128,
)
return "Seleccione un tipo de resumen válido."
# Interfaz dinámica
with gr.Blocks() as interface:
gr.Markdown("# Aplicación Híbrida para Resumir Documentos de Forma Extractiva y Abstractiva")
# Entrada de texto o archivo
with gr.Row():
with gr.Column(scale=2):
input_text = gr.Textbox(lines=9, label="Ingrese texto", interactive=True)
with gr.Row():
load_example_button = gr.Button("Load Example")
upload_file_button = gr.Button("Upload File")
with gr.Column(scale=1):
file = gr.File(label="Subir archivo (PDF, TXT)")
# Acciones de botones
load_example_button.click(
load_example_text,
inputs=[],
outputs=[input_text],
)
upload_file_button.click(
process_uploaded_file,
inputs=[file],
outputs=[input_text],
)
# Selección de tipo de resumen y opciones dinámicas
summary_type = gr.Radio(
["Extractivo", "Abstractivo", "Combinado"],
label="Tipo de resumen",
value="Extractivo",
)
method = gr.Radio(
["TF-IDF", "TextRank", "BERT", "TF-IDF + TextRank"],
label="Método Extractivo",
visible=True,
)
num_sentences = gr.Slider(
1, 10, value=3, step=1, label="Número de oraciones (Extractivo)", visible=True
)
model_name = gr.Radio(
["Pegasus", "T5", "BART"],
label="Modelo Abstractivo",
visible=False,
)
max_length = gr.Slider(
50, 300, value=128, step=10, label="Longitud máxima (Abstractivo)", visible=False
)
num_beams = gr.Slider(
1, 10, value=4, step=1, label="Número de haces (Abstractivo)", visible=False
)
def update_options(summary_type):
if summary_type == "Extractivo":
return (
gr.update(visible=True), gr.update(visible=True), gr.update(visible=False), gr.update(visible=False),
gr.update(visible=False))
elif summary_type == "Abstractivo":
return (
gr.update(visible=False), gr.update(visible=False), gr.update(visible=True), gr.update(visible=True),
gr.update(visible=True))
elif summary_type == "Combinado":
return (gr.update(visible=True), gr.update(visible=True), gr.update(visible=True), gr.update(visible=True),
gr.update(visible=True))
else:
return (
gr.update(visible=False), gr.update(visible=False), gr.update(visible=False), gr.update(visible=False),
gr.update(visible=False))
summary_type.change(
update_options,
inputs=[summary_type],
outputs=[method, num_sentences, model_name, max_length, num_beams],
)
summarize_button = gr.Button("Generar Resumen")
output = gr.Textbox(lines=10, label="Resumen generado", interactive=True)
copy_button = gr.Button("Copiar Resumen")
summarize_button.click(
summarize,
inputs=[input_text, file, summary_type, method, num_sentences, model_name, max_length, num_beams],
outputs=output,
)
def copy_summary(summary):
return summary
copy_button.click(
fn=copy_summary,
inputs=[output],
outputs=[output],
js="""function(summary) { navigator.clipboard.writeText(summary); return summary; }""",
)
if __name__ == "__main__":
interface.launch()