Spaces:
Running
Running
import gradio as gr | |
import torch | |
from transformers import pipeline | |
from datetime import datetime | |
import nltk | |
from nltk.tokenize import word_tokenize | |
from nltk.corpus import stopwords | |
from collections import Counter | |
import logging | |
from typing import Dict, List, Tuple, Optional | |
class GeradorTrilhaAprendizado: | |
def __init__(self): | |
try: | |
self.device = "cuda" if torch.cuda.is_available() else "cpu" | |
self.transcriber = pipeline("automatic-speech-recognition", | |
model="openai/whisper-base", | |
device=self.device) | |
self.generator = pipeline("text-generation", | |
model="gpt2-large", | |
device=self.device) | |
self.historico: List[Dict] = [] | |
for resource in ['punkt', 'stopwords']: | |
try: | |
nltk.data.find(f'tokenizers/{resource}') | |
except LookupError: | |
nltk.download(resource) | |
self.stop_words = set(stopwords.words('portuguese')) | |
except Exception as e: | |
logging.error(f"Initialization error: {str(e)}") | |
raise | |
def processar_audio(self, | |
audio_path: Optional[str], | |
nome_trilha: str, | |
nivel: str = "intermediário", | |
area: str = "geral", | |
duracao: str = "3 meses", | |
incluir_recursos: bool = True) -> Tuple[str, str, str, str]: | |
if not audio_path: | |
return ("", "", self._formatar_historico(), "❌ Nenhum áudio fornecido") | |
try: | |
transcricao = self.transcriber(audio_path)["text"] | |
if not transcricao.strip(): | |
return ("", "", self._formatar_historico(), "❌ Nenhum texto detectado no áudio") | |
analise = self._gerar_trilha_personalizada(transcricao, nivel, area, duracao) | |
if incluir_recursos: | |
recursos = self._gerar_recursos(nivel, area, transcricao) | |
analise += "\n\n" + recursos | |
self.historico.append({ | |
"data": datetime.now().strftime("%d/%m/%Y %H:%M"), | |
"nome": nome_trilha.strip(), | |
"nivel": nivel, | |
"area": area, | |
"duracao": duracao, | |
"transcricao": transcricao, | |
"analise": analise | |
}) | |
return (transcricao, analise, self._formatar_historico(), "✅ Trilha gerada com sucesso!") | |
except Exception as e: | |
logging.error(f"Processing error: {str(e)}") | |
return ("", "", self._formatar_historico(), f"❌ Erro: {str(e)}") | |
# Core change needed in _gerar_trilha_personalizada method: | |
def _gerar_trilha_personalizada(self, transcricao: str, nivel: str, area: str, duracao: str) -> str: | |
try: | |
palavras_chave = self._extrair_palavras_chave(transcricao) | |
modulos = self._get_modulos_por_area(area, nivel) | |
duracao_meses = int(duracao.split()[0]) | |
tempo_por_modulo = duracao_meses / len(modulos) | |
# Generate customized content using the model | |
prompt = f""" | |
Gere uma trilha de aprendizado para a área de {area} (nível {nivel}), duração de {duracao}. | |
Objetivos do usuário: {transcricao} | |
Palavras-chave identificadas: {', '.join(palavras_chave)} | |
""" | |
generated_content = self.generator( | |
prompt, | |
max_length=500, | |
num_return_sequences=1, | |
temperature=0.7 | |
)[0]['generated_text'] | |
# Combine generated content with structured data | |
return f""" | |
🎯 Objetivos Identificados: | |
{self._formatar_objetivos(palavras_chave, area)} | |
📚 Trilha Personalizada para {area.title()} - Nível {nivel}: | |
{generated_content} | |
{self._formatar_modulos(modulos, tempo_por_modulo)} | |
🚀 Projetos Práticos Sugeridos: | |
{self._gerar_projetos(area, nivel)} | |
📅 Cronograma ({duracao}): | |
{self._gerar_cronograma(duracao_meses, modulos)} | |
🎖️ Marcos de Avaliação: | |
{self._gerar_marcos_avaliacao(nivel)} | |
""" | |
except Exception as e: | |
logging.error(f"Error generating learning path: {str(e)}") | |
return "Erro ao gerar trilha de aprendizado" | |
def _extrair_palavras_chave(self, texto: str) -> List[str]: | |
try: | |
tokens = word_tokenize(texto.lower()) | |
palavras = [palavra for palavra in tokens | |
if palavra.isalnum() and | |
len(palavra) > 2 and | |
palavra not in self.stop_words] | |
return [palavra[0] for palavra in Counter(palavras).most_common(5)] | |
except Exception as e: | |
logging.error(f"Keyword extraction error: {str(e)}") | |
return ["erro ao extrair palavras-chave"] | |
def _get_modulos_por_area(self, area: str, nivel: str) -> List[str]: | |
modulos = { | |
"programação": { | |
"iniciante": [ | |
"Lógica de Programação Básica", | |
"Introdução a Algoritmos", | |
"Fundamentos de HTML/CSS", | |
"JavaScript Básico" | |
], | |
"intermediário": [ | |
"Estruturas de Dados", | |
"Programação Orientada a Objetos", | |
"Frameworks Front-end", | |
"Banco de Dados" | |
], | |
"avançado": [ | |
"Arquitetura de Software", | |
"DevOps e CI/CD", | |
"Microsserviços", | |
"Segurança e Performance" | |
] | |
}, | |
"data science": { | |
"iniciante": [ | |
"Estatística Básica", | |
"Python para Análise de Dados", | |
"SQL Fundamental", | |
"Visualização de Dados" | |
], | |
"intermediário": [ | |
"Machine Learning Básico", | |
"Deep Learning Fundamentos", | |
"Big Data Analytics", | |
"Feature Engineering" | |
], | |
"avançado": [ | |
"MLOps", | |
"Análise Avançada", | |
"IA Generativa", | |
"Pesquisa Aplicada" | |
] | |
}, | |
"design": { | |
"iniciante": [ | |
"Teoria das Cores", | |
"Tipografia", | |
"UI Básica", | |
"Ferramentas de Design" | |
], | |
"intermediário": [ | |
"Design Systems", | |
"UX Research", | |
"Prototipagem", | |
"Design Visual" | |
], | |
"avançado": [ | |
"Design Leadership", | |
"Design Estratégico", | |
"Design para Produto", | |
"Design Thinking Avançado" | |
] | |
} | |
} | |
if area not in modulos: | |
return [ | |
"Fundamentos da Área", | |
"Conceitos Intermediários", | |
"Práticas Avançadas", | |
"Especialização" | |
] | |
return modulos[area].get(nivel, modulos[area]["intermediário"]) | |
def _formatar_objetivos(self, palavras_chave: List[str], area: str) -> str: | |
objetivos = { | |
"programação": [ | |
"Desenvolver habilidades técnicas em {}", | |
"Criar projetos práticos usando {}", | |
"Dominar conceitos de {}" | |
], | |
"data science": [ | |
"Analisar dados usando {}", | |
"Construir modelos de {}", | |
"Implementar soluções com {}" | |
], | |
"design": [ | |
"Criar interfaces usando {}", | |
"Desenvolver projetos de {}", | |
"Aplicar princípios de {}" | |
] | |
} | |
templates = objetivos.get(area, objetivos["programação"]) | |
return "\n".join( | |
f"• {template.format(palavra)}" | |
for palavra, template in zip(palavras_chave[:3], templates) | |
) | |
def _formatar_modulos(self, modulos: List[str], tempo: float) -> str: | |
return "\n".join( | |
f"Módulo {i+1}: {modulo} ({tempo:.1f} meses)" | |
for i, modulo in enumerate(modulos) | |
) | |
def _gerar_projetos(self, area: str, nivel: str) -> str: | |
projetos = { | |
"iniciante": [ | |
"Projeto Tutorial Guiado", | |
"Mini-Projeto Prático", | |
"Exercícios Fundamentais" | |
], | |
"intermediário": [ | |
"Projeto Individual", | |
"Projeto em Equipe", | |
"Case Study Prático" | |
], | |
"avançado": [ | |
"Projeto Complexo", | |
"Contribuição Open Source", | |
"Projeto de Pesquisa" | |
] | |
} | |
return "\n".join(f"• {projeto}" for projeto in projetos.get(nivel, projetos["intermediário"])) | |
def _gerar_cronograma(self, duracao: int, modulos: List[str]) -> str: | |
meses_por_modulo = duracao / len(modulos) | |
return "\n".join( | |
f"Mês {i*meses_por_modulo+1:.1f}-{(i+1)*meses_por_modulo:.1f}: {modulo}" | |
for i, modulo in enumerate(modulos) | |
) | |
def _gerar_marcos_avaliacao(self, nivel: str) -> str: | |
marcos = { | |
"iniciante": [ | |
"Quiz de Conceitos Básicos", | |
"Exercícios Práticos", | |
"Projeto Final Básico" | |
], | |
"intermediário": [ | |
"Avaliação Técnica", | |
"Projeto Individual", | |
"Apresentação de Resultados" | |
], | |
"avançado": [ | |
"Defesa de Projeto", | |
"Contribuição Técnica", | |
"Artigo/Publicação" | |
] | |
} | |
return "\n".join(f"• {marco}" for marco in marcos.get(nivel, marcos["intermediário"])) | |
def _gerar_recursos(self, nivel: str, area: str, objetivo: str) -> str: | |
recursos = { | |
"iniciante": { | |
"cursos": ["Fundamentos Básicos", "Introdução Prática"], | |
"livros": ["Guia do Iniciante", "Primeiros Passos"], | |
"projetos": ["Projeto inicial guiado", "Mini-projetos práticos"] | |
}, | |
"intermediário": { | |
"cursos": ["Especialização Prática", "Técnicas Avançadas"], | |
"livros": ["Guia Completo", "Estudos de Caso"], | |
"projetos": ["Projetos médios", "Desafios práticos"] | |
}, | |
"avançado": { | |
"cursos": ["Masterclass", "Especialização Pro"], | |
"livros": ["Técnicas Avançadas", "Estado da Arte"], | |
"projetos": ["Projetos complexos", "Open-source"] | |
} | |
} | |
r = recursos.get(nivel, recursos["intermediário"]) | |
return f""" | |
📚 Recursos Recomendados: | |
1. Cursos: | |
- {r['cursos'][0]} | |
- {r['cursos'][1]} | |
2. Material: | |
- {r['livros'][0]} | |
- {r['livros'][1]} | |
3. Projetos: | |
- {r['projetos'][0]} | |
- {r['projetos'][1]} | |
4. Extras: | |
- Comunidades de prática | |
- Mentoria entre pares | |
- Workshops práticos | |
- Avaliações periódicas | |
""" | |
def _formatar_historico(self) -> str: | |
if not self.historico: | |
return "Nenhuma trilha gerada ainda" | |
return "📋 Histórico de Trilhas:\n\n" + "\n".join( | |
f"• {h['data']} - {h['nome']} ({h['nivel']}, {h['area']})" | |
for h in self.historico[-5:] | |
) | |
def criar_interface() -> gr.Blocks: | |
with gr.Blocks(theme=gr.themes.Soft()) as app: | |
gr.Markdown(""" | |
# 🎓 Gerador de Trilha de Aprendizado | |
Grave ou faça upload de um áudio descrevendo seus objetivos e receba uma trilha personalizada! | |
""") | |
with gr.Row(): | |
with gr.Column(): | |
audio_input = gr.Audio( | |
type="filepath", | |
label="Áudio", | |
sources=["microphone", "upload"] | |
) | |
nome_trilha = gr.Textbox( | |
label="Nome da Trilha", | |
placeholder="Dê um nome para sua trilha", | |
value="" | |
) | |
nivel = gr.Dropdown( | |
choices=["iniciante", "intermediário", "avançado"], | |
value="intermediário", | |
label="Nível de Dificuldade" | |
) | |
area = gr.Dropdown( | |
choices=["programação", "data science", "design", "marketing", "negócios", "geral"], | |
value="geral", | |
label="Área de Conhecimento" | |
) | |
duracao = gr.Dropdown( | |
choices=["1 mês", "3 meses", "6 meses", "1 ano"], | |
value="3 meses", | |
label="Duração Estimada" | |
) | |
incluir_recursos = gr.Checkbox( | |
label="Incluir Recursos Recomendados", | |
value=True | |
) | |
processar_btn = gr.Button("🚀 Gerar Trilha de Aprendizado") | |
with gr.Row(): | |
with gr.Column(): | |
status = gr.Markdown() | |
transcricao = gr.Textbox(label="Transcrição do Áudio", lines=4) | |
analise = gr.Textbox(label="Sua Trilha de Aprendizado", lines=10) | |
historico = gr.Markdown() | |
with gr.Accordion("ℹ️ Como usar"): | |
gr.Markdown(""" | |
1. Grave um áudio descrevendo seus objetivos de aprendizado | |
2. Escolha o nome da trilha, nível, área e duração | |
3. Clique em 'Gerar Trilha de Aprendizado' | |
4. Revise a transcrição e a trilha gerada | |
5. O histórico mostra suas últimas 5 trilhas geradas | |
""") | |
gerador = GeradorTrilhaAprendizado() | |
processar_btn.click( | |
fn=gerador.processar_audio, | |
inputs=[audio_input, nome_trilha, nivel, area, duracao, incluir_recursos], | |
outputs=[transcricao, analise, historico, status] | |
) | |
return app | |
if __name__ == "__main__": | |
logging.basicConfig(level=logging.INFO) | |
app = criar_interface() | |
app.queue() | |
app.launch() |