Spaces:
Runtime error
Runtime error
import os | |
from dotenv import load_dotenv | |
from src.presentation.web.gradio_interface import GradioInterface | |
import logging | |
import torch | |
import gc | |
import nvidia_smi | |
from src.domain.factories.detector_factory import force_gpu_init, is_gpu_available | |
# Configurar logging | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
) | |
logger = logging.getLogger(__name__) | |
def check_gpu_type(): | |
"""Verifica o tipo de GPU disponível no ambiente Hugging Face.""" | |
try: | |
nvidia_smi.nvmlInit() | |
handle = nvidia_smi.nvmlDeviceGetHandleByIndex(0) | |
info = nvidia_smi.nvmlDeviceGetMemoryInfo(handle) | |
gpu_name = nvidia_smi.nvmlDeviceGetName(handle) | |
total_memory = info.total / (1024**3) # Converter para GB | |
logger.info(f"GPU detectada: {gpu_name}") | |
logger.info(f"Memória total: {total_memory:.2f}GB") | |
# T4 dedicada tem tipicamente 16GB | |
if "T4" in gpu_name and total_memory > 14: | |
return "t4_dedicated" | |
# Zero-GPU compartilhada tem tipicamente menos memória | |
elif total_memory < 14: | |
return "zero_gpu_shared" | |
else: | |
return "unknown" | |
except Exception as e: | |
logger.error(f"Erro ao verificar tipo de GPU: {str(e)}") | |
return "unknown" | |
finally: | |
try: | |
nvidia_smi.nvmlShutdown() | |
except: | |
pass | |
def setup_gpu_environment(gpu_type: str) -> bool: | |
"""Configura o ambiente GPU com base no tipo detectado.""" | |
try: | |
# Verificar ambiente CUDA | |
if not torch.cuda.is_available(): | |
logger.warning("CUDA não está disponível") | |
return False | |
# Configurações comuns | |
os.environ['CUDA_DEVICE_ORDER'] = 'PCI_BUS_ID' | |
os.environ['CUDA_VISIBLE_DEVICES'] = '0' | |
# Limpar memória | |
torch.cuda.empty_cache() | |
gc.collect() | |
if gpu_type == "t4_dedicated": | |
# Configurações para T4 dedicada | |
logger.info("Configurando para T4 dedicada") | |
torch.backends.cuda.matmul.allow_tf32 = True | |
torch.backends.cudnn.benchmark = True | |
torch.backends.cudnn.allow_tf32 = True | |
# Usar mais memória pois temos GPU dedicada | |
torch.cuda.set_per_process_memory_fraction(0.9) | |
os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'max_split_size_mb:512' | |
elif gpu_type == "zero_gpu_shared": | |
# Configurações para Zero-GPU compartilhada | |
logger.info("Configurando para Zero-GPU compartilhada") | |
torch.backends.cudnn.benchmark = False | |
# Limitar uso de memória | |
torch.cuda.set_per_process_memory_fraction(0.6) | |
os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'max_split_size_mb:128' | |
# Verificar configuração | |
try: | |
device = torch.device('cuda') | |
dummy = torch.zeros(1, device=device) | |
del dummy | |
logger.info(f"Configurações GPU aplicadas com sucesso para: {gpu_type}") | |
return True | |
except Exception as e: | |
logger.error(f"Erro ao configurar GPU: {str(e)}") | |
return False | |
except Exception as e: | |
logger.error(f"Erro ao configurar ambiente GPU: {str(e)}") | |
return False | |
def main(): | |
"""Função principal que inicia a aplicação.""" | |
try: | |
# Verificar se está rodando no Hugging Face | |
IS_HUGGINGFACE = os.getenv('SPACE_ID') is not None | |
# Carregar configurações do ambiente apropriado | |
if IS_HUGGINGFACE: | |
load_dotenv('.env.huggingface') | |
logger.info("Ambiente HuggingFace detectado") | |
# Identificar e configurar GPU | |
gpu_type = check_gpu_type() | |
gpu_available = setup_gpu_environment(gpu_type) | |
if gpu_available: | |
logger.info(f"GPU configurada com sucesso: {gpu_type}") | |
else: | |
logger.warning("GPU não disponível ou não configurada corretamente") | |
else: | |
load_dotenv('.env') | |
logger.info("Ambiente local detectado") | |
gpu_available = False | |
# Criar e configurar interface | |
interface = GradioInterface() | |
demo = interface.create_interface() | |
if IS_HUGGINGFACE: | |
# Configurar com base no tipo de GPU | |
if gpu_type == "t4_dedicated": | |
max_concurrent = 2 # T4 pode lidar com mais requisições | |
queue_size = 10 | |
else: | |
max_concurrent = 1 # Zero-GPU precisa ser mais conservadora | |
queue_size = 5 | |
# Configurar fila | |
demo = demo.queue( | |
api_open=False, | |
max_size=queue_size, | |
status_update_rate="auto", | |
default_concurrency_limit=max_concurrent | |
) | |
# Launch | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False, | |
max_threads=max_concurrent | |
) | |
else: | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=True | |
) | |
except Exception as e: | |
logger.error(f"Erro ao iniciar aplicação: {str(e)}") | |
raise | |
if __name__ == "__main__": | |
main() |