File size: 5,538 Bytes
3eccbe1
0c4b567
 
 
 
3eccbe1
0c4b567
 
 
 
 
 
 
 
a8c5e8d
0c4b567
 
 
 
 
 
 
 
 
 
50a507d
0c4b567
 
 
 
 
 
 
 
 
 
a8c5e8d
0c4b567
 
a8c5e8d
0c4b567
 
 
 
 
 
 
 
50a507d
0c4b567
 
a8c5e8d
0c4b567
 
 
 
 
 
 
a8c5e8d
0c4b567
 
 
 
 
 
 
 
 
a8c5e8d
0c4b567
 
 
 
 
 
 
 
 
 
 
 
 
a8c5e8d
0c4b567
50a507d
0c4b567
 
50a507d
0c4b567
 
 
50a507d
 
 
0890b11
50a507d
0890b11
50a507d
0c4b567
0890b11
0c4b567
 
50a507d
0c4b567
50a507d
0890b11
50a507d
 
 
 
3eccbe1
50a507d
 
0c4b567
 
 
 
50a507d
0c4b567
50a507d
0c4b567
50a507d
0c4b567
 
50a507d
 
 
0c4b567
 
50a507d
a8c5e8d
50a507d
0c4b567
 
 
 
 
 
50a507d
0c4b567
 
 
50a507d
 
0c4b567
50a507d
 
 
a8c5e8d
 
 
0c4b567
a8c5e8d
0c4b567
a8c5e8d
0c4b567
a8c5e8d
0c4b567
50a507d
0c4b567
50a507d
 
 
0c4b567
 
 
50a507d
0c4b567
50a507d
a8c5e8d
0890b11
50a507d
 
 
 
 
 
 
0c4b567
 
 
 
50a507d
3eccbe1
 
0c4b567
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import gradio as gr
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import warnings
warnings.filterwarnings("ignore")

# Cache global para modelos
model_cache = {}

def load_model(model_name):
    """Carrega modelo com cache para evitar recarregamentos"""
    if model_name in model_cache:
        return model_cache[model_name]
    
    try:
        if "blenderbot" in model_name.lower():
            # Para modelos de conversação
            pipe = pipeline(
                "conversational",
                model=model_name,
                tokenizer=model_name,
                device=-1,  # CPU
                max_length=150,
                truncation=True
            )
        else:
            # Para modelos de geração de texto
            pipe = pipeline(
                "text-generation",
                model=model_name,
                tokenizer=model_name,
                device=-1,  # CPU
                max_length=100,
                truncation=True,
                pad_token_id=50256
            )
        
        model_cache[model_name] = pipe
        return pipe
        
    except Exception as e:
        return None

def chat_with_model(message, history, model_name):
    """Conversa com o modelo selecionado"""
    try:
        # Carregar modelo
        pipe = load_model(model_name)
        
        if pipe is None:
            return "❌ Erro ao carregar modelo. Tente outro modelo."
        
        # Gerar resposta
        if "blenderbot" in model_name.lower():
            # Conversational pipeline
            from transformers import Conversation
            conversation = Conversation(message)
            result = pipe(conversation)
            response = result.generated_responses[-1]
        else:
            # Text generation pipeline
            result = pipe(
                message,
                max_new_tokens=50,
                temperature=0.7,
                do_sample=True,
                pad_token_id=50256,
                eos_token_id=50256
            )
            
            generated_text = result[0]['generated_text']
            # Remover o input original da resposta
            if generated_text.startswith(message):
                response = generated_text[len(message):].strip()
            else:
                response = generated_text.strip()
            
            # Se resposta vazia, usar parte da geração
            if not response:
                response = generated_text[-100:].strip()
        
        return response if response else "🤔 Modelo não gerou uma resposta clara."
        
    except Exception as e:
        return f"🚨 Erro: {str(e)[:100]}... Tente um modelo menor."

# Modelos otimizados para Spaces (menores e mais rápidos)
MODELOS_DISPONIVEIS = [
    "distilgpt2",
    "gpt2", 
    "microsoft/DialoGPT-small",
    "facebook/blenderbot_small-90M"
]

def responder(message, history, modelo_selecionado):
    if not message.strip():
        return history, ""
    
    # Adicionar mensagem do usuário
    history.append([message, "🤖 Gerando resposta..."])
    
    # Obter resposta
    resposta = chat_with_model(message, history, modelo_selecionado)
    
    # Atualizar com resposta real
    history[-1][1] = resposta
    
    return history, ""

def limpar_chat():
    return []

def info_modelo(modelo):
    info = {
        "distilgpt2": "⚡ **DistilGPT-2** - Rápido e eficiente",
        "gpt2": "📝 **GPT-2** - Geração de texto criativo", 
        "microsoft/DialoGPT-small": "💬 **DialoGPT** - Conversação natural",
        "facebook/blenderbot_small-90M": "🤖 **BlenderBot** - Chat empático"
    }
    return info.get(modelo, "🤖 Modelo selecionado")

# Interface Gradio
with gr.Blocks(
    title="🤖 Chat Multi-Modelo Local",
    theme=gr.themes.Soft()
) as demo:
    
    gr.Markdown("""
    # 🤖 **Chat Multi-Modelo Local**
    ### ⚡ Modelos rodando diretamente no Hugging Face Spaces
    """)
    
    with gr.Row():
        modelo = gr.Dropdown(
            choices=MODELOS_DISPONIVEIS,
            value="distilgpt2",
            label="🎯 Escolha o Modelo",
            info="Modelos otimizados para Spaces"
        )
        
        info_display = gr.Markdown(
            info_modelo("distilgpt2")
        )
    
    chatbot = gr.Chatbot(
        height=400,
        label="💬 Conversa",
        avatar_images=["👤", "🤖"]
    )
    
    with gr.Row():
        msg = gr.Textbox(
            placeholder="Digite sua mensagem...",
            container=False,
            scale=4
        )
        send = gr.Button("📤", scale=1, variant="primary")
    
    clear = gr.Button("🗑️ Limpar Chat")
    
    # Exemplos
    gr.Examples(
        examples=[
            "Olá! Como você está?",
            "Me conte uma piada",
            "Qual é a capital do Brasil?",
            "Escreva um poema curto"
        ],
        inputs=msg
    )
    
    # Eventos
    send.click(responder, [msg, chatbot, modelo], [chatbot, msg])
    msg.submit(responder, [msg, chatbot, modelo], [chatbot, msg])
    clear.click(limpar_chat, outputs=chatbot)
    modelo.change(info_modelo, inputs=modelo, outputs=info_display)
    
    gr.Markdown("""
    ---
    ### ℹ️ **Informações:**
    - 🏃‍♂️ **Modelos locais** - Sem dependência de APIs externas
    - ⚡ **Otimizados** - Para funcionar bem no Spaces
    - 🔄 **Primeiro uso** - Pode demorar para carregar modelo
    """)

if __name__ == "__main__":
    demo.launch()