aldohenrique's picture
Update app.py
f168caf verified
raw
history blame
11.2 kB
import gradio as gr
from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM
import torch
import time
import threading
from collections import deque
# === Modelos otimizados para velocidade ===
MODEL_OPTIONS = {
"Microsoft DialoGPT": "microsoft/DialoGPT-small", # Otimizado para conversas
"DistilGPT2": "distilgpt2", # Backup rápido
"GPT2 Small": "gpt2" # Fallback
}
# === Configurações otimizadas ===
MODEL_NAME = MODEL_OPTIONS["Microsoft DialoGPT"]
CACHE_SIZE = 50 # Cache das últimas respostas
MAX_TOKENS = 100 # Reduzido para velocidade
TEMPERATURE = 0.8 # Aumentado para criatividade
# === Cache para respostas frequentes ===
response_cache = {}
recent_questions = deque(maxlen=CACHE_SIZE)
# === Respostas pré-definidas para perguntas comuns ===
QUICK_RESPONSES = {
"ponteiros": """**Ponteiros em C** são variáveis que armazenam endereços de memória.
**Exemplo básico:**
```c
int x = 10;
int *ptr = &x; // ptr aponta para x
printf("%d", *ptr); // Imprime 10
```
**Usos principais:**
- Passagem por referência
- Alocação dinâmica de memória
- Estruturas de dados (listas, árvores)""",
"java equals": """**Diferença entre == e equals() em Java:**
**==** compara referências (endereços na memória)
**equals()** compara conteúdo dos objetos
**Exemplo:**
```java
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
```""",
"machine learning": """**Machine Learning** é um subcampo da IA onde máquinas aprendem padrões a partir de dados.
**Tipos principais:**
1. **Supervisionado**: Aprende com exemplos rotulados
2. **Não-supervisionado**: Encontra padrões em dados
3. **Por reforço**: Aprende através de tentativa e erro
**Aplicações**: Reconhecimento de imagem, processamento de linguagem, recomendações.""",
"html css javascript": """**Tecnologias Web Fundamentais:**
**HTML**: Estrutura da página (esqueleto)
**CSS**: Estilização e layout (aparência)
**JavaScript**: Interatividade e lógica (comportamento)
**Analogia**:
- HTML = Estrutura da casa
- CSS = Decoração e pintura
- JavaScript = Eletricidade e automação""",
"algoritmos ordenação": """**Algoritmos de Ordenação:**
**Bubble Sort**: O(n²) - Simples, mas lento
**Quick Sort**: O(n log n) - Rápido e eficiente
**Merge Sort**: O(n log n) - Estável e confiável
**Exemplo Quick Sort:**
```c
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
```"""
}
def get_quick_response(pergunta):
"""Verifica se há uma resposta rápida para a pergunta"""
pergunta_lower = pergunta.lower()
for keyword, response in QUICK_RESPONSES.items():
if keyword in pergunta_lower:
return response
return None
def load_model_optimized():
"""Carrega modelo com configurações otimizadas"""
try:
print(f"🚀 Carregando modelo otimizado: {MODEL_NAME}")
# Carrega com configurações de velocidade
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, padding_side='left')
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
low_cpu_mem_usage=True
)
# Pipeline otimizado
gerador = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
device=0 if torch.cuda.is_available() else -1,
max_new_tokens=MAX_TOKENS,
temperature=TEMPERATURE,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
print("✅ Modelo carregado com sucesso!")
return gerador, tokenizer
except Exception as e:
print(f"❌ Erro ao carregar {MODEL_NAME}: {e}")
# Fallback para DistilGPT2
return load_fallback_model()
def load_fallback_model():
"""Carrega modelo de fallback"""
try:
print("🔄 Carregando modelo de fallback...")
fallback_name = MODEL_OPTIONS["DistilGPT2"]
tokenizer = AutoTokenizer.from_pretrained(fallback_name)
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(fallback_name)
gerador = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
device=-1, # Força CPU para economia
max_new_tokens=MAX_TOKENS,
temperature=TEMPERATURE,
do_sample=True
)
print("✅ Modelo de fallback carregado!")
return gerador, tokenizer
except Exception as e:
raise Exception(f"Falha ao carregar qualquer modelo: {e}")
# === Carrega modelo na inicialização ===
gerador, tokenizer = load_model_optimized()
def responder_como_aldo(pergunta):
"""Função principal otimizada"""
if not pergunta.strip():
return "Por favor, faça uma pergunta específica."
start_time = time.time()
# 1. Verifica cache de respostas rápidas
quick_response = get_quick_response(pergunta)
if quick_response:
return f"📚 **Resposta Rápida do Dr. Aldo:**\n\n{quick_response}"
# 2. Verifica cache de respostas anteriores
pergunta_hash = hash(pergunta.lower().strip())
if pergunta_hash in response_cache:
cached_response = response_cache[pergunta_hash]
return f"💾 **Dr. Aldo responde:**\n\n{cached_response}"
# 3. Gera nova resposta
try:
# Prompt otimizado e conciso
if "DialoGPT" in MODEL_NAME:
prompt = f"Professor: {pergunta}\nDr. Aldo:"
else:
prompt = f"Pergunta: {pergunta}\nDr. Aldo Henrique responde:"
# Geração com timeout implícito
response = gerador(
prompt,
max_new_tokens=MAX_TOKENS,
num_return_sequences=1,
truncation=True
)[0]["generated_text"]
# Limpa resposta
if "Dr. Aldo:" in response:
resposta_limpa = response.split("Dr. Aldo:")[-1].strip()
elif "responde:" in response:
resposta_limpa = response.split("responde:")[-1].strip()
else:
resposta_limpa = response.replace(prompt, "").strip()
# Remove repetições comuns
resposta_limpa = resposta_limpa.replace(pergunta, "").strip()
if not resposta_limpa or len(resposta_limpa) < 10:
resposta_limpa = "Desculpe, não consegui gerar uma resposta adequada. Tente reformular sua pergunta."
# Salva no cache
response_cache[pergunta_hash] = resposta_limpa
recent_questions.append(pergunta)
elapsed_time = time.time() - start_time
return f"🎓 **Dr. Aldo responde** ⚡ *({elapsed_time:.1f}s)*:\n\n{resposta_limpa}"
except Exception as e:
return f"❌ **Erro temporário**: {str(e)}\n\nTente novamente ou reformule sua pergunta."
# === Interface Gradio otimizada ===
def create_interface():
with gr.Blocks(
title="Dr. Aldo Henrique - IA Educacional",
theme=gr.themes.Soft(),
css="""
.gradio-container { max-width: 900px; margin: auto; }
.output-text { font-family: 'Segoe UI', Arial, sans-serif; }
.quick-stats { background: #f0f0f0; padding: 10px; border-radius: 5px; }
"""
) as interface:
gr.Markdown("""
# 🎓 Dr. Aldo Henrique - Professor Virtual
### 💻 Especialista em C, Java, Web e Inteligência Artificial
""")
with gr.Row():
gr.Markdown(f"""
<div class="quick-stats">
📊 <strong>Status:</strong> Modelo {MODEL_NAME.split('/')[-1]} carregado<br>
⚡ <strong>Performance:</strong> Otimizado para respostas rápidas<br>
💾 <strong>Cache:</strong> {len(QUICK_RESPONSES)} respostas instantâneas
</div>
""")
with gr.Row():
with gr.Column(scale=2):
entrada = gr.Textbox(
label="🤔 Sua pergunta para o Dr. Aldo",
placeholder="Ex: Como usar ponteiros em C? ou Explique machine learning",
lines=3,
max_lines=5
)
with gr.Row():
botao = gr.Button("🚀 Perguntar", variant="primary", size="lg")
limpar = gr.Button("🗑️ Limpar", variant="secondary")
with gr.Column(scale=3):
saida = gr.Textbox(
label="💡 Resposta do Dr. Aldo",
lines=12,
max_lines=20,
interactive=False,
elem_classes=["output-text"]
)
# Exemplos organizados por categoria
with gr.Accordion("📚 Exemplos de Perguntas", open=False):
gr.Examples(
examples=[
["Como usar ponteiros em C?"],
["Diferença entre == e equals() em Java"],
["O que é machine learning?"],
["Explique HTML, CSS e JavaScript"],
["Quais são os algoritmos de ordenação?"],
["Como implementar uma lista ligada?"],
["O que são estruturas de dados?"],
["Como funciona recursão?"],
["Diferença entre pilha e fila"],
["O que é programação orientada a objetos?"]
],
inputs=entrada,
label="Clique em qualquer exemplo"
)
# Eventos
botao.click(fn=responder_como_aldo, inputs=entrada, outputs=saida)
limpar.click(fn=lambda: ("", ""), outputs=[entrada, saida])
entrada.submit(fn=responder_como_aldo, inputs=entrada, outputs=saida)
gr.Markdown("""
---
<center>
✨ <strong>Dica:</strong> Para respostas mais rápidas, use palavras-chave como "ponteiros", "java equals", "machine learning"<br>
🔧 <strong>Desenvolvido com:</strong> Transformers + Gradio | <strong>Otimizado para:</strong> Educação em Programação
</center>
""")
return interface
# === Lançamento ===
if __name__ == "__main__":
print("🎯 Iniciando Dr. Aldo Henrique - Versão Otimizada")
interface = create_interface()
interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True,
show_tips=False,
quiet=False
)