import streamlit as st
import streamlit_authenticator as stauth
import sqlite3
import os
import jwt
from datetime import datetime, timedelta
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
import torch
from PIL import Image
import io
import librosa
import numpy as np
import logging
import tempfile
from streamlit.runtime.uploaded_file_manager import UploadedFile
from diffusers import StableDiffusionPipeline
import sentry_sdk
import streamlit.components.v1 as components
import mimetypes
mimetypes.add_type('application/javascript', '.js')
mimetypes.add_type('text/css', '.css')
# Configurar página
st.set_page_config(
page_title="Aplicação de IA Multi-Modal",
page_icon="🤖",
layout="wide"
)
# Configurar logging e Sentry
sentry_sdk.init(os.getenv('SENTRY_DSN', ''), traces_sample_rate=1.0)
logging.basicConfig(
filename='private/app_errors.log',
level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# Configurar banco de dados
def init_db():
"""Inicializa o banco de dados SQLite com tabela de usuários"""
db_path = os.getenv('DB_PATH', 'private/users.db')
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
username TEXT PRIMARY KEY,
name TEXT NOT NULL,
password TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'user'
)
''')
# Adicionar admin padrão (remover em produção)
try:
hashed_password = stauth.Hasher(['admin123']).generate()[0]
cursor.execute('''
INSERT OR IGNORE INTO users (username, name, password, role)
VALUES (?, ?, ?, ?)
''', ('admin', 'Administrador', hashed_password, 'admin'))
conn.commit()
except Exception as e:
logging.error(f"Erro ao inicializar banco de dados: {e}")
sentry_sdk.capture_exception(e)
st.error(f"Erro ao inicializar banco de dados: {str(e)}")
conn.close()
def load_users_from_db():
"""Carrega usuários do banco de dados SQLite"""
try:
db_path = os.getenv('DB_PATH', 'private/users.db')
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("SELECT username, name, password, role FROM users")
users = {row[0]: {'name': row[1], 'password': row[2], 'role': row[3]} for row in cursor.fetchall()}
conn.close()
config = {
'credentials': {'usernames': users},
'cookie': {'name': 'ai_app_cookie', 'key': 'random_key_123', 'expiry_days': 30},
'preauthorized': {'emails': []}
}
return config
except Exception as e:
st.error(f"Erro ao carregar usuários: {str(e)}")
logging.error(f"Erro ao carregar usuários: {e}")
sentry_sdk.capture_exception(e)
return None
# Cache para modelos
@st.cache_resource(show_spinner=False)
def load_model(model_key):
"""Carrega modelo específico com cache persistente"""
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
cache_dir = "model_cache"
os.makedirs(cache_dir, exist_ok=True)
logging.info(f"Carregando modelo {model_key} em {device} com cache em {cache_dir}")
try:
if model_key == 'sentiment_analysis':
return pipeline("sentiment-analysis", model="cardiffnlp/twitter-roberta-base-sentiment-latest", device=device, cache_dir=cache_dir)
elif model_key == 'text_classification':
return pipeline("text-classification", model="distilbert-base-uncased-finetuned-sst-2-english", device=device, cache_dir=cache_dir)
elif model_key == 'summarization':
return pipeline("summarization", model="facebook/bart-large-cnn", device=device, max_length=150, min_length=30, cache_dir=cache_dir)
elif model_key == 'question_answering':
return pipeline("question-answering", model="deepset/roberta-base-squad2", device=device, cache_dir=cache_dir)
elif model_key == 'translation':
return pipeline("translation", model="Helsinki-NLP/opus-mt-tc-big-en-pt", device=device, cache_dir=cache_dir)
elif model_key == 'text_generation':
tokenizer = AutoTokenizer.from_pretrained("gpt2", cache_dir=cache_dir)
model = AutoModelForCausalLM.from_pretrained("gpt2", cache_dir=cache_dir)
model.config.pad_token_id = model.config.eos_token_id
return pipeline("text-generation", model=model, tokenizer=tokenizer, device=device)
elif model_key == 'ner':
return pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english", device=device, aggregation_strategy="simple", cache_dir=cache_dir)
elif model_key == 'image_classification':
return pipeline("image-classification", model="google/vit-base-patch16-224", device=device, cache_dir=cache_dir)
elif model_key == 'object_detection':
return pipeline("object-detection", model="facebook/detr-resnet-50", device=device, cache_dir=cache_dir)
elif model_key == 'image_segmentation':
return pipeline("image-segmentation", model="facebook/detr-resnet-50-panoptic", device=device, cache_dir=cache_dir)
elif model_key == 'facial_recognition':
return pipeline("image-classification", model="mo-thecreator/vit-Facial-Expression-Recognition", device=device, cache_dir=cache_dir)
elif model_key == 'speech_to_text':
return pipeline("automatic-speech-recognition", model="openai/whisper-base", device=device, cache_dir=cache_dir)
elif model_key == 'audio_classification':
return pipeline("audio-classification", model="superb/hubert-base-superb-er", device=device, cache_dir=cache_dir)
elif model_key == 'text_to_image':
return StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True, safety_checker=None, variant="fp16", cache_dir=cache_dir
)
except Exception as e:
st.error(f"Erro ao carregar modelo {model_key}: {str(e)}")
logging.error(f"Erro ao carregar modelo {model_key}: {e}")
sentry_sdk.capture_exception(e)
return None
def validate_audio_file(file: UploadedFile) -> bool:
"""Valida o arquivo de áudio"""
valid_extensions = ['.wav', '.mp3', '.flac', '.m4a']
return any(file.name.lower().endswith(ext) for ext in valid_extensions)
def validate_image_file(file: UploadedFile) -> bool:
"""Valida o arquivo de imagem"""
valid_extensions = ['.jpg', '.jpeg', '.png', '.bmp']
if not any(file.name.lower().endswith(ext) for ext in valid_extensions):
return False
try:
Image.open(file).verify()
return True
except Exception:
return False
def process_audio_file(audio_file):
"""Processa arquivo de áudio para o formato correto"""
try:
with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(audio_file.name)[1]) as tmp_file:
tmp_file.write(audio_file.read())
tmp_file_path = tmp_file.name
audio_array, sample_rate = librosa.load(tmp_file_path, sr=16000)
os.unlink(tmp_file_path)
return audio_array
except Exception as e:
st.error(f"Erro ao processar áudio: {str(e)}")
logging.error(f"Erro no processamento de áudio: {e}")
sentry_sdk.capture_exception(e)
return None
def process_image_file(image_file):
"""Processa arquivo de imagem"""
try:
image = Image.open(image_file)
if image.mode != 'RGB':
image = image.convert('RGB')
return image
except Exception as e:
st.error(f"Erro ao processar imagem: {str(e)}")
logging.error(f"Erro no processamento de imagem: {e}")
sentry_sdk.capture_exception(e)
return None
def display_results(result, model_key, input_text=None):
"""Exibe resultados formatados de acordo com o tipo de modelo"""
if model_key == 'summarization':
st.subheader("📝 Resumo Gerado")
if input_text:
st.markdown("**Texto Original:**")
st.write(input_text)
st.markdown("**Resumo:**")
st.info(result[0]['summary_text'])
elif model_key == 'translation':
st.subheader("🌍 Tradução")
st.success(result[0]['translation_text'])
elif model_key in ['sentiment_analysis', 'text_classification']:
st.subheader("📊 Resultados")
for res in result:
label = res['label']
score = res['score']
st.progress(float(score), text=f"{label} ({score:.2%})")
elif model_key == 'ner':
st.subheader("🔍 Entidades Reconhecidas")
for entity in result:
st.write(f"- **{entity['word']}**: {entity['entity_group']} (confiança: {entity['score']:.2%})")
elif model_key == 'text_generation':
st.subheader("🧠 Texto Gerado")
st.write(result[0]['generated_text'])
elif model_key == 'image_classification':
st.subheader("🏷️ Classificação")
for res in result[:5]:
st.write(f"- **{res['label']}**: {res['score']:.2%}")
elif model_key == 'object_detection':
st.subheader("📦 Objetos Detectados")
for obj in result:
st.write(f"- {obj['label']} (confiança: {obj['score']:.2%})")
elif model_key == 'image_segmentation':
st.subheader("🧩 Segmentação")
st.image(result[0]['mask'], caption="Máscara de segmentação")
elif model_key == 'facial_recognition':
st.subheader("😊 Reconhecimento Facial")
top_result = result[0]
st.write(f"**Emoção predominante**: {top_result['label']} (confiança: {top_result['score']:.2%})")
elif model_key == 'speech_to_text':
st.subheader("🔈 Transcrição")
st.success(result['text'])
elif model_key == 'audio_classification':
st.subheader("🎧 Classificação de Áudio")
top_emotion = result[0]
st.write(f"**Emoção detectada**: {top_emotion['label']} (confiança: {top_emotion['score']:.2%})")
elif model_key == 'text_to_image':
st.subheader("🎨 Imagem Gerada")
st.image(result[0], caption="Imagem gerada a partir do texto")
def load_branding(username):
"""Carrega branding personalizado por usuário"""
branding = {
'admin': {'logo': 'logos/admin_logo.png', 'title': 'Bem-vindo, Administrador!'},
'cliente': {'logo': 'logos/cliente_logo.png', 'title': 'Bem-vindo, Cliente!'},
'empresa1': {'logo': 'logos/empresa1_logo.png', 'title': 'Bem-vindo, Empresa Um!'}
}
return branding.get(username, {'logo': None, 'title': 'Bem-vindo!'})
def admin_panel(authenticator):
"""Painel administrativo para gerenciar usuários"""
if st.session_state.get('role') == 'admin':
st.sidebar.subheader("Painel Admin")
with st.sidebar.form("add_user_form"):
username = st.text_input("Username")
name = st.text_input("Nome")
password = st.text_input("Senha", type="password")
role = st.selectbox("Role", ["user", "admin"])
if st.form_submit_button("Adicionar Usuário"):
hashed_password = stauth.Hasher([password]).generate()[0]
db_path = os.getenv('DB_PATH', 'private/users.db')
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
try:
cursor.execute('INSERT INTO users (username, name, password, role) VALUES (?, ?, ?, ?)',
(username, name, hashed_password, role))
conn.commit()
st.success(f"Usuário {username} adicionado!")
except sqlite3.IntegrityError:
st.error("Usuário já existe.")
except Exception as e:
st.error(f"Erro ao adicionar usuário: {str(e)}")
logging.error(f"Erro ao adicionar usuário: {e}")
sentry_sdk.capture_exception(e)
conn.close()
with st.sidebar.form("remove_user_form"):
username_to_remove = st.text_input("Username para Remover")
if st.form_submit_button("Remover Usuário"):
db_path = os.getenv('DB_PATH', 'private/users.db')
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
try:
cursor.execute('DELETE FROM users WHERE username = ?', (username_to_remove,))
conn.commit()
if cursor.rowcount > 0:
st.success(f"Usuário {username_to_remove} removido!")
else:
st.error("Usuário não encontrado.")
except Exception as e:
st.error(f"Erro ao remover usuário: {str(e)}")
logging.error(f"Erro ao remover usuário: {e}")
sentry_sdk.capture_exception(e)
conn.close()
def get_use_cases():
"""Retorna os casos de uso para cada modelo"""
return {
'sentiment_analysis': {
'title': "Análise de Sentimento",
'description': "Analisa o sentimento (positivo, negativo, neutro) em comentários, avaliações ou postagens de clientes em redes sociais.",
'example': "Uma empresa de varejo monitora menções da marca no Twitter/X, identificando feedback negativo para responder proativamente ou destacando comentários positivos em campanhas de marketing.",
'benefit': "Melhoria na gestão de reputação online e resposta rápida a crises de imagem.",
'demo_input': "A entrega foi super rápida, adorei!",
'demo_type': 'text'
},
# Outros casos de uso mantidos idênticos ao original
'text_classification': {
'title': "Classificação de Texto",
'description': "Classifica e-mails recebidos como positivos ou negativos para priorizar respostas ou identificar reclamações.",
'example': "Um call center categoriza e-mails de clientes, direcionando mensagens negativas para equipes de suporte prioritário.",
'benefit': "Otimização do tempo da equipe de atendimento e melhoria na experiência do cliente.",
'demo_input': "Estou insatisfeito com o produto",
'demo_type': 'text'
},
'summarization': {
'title': "Resumo de Texto",
'description': "Gera resumos concisos de documentos longos, como relatórios financeiros ou atas de reuniões.",
'example': "Uma consultoria financeira resume relatórios anuais de empresas em poucos parágrafos para facilitar a análise de investidores.",
'benefit': "Economia de tempo na leitura de documentos extensos e tomada de decisão mais rápida.",
'demo_input': "A empresa XYZ reportou um crescimento de 15% no último trimestre, impulsionado por novas parcerias estratégicas e expansão no mercado asiático. No entanto, desafios logísticos aumentaram os custos operacionais em 5%. A diretoria planeja investir em automação para mitigar esses custos no próximo ano.",
'demo_type': 'text'
},
'question_answering': {
'title': "Perguntas e Respostas",
'description': "Responde perguntas específicas com base em manuais, FAQs ou documentos internos.",
'example': "Um chatbot de suporte técnico responde perguntas como 'Como configurar o produto X?' extraindo respostas diretamente do manual do produto.",
'benefit': "Redução do tempo de suporte e maior autonomia para os usuários finais.",
'demo_input': {
'context': "O produto X tem garantia de 2 anos e pode ser configurado via aplicativo móvel em 5 minutos.",
'question': "Qual é o tempo de garantia do produto X?"
},
'demo_type': 'qa'
},
'translation': {
'title': "Tradução (EN→PT)",
'description': "Traduz conteúdo de marketing, manuais ou comunicações de inglês para português.",
'example': "Uma empresa de software traduz descrições de produtos para lançar no mercado brasileiro.",
'benefit': "Expansão de mercado com conteúdo adaptado e redução de custos com tradutores humanos.",
'demo_input': "Our product ensures high performance",
'demo_type': 'text'
},
'ner': {
'title': "Reconhecimento de Entidades",
'description': "Identifica entidades como nomes de pessoas, organizações e locais em contratos ou documentos legais.",
'example': "Um escritório de advocacia extrai automaticamente nomes de partes envolvidas em contratos, agilizando revisões.",
'benefit': "Redução de erros manuais e maior eficiência na análise de documentos.",
'demo_input': "Microsoft assinou um contrato com a empresa XYZ em Nova York.",
'demo_type': 'text'
},
'text_generation': {
'title': "Geração de Texto",
'description': "Gera textos criativos para campanhas de marketing, postagens em redes sociais ou roteiros.",
'example': "Uma agência de publicidade cria slogans ou descrições de produtos a partir de prompts iniciais.",
'benefit': "Aceleração do processo criativo e geração de ideias inovadoras.",
'demo_input': "Um futuro onde a tecnologia conecta todos",
'demo_type': 'text'
},
'image_classification': {
'title': "Classificação de Imagem",
'description': "Identifica defeitos ou classifica produtos em linhas de produção com base em imagens.",
'example': "Uma fábrica de eletrônicos classifica imagens de circuitos como 'Defeituoso' ou 'Aprovado' para controle de qualidade.",
'benefit': "Redução de erros humanos e aumento da eficiência na inspeção.",
'demo_input': None,
'demo_type': 'image'
},
'object_detection': {
'title': "Detecção de Objetos",
'description': "Detecta objetos como pessoas, veículos ou itens em imagens de câmeras de segurança.",
'example': "Um sistema de segurança identifica veículos em um estacionamento para monitoramento automático.",
'benefit': "Maior segurança e automação de processos de monitoramento.",
'demo_input': None,
'demo_type': 'image'
},
'image_segmentation': {
'title': "Segmentação de Imagem",
'description': "Segmenta diferentes partes de uma imagem, como órgãos em exames médicos.",
'example': "Um hospital segmenta tumores em imagens de ressonância magnética, facilitando diagnósticos.",
'benefit': "Apoio a diagnósticos médicos com maior precisão e rapidez.",
'demo_input': None,
'demo_type': 'image'
},
'facial_recognition': {
'title': "Reconhecimento Facial",
'description': "Identifica emoções faciais em vídeos ou fotos de clientes em lojas ou eventos.",
'example': "Uma loja de varejo analisa expressões faciais de clientes para avaliar a satisfação durante interações com produtos.",
'benefit': "Melhoria na experiência do cliente com base em dados emocionais.",
'demo_input': None,
'demo_type': 'image'
},
'speech_to_text': {
'title': "Transcrição de Áudio",
'description': "Converte gravações de reuniões ou entrevistas em texto para documentação.",
'example': "Uma empresa transcreve automaticamente reuniões para criar atas ou resumos.",
'benefit': "Economia de tempo na documentação e maior acessibilidade de conteúdo.",
'demo_input': None,
'demo_type': 'audio'
},
'audio_classification': {
'title': "Classificação de Áudio",
'description': "Classifica emoções em chamadas de suporte para avaliar a qualidade do atendimento.",
'example': "Um call center analisa chamadas para identificar emoções como 'Frustração' ou 'Satisfação' dos clientes.",
'benefit': "Melhoria na formação de equipes e na experiência do cliente.",
'demo_input': None,
'demo_type': 'audio'
},
'text_to_image': {
'title': "Texto para Imagem",
'description': "Gera imagens personalizadas a partir de descrições textuais para campanhas publicitárias ou design de produtos.",
'example': "Uma agência de design cria mockups de produtos com base em prompts como 'Um smartphone futurista em um fundo azul neon'.",
'benefit': "Redução de custos com designers gráficos e maior agilidade na criação de conteúdo visual.",
'demo_input': "Uma paisagem tropical ao pôr do sol",
'demo_type': 'text'
}
}
def handle_use_case_demo(models, use_case_key, use_case):
"""Executa a demonstração de um caso de uso com entrada pré-definida"""
if use_case['demo_input'] is None:
st.warning("⚠️ Demonstração não disponível. Este modelo requer upload de imagem ou áudio.")
return
st.subheader("📊 Demonstração")
try:
model = models.get(use_case_key) or load_model(use_case_key)
if use_case['demo_type'] == 'text':
with st.spinner("Processando demonstração..."):
result = model(use_case['demo_input'])
display_results(result, use_case_key, input_text=use_case['demo_input'])
elif use_case['demo_type'] == 'qa':
with st.spinner("Processando demonstração..."):
result = model(
question=use_case['demo_input']['question'],
context=use_case['demo_input']['context']
)
st.success("🔍 Resposta encontrada:")
st.markdown(f"**Contexto:** {use_case['demo_input']['context']}")
st.markdown(f"**Pergunta:** {use_case['demo_input']['question']}")
st.markdown(f"**Resposta:** {result['answer']}")
st.markdown(f"**Confiança:** {result['score']:.2%}")
except Exception as e:
st.error(f"Erro ao executar demonstração: {str(e)}")
logging.error(f"Erro na demonstração do caso de uso {use_case_key}: {e}")
sentry_sdk.capture_exception(e)
def main():
# Inicializar banco de dados
init_db()
# Carregar configuração de autenticação
config = load_users_from_db()
if not config:
st.error("Falha ao carregar autenticação. Contate o administrador.")
return
authenticator = stauth.Authenticate(
config['credentials'],
config['cookie']['name'],
config['cookie']['key'],
config['cookie']['expiry_days'],
config['preauthorized']
)
# Tela de login
name, authentication_status, username = authenticator.login('Login', 'main')
if authentication_status:
# Gerenciar sessão
if "user_id" not in st.session_state:
st.session_state.user_id = username
st.session_state.role = config['credentials']['usernames'][username]['role']
# Carregar branding
branding = load_branding(username)
if branding['logo'] and os.path.exists(branding['logo']):
st.image(branding['logo'], width=150)
st.title(branding['title'])
authenticator.logout('Logout', 'sidebar')
admin_panel(authenticator)
# Tour guiado
if st.sidebar.button("Iniciar Tour"):
components.html("""
""", height=0)
# Carregar modelos sob demanda
models = {}
model_categories = {
"📝 Processamento de Texto": [
("Análise de Sentimento", "sentiment_analysis"),
("Classificação de Texto", "text_classification"),
("Resumo de Texto", "summarization"),
("Perguntas e Respostas", "question_answering"),
("Tradução (EN→PT)", "translation"),
("Reconhecimento de Entidades", "ner"),
("Geração de Texto", "text_generation")
],
"🖼️ Processamento de Imagem": [
("Classificação de Imagem", "image_classification"),
("Detecção de Objetos", "object_detection"),
("Segmentação de Imagem", "image_segmentation"),
("Reconhecimento Facial", "facial_recognition")
],
"🎵 Processamento de Áudio": [
("Transcrição de Áudio", "speech_to_text"),
("Classificação de Emoções", "audio_classification")
],
"✨ Modelos Generativos": [
("Texto para Imagem", "text_to_image")
]
}
# Abas para navegação
tab1, tab2 = st.tabs(["Explorar Modelos", "Casos de Uso"])
with tab1:
st.sidebar.title("⚙️ Configurações")
selected_category = st.sidebar.selectbox(
"Categoria",
list(model_categories.keys()),
index=0
)
selected_model = st.sidebar.selectbox(
"Modelo",
[name for name, key in model_categories[selected_category]],
format_func=lambda x: x,
index=0
)
model_key = next(key for name, key in model_categories[selected_category] if name == selected_model)
# Carregar modelo com barra de progresso
if model_key not in models:
with st.spinner(f"Carregando modelo {selected_model}..."):
progress = st.progress(0)
models[model_key] = load_model(model_key)
progress.progress(100)
st.header(f"{selected_model}")
with st.expander("ℹ️ Sobre este modelo"):
model_info = {
'sentiment_analysis': "Analisa o sentimento expresso em um texto (positivo/negativo/neutro).",
'text_classification': "Classifica textos em categorias pré-definidas.",
'summarization': "Gera um resumo conciso de um texto longo.",
'question_answering': "Responde perguntas baseadas em um contexto fornecido.",
'translation': "Traduz texto de inglês para português.",
'ner': "Identifica e classifica entidades nomeadas (pessoas, lugares, organizações).",
'text_generation': "Gera texto criativo continuando a partir de um prompt.",
'image_classification': "Identifica objetos e cenas em imagens.",
'object_detection': "Detecta e localiza múltiplos objetos em uma imagem.",
'image_segmentation': "Segmenta diferentes elementos em uma imagem.",
'facial_recognition': "Reconhece características faciais e emoções.",
'speech_to_text': "Transcreve fala em texto.",
'audio_classification': "Classifica emoções em arquivos de áudio.",
'text_to_image': "Gera imagens a partir de descrições textuais."
}
st.info(model_info.get(model_key, "Informações detalhadas sobre este modelo."))
try:
if model_key in ['sentiment_analysis', 'text_classification', 'summarization',
'translation', 'text_generation', 'ner']:
handle_text_models(models, model_key, selected_model)
elif model_key == 'question_answering':
handle_qa_model(models, model_key)
elif model_key in ['image_classification', 'object_detection',
'image_segmentation', 'facial_recognition']:
handle_image_models(models, model_key, selected_model)
elif model_key in ['speech_to_text', 'audio_classification']:
handle_audio_models(models, model_key)
elif model_key == 'text_to_image':
handle_generative_models(models, model_key)
except Exception as e:
st.error(f"Erro inesperado durante a execução: {str(e)}")
logging.error(f"Erro durante a execução do modelo {model_key}: {e}")
sentry_sdk.capture_exception(e)
with tab2:
st.header("Casos de Uso")
st.markdown("Explore casos práticos de aplicação dos modelos para resolver problemas reais.")
use_cases = get_use_cases()
selected_use_case = st.selectbox(
"Selecione um caso de uso",
list(use_cases.keys()),
format_func=lambda x: use_cases[x]['title']
)
use_case = use_cases[selected_use_case]
st.subheader(use_case['title'])
with st.expander("ℹ️ Detalhes do Caso de Uso"):
st.markdown(f"**Descrição**: {use_case['description']}")
st.markdown(f"**Exemplo Prático**: {use_case['example']}")
st.markdown(f"**Benefício**: {use_case['benefit']}")
if use_case['demo_input'] is not None:
if st.button("🚀 Executar Demonstração", key=f"demo_{selected_use_case}"):
handle_use_case_demo(models, selected_use_case, use_case)
def handle_text_models(models, model_key, model_name):
"""Manipula modelos de texto"""
input_text = st.text_area(
f"Digite o texto para {model_name.lower()}:",
height=200,
placeholder="Cole ou digite seu texto aqui...",
key=f"text_input_{model_key}"
)
advanced_params = {}
if model_key == 'summarization':
with st.expander("⚙️ Parâmetros Avançados"):
advanced_params['max_length'] = st.slider("Comprimento máximo", 50, 300, 150)
advanced_params['min_length'] = st.slider("Comprimento mínimo", 10, 100, 30)
if model_key == 'text_generation':
with st.expander("⚙️ Parâmetros Avançados"):
advanced_params['max_length'] = st.slider("Comprimento do texto", 50, 500, 100)
advanced_params['temperature'] = st.slider("Criatividade", 0.1, 1.0, 0.7)
advanced_params['num_return_sequences'] = st.slider("Número de resultados", 1, 5, 1)
if st.button(f"🚀 Executar {model_name}", type="primary", key=f"btn_{model_key}"):
if input_text.strip():
with st.spinner("Processando..."):
try:
model = models.get(model_key) or load_model(model_key)
if model_key == 'ner':
result = model(input_text)
elif model_key == 'text_generation':
result = model(
input_text,
max_new_tokens=advanced_params.get('max_length', 100),
do_sample=True,
temperature=advanced_params.get('temperature', 0.7),
top_k=50,
top_p=0.95,
num_return_sequences=advanced_params.get('num_return_sequences', 1)
)
else:
result = model(input_text, **advanced_params)
display_results(result, model_key, input_text=input_text)
except Exception as e:
st.error(f"Erro ao processar texto: {str(e)}")
logging.error(f"Erro no modelo {model_key}: {e}")
sentry_sdk.capture_exception(e)
else:
st.warning("⚠️ Por favor, insira um texto válido.")
def handle_qa_model(models, model_key):
"""Manipula modelo de Q&A"""
col1, col2 = st.columns(2)
with col1:
context = st.text_area(
"Contexto:",
height=200,
placeholder="Cole o texto que contém a informação...",
key="qa_context"
)
with col2:
question = st.text_area(
"Pergunta:",
height=150,
placeholder="Faça sua pergunta sobre o contexto...",
key="qa_question"
)
with st.expander("⚙️ Parâmetros Avançados"):
confidence_threshold = st.slider("Limite de confiança", 0.0, 1.0, 0.5, 0.01)
if st.button("🚀 Executar Pergunta e Resposta", type="primary", key="btn_qa"):
if context.strip() and question.strip():
with st.spinner("Buscando resposta..."):
try:
model = models.get(model_key) or load_model(model_key)
result = model(question=question, context=context)
if result['score'] < confidence_threshold:
st.warning(f"⚠️ Confiança baixa na resposta ({result['score']:.2%})")
st.success("🔍 Resposta encontrada:")
st.markdown(f"**Contexto:** {context}")
st.markdown(f"**Pergunta:** {question}")
st.markdown(f"**Resposta:** {result['answer']}")
st.markdown(f"**Confiança:** {result['score']:.2%}")
except Exception as e:
st.error(f"Erro ao processar Q&A: {str(e)}")
logging.error(f"Erro no modelo Q&A: {e}")
sentry_sdk.capture_exception(e)
else:
st.warning("⚠️ Por favor, forneça tanto o contexto quanto a pergunta.")
def handle_image_models(models, model_key, model_name):
"""Manipula modelos de imagem"""
uploaded_file = st.file_uploader(
"Carregue uma imagem",
type=["jpg", "png", "jpeg", "bmp"],
help="Formatos suportados: JPG, PNG, JPEG, BMP",
key=f"img_upload_{model_key}"
)
if uploaded_file is not None:
if not validate_image_file(uploaded_file):
st.error("⚠️ Formato de arquivo inválido ou arquivo corrompido.")
return
col1, col2 = st.columns(2)
with col1:
st.subheader("🖼️ Imagem Original")
image = process_image_file(uploaded_file)
if image:
st.image(image)
with col2:
st.subheader("📊 Resultados")
if st.button(f"🚀 Executar {model_name}", type="primary", key=f"btn_img_{model_key}"):
if image:
with st.spinner("Analisando imagem..."):
try:
model = models.get(model_key) or load_model(model_key)
result = model(image)
display_results(result, model_key)
except Exception as e:
st.error(f"Erro ao processar imagem: {str(e)}")
logging.error(f"Erro no modelo {model_key}: {e}")
sentry_sdk.capture_exception(e)
def handle_audio_models(models, model_key):
"""Manipula modelos de áudio"""
model_name = "Transcrição de Áudio" if model_key == 'speech_to_text' else "Classificação de Áudio"
uploaded_file = st.file_uploader(
f"Carregue um arquivo de áudio para {model_name}",
type=["wav", "mp3", "flac", "m4a"],
help="Formatos suportados: WAV, MP3, FLAC, M4A",
key=f"audio_upload_{model_key}"
)
if uploaded_file is not None:
if not validate_audio_file(uploaded_file):
st.error("⚠️ Formato de arquivo inválido ou não suportado.")
return
st.audio(uploaded_file, format="audio/wav")
if st.button(f"🚀 Executar {model_name}", type="primary", key=f"btn_audio_{model_key}"):
with st.spinner("Processando áudio..."):
try:
audio_array = process_audio_file(uploaded_file)
if audio_array is not None:
model = models.get(model_key) or load_model(model_key)
result = model(audio_array)
display_results(result, model_key)
else:
st.error("Não foi possível processar o arquivo de áudio.")
except Exception as e:
st.error(f"Erro ao processar áudio: {str(e)}")
logging.error(f"Erro no modelo {model_key}: {e}")
sentry_sdk.capture_exception(e)
def handle_generative_models(models, model_key):
"""Manipula modelos generativos"""
prompt = st.text_area(
"Descrição da imagem:",
height=150,
placeholder="Descreva a imagem que deseja gerar...",
key="text_to_image_prompt"
)
with st.expander("⚙️ Parâmetros Avançados"):
cols = st.columns(2)
with cols[0]:
width = st.slider("Largura", 256, 1024, 512, 64)
with cols[1]:
height = st.slider("Altura", 256, 1024, 512, 64)
num_images = st.slider("Número de imagens", 1, 4, 1)
guidance_scale = st.slider("Escala de orientação", 1.0, 20.0, 7.5)
if st.button("🚀 Gerar Imagem", type="primary", key="btn_text_to_image"):
if prompt.strip():
with st.spinner("Criando imagem..."):
try:
model = models.get(model_key) or load_model(model_key)
result = model(
prompt,
height=height,
width=width,
num_images_per_prompt=num_images,
guidance_scale=guidance_scale
)
display_results(result, model_key)
except Exception as e:
st.error(f"Erro ao gerar imagem: {str(e)}")
logging.error(f"Erro no modelo text-to-image: {e}")
sentry_sdk.capture_exception(e)
else:
st.warning("⚠️ Por favor, insira uma descrição para a imagem.")
if __name__ == "__main__":
main()