Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
import streamlit as st
|
|
|
|
|
|
|
|
|
2 |
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
|
3 |
import torch
|
4 |
from PIL import Image
|
@@ -7,7 +11,6 @@ import librosa
|
|
7 |
import numpy as np
|
8 |
import logging
|
9 |
import tempfile
|
10 |
-
import os
|
11 |
from streamlit.runtime.uploaded_file_manager import UploadedFile
|
12 |
from diffusers import StableDiffusionPipeline
|
13 |
|
@@ -25,6 +28,50 @@ logging.basicConfig(
|
|
25 |
format='%(asctime)s - %(levelname)s - %(message)s'
|
26 |
)
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
# Cache para evitar recarregar modelos a cada execução
|
29 |
@st.cache_resource(show_spinner=False)
|
30 |
def load_models():
|
@@ -185,10 +232,14 @@ def process_image_file(image_file):
|
|
185 |
logging.error(f"Erro no processamento de imagem: {e}")
|
186 |
return None
|
187 |
|
188 |
-
def display_results(result, model_key):
|
189 |
"""Exibe resultados formatados de acordo com o tipo de modelo"""
|
190 |
if model_key == 'summarization':
|
191 |
st.subheader("📝 Resumo Gerado")
|
|
|
|
|
|
|
|
|
192 |
st.info(result[0]['summary_text'])
|
193 |
|
194 |
elif model_key == 'translation':
|
@@ -310,7 +361,7 @@ def get_use_cases():
|
|
310 |
'description': "Identifica defeitos ou classifica produtos em linhas de produção com base em imagens.",
|
311 |
'example': "Uma fábrica de eletrônicos classifica imagens de circuitos como 'Defeituoso' ou 'Aprovado' para controle de qualidade.",
|
312 |
'benefit': "Redução de erros humanos e aumento da eficiência na inspeção.",
|
313 |
-
'demo_input': None,
|
314 |
'demo_type': 'image'
|
315 |
},
|
316 |
'object_detection': {
|
@@ -374,7 +425,7 @@ def handle_use_case_demo(models, use_case_key, use_case):
|
|
374 |
if use_case['demo_type'] == 'text':
|
375 |
with st.spinner("Processando demonstração..."):
|
376 |
result = models[use_case_key](use_case['demo_input'])
|
377 |
-
display_results(result, use_case_key)
|
378 |
elif use_case['demo_type'] == 'qa':
|
379 |
with st.spinner("Processando demonstração..."):
|
380 |
result = models[use_case_key](
|
@@ -382,6 +433,8 @@ def handle_use_case_demo(models, use_case_key, use_case):
|
|
382 |
context=use_case['demo_input']['context']
|
383 |
)
|
384 |
st.success("🔍 Resposta encontrada:")
|
|
|
|
|
385 |
st.markdown(f"**Resposta:** {result['answer']}")
|
386 |
st.markdown(f"**Confiança:** {result['score']:.2%}")
|
387 |
except Exception as e:
|
@@ -389,132 +442,153 @@ def handle_use_case_demo(models, use_case_key, use_case):
|
|
389 |
logging.error(f"Erro na demonstração do caso de uso {use_case_key}: {e}")
|
390 |
|
391 |
def main():
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
with st.spinner("Carregando modelos de IA... (Isso pode levar alguns minutos na primeira execução)"):
|
397 |
-
models = load_models()
|
398 |
-
|
399 |
-
if not models:
|
400 |
-
st.error("Falha crítica ao carregar os modelos. Verifique os logs para mais detalhes.")
|
401 |
return
|
402 |
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
("Classificação de Imagem", "image_classification"),
|
421 |
-
("Detecção de Objetos", "object_detection"),
|
422 |
-
("Segmentação de Imagem", "image_segmentation"),
|
423 |
-
("Reconhecimento Facial", "facial_recognition")
|
424 |
-
],
|
425 |
-
"🎵 Processamento de Áudio": [
|
426 |
-
("Transcrição de Áudio", "speech_to_text"),
|
427 |
-
("Classificação de Emoções", "audio_classification")
|
428 |
-
],
|
429 |
-
"✨ Modelos Generativos": [
|
430 |
-
("Texto para Imagem", "text_to_image")
|
431 |
-
]
|
432 |
-
}
|
433 |
-
|
434 |
-
selected_category = st.sidebar.selectbox(
|
435 |
-
"Categoria",
|
436 |
-
list(model_categories.keys()),
|
437 |
-
index=0
|
438 |
-
)
|
439 |
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
format_func=lambda x: x,
|
444 |
-
index=0
|
445 |
-
)
|
446 |
|
447 |
-
|
448 |
-
|
|
|
449 |
|
450 |
-
#
|
451 |
-
st.
|
452 |
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
}
|
471 |
-
st.info(model_info.get(model_key, "Informações detalhadas sobre este modelo."))
|
472 |
-
|
473 |
-
# Processamento baseado no tipo de modelo
|
474 |
-
try:
|
475 |
-
if model_key in ['sentiment_analysis', 'text_classification', 'summarization',
|
476 |
-
'translation', 'text_generation', 'ner']:
|
477 |
-
handle_text_models(models, model_key, selected_model)
|
478 |
|
479 |
-
|
480 |
-
|
|
|
|
|
|
|
481 |
|
482 |
-
|
483 |
-
|
484 |
-
|
|
|
|
|
|
|
485 |
|
486 |
-
|
487 |
-
|
488 |
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
st.
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
514 |
|
515 |
-
|
516 |
-
|
517 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
518 |
|
519 |
def handle_text_models(models, model_key, model_name):
|
520 |
"""Manipula modelos de texto"""
|
@@ -557,7 +631,7 @@ def handle_text_models(models, model_key, model_name):
|
|
557 |
else:
|
558 |
result = models[model_key](input_text, **advanced_params)
|
559 |
|
560 |
-
display_results(result, model_key)
|
561 |
|
562 |
except Exception as e:
|
563 |
st.error(f"Erro ao processar texto: {str(e)}")
|
@@ -598,6 +672,8 @@ def handle_qa_model(models, model_key):
|
|
598 |
st.warning(f"⚠️ Confiança baixa na resposta ({result['score']:.2%})")
|
599 |
|
600 |
st.success("🔍 Resposta encontrada:")
|
|
|
|
|
601 |
st.markdown(f"**Resposta:** {result['answer']}")
|
602 |
st.markdown(f"**Confiança:** {result['score']:.2%}")
|
603 |
|
|
|
1 |
import streamlit as st
|
2 |
+
import streamlit_authenticator as stauth
|
3 |
+
import yaml
|
4 |
+
from yaml.loader import SafeLoader
|
5 |
+
import os
|
6 |
from transformers import pipeline, AutoModelForCausalLM, AutoTokenizer
|
7 |
import torch
|
8 |
from PIL import Image
|
|
|
11 |
import numpy as np
|
12 |
import logging
|
13 |
import tempfile
|
|
|
14 |
from streamlit.runtime.uploaded_file_manager import UploadedFile
|
15 |
from diffusers import StableDiffusionPipeline
|
16 |
|
|
|
28 |
format='%(asctime)s - %(levelname)s - %(message)s'
|
29 |
)
|
30 |
|
31 |
+
# Configurar autenticação
|
32 |
+
def load_auth_config():
|
33 |
+
"""Carrega configuração de autenticação de variável de ambiente ou arquivo"""
|
34 |
+
try:
|
35 |
+
# Tenta carregar da variável de ambiente (Hugging Face Secrets)
|
36 |
+
config_yaml = os.getenv('AUTH_CONFIG')
|
37 |
+
if config_yaml:
|
38 |
+
config = yaml.load(config_yaml, Loader=SafeLoader)
|
39 |
+
return config
|
40 |
+
|
41 |
+
# Alternativa: carregar de um arquivo externo
|
42 |
+
config_path = os.getenv('AUTH_CONFIG_PATH', '~/.streamlit/config.yaml')
|
43 |
+
config_path = os.path.expanduser(config_path)
|
44 |
+
if os.path.exists(config_path):
|
45 |
+
with open(config_path, 'r') as file:
|
46 |
+
config = yaml.load(file, Loader=SafeLoader)
|
47 |
+
return config
|
48 |
+
|
49 |
+
# Configuração padrão para testes (remover em produção)
|
50 |
+
st.warning("⚠️ Nenhuma configuração de autenticação encontrada. Usando credenciais padrão (inseguro).")
|
51 |
+
config = {
|
52 |
+
'credentials': {
|
53 |
+
'usernames': {
|
54 |
+
'cliente': {
|
55 |
+
'name': 'Cliente',
|
56 |
+
'password': '$2b$12$6r1z.7zM7kL9vJ8K2Qf3Ce7V8Z9Qz3q0zXzY7W8K9vJ8K2Qf3Ce7' # Senha: senha123
|
57 |
+
}
|
58 |
+
}
|
59 |
+
},
|
60 |
+
'cookie': {
|
61 |
+
'name': 'ai_app_cookie',
|
62 |
+
'key': 'random_key_123',
|
63 |
+
'expiry_days': 30
|
64 |
+
},
|
65 |
+
'preauthorized': {
|
66 |
+
'emails': []
|
67 |
+
}
|
68 |
+
}
|
69 |
+
return config
|
70 |
+
except Exception as e:
|
71 |
+
st.error(f"Erro ao carregar configuração de autenticação: {str(e)}")
|
72 |
+
logging.error(f"Erro na configuração de autenticação: {e}")
|
73 |
+
return None
|
74 |
+
|
75 |
# Cache para evitar recarregar modelos a cada execução
|
76 |
@st.cache_resource(show_spinner=False)
|
77 |
def load_models():
|
|
|
232 |
logging.error(f"Erro no processamento de imagem: {e}")
|
233 |
return None
|
234 |
|
235 |
+
def display_results(result, model_key, input_text=None):
|
236 |
"""Exibe resultados formatados de acordo com o tipo de modelo"""
|
237 |
if model_key == 'summarization':
|
238 |
st.subheader("📝 Resumo Gerado")
|
239 |
+
if input_text:
|
240 |
+
st.markdown("**Texto Original:**")
|
241 |
+
st.write(input_text)
|
242 |
+
st.markdown("**Resumo:**")
|
243 |
st.info(result[0]['summary_text'])
|
244 |
|
245 |
elif model_key == 'translation':
|
|
|
361 |
'description': "Identifica defeitos ou classifica produtos em linhas de produção com base em imagens.",
|
362 |
'example': "Uma fábrica de eletrônicos classifica imagens de circuitos como 'Defeituoso' ou 'Aprovado' para controle de qualidade.",
|
363 |
'benefit': "Redução de erros humanos e aumento da eficiência na inspeção.",
|
364 |
+
'demo_input': None,
|
365 |
'demo_type': 'image'
|
366 |
},
|
367 |
'object_detection': {
|
|
|
425 |
if use_case['demo_type'] == 'text':
|
426 |
with st.spinner("Processando demonstração..."):
|
427 |
result = models[use_case_key](use_case['demo_input'])
|
428 |
+
display_results(result, use_case_key, input_text=use_case['demo_input'])
|
429 |
elif use_case['demo_type'] == 'qa':
|
430 |
with st.spinner("Processando demonstração..."):
|
431 |
result = models[use_case_key](
|
|
|
433 |
context=use_case['demo_input']['context']
|
434 |
)
|
435 |
st.success("🔍 Resposta encontrada:")
|
436 |
+
st.markdown(f"**Contexto:** {use_case['demo_input']['context']}")
|
437 |
+
st.markdown(f"**Pergunta:** {use_case['demo_input']['question']}")
|
438 |
st.markdown(f"**Resposta:** {result['answer']}")
|
439 |
st.markdown(f"**Confiança:** {result['score']:.2%}")
|
440 |
except Exception as e:
|
|
|
442 |
logging.error(f"Erro na demonstração do caso de uso {use_case_key}: {e}")
|
443 |
|
444 |
def main():
|
445 |
+
# Carregar configuração de autenticação
|
446 |
+
config = load_auth_config()
|
447 |
+
if not config:
|
448 |
+
st.error("Falha ao carregar autenticação. Contate o administrador.")
|
|
|
|
|
|
|
|
|
|
|
449 |
return
|
450 |
|
451 |
+
authenticator = stauth.Authenticate(
|
452 |
+
config['credentials'],
|
453 |
+
config['cookie']['name'],
|
454 |
+
config['cookie']['key'],
|
455 |
+
config['cookie']['expiry_days'],
|
456 |
+
config['preauthorized']
|
457 |
+
)
|
458 |
+
|
459 |
+
# Tela de login
|
460 |
+
name, authentication_status, username = authenticator.login('Login', 'main')
|
461 |
+
|
462 |
+
if authentication_status:
|
463 |
+
st.write(f"Bem-vindo, {name}!")
|
464 |
+
authenticator.logout('Logout', 'sidebar')
|
465 |
+
|
466 |
+
st.title("🤖 Aplicação de IA Multi-Modal Avançada")
|
467 |
+
st.markdown("---")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
|
469 |
+
# Carregar modelos
|
470 |
+
with st.spinner("Carregando modelos de IA... (Isso pode levar alguns minutos na primeira execução)"):
|
471 |
+
models = load_models()
|
|
|
|
|
|
|
472 |
|
473 |
+
if not models:
|
474 |
+
st.error("Falha crítica ao carregar os modelos. Verifique os logs para mais detalhes.")
|
475 |
+
return
|
476 |
|
477 |
+
# Abas para navegação
|
478 |
+
tab1, tab2 = st.tabs(["Explorar Modelos", "Casos de Uso"])
|
479 |
|
480 |
+
with tab1:
|
481 |
+
# Sidebar para seleção de modelo
|
482 |
+
st.sidebar.title("⚙️ Configurações")
|
483 |
+
model_categories = {
|
484 |
+
"📝 Processamento de Texto": [
|
485 |
+
("Análise de Sentimento", "sentiment_analysis"),
|
486 |
+
("Classificação de Texto", "text_classification"),
|
487 |
+
("Resumo de Texto", "summarization"),
|
488 |
+
("Perguntas e Respostas", "question_answering"),
|
489 |
+
("Tradução (EN→PT)", "translation"),
|
490 |
+
("Reconhecimento de Entidades", "ner"),
|
491 |
+
("Geração de Texto", "text_generation")
|
492 |
+
],
|
493 |
+
"🖼️ Processamento de Imagem": [
|
494 |
+
("Classificação de Imagem", "image_classification"),
|
495 |
+
("Detecção de Objetos", "object_detection"),
|
496 |
+
("Segmentação de Imagem", "image_segmentation"),
|
497 |
+
("Reconhecimento Facial", "facial_recognition")
|
498 |
+
],
|
499 |
+
"🎵 Processamento de Áudio": [
|
500 |
+
("Transcrição de Áudio", "speech_to_text"),
|
501 |
+
("Classificação de Emoções", "audio_classification")
|
502 |
+
],
|
503 |
+
"✨ Modelos Generativos": [
|
504 |
+
("Texto para Imagem", "text_to_image")
|
505 |
+
]
|
506 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
|
508 |
+
selected_category = st.sidebar.selectbox(
|
509 |
+
"Categoria",
|
510 |
+
list(model_categories.keys()),
|
511 |
+
index=0
|
512 |
+
)
|
513 |
|
514 |
+
selected_model = st.sidebar.selectbox(
|
515 |
+
"Modelo",
|
516 |
+
[name for name, key in model_categories[selected_category]],
|
517 |
+
format_func=lambda x: x,
|
518 |
+
index=0
|
519 |
+
)
|
520 |
|
521 |
+
# Obter chave do modelo selecionado
|
522 |
+
model_key = next(key for name, key in model_categories[selected_category] if name == selected_model)
|
523 |
|
524 |
+
# Interface principal
|
525 |
+
st.header(f"{selected_model}")
|
526 |
+
|
527 |
+
# Accordion para informações do modelo
|
528 |
+
with st.expander("ℹ️ Sobre este modelo"):
|
529 |
+
model_info = {
|
530 |
+
'sentiment_analysis': "Analisa o sentimento expresso em um texto (positivo/negativo/neutro).",
|
531 |
+
'text_classification': "Classifica textos em categorias pré-definidas.",
|
532 |
+
'summarization': "Gera um resumo conciso de um texto longo.",
|
533 |
+
'question_answering': "Responde perguntas baseadas em um contexto fornecido.",
|
534 |
+
'translation': "Traduz texto de inglês para português.",
|
535 |
+
'ner': "Identifica e classifica entidades nomeadas (pessoas, lugares, organizações).",
|
536 |
+
'text_generation': "Gera texto criativo continuando a partir de um prompt.",
|
537 |
+
'image_classification': "Identifica objetos e cenas em imagens.",
|
538 |
+
'object_detection': "Detecta e localiza múltiplos objetos em uma imagem.",
|
539 |
+
'image_segmentation': "Segmenta diferentes elementos em uma imagem.",
|
540 |
+
'facial_recognition': "Reconhece características faciais e emoções.",
|
541 |
+
'speech_to_text': "Transcreve fala em texto.",
|
542 |
+
'audio_classification': "Classifica emoções em arquivos de áudio.",
|
543 |
+
'text_to_image': "Gera imagens a partir de descrições textuais."
|
544 |
+
}
|
545 |
+
st.info(model_info.get(model_key, "Informações detalhadas sobre este modelo."))
|
546 |
+
|
547 |
+
# Processamento baseado no tipo de modelo
|
548 |
+
try:
|
549 |
+
if model_key in ['sentiment_analysis', 'text_classification', 'summarization',
|
550 |
+
'translation', 'text_generation', 'ner']:
|
551 |
+
handle_text_models(models, model_key, selected_model)
|
552 |
+
|
553 |
+
elif model_key == 'question_answering':
|
554 |
+
handle_qa_model(models, model_key)
|
555 |
+
|
556 |
+
elif model_key in ['image_classification', 'object_detection',
|
557 |
+
'image_segmentation', 'facial_recognition']:
|
558 |
+
handle_image_models(models, model_key, selected_model)
|
559 |
+
|
560 |
+
elif model_key in ['speech_to_text', 'audio_classification']:
|
561 |
+
handle_audio_models(models, model_key)
|
562 |
+
|
563 |
+
elif model_key == 'text_to_image':
|
564 |
+
handle_generative_models(models, model_key)
|
565 |
+
|
566 |
+
except Exception as e:
|
567 |
+
st.error(f"Erro inesperado durante a execução: {str(e)}")
|
568 |
+
logging.exception("Erro durante a execução do modelo")
|
569 |
|
570 |
+
with tab2:
|
571 |
+
st.header("Casos de Uso")
|
572 |
+
st.markdown("Explore casos práticos de aplicação dos modelos para resolver problemas reais.")
|
573 |
+
|
574 |
+
use_cases = get_use_cases()
|
575 |
+
selected_use_case = st.selectbox(
|
576 |
+
"Selecione um caso de uso",
|
577 |
+
list(use_cases.keys()),
|
578 |
+
format_func=lambda x: use_cases[x]['title']
|
579 |
+
)
|
580 |
+
|
581 |
+
use_case = use_cases[selected_use_case]
|
582 |
+
|
583 |
+
st.subheader(use_case['title'])
|
584 |
+
with st.expander("ℹ️ Detalhes do Caso de Uso"):
|
585 |
+
st.markdown(f"**Descrição**: {use_case['description']}")
|
586 |
+
st.markdown(f"**Exemplo Prático**: {use_case['example']}")
|
587 |
+
st.markdown(f"**Benefício**: {use_case['benefit']}")
|
588 |
+
|
589 |
+
if use_case['demo_input'] is not None:
|
590 |
+
if st.button("🚀 Executar Demonstração", key=f"demo_{selected_use_case}"):
|
591 |
+
handle_use_case_demo(models, selected_use_case, use_case)
|
592 |
|
593 |
def handle_text_models(models, model_key, model_name):
|
594 |
"""Manipula modelos de texto"""
|
|
|
631 |
else:
|
632 |
result = models[model_key](input_text, **advanced_params)
|
633 |
|
634 |
+
display_results(result, model_key, input_text=input_text)
|
635 |
|
636 |
except Exception as e:
|
637 |
st.error(f"Erro ao processar texto: {str(e)}")
|
|
|
672 |
st.warning(f"⚠️ Confiança baixa na resposta ({result['score']:.2%})")
|
673 |
|
674 |
st.success("🔍 Resposta encontrada:")
|
675 |
+
st.markdown(f"**Contexto:** {context}")
|
676 |
+
st.markdown(f"**Pergunta:** {question}")
|
677 |
st.markdown(f"**Resposta:** {result['answer']}")
|
678 |
st.markdown(f"**Confiança:** {result['score']:.2%}")
|
679 |
|