File size: 4,993 Bytes
fc8535f
34f9233
fc8535f
 
 
 
 
 
4f94531
 
 
 
 
 
 
 
 
 
 
 
 
34f9233
ffc2174
34f9233
 
 
ffc2174
34f9233
 
 
 
 
 
 
 
 
fc8535f
4f94531
ffc2174
fc8535f
4f94531
fc8535f
0728541
fc8535f
 
 
 
 
 
 
 
 
 
 
0728541
fc8535f
 
 
4f94531
 
fc8535f
 
 
 
4f94531
fc8535f
 
 
4f94531
0728541
fc8535f
 
 
 
 
 
 
34f9233
fc8535f
ffc2174
34f9233
 
 
 
 
 
4f94531
9e4f56c
fc8535f
34f9233
 
 
 
 
 
 
9e4f56c
34f9233
4f94531
0728541
34f9233
 
0728541
34f9233
0728541
34f9233
 
 
0728541
34f9233
 
 
 
 
 
0728541
34f9233
 
 
 
 
0728541
34f9233
 
 
9e4f56c
 
34f9233
 
 
ffc2174
0b10f72
ffc2174
 
0b10f72
ffc2174
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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
126
127
128
129
130
131
132
133
134
135
136
137
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
import gradio as gr

# Variables globales para el modelo de chat
chat_model_state = None
chat_tokenizer_state = None

# Inicialización de ZeroGPU (opcional)
def initialize_zero_gpu():
    """Inicializa ZeroGPU si es requerido por el entorno."""
    try:
        import spaces
        spaces.GPU(lambda x: x)  # Realiza una inicialización dummy
        print("ZeroGPU inicializado correctamente.")
    except ImportError:
        print("ZeroGPU no está disponible o no es necesario en este entorno.")

# Llamamos a la inicialización de ZeroGPU al inicio
initialize_zero_gpu()

def load_chat_model():
    """Función para cargar el modelo de chat."""
    global chat_model_state, chat_tokenizer_state
    try:
        model_name = "Qwen/Qwen2.5-3B-Instruct"
        # Cargar el modelo en CPU o GPU según disponibilidad
        chat_model_state = AutoModelForCausalLM.from_pretrained(
            model_name,
            torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
            device_map="auto" if torch.cuda.is_available() else None
        )
        chat_tokenizer_state = AutoTokenizer.from_pretrained(model_name)
        print("Modelo cargado exitosamente.")
    except Exception as e:
        print(f"Error al cargar el modelo de chat: {e}")

def generate_response(messages, model, tokenizer):
    """Genera una respuesta usando el modelo de chat."""
    try:
        if model is None or tokenizer is None:
            raise ValueError("El modelo de chat o el tokenizer no están cargados.")
        
        # Construir el prompt manualmente a partir del historial de mensajes
        prompt = ""
        for message in messages:
            role = message.get("role", "")
            content = message.get("content", "")
            if role == "system":
                prompt += f"System: {content}\n"
            elif role == "user":
                prompt += f"User: {content}\n"
            elif role == "assistant":
                prompt += f"Assistant: {content}\n"
        
        prompt += "Assistant:"

        # Tokenizar el prompt
        model_inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
        generated_ids = model.generate(
            **model_inputs,
            max_new_tokens=512,
            temperature=0.7,
            top_p=0.95,
            eos_token_id=tokenizer.eos_token_id,
        )

        # Decodificar la respuesta generada
        generated_text = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
        
        # Extraer solo la respuesta del asistente
        response = generated_text[len(prompt):].strip()
        return response
    except Exception as e:
        print(f"Error en generate_response: {e}")
        return "Lo siento, ocurrió un error al generar la respuesta."

# Gradio Interface
with gr.Blocks() as app_chat:
    gr.Markdown("### Chatbot Simple (CPU/GPU Compatible)")
    chatbot_interface = gr.Chatbot(label="Conversación")
    text_input_chat = gr.Textbox(label="Escribe tu mensaje", lines=1)
    send_btn_chat = gr.Button("Enviar")
    clear_btn_chat = gr.Button("Limpiar Conversación")

    conversation_state = gr.State(
        value=[{"role": "system", "content": "Eres un chatbot. Responde a las preguntas del usuario de manera concisa y clara."}]
    )

    def process_input(text, history, conv_state):
        """Procesa la entrada de texto del usuario y genera una respuesta."""
        if not text.strip():
            return history, conv_state, ""
        
        conv_state.append({"role": "user", "content": text})
        history.append((text, None))

        # Generar la respuesta del modelo de chat
        response = generate_response(conv_state, chat_model_state, chat_tokenizer_state)

        conv_state.append({"role": "assistant", "content": response})
        history[-1] = (text, response)

        return history, conv_state, ""

    def clear_conversation():
        """Resetea la conversación"""
        return [], [{"role": "system", "content": "Eres un chatbot. Responde a las preguntas del usuario de manera concisa y clara."}]

    # Manejar entrada de texto y botones
    text_input_chat.submit(
        process_input,
        inputs=[text_input_chat, chatbot_interface, conversation_state],
        outputs=[chatbot_interface, conversation_state, text_input_chat],
    )

    send_btn_chat.click(
        process_input,
        inputs=[text_input_chat, chatbot_interface, conversation_state],
        outputs=[chatbot_interface, conversation_state, text_input_chat],
    )

    clear_btn_chat.click(
        clear_conversation,
        outputs=[chatbot_interface, conversation_state],
    )

# Cargar el modelo al iniciar
load_chat_model()

# Ejecutar la aplicación con configuración segura
app_chat.launch(
    server_name="0.0.0.0",  # Permite acceso local
    server_port=7860,  # Puerto local
    share=True  # Crea un enlace público
)