aldohenrique commited on
Commit
f168caf
·
verified ·
1 Parent(s): 67a5668

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +303 -52
app.py CHANGED
@@ -1,70 +1,321 @@
1
  import gradio as gr
2
  from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
3
  import torch
 
 
 
4
 
5
- # === Modelos leves recomendados ===
6
  MODEL_OPTIONS = {
7
- "DistilGPT2": "distilgpt2", # muito rápido e leve (~80MB)
8
- "TinyLLaMA": "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
 
9
  }
10
 
11
- # === Escolha o modelo padrão mais leve ===
12
- MODEL_NAME = MODEL_OPTIONS["DistilGPT2"]
13
-
14
- # === Carrega modelo e tokenizer uma vez ===
15
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
16
- model = AutoModelForCausalLM.from_pretrained(MODEL_NAME)
17
- gerador = pipeline(
18
- "text-generation",
19
- model=model,
20
- tokenizer=tokenizer,
21
- device=0 if torch.cuda.is_available() else -1,
22
- max_new_tokens=200,
23
- temperature=0.7,
24
- top_p=0.9,
25
- do_sample=True
26
- )
27
-
28
- # === Função principal ===
29
- def responder_como_aldo(pergunta):
30
- prompt = f"""Você é o professor Dr. Aldo Henrique, especialista em C, Java, Web e IA. Responda de forma clara, acadêmica e precisa.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- Pergunta: {pergunta}
33
- Resposta:"""
 
 
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  try:
36
- resposta = gerador(prompt, max_new_tokens=200)[0]["generated_text"]
37
- resposta_limpa = resposta.replace(prompt, "").strip()
38
- return resposta_limpa if resposta_limpa else "Desculpe, não consegui gerar uma resposta adequada."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  except Exception as e:
40
- return f"Erro: {str(e)}"
41
 
42
- # === Interface Gradio ===
43
- with gr.Blocks(title="Pergunte ao Dr. Aldo Henrique") as interface:
44
- gr.Markdown("## 🤖 Pergunte ao Dr. Aldo Henrique")
45
- gr.Markdown(f"**Modelo carregado:** `{MODEL_NAME}`")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- entrada = gr.Textbox(label="Pergunta", placeholder="Ex: Como usar ponteiros em C?", lines=4)
48
- saida = gr.Textbox(label="Resposta do Dr. Aldo", lines=8, interactive=False)
49
- botao = gr.Button("Responder")
50
-
51
- exemplos = gr.Examples(
52
- examples=[
53
- ["Como implementar uma lista ligada em C?"],
54
- ["Qual a diferença entre == e equals() em Java?"],
55
- ["Como funciona o machine learning?"],
56
- ["Explique os conceitos de HTML, CSS e JavaScript"],
57
- ["O que são algoritmos de ordenação?"]
58
- ],
59
- inputs=entrada
60
- )
61
-
62
- botao.click(fn=responder_como_aldo, inputs=entrada, outputs=saida)
63
-
64
- # === Lançamento com configurações otimizadas para HuggingFace ===
65
  if __name__ == "__main__":
 
 
66
  interface.launch(
67
  server_name="0.0.0.0",
68
  server_port=7860,
69
- share=False
 
 
 
70
  )
 
1
  import gradio as gr
2
  from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
3
  import torch
4
+ import time
5
+ import threading
6
+ from collections import deque
7
 
8
+ # === Modelos otimizados para velocidade ===
9
  MODEL_OPTIONS = {
10
+ "Microsoft DialoGPT": "microsoft/DialoGPT-small", # Otimizado para conversas
11
+ "DistilGPT2": "distilgpt2", # Backup rápido
12
+ "GPT2 Small": "gpt2" # Fallback
13
  }
14
 
15
+ # === Configurações otimizadas ===
16
+ MODEL_NAME = MODEL_OPTIONS["Microsoft DialoGPT"]
17
+ CACHE_SIZE = 50 # Cache das últimas respostas
18
+ MAX_TOKENS = 100 # Reduzido para velocidade
19
+ TEMPERATURE = 0.8 # Aumentado para criatividade
20
+
21
+ # === Cache para respostas frequentes ===
22
+ response_cache = {}
23
+ recent_questions = deque(maxlen=CACHE_SIZE)
24
+
25
+ # === Respostas pré-definidas para perguntas comuns ===
26
+ QUICK_RESPONSES = {
27
+ "ponteiros": """**Ponteiros em C** são variáveis que armazenam endereços de memória.
28
+
29
+ **Exemplo básico:**
30
+ ```c
31
+ int x = 10;
32
+ int *ptr = &x; // ptr aponta para x
33
+ printf("%d", *ptr); // Imprime 10
34
+ ```
35
+
36
+ **Usos principais:**
37
+ - Passagem por referência
38
+ - Alocação dinâmica de memória
39
+ - Estruturas de dados (listas, árvores)""",
40
+
41
+ "java equals": """**Diferença entre == e equals() em Java:**
42
+
43
+ **==** compara referências (endereços na memória)
44
+ **equals()** compara conteúdo dos objetos
45
+
46
+ **Exemplo:**
47
+ ```java
48
+ String a = new String("Hello");
49
+ String b = new String("Hello");
50
+ System.out.println(a == b); // false
51
+ System.out.println(a.equals(b)); // true
52
+ ```""",
53
+
54
+ "machine learning": """**Machine Learning** é um subcampo da IA onde máquinas aprendem padrões a partir de dados.
55
 
56
+ **Tipos principais:**
57
+ 1. **Supervisionado**: Aprende com exemplos rotulados
58
+ 2. **Não-supervisionado**: Encontra padrões em dados
59
+ 3. **Por reforço**: Aprende através de tentativa e erro
60
 
61
+ **Aplicações**: Reconhecimento de imagem, processamento de linguagem, recomendações.""",
62
+
63
+ "html css javascript": """**Tecnologias Web Fundamentais:**
64
+
65
+ **HTML**: Estrutura da página (esqueleto)
66
+ **CSS**: Estilização e layout (aparência)
67
+ **JavaScript**: Interatividade e lógica (comportamento)
68
+
69
+ **Analogia**:
70
+ - HTML = Estrutura da casa
71
+ - CSS = Decoração e pintura
72
+ - JavaScript = Eletricidade e automação""",
73
+
74
+ "algoritmos ordenação": """**Algoritmos de Ordenação:**
75
+
76
+ **Bubble Sort**: O(n²) - Simples, mas lento
77
+ **Quick Sort**: O(n log n) - Rápido e eficiente
78
+ **Merge Sort**: O(n log n) - Estável e confiável
79
+
80
+ **Exemplo Quick Sort:**
81
+ ```c
82
+ void quickSort(int arr[], int low, int high) {
83
+ if (low < high) {
84
+ int pi = partition(arr, low, high);
85
+ quickSort(arr, low, pi - 1);
86
+ quickSort(arr, pi + 1, high);
87
+ }
88
+ }
89
+ ```"""
90
+ }
91
+
92
+ def get_quick_response(pergunta):
93
+ """Verifica se há uma resposta rápida para a pergunta"""
94
+ pergunta_lower = pergunta.lower()
95
+
96
+ for keyword, response in QUICK_RESPONSES.items():
97
+ if keyword in pergunta_lower:
98
+ return response
99
+ return None
100
+
101
+ def load_model_optimized():
102
+ """Carrega modelo com configurações otimizadas"""
103
+ try:
104
+ print(f"🚀 Carregando modelo otimizado: {MODEL_NAME}")
105
+
106
+ # Carrega com configurações de velocidade
107
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, padding_side='left')
108
+ if tokenizer.pad_token is None:
109
+ tokenizer.pad_token = tokenizer.eos_token
110
+
111
+ model = AutoModelForCausalLM.from_pretrained(
112
+ MODEL_NAME,
113
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
114
+ low_cpu_mem_usage=True
115
+ )
116
+
117
+ # Pipeline otimizado
118
+ gerador = pipeline(
119
+ "text-generation",
120
+ model=model,
121
+ tokenizer=tokenizer,
122
+ device=0 if torch.cuda.is_available() else -1,
123
+ max_new_tokens=MAX_TOKENS,
124
+ temperature=TEMPERATURE,
125
+ top_p=0.9,
126
+ do_sample=True,
127
+ pad_token_id=tokenizer.eos_token_id
128
+ )
129
+
130
+ print("✅ Modelo carregado com sucesso!")
131
+ return gerador, tokenizer
132
+
133
+ except Exception as e:
134
+ print(f"❌ Erro ao carregar {MODEL_NAME}: {e}")
135
+ # Fallback para DistilGPT2
136
+ return load_fallback_model()
137
+
138
+ def load_fallback_model():
139
+ """Carrega modelo de fallback"""
140
+ try:
141
+ print("🔄 Carregando modelo de fallback...")
142
+ fallback_name = MODEL_OPTIONS["DistilGPT2"]
143
+
144
+ tokenizer = AutoTokenizer.from_pretrained(fallback_name)
145
+ if tokenizer.pad_token is None:
146
+ tokenizer.pad_token = tokenizer.eos_token
147
+
148
+ model = AutoModelForCausalLM.from_pretrained(fallback_name)
149
+
150
+ gerador = pipeline(
151
+ "text-generation",
152
+ model=model,
153
+ tokenizer=tokenizer,
154
+ device=-1, # Força CPU para economia
155
+ max_new_tokens=MAX_TOKENS,
156
+ temperature=TEMPERATURE,
157
+ do_sample=True
158
+ )
159
+
160
+ print("✅ Modelo de fallback carregado!")
161
+ return gerador, tokenizer
162
+
163
+ except Exception as e:
164
+ raise Exception(f"Falha ao carregar qualquer modelo: {e}")
165
+
166
+ # === Carrega modelo na inicialização ===
167
+ gerador, tokenizer = load_model_optimized()
168
+
169
+ def responder_como_aldo(pergunta):
170
+ """Função principal otimizada"""
171
+ if not pergunta.strip():
172
+ return "Por favor, faça uma pergunta específica."
173
+
174
+ start_time = time.time()
175
+
176
+ # 1. Verifica cache de respostas rápidas
177
+ quick_response = get_quick_response(pergunta)
178
+ if quick_response:
179
+ return f"📚 **Resposta Rápida do Dr. Aldo:**\n\n{quick_response}"
180
+
181
+ # 2. Verifica cache de respostas anteriores
182
+ pergunta_hash = hash(pergunta.lower().strip())
183
+ if pergunta_hash in response_cache:
184
+ cached_response = response_cache[pergunta_hash]
185
+ return f"💾 **Dr. Aldo responde:**\n\n{cached_response}"
186
+
187
+ # 3. Gera nova resposta
188
  try:
189
+ # Prompt otimizado e conciso
190
+ if "DialoGPT" in MODEL_NAME:
191
+ prompt = f"Professor: {pergunta}\nDr. Aldo:"
192
+ else:
193
+ prompt = f"Pergunta: {pergunta}\nDr. Aldo Henrique responde:"
194
+
195
+ # Geração com timeout implícito
196
+ response = gerador(
197
+ prompt,
198
+ max_new_tokens=MAX_TOKENS,
199
+ num_return_sequences=1,
200
+ truncation=True
201
+ )[0]["generated_text"]
202
+
203
+ # Limpa resposta
204
+ if "Dr. Aldo:" in response:
205
+ resposta_limpa = response.split("Dr. Aldo:")[-1].strip()
206
+ elif "responde:" in response:
207
+ resposta_limpa = response.split("responde:")[-1].strip()
208
+ else:
209
+ resposta_limpa = response.replace(prompt, "").strip()
210
+
211
+ # Remove repetições comuns
212
+ resposta_limpa = resposta_limpa.replace(pergunta, "").strip()
213
+
214
+ if not resposta_limpa or len(resposta_limpa) < 10:
215
+ resposta_limpa = "Desculpe, não consegui gerar uma resposta adequada. Tente reformular sua pergunta."
216
+
217
+ # Salva no cache
218
+ response_cache[pergunta_hash] = resposta_limpa
219
+ recent_questions.append(pergunta)
220
+
221
+ elapsed_time = time.time() - start_time
222
+
223
+ return f"🎓 **Dr. Aldo responde** ⚡ *({elapsed_time:.1f}s)*:\n\n{resposta_limpa}"
224
+
225
  except Exception as e:
226
+ return f"❌ **Erro temporário**: {str(e)}\n\nTente novamente ou reformule sua pergunta."
227
 
228
+ # === Interface Gradio otimizada ===
229
+ def create_interface():
230
+ with gr.Blocks(
231
+ title="Dr. Aldo Henrique - IA Educacional",
232
+ theme=gr.themes.Soft(),
233
+ css="""
234
+ .gradio-container { max-width: 900px; margin: auto; }
235
+ .output-text { font-family: 'Segoe UI', Arial, sans-serif; }
236
+ .quick-stats { background: #f0f0f0; padding: 10px; border-radius: 5px; }
237
+ """
238
+ ) as interface:
239
+
240
+ gr.Markdown("""
241
+ # 🎓 Dr. Aldo Henrique - Professor Virtual
242
+ ### 💻 Especialista em C, Java, Web e Inteligência Artificial
243
+ """)
244
+
245
+ with gr.Row():
246
+ gr.Markdown(f"""
247
+ <div class="quick-stats">
248
+ 📊 <strong>Status:</strong> Modelo {MODEL_NAME.split('/')[-1]} carregado<br>
249
+ ⚡ <strong>Performance:</strong> Otimizado para respostas rápidas<br>
250
+ 💾 <strong>Cache:</strong> {len(QUICK_RESPONSES)} respostas instantâneas
251
+ </div>
252
+ """)
253
+
254
+ with gr.Row():
255
+ with gr.Column(scale=2):
256
+ entrada = gr.Textbox(
257
+ label="🤔 Sua pergunta para o Dr. Aldo",
258
+ placeholder="Ex: Como usar ponteiros em C? ou Explique machine learning",
259
+ lines=3,
260
+ max_lines=5
261
+ )
262
+
263
+ with gr.Row():
264
+ botao = gr.Button("🚀 Perguntar", variant="primary", size="lg")
265
+ limpar = gr.Button("🗑️ Limpar", variant="secondary")
266
+
267
+ with gr.Column(scale=3):
268
+ saida = gr.Textbox(
269
+ label="💡 Resposta do Dr. Aldo",
270
+ lines=12,
271
+ max_lines=20,
272
+ interactive=False,
273
+ elem_classes=["output-text"]
274
+ )
275
+
276
+ # Exemplos organizados por categoria
277
+ with gr.Accordion("📚 Exemplos de Perguntas", open=False):
278
+ gr.Examples(
279
+ examples=[
280
+ ["Como usar ponteiros em C?"],
281
+ ["Diferença entre == e equals() em Java"],
282
+ ["O que é machine learning?"],
283
+ ["Explique HTML, CSS e JavaScript"],
284
+ ["Quais são os algoritmos de ordenação?"],
285
+ ["Como implementar uma lista ligada?"],
286
+ ["O que são estruturas de dados?"],
287
+ ["Como funciona recursão?"],
288
+ ["Diferença entre pilha e fila"],
289
+ ["O que é programação orientada a objetos?"]
290
+ ],
291
+ inputs=entrada,
292
+ label="Clique em qualquer exemplo"
293
+ )
294
+
295
+ # Eventos
296
+ botao.click(fn=responder_como_aldo, inputs=entrada, outputs=saida)
297
+ limpar.click(fn=lambda: ("", ""), outputs=[entrada, saida])
298
+ entrada.submit(fn=responder_como_aldo, inputs=entrada, outputs=saida)
299
+
300
+ gr.Markdown("""
301
+ ---
302
+ <center>
303
+ ✨ <strong>Dica:</strong> Para respostas mais rápidas, use palavras-chave como "ponteiros", "java equals", "machine learning"<br>
304
+ 🔧 <strong>Desenvolvido com:</strong> Transformers + Gradio | <strong>Otimizado para:</strong> Educação em Programação
305
+ </center>
306
+ """)
307
 
308
+ return interface
309
+
310
+ # === Lançamento ===
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  if __name__ == "__main__":
312
+ print("🎯 Iniciando Dr. Aldo Henrique - Versão Otimizada")
313
+ interface = create_interface()
314
  interface.launch(
315
  server_name="0.0.0.0",
316
  server_port=7860,
317
+ share=False,
318
+ show_error=True,
319
+ show_tips=False,
320
+ quiet=False
321
  )