Spaces:
Sleeping
Sleeping
Gemini APP
Browse files- app.py +126 -113
- requirements.txt +4 -2
app.py
CHANGED
|
@@ -1,127 +1,140 @@
|
|
| 1 |
import gradio as gr
|
|
|
|
|
|
|
| 2 |
import os
|
| 3 |
-
from huggingface_hub import InferenceClient
|
| 4 |
|
| 5 |
-
#
|
| 6 |
-
HF_TOKEN = os.environ.get("HF_TOKEN")
|
| 7 |
|
| 8 |
-
#
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
token=HF_TOKEN
|
| 12 |
-
)
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
"""
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
Args:
|
| 19 |
-
text_or_history: Puede ser texto simple o una lista de mensajes
|
| 20 |
-
max_length: Longitud máxima del título
|
| 21 |
-
|
| 22 |
-
Returns:
|
| 23 |
-
El título generado
|
| 24 |
"""
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
{
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
for message in client.chat_completion(
|
| 50 |
-
messages=messages,
|
| 51 |
-
max_tokens=max_length,
|
| 52 |
-
temperature=0.7,
|
| 53 |
-
stream=True
|
| 54 |
-
):
|
| 55 |
-
token = message.choices[0].delta.content
|
| 56 |
-
if token:
|
| 57 |
-
response += token
|
| 58 |
-
|
| 59 |
-
# Limpiar el título (quitar saltos de línea extra, etc.)
|
| 60 |
-
title = response.strip().split("\n")[0]
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
return title
|
| 63 |
-
|
| 64 |
except Exception as e:
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
text_input = gr.Textbox(
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
)
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
text_button.click(
|
| 82 |
-
fn=generate_title,
|
| 83 |
-
inputs=[text_input],
|
| 84 |
-
outputs=[text_output]
|
| 85 |
-
)
|
| 86 |
-
|
| 87 |
-
with gr.Tab("History/List Input"):
|
| 88 |
-
gr.Markdown("Enter conversation history as JSON format:")
|
| 89 |
-
gr.Markdown('Example: `[{"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi there!"}]`')
|
| 90 |
-
|
| 91 |
-
history_input = gr.Textbox(
|
| 92 |
-
label="Conversation History (JSON)",
|
| 93 |
-
placeholder='[{"role": "user", "content": "Your message here"}]',
|
| 94 |
-
lines=10
|
| 95 |
)
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
```
|
| 123 |
-
""")
|
| 124 |
-
|
| 125 |
-
# Lanzar la aplicación con API habilitada
|
| 126 |
if __name__ == "__main__":
|
| 127 |
-
demo.launch(
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
import transformers
|
| 3 |
+
import torch
|
| 4 |
import os
|
|
|
|
| 5 |
|
| 6 |
+
# --- 1. Configuración del Modelo ---
|
|
|
|
| 7 |
|
| 8 |
+
# Obtenemos el HF_TOKEN de los "Secrets" del Space.
|
| 9 |
+
# ¡NUNCA escribas tu token directamente en el código!
|
| 10 |
+
HF_TOKEN = os.environ.get("HF_TOKEN")
|
|
|
|
|
|
|
| 11 |
|
| 12 |
+
if not HF_TOKEN:
|
| 13 |
+
print("ADVERTENCIA: No se ha configurado el secret 'HF_TOKEN'.")
|
| 14 |
+
# Si no hay token, la app puede fallar al cargar el modelo gated.
|
| 15 |
+
# Para pruebas locales, puedes crear un archivo .env o setear la variable.
|
| 16 |
+
# raise ValueError("Falta el HF_TOKEN. Configúralo en los secrets del Space.")
|
| 17 |
+
|
| 18 |
+
# Cargamos el modelo Llama-3.2-1B-Instruct
|
| 19 |
+
# Usamos un pipeline para facilitar la generación de texto
|
| 20 |
+
try:
|
| 21 |
+
generator = transformers.pipeline(
|
| 22 |
+
"text-generation",
|
| 23 |
+
model="meta-llama/Llama-3.2-1B-Instruct",
|
| 24 |
+
model_kwargs={"torch_dtype": torch.bfloat16}, # Optimización para velocidad y memoria
|
| 25 |
+
device_map="auto", # Usa GPU si está disponible
|
| 26 |
+
token=HF_TOKEN # Token para acceder al modelo gated
|
| 27 |
+
)
|
| 28 |
+
print("Pipeline de Llama-3.2-1B cargado exitosamente.")
|
| 29 |
+
except Exception as e:
|
| 30 |
+
print(f"Error cargando el pipeline: {e}")
|
| 31 |
+
# Si falla aquí, probablemente es por el token o falta de acceso.
|
| 32 |
+
generator = None # Marcamos que falló
|
| 33 |
+
|
| 34 |
+
# --- 2. Lógica de Generación ---
|
| 35 |
+
|
| 36 |
+
def generate_title(text_input):
|
| 37 |
"""
|
| 38 |
+
Toma un texto (o historial) y genera un título conciso.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
"""
|
| 40 |
+
if not generator:
|
| 41 |
+
return "Error: El modelo no pudo cargarse. ¿Configuraste el HF_TOKEN y tienes acceso a meta-llama/Llama-3.2-1B-Instruct?"
|
| 42 |
+
|
| 43 |
+
if not text_input or text_input.strip() == "":
|
| 44 |
+
return "Por favor, introduce un texto."
|
| 45 |
+
|
| 46 |
+
# Prompt engineering: Damos instrucciones claras al modelo.
|
| 47 |
+
# Llama 3.2 usa un formato de chat específico.
|
| 48 |
+
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."
|
| 49 |
+
|
| 50 |
+
user_prompt = f"Genera un título para el siguiente contenido:\n\n---\n{text_input}\n---"
|
| 51 |
+
|
| 52 |
+
messages = [
|
| 53 |
+
{"role": "system", "content": system_prompt},
|
| 54 |
+
{"role": "user", "content": user_prompt},
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
# Parámetros para una respuesta corta (título)
|
| 58 |
+
# Definimos terminadores para que pare después del título
|
| 59 |
+
terminators = [
|
| 60 |
+
generator.tokenizer.eos_token_id,
|
| 61 |
+
generator.tokenizer.convert_tokens_to_ids("<|eot_id|>"),
|
| 62 |
+
generator.tokenizer.convert_tokens_to_ids("\n") # Parar si genera un salto de línea
|
| 63 |
+
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
+
try:
|
| 66 |
+
outputs = generator(
|
| 67 |
+
messages,
|
| 68 |
+
max_new_tokens=20, # Un título no necesita más de 20 tokens
|
| 69 |
+
eos_token_id=terminators,
|
| 70 |
+
do_sample=False, # Queremos la respuesta más probable, no creativa
|
| 71 |
+
temperature=None, # No necesario si do_sample=False
|
| 72 |
+
top_p=None, # No necesario si do_sample=False
|
| 73 |
+
pad_token_id=generator.tokenizer.eos_token_id # Evita warnings
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
# Extraemos la respuesta del asistente
|
| 77 |
+
# La estructura es: outputs[0]["generated_text"] es una *lista* de mensajes
|
| 78 |
+
# El último mensaje [-1] es el del asistente
|
| 79 |
+
title = outputs[0]["generated_text"][-1]["content"]
|
| 80 |
+
|
| 81 |
+
# Limpiamos el título (quitar espacios, comillas, etc.)
|
| 82 |
+
title = title.strip().replace('"', '').replace("Título:", "").strip()
|
| 83 |
+
|
| 84 |
+
if not title:
|
| 85 |
+
return "No se pudo generar un título."
|
| 86 |
+
|
| 87 |
return title
|
| 88 |
+
|
| 89 |
except Exception as e:
|
| 90 |
+
print(f"Error durante la generación: {e}")
|
| 91 |
+
return f"Error al generar: {e}"
|
| 92 |
+
|
| 93 |
+
# --- 3. Interfaz de Gradio ---
|
| 94 |
+
|
| 95 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 96 |
+
gr.Markdown(
|
| 97 |
+
"""
|
| 98 |
+
# 🔥 Generador de Títulos con Llama-3.2-1B
|
| 99 |
+
Introduce un texto largo o un historial de chat (copiado y pegado) y la IA generará un título corto y conciso.
|
| 100 |
+
"""
|
| 101 |
+
)
|
| 102 |
+
|
| 103 |
+
with gr.Row():
|
| 104 |
text_input = gr.Textbox(
|
| 105 |
+
lines=15,
|
| 106 |
+
label="Texto o Historial de Chat",
|
| 107 |
+
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."
|
| 108 |
)
|
| 109 |
+
title_output = gr.Textbox(
|
| 110 |
+
label="Título Generado",
|
| 111 |
+
interactive=False # El usuario no puede editar esto
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
)
|
| 113 |
+
|
| 114 |
+
generate_btn = gr.Button("🚀 Generar Título", variant="primary")
|
| 115 |
+
|
| 116 |
+
# Conectamos el botón a la función
|
| 117 |
+
# api_name="generate_title" habilita el endpoint /api/generate_title
|
| 118 |
+
generate_btn.click(
|
| 119 |
+
fn=generate_title,
|
| 120 |
+
inputs=text_input,
|
| 121 |
+
outputs=title_output,
|
| 122 |
+
api_name="generate_title"
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
+
gr.Examples(
|
| 126 |
+
[
|
| 127 |
+
[
|
| 128 |
+
"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."
|
| 129 |
+
],
|
| 130 |
+
[
|
| 131 |
+
"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."
|
| 132 |
+
]
|
| 133 |
+
],
|
| 134 |
+
inputs=text_input,
|
| 135 |
+
label="Ejemplos de Entrada"
|
| 136 |
+
)
|
| 137 |
+
|
| 138 |
+
# Lanzamos la aplicación
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
if __name__ == "__main__":
|
| 140 |
+
demo.launch()
|
requirements.txt
CHANGED
|
@@ -1,2 +1,4 @@
|
|
| 1 |
-
gradio
|
| 2 |
-
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
transformers
|
| 3 |
+
torch
|
| 4 |
+
accelerate
|