import gradio as gr import transformers import torch import os # --- 1. Configuración del Modelo --- # Obtenemos el HF_TOKEN de los "Secrets" del Space. # ¡NUNCA escribas tu token directamente en el código! HF_TOKEN = os.environ.get("HF_TOKEN") if not HF_TOKEN: print("ADVERTENCIA: No se ha configurado el secret 'HF_TOKEN'.") # Si no hay token, la app puede fallar al cargar el modelo gated. # Para pruebas locales, puedes crear un archivo .env o setear la variable. # raise ValueError("Falta el HF_TOKEN. Configúralo en los secrets del Space.") # Cargamos el modelo Llama-3.2-1B-Instruct # Usamos un pipeline para facilitar la generación de texto try: generator = transformers.pipeline( "text-generation", model="meta-llama/Llama-3.2-1B-Instruct", dtype=torch.bfloat16, # Optimización para velocidad y memoria (reemplaza a torch_dtype) device_map="auto", # Usa GPU si está disponible token=HF_TOKEN # Token para acceder al modelo gated ) # --- INICIO DE LA CORRECCIÓN --- # CORRECCIÓN 1: Asegurarse de que pad_token_id esté configurado # Algunos modelos no tienen un pad_token_id por defecto, lo que causa el error 'NoneType' if generator.tokenizer.pad_token_id is None: generator.tokenizer.pad_token_id = generator.tokenizer.eos_token_id print("INFO: pad_token_id no estaba configurado. Se ha establecido en eos_token_id.") # --- FIN DE LA CORRECCIÓN --- print("Pipeline de Llama-3.2-1B cargado exitosamente.") except Exception as e: print(f"Error cargando el pipeline: {e}") # Si falla aquí, probablemente es por el token o falta de acceso. generator = None # Marcamos que falló # --- 2. Lógica de Generación --- def generate_title(text_input): """ Toma un texto (o historial) y genera un título conciso. """ if not generator: return "Error: El modelo no pudo cargarse. ¿Configuraste el HF_TOKEN y tienes acceso a meta-llama/Llama-3.2-1B-Instruct?" if not text_input or text_input.strip() == "": return "Por favor, introduce un texto." # Prompt engineering: Damos instrucciones claras al modelo. # Llama 3.2 usa un formato de chat específico. system_prompt = "Eres un experto en resumir textos en títulos cortos y llamativos. Te daré un texto o un historial de chat y tú generarás un título de entre 3 y 7 palabras. Responde SOLAMENTE con el título y nada más." user_prompt = f"Genera un título para el siguiente contenido:\n\n---\n{text_input}\n---" messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ] # --- INICIO DE LA CORRECCIÓN --- # CORRECCIÓN 2: Lista de terminadores robusta # El ID para "\n" (nueva línea) en Llama 3 es 13. # generator.tokenizer.eos_token_id es el ID de <|eot_id|> # Usamos una lista explícita de enteros para evitar 'None'. terminators_safe = list(set([ generator.tokenizer.eos_token_id, 13 # ID del token de nueva línea (\n) ])) # --- FIN DE LA CORRECCIÓN --- try: outputs = generator( messages, max_new_tokens=20, # Un título no necesita más de 20 tokens eos_token_id=terminators_safe, # Usamos la lista corregida do_sample=False, # Queremos la respuesta más probable, no creativa temperature=None, # No necesario si do_sample=False top_p=None, # No necesario si do_sample=False pad_token_id=generator.tokenizer.eos_token_id # Ahora es seguro usar esto ) # Extraemos la respuesta del asistente # La estructura es: outputs[0]["generated_text"] es una *lista* de mensajes # El último mensaje [-1] es el del asistente title = outputs[0]["generated_text"][-1]["content"] # Limpiamos el título (quitar espacios, comillas, etc.) title = title.strip().replace('"', '').replace("Título:", "").strip() if not title: return "No se pudo generar un título." return title except Exception as e: print(f"Error durante la generación: {e}") return f"Error al generar: {e}" # --- 3. Interfaz de Gradio --- with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown( """ # 🔥 Generador de Títulos con Llama-3.2-1B Introduce un texto largo o un historial de chat (copiado y pegado) y la IA generará un título corto y conciso. """ ) with gr.Row(): text_input = gr.Textbox( lines=15, label="Texto o Historial de Chat", placeholder="Pega tu contenido aquí. Por ejemplo:\n\nUser: ¿Qué es la IA?\nAssistant: La IA es...\nUser: ¿Y el machine learning?\n\nO simplemente pega un artículo largo." ) title_output = gr.Textbox( label="Título Generado", interactive=False # El usuario no puede editar esto ) generate_btn = gr.Button("🚀 Generar Título", variant="primary") # Conectamos el botón a la función # api_name="generate_title" habilita el endpoint /api/generate_title generate_btn.click( fn=generate_title, inputs=text_input, outputs=title_output, api_name="generate_title" ) gr.Examples( [ [ "User: Hola, ¿cómo estás?\nAssistant: ¡Hola! Estoy bien, soy un modelo de lenguaje. ¿En qué puedo ayudarte hoy?\nUser: Quería preguntarte sobre la historia de la computación.\nAssistant: Claro. La historia de la computación se remonta al ábaco, pero la primera computadora moderna fue el ENIAC en 1945." ], [ "La inteligencia artificial (IA) es un campo de la informática que se centra en la creación de sistemas que pueden realizar tareas que normalmente requieren inteligencia humana, como el aprendizaje, el razonamiento y la percepción. En los últimos años, la IA ha experimentado un crecimiento exponencial, impulsado por los avances en el aprendizaje profundo y la disponibilidad de grandes conjuntos de datos." ] ], inputs=text_input, label="Ejemplos de Entrada" ) # Lanzamos la aplicación if __name__ == "__main__": demo.launch()