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()