Spaces:
Runtime error
Runtime error
Upload 2 files
Browse files- app.py +100 -0
- requirements.txt +4 -0
app.py
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from flask import Flask, request, jsonify
|
3 |
+
from flask_cors import CORS
|
4 |
+
import requests
|
5 |
+
from transformers import AutoTokenizer
|
6 |
+
|
7 |
+
app = Flask(__name__)
|
8 |
+
CORS(app) # Esto es crucial para permitir peticiones desde tu index.html en GitHub Pages
|
9 |
+
|
10 |
+
# --- Configuración de la API de Hugging Face ---
|
11 |
+
# Es VITAL que este token NO esté aquí directamente en un repo público.
|
12 |
+
# Lo obtendremos de las variables de entorno en Hugging Face Spaces.
|
13 |
+
HUGGINGFACE_API_TOKEN = os.getenv("HF_API_TOKEN")
|
14 |
+
|
15 |
+
# URL del modelo de inferencia de Hugging Face.
|
16 |
+
# Usa el modelo Falcon-H1-1.5B-Deep-Instruct que te interesa.
|
17 |
+
HUGGINGFACE_API_URL = "https://api-inference.huggingface.co/models/tiiuae/Falcon-H1-1.5B-Deep-Instruct"
|
18 |
+
|
19 |
+
# Inicializa el tokenizador (solo para formatear el chat, no para cargar el modelo completo)
|
20 |
+
try:
|
21 |
+
tokenizer = AutoTokenizer.from_pretrained("tiiuae/Falcon-H1-1.5B-Deep-Instruct")
|
22 |
+
except Exception as e:
|
23 |
+
print(f"Error al inicializar el tokenizador: {e}")
|
24 |
+
tokenizer = None # En caso de error, el tokenizer será None
|
25 |
+
|
26 |
+
@app.route('/chat', methods=['POST'])
|
27 |
+
def chat():
|
28 |
+
if not HUGGINGFACE_API_TOKEN:
|
29 |
+
return jsonify({"error": "Hugging Face API token no configurado."}), 500
|
30 |
+
|
31 |
+
user_message = request.json.get('message')
|
32 |
+
conversation_history = request.json.get('history', [])
|
33 |
+
|
34 |
+
if not user_message:
|
35 |
+
return jsonify({"error": "Mensaje no proporcionado"}), 400
|
36 |
+
|
37 |
+
# Personalidad de Amside AI (System Prompt)
|
38 |
+
system_message = (
|
39 |
+
"Eres Amside AI, una inteligencia artificial creada por Hodelygil. "
|
40 |
+
"Tu propósito principal es asistir en el estudio y el aprendizaje, "
|
41 |
+
"proporcionando información y explicaciones detalladas. "
|
42 |
+
"Sin embargo, también eres amigable y puedes mantener conversaciones informales y agradables. "
|
43 |
+
"Responde de manera informativa y útil, pero con un tono conversacional."
|
44 |
+
)
|
45 |
+
|
46 |
+
# Formatear el historial de conversación para el modelo
|
47 |
+
messages = [{"role": "system", "content": system_message}]
|
48 |
+
for human_msg, ai_msg in conversation_history:
|
49 |
+
messages.append({"role": "user", "content": human_msg})
|
50 |
+
messages.append({"role": "assistant", "content": ai_msg})
|
51 |
+
messages.append({"role": "user", "content": user_message})
|
52 |
+
|
53 |
+
# Usar el tokenizador para aplicar la plantilla de chat
|
54 |
+
# Esto es vital para que el modelo entienda el formato del diálogo.
|
55 |
+
if tokenizer:
|
56 |
+
formatted_input = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
|
57 |
+
else:
|
58 |
+
# Fallback simple si el tokenizer no pudo inicializarse
|
59 |
+
formatted_input = "\n".join([f"{m['role']}: {m['content']}" for m in messages]) + "\nassistant:"
|
60 |
+
|
61 |
+
|
62 |
+
# Datos a enviar a la API de Hugging Face
|
63 |
+
payload = {
|
64 |
+
"inputs": formatted_input,
|
65 |
+
"parameters": {
|
66 |
+
"max_new_tokens": 500,
|
67 |
+
"do_sample": True,
|
68 |
+
"temperature": 0.7,
|
69 |
+
"top_p": 0.9,
|
70 |
+
"repetition_penalty": 1.1,
|
71 |
+
"return_full_text": False # Para que solo devuelva la respuesta del modelo
|
72 |
+
}
|
73 |
+
}
|
74 |
+
headers = {
|
75 |
+
"Authorization": f"Bearer {HUGGINGFACE_API_TOKEN}"
|
76 |
+
}
|
77 |
+
|
78 |
+
try:
|
79 |
+
response = requests.post(HUGGINGFACE_API_URL, headers=headers, json=payload)
|
80 |
+
response.raise_for_status() # Lanza una excepción si la petición HTTP falla (4xx o 5xx)
|
81 |
+
result = response.json()
|
82 |
+
|
83 |
+
# La respuesta de la API es una lista de diccionarios, y el texto está en 'generated_text'
|
84 |
+
generated_text = result[0].get("generated_text", "No se pudo generar respuesta.")
|
85 |
+
return jsonify({"response": generated_text})
|
86 |
+
|
87 |
+
except requests.exceptions.RequestException as e:
|
88 |
+
print(f"Error al llamar a la API de Hugging Face: {e}")
|
89 |
+
return jsonify({"error": f"Error al comunicarse con la API de IA: {e}"}), 500
|
90 |
+
except IndexError: # Si result está vacío
|
91 |
+
return jsonify({"error": "La API de IA devolvió una respuesta inesperada o vacía."}), 500
|
92 |
+
except Exception as e:
|
93 |
+
print(f"Error inesperado: {e}")
|
94 |
+
return jsonify({"error": f"Error inesperado en el servidor: {e}"}), 500
|
95 |
+
|
96 |
+
if __name__ == '__main__':
|
97 |
+
# En Hugging Face Spaces, la app se ejecuta con un servidor Gunicorn/Uvicorn,
|
98 |
+
# así que esta parte solo es útil para pruebas locales.
|
99 |
+
# app.run(host='0.0.0.0', port=5000, debug=True)
|
100 |
+
pass # No hacemos un app.run() aquí para que Spaces lo maneje correctamente
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Flask==3.1.0
|
2 |
+
Flask-Cors==4.0.1
|
3 |
+
requests==2.32.3
|
4 |
+
transformers>=4.40.0
|