# AIDA — imagem para Hugging Face Spaces (SDK: docker) # # Por que Docker e não Gradio/Streamlit: o front-end do AIDA é um site próprio, # em outro domínio, que consome a API por HTTP. Os SDKs de UI do HF servem para # interfaces geradas por eles; aqui precisamos expor um endpoint REST. # # O Spaces publica o container em HTTPS numa URL do tipo # https://-.hf.space # e espera que a aplicação escute na porta 7860. FROM python:3.12-slim # libGL e libglib: dependências nativas do opencv-python. # Sem elas o import de cv2 falha com "libGL.so.1: cannot open shared object". RUN apt-get update && apt-get install -y --no-install-recommends \ libgl1 \ libglib2.0-0 \ && rm -rf /var/lib/apt/lists/* # O Spaces roda o container como usuário 1000. Criar o usuário e trabalhar na # home dele evita erros de permissão quando a aplicação grava saídas. RUN useradd -m -u 1000 aida USER aida ENV HOME=/home/aida \ PATH=/home/aida/.local/bin:$PATH \ PYTHONUNBUFFERED=1 \ # Cache do HuggingFace dentro da home, senão o download do CLIP falha. HF_HOME=/home/aida/.cache/huggingface WORKDIR /home/aida/app COPY --chown=aida requirements.txt constraints.txt ./ # Índice de CPU do PyTorch: a roda padrão traz CUDA (~2 GB) que não é usada. # constraints.txt trava as versões validadas (sem ele, cada rebuild pega a última). RUN pip install --no-cache-dir --user -r requirements.txt -c constraints.txt \ --extra-index-url https://download.pytorch.org/whl/cpu COPY --chown=aida . . # Baixa os pesos do CLIP na construção da imagem, não na primeira requisição. # Sem isto, o primeiro usuário depois de um cold start espera ~350 MB de # download antes de ver qualquer resposta. RUN python -c "import open_clip; open_clip.create_model_and_transforms('ViT-B-32-quickgelu', pretrained='openai')" EXPOSE 7860 ENV PORT=7860 # 1 worker: cada worker carrega sua própria cópia do CLIP (~1 GB). Vários # workers multiplicam a memória sem ganho, porque a carga é limitada por CPU. # threads=4 atende requisições concorrentes compartilhando o mesmo modelo. # timeout=180: uma foto de 50 MP leva ~6 s, mas o cold start é bem mais lento. CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "1", "--threads", "4", \ "--timeout", "180", "--access-logfile", "-", "site_api.app:app"]