euiiiia commited on
Commit
270fc4d
·
verified ·
1 Parent(s): fcecb2e

Upload 8 files

Browse files
Files changed (6) hide show
  1. Dockerfile +79 -75
  2. compose.yaml +31 -18
  3. entrypoint.sh +36 -13
  4. requirements.txt +3 -0
  5. setup.py +114 -120
  6. start.sh +70 -36
Dockerfile CHANGED
@@ -1,127 +1,131 @@
1
  # =============================================================================
2
- # ADUC-SDR Video Suite — High-Perf Diffusers for 8× L40S (SM 8.9)
 
3
  # CUDA 12.8 | PyTorch 2.8.0+cu128 | Ubuntu 22.04
4
  # =============================================================================
5
  FROM nvidia/cuda:12.8.0-devel-ubuntu22.04
6
 
7
- LABEL maintainer="Carlos Rodrigues dos Santos & Development Partner"
8
- LABEL description="High-performance Diffusers stack with FA2/SDPA, 8×L40S"
9
- LABEL version="4.4.0"
10
  LABEL cuda_version="12.8.0"
11
  LABEL python_version="3.10"
12
  LABEL pytorch_version="2.8.0+cu128"
13
  LABEL gpu_optimized_for="8x_NVIDIA_L40S"
14
 
15
- # ---------------- Core env & caches ----------------
 
 
16
  ENV DEBIAN_FRONTEND=noninteractive TZ=UTC LANG=C.UTF-8 LC_ALL=C.UTF-8 \
17
  PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 \
18
- PIP_NO_CACHE_DIR=1 PIP_DISABLE_PIP_VERSION_CHECK=1
19
 
20
- # GPU/Compute
21
- ENV NVIDIA_VISIBLE_DEVICES=all
22
- ENV TORCH_CUDA_ARCH_LIST="8.9"
23
- ENV CUDA_DEVICE_ORDER=PCI_BUS_ID
24
- ENV CUDA_DEVICE_MAX_CONNECTIONS=32
25
 
26
- # Threads
27
  ENV OMP_NUM_THREADS=8 MKL_NUM_THREADS=8 MAX_JOBS=160
28
 
29
- # Alloc/caches
30
- ENV PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512,garbage_collection_threshold:0.8
31
- ENV CUDA_LAUNCH_BLOCKING=0 CUDA_CACHE_MAXSIZE=2147483648 CUDA_CACHE_DISABLE=0
32
 
33
- # App paths
34
- ENV APP_HOME=/app
35
- WORKDIR $APP_HOME
 
 
 
 
 
 
36
 
37
- # Persistent data and caches in /data
38
- ENV HF_HOME=/data/.cache/huggingface
39
- ENV TORCH_HOME=/data/.cache/torch
40
- ENV HF_DATASETS_CACHE=/data/.cache/datasets
41
- ENV TRANSFORMERS_CACHE=/data/.cache/transformers
42
- ENV DIFFUSERS_CACHE=/data/.cache/diffusers
43
- ENV HF_HUB_ENABLE_HF_TRANSFER=1
44
- ENV TOKENIZERS_PARALLELISM=false
45
 
46
- # Create non-root user and data dirs early, fix ownership
 
 
 
 
47
  RUN useradd -m -u 1000 -s /bin/bash appuser && \
48
- mkdir -p /data /data/models \
49
- /data/.cache/huggingface /data/.cache/torch \
50
- /data/.cache/datasets /data/.cache/transformers /data/.cache/diffusers && \
51
- chown -R appuser:appuser /data
52
 
53
- # Models live in /data/models and are visible at /app/models
54
- ENV MODELS_DIR=/data/models
55
- RUN ln -sf /data/models /app/models
56
-
57
- # ---------------- System & Python ----------------
58
  RUN apt-get update && apt-get install -y --no-install-recommends \
59
  build-essential gosu tree cmake git git-lfs curl wget ffmpeg ninja-build \
60
  python3.10 python3.10-dev python3.10-distutils python3-pip \
61
  ca-certificates libglib2.0-0 libgl1 \
62
  && apt-get clean && rm -rf /var/lib/apt/lists/*
63
 
64
- RUN ln -sf /usr/bin/python3.10 /usr/bin/python3 && \
65
- ln -sf /usr/bin/python3.10 /usr/bin/python && \
66
  python3 -m pip install --upgrade pip
67
 
68
- # ---------------- PyTorch cu128 (pinned) ----------------
 
 
 
 
69
  RUN pip install --index-url https://download.pytorch.org/whl/cu128 \
70
  torch>=2.8.0+cu128 torchvision>=0.23.0+cu128 torchaudio>=2.8.0+cu128
71
 
72
- # ---------------- Toolchain, Triton, FA2 (no bnb build) ----------------
73
  RUN pip install packaging ninja cmake pybind11 scikit-build cython hf_transfer "numpy>=1.24.4"
74
 
75
- # Triton 3.x (no triton.ops)
76
  RUN pip uninstall -y triton || true && \
77
  pip install -v --no-build-isolation triton==3.4.0
78
 
 
 
 
 
 
79
 
80
- # FlashAttention 2.8.x
81
- #RUN pip install flash-attn==2.8.3 --no-build-isolation || \
82
- # pip install flash-attn==2.8.2 --no-build-isolation || \
83
- # pip install flash-attn==2.8.1 --no-build-isolation || \
84
- # pip install flash-attn==2.8.0.post2 --no-build-isolation
85
-
86
-
87
- --------------- App dependencies ----------------
88
- COPY requirements.txt ./requirements.txt
89
  RUN pip install --no-cache-dir -r requirements.txt
90
 
91
- # Pin bnb to avoid surprise CUDA/PTX mismatches (adjust as needed)
92
  RUN pip install --upgrade bitsandbytes
93
 
94
- # Custom .whl (Apex + dropout_layer_norm)
 
 
 
 
95
  RUN echo "Installing custom wheels..." && \
96
  pip install --no-cache-dir \
97
  "https://huggingface.co/euIaxs22/Aduc-sdr/resolve/main/apex-0.1-cp310-cp310-linux_x86_64.whl" \
98
  "https://huggingface.co/euIaxs22/Aduc-sdr/resolve/main/dropout_layer_norm-0.1-cp310-cp310-linux_x86_64.whl"
 
 
 
 
 
 
99
 
100
- # ====================================================================
101
- # Optional: q8_kernels + LTX-Video (enable if needed; ensure wheel ABI)
102
- RUN pip install --no-cache-dir \
103
- "https://huggingface.co/euIaxs22/Aduc-sdr/resolve/main/q8_kernels-0.0.5-cp310-cp310-linux_x86_64.whl"
104
- # RUN git clone https://github.com/Lightricks/LTX-Video.git /data/LTX-Video && \
105
- # cd /data/LTX-Video && python -m pip install -e .[inference]
106
- # ====================================================================
107
-
108
- # Scripts and app
109
- COPY info.sh ./app/info.sh
110
- COPY builder.sh ./app/builder.sh
111
- COPY start.sh ./app/start.sh
112
- COPY entrypoint.sh ./app/entrypoint.sh
113
-
114
- # Copy the rest of the source last for better caching
115
- COPY . .
116
-
117
- # Permissions on app tree
118
- RUN chown -R appuser:appuser /app /data && \
119
- chmod 0755 /app/entrypoint.sh /app/start.sh /app/info.sh /app/builder.sh
120
 
 
 
 
 
121
  VOLUME /data
122
 
123
- ENTRYPOINT ["/app/entrypoint.sh"]
124
  USER appuser
125
 
126
- # ---------------- Entry ----------------
127
- CMD ["/app/start.sh"]
 
 
 
 
1
  # =============================================================================
2
+ # ADUC-SDR Video Suite — Dockerfile Otimizado
3
+ # Preserva a estrutura de instalação original para alta performance.
4
  # CUDA 12.8 | PyTorch 2.8.0+cu128 | Ubuntu 22.04
5
  # =============================================================================
6
  FROM nvidia/cuda:12.8.0-devel-ubuntu22.04
7
 
8
+ LABEL maintainer="Carlos Rodrigues dos Santos"
9
+ LABEL description="ADUC-SDR: High-performance Diffusers stack for 8x NVIDIA L40S with LTX-Video and SeedVR"
10
+ LABEL version="5.0.0"
11
  LABEL cuda_version="12.8.0"
12
  LABEL python_version="3.10"
13
  LABEL pytorch_version="2.8.0+cu128"
14
  LABEL gpu_optimized_for="8x_NVIDIA_L40S"
15
 
16
+ # =============================================================================
17
+ # 1. Variáveis de Ambiente e Configuração de Paths
18
+ # =============================================================================
19
  ENV DEBIAN_FRONTEND=noninteractive TZ=UTC LANG=C.UTF-8 LC_ALL=C.UTF-8 \
20
  PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 \
21
+ PIP_NO_CACHE_DIR=0 PIP_DISABLE_PIP_VERSION_CHECK=1
22
 
23
+ # --- Configurações de GPU e Computação ---
24
+ ENV NVIDIA_VISIBLE_DEVICES=all \
25
+ TORCH_CUDA_ARCH_LIST="8.9" \
26
+ CUDA_DEVICE_ORDER=PCI_BUS_ID \
27
+ CUDA_DEVICE_MAX_CONNECTIONS=32
28
 
29
+ # --- Configurações de Threads ---
30
  ENV OMP_NUM_THREADS=8 MKL_NUM_THREADS=8 MAX_JOBS=160
31
 
32
+ # --- Configurações de Alocador de Memória e Caches de GPU ---
33
+ ENV PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512,garbage_collection_threshold:0.8 \
34
+ CUDA_LAUNCH_BLOCKING=0 CUDA_CACHE_MAXSIZE=2147483648 CUDA_CACHE_DISABLE=0
35
 
36
+ # --- Paths da Aplicação e Dados Persistentes ---
37
+ ENV APP_HOME=/app \
38
+ HF_HOME=/data/.cache/huggingface \
39
+ TORCH_HOME=/data/.cache/torch \
40
+ HF_DATASETS_CACHE=/data/.cache/datasets \
41
+ TRANSFORMERS_CACHE=/data/.cache/transformers \
42
+ DIFFUSERS_CACHE=/data/.cache/diffusers \
43
+ HF_HUB_ENABLE_HF_TRANSFER=1 \
44
+ TOKENIZERS_PARALLELISM=false
45
 
46
+ WORKDIR $APP_HOME
 
 
 
 
 
 
 
47
 
48
+ # =============================================================================
49
+ # 2. Setup de Usuário e Sistema
50
+ # =============================================================================
51
+ # Cria usuário não-root e diretórios de dados/app.
52
+ # As permissões finais serão aplicadas no final.
53
  RUN useradd -m -u 1000 -s /bin/bash appuser && \
54
+ mkdir -p /data $APP_HOME /app/output
 
 
 
55
 
56
+ # --- Instalação de Pacotes de Sistema e Python ---
 
 
 
 
57
  RUN apt-get update && apt-get install -y --no-install-recommends \
58
  build-essential gosu tree cmake git git-lfs curl wget ffmpeg ninja-build \
59
  python3.10 python3.10-dev python3.10-distutils python3-pip \
60
  ca-certificates libglib2.0-0 libgl1 \
61
  && apt-get clean && rm -rf /var/lib/apt/lists/*
62
 
63
+ RUN ln -sf /usr/bin/python3.10 /usr/bin/python && \
 
64
  python3 -m pip install --upgrade pip
65
 
66
+ # =============================================================================
67
+ # 3. Instalação da Toolchain de Machine Learning (Mantida 100% Original)
68
+ # =============================================================================
69
+
70
+ # --- PyTorch para CUDA 12.8 ---
71
  RUN pip install --index-url https://download.pytorch.org/whl/cu128 \
72
  torch>=2.8.0+cu128 torchvision>=0.23.0+cu128 torchaudio>=2.8.0+cu128
73
 
74
+ # --- Ferramentas de Compilação, Triton e FlashAttention ---
75
  RUN pip install packaging ninja cmake pybind11 scikit-build cython hf_transfer "numpy>=1.24.4"
76
 
77
+ # --- Triton 3.x ---
78
  RUN pip uninstall -y triton || true && \
79
  pip install -v --no-build-isolation triton==3.4.0
80
 
81
+ # --- FlashAttention 2.8.x ---
82
+ RUN pip install flash-attn==2.8.3 --no-build-isolation || \
83
+ pip install flash-attn==2.8.2 --no-build-isolation || \
84
+ pip install flash-attn==2.8.1 --no-build-isolation || \
85
+ pip install flash-attn==2.8.0.post2 --no-build-isolation
86
 
87
+ # =============================================================================
88
+ # 4. Instalação das Dependências da Aplicação
89
+ # =============================================================================
90
+ # Copia e instala requirements.txt primeiro para otimizar o cache de camadas do Docker.
91
+ COPY --chown=appuser:appuser requirements.txt ./requirements.txt
 
 
 
 
92
  RUN pip install --no-cache-dir -r requirements.txt
93
 
94
+ # --- Instalação de bitsandbytes e Wheels Customizados (Mantido 100% Original) ---
95
  RUN pip install --upgrade bitsandbytes
96
 
97
+ # Instala wheels customizados (Apex, etc.)
98
+ # Instala q8_kernels
99
+ RUN pip install --no-cache-dir \
100
+ "https://huggingface.co/euIaxs22/Aduc-sdr/resolve/main/q8_kernels-0.0.5-cp310-cp310-linux_x86_64.whl"
101
+
102
  RUN echo "Installing custom wheels..." && \
103
  pip install --no-cache-dir \
104
  "https://huggingface.co/euIaxs22/Aduc-sdr/resolve/main/apex-0.1-cp310-cp310-linux_x86_64.whl" \
105
  "https://huggingface.co/euIaxs22/Aduc-sdr/resolve/main/dropout_layer_norm-0.1-cp310-cp310-linux_x86_64.whl"
106
+
107
+ # =============================================================================
108
+ # 5. Cópia do Código-Fonte e Configuração Final
109
+ # =============================================================================
110
+ # Copia o restante do código-fonte da aplicação por último.
111
+ COPY --chown=appuser:appuser . .
112
 
113
+ # Garante que todos os scripts de inicialização sejam executáveis
114
+ # e que o usuário 'appuser' seja o dono de todos os arquivos.
115
+ RUN chown -R appuser:appuser $APP_HOME /data && \
116
+ chmod +x /app/entrypoint.sh /app/start.sh /app/info.sh /app/builder.sh
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
+ # =============================================================================
119
+ # 6. Ponto de Entrada
120
+ # =============================================================================
121
+ # Expõe o diretório /data para ser montado como um volume persistente.
122
  VOLUME /data
123
 
124
+ # Define o usuário padrão para a execução do contêiner.
125
  USER appuser
126
 
127
+ # Define o script que será executado na inicialização do contêiner.
128
+ ENTRYPOINT ["/app/entrypoint.sh"]
129
+
130
+ # Define o comando padrão a ser executado pelo entrypoint.
131
+ CMD ["/app/start.sh"]
compose.yaml CHANGED
@@ -1,26 +1,39 @@
 
 
 
1
  services:
2
- vincie:
3
- image: img2img:edit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  deploy:
5
  resources:
6
  reservations:
7
  devices:
8
- - capabilities: [gpu]
 
 
9
  ports:
10
- - "7860:7860"
11
- environment:
12
- GRADIO_SERVER_PORT: "7860"
13
- HF_HUB_CACHE: "/data/.cache/huggingface/hub"
14
- CKPT_ROOT: "/data/ckpt/VINCIE-3B"
15
- VINCIE_ROOT: "/data/VINCIE"
16
  volumes:
17
- - vincie_hub:/data/.cache/huggingface/hub
18
- - vincie_ckpt:/data/ckpt/VINCIE-3B
19
- - vincie_out:/app/outputs
20
- - vincie_repo:/data/VINCIE
21
  volumes:
22
- vincie_hub: {}
23
- vincie_ckpt: {}
24
- vincie_out: {}
25
- vincie_repo: {}
26
-
 
1
+ # compose.yaml (Versão com VINCIE)
2
+ version: '3.8'
3
+
4
  services:
5
+ aduc-sdr-app:
6
+ build: .
7
+ environment:
8
+ ADUC_LOG_LEVEL: "DEBUG"
9
+ image: aduc-sdr-videosuite:latest
10
+ # (deploy, resources... mantidos como antes)
11
+ ports:
12
+ - "7860:7860" # Porta para a UI principal (LTX + SeedVR)
13
+ - "7861:7861" # Porta para a nova UI do VINCIE
14
+ volumes:
15
+ # O volume 'aduc_data' agora armazena tudo: cache, modelos e repos.
16
+ - aduc_data:/data
17
+ - ./output:/app/output
18
+ # O entrypoint cuidará do setup na inicialização.
19
+ # O CMD padrão iniciará a UI principal. Para VINCIE, usaremos um comando diferente.
20
+
21
+ # Novo serviço para a interface do VINCIE
22
+ vince-ui:
23
+ image: aduc-sdr-videosuite:latest # Usa a mesma imagem já construída
24
+ command: python3 /app/app_vince.py # Sobrescreve o CMD padrão para iniciar a UI do VINCIE
25
  deploy:
26
  resources:
27
  reservations:
28
  devices:
29
+ - driver: nvidia
30
+ count: all
31
+ capabilities: [gpu]
32
  ports:
33
+ - "7861:7861"
 
 
 
 
 
34
  volumes:
35
+ - aduc_data:/data
36
+ - ./output:/app/output
37
+
 
38
  volumes:
39
+ aduc_data:
 
 
 
 
entrypoint.sh CHANGED
@@ -1,21 +1,44 @@
1
- #!/bin/sh
2
- # entrypoint.sh - Executado como root para corrigir permissões.
3
  set -e
4
 
5
- echo "🔐 ENTRYPOINT (root): Corrigindo permissões para os diretórios de dados e saída..."
6
 
7
- # Lista de diretórios a serem criados e terem suas permissões ajustadas
8
- # Usamos os valores padrão, pois as variáveis de ambiente podem não estar disponíveis aqui.
9
- DIRS_TO_OWN="/app/outputs /app/inputs"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- # Garante que os diretórios existam
12
- mkdir -p $DIRS_TO_OWN
 
 
 
13
 
14
- # Muda o proprietário para o UID e GID 1000, que corresponde ao 'appuser'
15
- # Usar UID/GID é mais robusto em ambientes de contêiner.
16
- chown -R 1000:1000 $DIRS_TO_OWN
 
17
 
18
- echo "✅ ENTRYPOINT (root): Permissões corrigidas."
19
 
20
- # Passa a execução para o comando principal (CMD) definido no Dockerfile.
 
 
 
 
 
21
  exec "$@"
 
1
+ #!/bin/bash
 
2
  set -e
3
 
4
+ echo "🚀 ADUC-SDR Entrypoint: Configurando o ambiente de execução..."
5
 
6
+ # --- Configuração de Performance (CPU & GPU) ---
7
+ NUM_VCPUS=$(nproc)
8
+ NUM_GPUS=$(nvidia-smi --query-gpu=count --format=csv,noheader | head -n 1 || echo 0)
9
+ echo " > Hardware: ${NUM_VCPUS} vCPUs, ${NUM_GPUS} GPUs"
10
+ if [[ ${NUM_GPUS} -gt 0 ]]; then
11
+ VCPUS_PER_GPU=$((NUM_VCPUS / NUM_GPUS))
12
+ THREADS_PER_PROCESS=$((VCPUS_PER_GPU / 2))
13
+ else
14
+ THREADS_PER_PROCESS=$((NUM_VCPUS / 2))
15
+ fi
16
+ MIN_THREADS=4; MAX_THREADS=16
17
+ if [[ ${THREADS_PER_PROCESS} -lt ${MIN_THREADS} ]]; then THREADS_PER_PROCESS=${MIN_THREADS}; fi
18
+ if [[ ${THREADS_PER_PROCESS} -gt ${MAX_THREADS} ]]; then THREADS_PER_PROCESS=${MAX_THREADS}; fi
19
+ export OMP_NUM_THREADS=${OMP_NUM_THREADS:-${THREADS_PER_PROCESS}}
20
+ export MKL_NUM_THREADS=${MKL_NUM_THREADS:-${THREADS_PER_PROCESS}}
21
+ export MAX_JOBS=${MAX_JOBS:-${NUM_VCPUS}}
22
+ export PYTORCH_CUDA_ALLOC_CONF=${PYTORCH_CUDA_ALLOC_CONF:-"max_split_size_mb:512"}
23
+ export NVIDIA_TF32_OVERRIDE=${NVIDIA_TF32_OVERRIDE:-1}
24
 
25
+ # --- Configuração de Depuração e Logging ---
26
+ export ADUC_LOG_LEVEL=${ADUC_LOG_LEVEL:-"INFO"}
27
+ export CUDA_LAUNCH_BLOCKING=${CUDA_LAUNCH_BLOCKING:-0}
28
+ export PYTHONFAULTHANDLER=1
29
+ export GRADIO_DEBUG=${GRADIO_DEBUG:-"False"}
30
 
31
+ echo " > Performance: OMP_NUM_THREADS=${OMP_NUM_THREADS}, MKL_NUM_THREADS=${MKL_NUM_THREADS}"
32
+ echo " > Depuração: ADUC_LOG_LEVEL=${ADUC_LOG_LEVEL}, CUDA_LAUNCH_BLOCKING=${CUDA_LAUNCH_BLOCKING}"
33
+ echo ""
34
+ echo ""
35
 
36
+ #/bin/bash /app/info.sh
37
 
38
+ # --- Setup de Dependências ---
39
+ echo " > Verificando dependências com setup.py..."
40
+ python3 /app/setup.py
41
+
42
+ echo "---------------------------------------------------------"
43
+ echo "🔥 Ambiente configurado. Iniciando o comando principal: $@"
44
  exec "$@"
requirements.txt CHANGED
@@ -12,9 +12,12 @@ imageio-ffmpeg
12
  einops
13
  timm
14
  av
 
15
  git+https://github.com/huggingface/diffusers.git@main
16
 
17
 
 
 
18
  lpips>=0.1.4 # LPIPS model for VAE training
19
 
20
  # Dataloading
 
12
  einops
13
  timm
14
  av
15
+ #flash-attn-3@https://huggingface.co/alexnasa/flash-attn-3/resolve/main/128/flash_attn_3-3.0.0b1-cp39-abi3-linux_x86_64.whl
16
  git+https://github.com/huggingface/diffusers.git@main
17
 
18
 
19
+ Common
20
+ # Configuration system.
21
  lpips>=0.1.4 # LPIPS model for VAE training
22
 
23
  # Dataloading
setup.py CHANGED
@@ -2,179 +2,173 @@
2
  #
3
  # Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos
4
  #
5
- # Versão 2.3.0 (Setup Robusto e Idempotente)
6
- # - Verifica a existência de repositórios e arquivos de modelo antes de baixar.
7
- # - Pula downloads se os artefatos existirem, sem gerar erros.
8
- # - Unifica o download de todas as dependências (Git, LTX Models, SeedVR Models).
9
 
10
  import os
11
  import subprocess
12
  import sys
13
  from pathlib import Path
14
  import yaml
15
- from huggingface_hub import hf_hub_download
16
 
17
- # --- Configuração Geral ---
 
 
 
18
  DEPS_DIR = Path("/data")
 
19
 
20
- # --- Configuração Específica LTX-Video ---
21
  LTX_VIDEO_REPO_DIR = DEPS_DIR / "LTX-Video"
 
 
 
22
 
23
- # --- Configuração Específica SeedVR ---
24
- SEEDVR_MODELS_DIR = DEPS_DIR / "SeedVR"
25
-
26
- # --- Repositórios para Clonar ---
27
  REPOS_TO_CLONE = {
28
  "LTX-Video": "https://huggingface.co/spaces/Lightricks/ltx-video-distilled",
29
  "SeedVR": "https://github.com/numz/ComfyUI-SeedVR2_VideoUpscaler",
30
- "MMAudio": "https://github.com/hkchengrex/MMAudio.git"
31
  }
32
 
 
 
 
 
33
  def run_command(command, cwd=None):
34
- """Executa um comando no terminal e lida com erros."""
35
  print(f"Executando: {' '.join(command)}")
36
  try:
37
  subprocess.run(
38
- command,
39
- check=True,
40
- cwd=cwd,
41
- stdin=subprocess.DEVNULL,
42
  )
43
  except subprocess.CalledProcessError as e:
44
- print(f"ERRO: O comando falhou com o código de saída {e.returncode}\nStderr: {e.stderr}")
45
  sys.exit(1)
46
  except FileNotFoundError:
47
- print(f"ERRO: O comando '{command[0]}' não foi encontrado. Certifique-se de que o git está instalado e no seu PATH.")
48
  sys.exit(1)
49
 
50
- # --- Funções de Download (LTX-Video) ---
51
-
52
  def _load_ltx_config():
53
  """Carrega o arquivo de configuração YAML do LTX-Video."""
54
  print("--- Carregando Configuração do LTX-Video ---")
55
- base = LTX_VIDEO_REPO_DIR / "configs"
56
- candidates = [
57
- base / "ltxv-13b-0.9.8-dev-fp8.yaml",
58
- base / "ltxv-13b-0.9.8-distilled-fp8.yaml",
59
- base / "ltxv-13b-0.9.8-distilled.yaml",
60
- ]
61
- for cfg_path in candidates:
62
- if cfg_path.exists():
63
- print(f"Configuração encontrada: {cfg_path}")
64
- with open(cfg_path, "r") as file:
65
- return yaml.safe_load(file)
66
-
67
- fallback_path = base / "ltxv-13b-0.9.8-distilled-fp8.yaml"
68
- print(f"AVISO: Nenhuma configuração preferencial encontrada. Usando fallback: {fallback_path}")
69
- if not fallback_path.exists():
70
- print(f"ERRO: Arquivo de configuração fallback '{fallback_path}' não encontrado.")
71
  return None
72
-
73
- with open(fallback_path, "r") as file:
74
  return yaml.safe_load(file)
75
 
76
- def _download_ltx_models(config):
77
- """Baixa os modelos principais do LTX-Video, pulando os que existem."""
78
- print("\n--- Verificando Modelos do LTX-Video ---")
79
- LTX_REPO = "Lightricks/LTX-Video"
80
-
81
- if "checkpoint_path" not in config or "spatial_upscaler_model_path" not in config:
82
- print("ERRO: Chaves de modelo não encontradas no arquivo de configuração do LTX.")
83
- sys.exit(1)
84
-
85
- models_to_download = {
86
- config["checkpoint_path"]: "checkpoint principal",
87
- config["spatial_upscaler_model_path"]: "upscaler espacial"
88
- }
89
-
90
- # O hf_hub_download já verifica o cache, mas vamos verificar o diretório final para clareza
91
- # e para garantir que a lógica seja explícita.
92
- for filename, description in models_to_download.items():
93
- # A biblioteca huggingface_hub gerencia o local exato, então confiamos nela.
94
- # A verificação aqui é para garantir que o download seja tentado.
95
- print(f"Garantindo a existência do {description}: {filename}...")
96
- try:
97
- hf_hub_download(
98
- repo_id=LTX_REPO, filename=filename,
99
- local_dir=os.getenv("HF_HOME"), cache_dir=os.getenv("HF_HOME_CACHE"), token=os.getenv("HF_TOKEN")
100
- )
101
- print(f"{description.capitalize()} está disponível.")
102
- except Exception as e:
103
- print(f"ERRO ao baixar o {description}: {e}")
104
- sys.exit(1)
105
-
106
-
107
- def _download_seedvr_models():
108
- """Baixa os modelos do SeedVR, pulando os que já existem."""
109
- print(f"\n--- Verificando Checkpoints do SeedVR em {SEEDVR_MODELS_DIR} ---")
110
- SEEDVR_MODELS_DIR.mkdir(exist_ok=True)
111
-
112
- model_files = {
113
- "seedvr2_ema_7b_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
114
- "seedvr2_ema_7b_sharp_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
115
- "seedvr2_ema_3b_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
116
- "ema_vae_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
117
- "pos_emb.pt": "ByteDance-Seed/SeedVR2-3B",
118
- "neg_emb.pt": "ByteDance-Seed/SeedVR2-3B"
119
- }
120
 
121
- for filename, repo_id in model_files.items():
122
- local_path = SEEDVR_MODELS_DIR / filename
123
- if not local_path.is_file(): # Verifica se é um arquivo
124
- print(f"Baixando {filename} de {repo_id}...")
125
- try:
126
  hf_hub_download(
127
- repo_id=repo_id,
128
- filename=filename,
129
- local_dir=str(SEEDVR_MODELS_DIR),
130
- cache_dir=os.getenv("HF_HOME_CACHE"),
131
  token=os.getenv("HF_TOKEN"),
132
  )
133
- print(f"'{filename}' baixado com sucesso.")
134
- except Exception as e:
135
- print(f"ERRO ao baixar o modelo SeedVR '{filename}': {e}")
136
- sys.exit(1)
137
- else:
138
- print(f"Arquivo '{filename}' já existe. Pulando.")
139
- print("Checkpoints do SeedVR estão no local correto.")
 
 
 
 
140
 
141
- # --- Função Principal ---
 
 
142
 
143
  def main():
144
- print("--- Iniciando Setup do Ambiente ADUC-SDR (Versão Robusta) ---")
 
145
  DEPS_DIR.mkdir(exist_ok=True)
 
146
 
147
  # --- ETAPA 1: Clonar Repositórios ---
148
- print("\n--- ETAPA 1: Clonando Repositórios Git ---")
149
  for repo_name, repo_url in REPOS_TO_CLONE.items():
150
  repo_path = DEPS_DIR / repo_name
151
- if repo_path.is_dir(): # Verifica se é um diretório
152
- print(f"Repositório '{repo_name}' já existe. Pulando.")
153
  else:
154
  print(f"Clonando '{repo_name}' de {repo_url}...")
155
  run_command(["git", "clone", "--depth", "1", repo_url, str(repo_path)])
156
- print(f"'{repo_name}' clonado com sucesso.")
157
 
158
- # --- ETAPA 2: Baixar Modelos do LTX-Video ---
159
- print("\n--- ETAPA 2: Preparando Modelos LTX-Video ---")
160
- if not LTX_VIDEO_REPO_DIR.is_dir():
161
- print(f"ERRO: Diretório '{LTX_VIDEO_REPO_DIR}' não encontrado. Execute a clonagem primeiro.")
162
- sys.exit(1)
163
-
164
  ltx_config = _load_ltx_config()
165
- if ltx_config:
166
- _download_ltx_models(ltx_config)
167
- else:
168
  print("ERRO: Não foi possível carregar a configuração do LTX-Video. Abortando.")
169
  sys.exit(1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
- # --- ETAPA 3: Baixar Modelos do SeedVR ---
172
- print("\n--- ETAPA 3: Preparando Modelos SeedVR ---")
173
- _download_seedvr_models()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
- print("\n\n--- Setup do Ambiente Concluído com Sucesso! ---")
176
- print("Todos os repositórios e modelos necessários foram verificados e estão prontos.")
177
- print("Você agora pode iniciar a aplicação principal.")
178
 
179
  if __name__ == "__main__":
180
  main()
 
2
  #
3
  # Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos
4
  #
5
+ # Versão 3.1.0 (Setup Unificado com LTX, SeedVR e VINCIE com Cache Robusto)
6
+ # - Orquestra a instalação de todos os repositórios e modelos para a suíte ADUC-SDR.
7
+ # - Usa snapshot_download para baixar dependências de forma eficiente e correta.
 
8
 
9
  import os
10
  import subprocess
11
  import sys
12
  from pathlib import Path
13
  import yaml
14
+ from huggingface_hub import hf_hub_download, snapshot_download
15
 
16
+ # ==============================================================================
17
+ # --- CONFIGURAÇÃO DE PATHS E CACHE ---
18
+ # ==============================================================================
19
+ # Assume que /data é um volume persistente montado no contêiner.
20
  DEPS_DIR = Path("/data")
21
+ CACHE_DIR = DEPS_DIR / ".cache" / "huggingface"
22
 
23
+ # --- Paths dos Módulos da Aplicação ---
24
  LTX_VIDEO_REPO_DIR = DEPS_DIR / "LTX-Video"
25
+ SEEDVR_MODELS_DIR = DEPS_DIR / "models" / "SeedVR"
26
+ VINCIE_REPO_DIR = DEPS_DIR / "VINCIE"
27
+ VINCIE_CKPT_DIR = DEPS_DIR / "ckpt" / "VINCIE-3B"
28
 
29
+ # --- Repositórios Git para Clonar ---
 
 
 
30
  REPOS_TO_CLONE = {
31
  "LTX-Video": "https://huggingface.co/spaces/Lightricks/ltx-video-distilled",
32
  "SeedVR": "https://github.com/numz/ComfyUI-SeedVR2_VideoUpscaler",
33
+ "VINCIE": "https://github.com/ByteDance-Seed/VINCIE",
34
  }
35
 
36
+ # ==============================================================================
37
+ # --- FUNÇÕES AUXILIARES ---
38
+ # ==============================================================================
39
+
40
  def run_command(command, cwd=None):
41
+ """Executa um comando no terminal de forma segura e com logs claros."""
42
  print(f"Executando: {' '.join(command)}")
43
  try:
44
  subprocess.run(
45
+ command, check=True, cwd=cwd,
46
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True,
 
 
47
  )
48
  except subprocess.CalledProcessError as e:
49
+ print(f"ERRO: O comando falhou com o código {e.returncode}\nStderr:\n{e.stderr.strip()}")
50
  sys.exit(1)
51
  except FileNotFoundError:
52
+ print(f"ERRO: Comando '{command[0]}' não encontrado. Verifique se o git está instalado.")
53
  sys.exit(1)
54
 
 
 
55
  def _load_ltx_config():
56
  """Carrega o arquivo de configuração YAML do LTX-Video."""
57
  print("--- Carregando Configuração do LTX-Video ---")
58
+ config_file = LTX_VIDEO_REPO_DIR / "configs" / "ltxv-13b-0.9.8-distilled-fp8.yaml"
59
+ if not config_file.exists():
60
+ print(f"ERRO: Arquivo de configuração do LTX não encontrado em '{config_file}'")
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  return None
62
+ print(f"Configuração LTX encontrada: {config_file}")
63
+ with open(config_file, "r") as file:
64
  return yaml.safe_load(file)
65
 
66
+ def _ensure_hf_model(repo_id, filenames=None, allow_patterns=None, local_dir=None):
67
+ """Função genérica para baixar um ou mais arquivos (hf_hub_download) ou um snapshot (snapshot_download)."""
68
+ if not repo_id: return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
+ print(f"Verificando/Baixando modelo do repositório: '{repo_id}'...")
71
+ try:
72
+ if filenames: # Baixa arquivos específicos
73
+ for filename in filenames:
74
+ if not filename: continue
75
  hf_hub_download(
76
+ repo_id=repo_id, filename=filename, cache_dir=str(CACHE_DIR),
77
+ local_dir=str(local_dir) if local_dir else None,
78
+ #local_dir_use_symlinks=False,
 
79
  token=os.getenv("HF_TOKEN"),
80
  )
81
+ else: # Baixa um snapshot (partes de um repositório)
82
+ snapshot_download(
83
+ repo_id=repo_id, cache_dir=str(CACHE_DIR),
84
+ local_dir=str(local_dir) if local_dir else None,
85
+ allow_patterns=allow_patterns,
86
+ token=os.getenv("HF_TOKEN"),
87
+ )
88
+ print(f"-> Modelo '{repo_id}' está disponível.")
89
+ except Exception as e:
90
+ print(f"ERRO CRÍTICO ao baixar o modelo '{repo_id}': {e}")
91
+ sys.exit(1)
92
 
93
+ # ==============================================================================
94
+ # --- FUNÇÃO PRINCIPAL DE SETUP ---
95
+ # ==============================================================================
96
 
97
  def main():
98
+ """Orquestra todo o processo de setup do ambiente."""
99
+ print("--- Iniciando Setup do Ambiente ADUC-SDR (LTX + SeedVR + VINCIE) ---")
100
  DEPS_DIR.mkdir(exist_ok=True)
101
+ CACHE_DIR.mkdir(parents=True, exist_ok=True)
102
 
103
  # --- ETAPA 1: Clonar Repositórios ---
104
+ print("\n--- ETAPA 1: Verificando Repositórios Git ---")
105
  for repo_name, repo_url in REPOS_TO_CLONE.items():
106
  repo_path = DEPS_DIR / repo_name
107
+ if repo_path.is_dir():
108
+ print(f"Repositório '{repo_name}' já existe em '{repo_path}'. Pulando.")
109
  else:
110
  print(f"Clonando '{repo_name}' de {repo_url}...")
111
  run_command(["git", "clone", "--depth", "1", repo_url, str(repo_path)])
112
+ print(f"-> '{repo_name}' clonado com sucesso.")
113
 
114
+ # --- ETAPA 2: Baixar Modelos LTX-Video e Dependências ---
115
+ print("\n--- ETAPA 2: Verificando Modelos LTX-Video e Dependências ---")
 
 
 
 
116
  ltx_config = _load_ltx_config()
117
+ if not ltx_config:
 
 
118
  print("ERRO: Não foi possível carregar a configuração do LTX-Video. Abortando.")
119
  sys.exit(1)
120
+
121
+ _ensure_hf_model(
122
+ repo_id="Lightricks/LTX-Video",
123
+ filenames=[
124
+ ltx_config.get("checkpoint_path"),
125
+ ltx_config.get("spatial_upscaler_model_path") # <-- Adicione esta linha
126
+ ]
127
+ )
128
+
129
+ _ensure_hf_model(
130
+ repo_id=ltx_config.get("text_encoder_model_name_or_path"),
131
+ allow_patterns=["*.json", "*.safetensors"]
132
+ )
133
+
134
+ enhancer_repos = [
135
+ ltx_config.get("prompt_enhancer_image_caption_model_name_or_path"),
136
+ ltx_config.get("prompt_enhancer_llm_model_name_or_path"),
137
+ ]
138
+ for repo_id in filter(None, enhancer_repos):
139
+ _ensure_hf_model(repo_id=repo_id, allow_patterns=["*.json", "*.safetensors", "*.bin"])
140
 
141
+ # --- ETAPA 3: Baixar Modelos SeedVR ---
142
+ print("\n--- ETAPA 3: Verificando Modelos SeedVR ---")
143
+ SEEDVR_MODELS_DIR.mkdir(parents=True, exist_ok=True)
144
+ seedvr_files = {
145
+ "seedvr2_ema_7b_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
146
+ "seedvr2_ema_7b_sharp_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
147
+ "ema_vae_fp16.safetensors": "MonsterMMORPG/SeedVR2_SECourses",
148
+ }
149
+ for filename, repo_id in seedvr_files.items():
150
+ if not (SEEDVR_MODELS_DIR / filename).is_file():
151
+ _ensure_hf_model(repo_id=repo_id, filenames=[filename], local_dir=SEEDVR_MODELS_DIR)
152
+ else:
153
+ print(f"Arquivo SeedVR '{filename}' já existe. Pulando.")
154
+
155
+ # --- ETAPA 4: Baixar Modelos VINCIE ---
156
+ print("\n--- ETAPA 4: Verificando Modelos VINCIE ---")
157
+ VINCIE_CKPT_DIR.mkdir(parents=True, exist_ok=True)
158
+ _ensure_hf_model(repo_id="ByteDance-Seed/VINCIE-3B", local_dir=VINCIE_CKPT_DIR)
159
+
160
+ # Cria o symlink de compatibilidade, se necessário
161
+ repo_ckpt_dir = VINCIE_REPO_DIR / "ckpt"
162
+ repo_ckpt_dir.mkdir(parents=True, exist_ok=True)
163
+ link = repo_ckpt_dir / "VINCIE-3B"
164
+ if not link.exists():
165
+ link.symlink_to(VINCIE_CKPT_DIR.resolve(), target_is_directory=True)
166
+ print(f"-> Symlink de compatibilidade VINCIE criado: '{link}' -> '{VINCIE_CKPT_DIR.resolve()}'")
167
+ else:
168
+ print(f"-> Symlink de compatibilidade VINCIE já existe.")
169
 
170
+ print("\n\n--- Setup Completo do Ambiente ADUC-SDR Concluído com Sucesso! ---")
171
+ print("Todos os repositórios e modelos foram verificados e estão prontos para uso.")
 
172
 
173
  if __name__ == "__main__":
174
  main()
start.sh CHANGED
@@ -1,49 +1,83 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
 
 
 
 
 
 
4
 
 
 
 
5
 
6
- tree -L 4 /app
7
- tree -L 4 /data
 
 
 
8
 
9
- echo "🚀 Iniciando o script de setup e lançamento do LTX-Video..."
10
- echo "Usuário atual: $(whoami)"
 
 
 
11
 
12
- # Define as variáveis de ambiente que o LTXServer irá consumir
13
- export HF_HOME="${HF_HOME:-/data/.cache/huggingface}"
14
- export OUTPUT_ROOT="${OUTPUT_ROOT:-/app/outputs/ltx}"
15
- export LTXV_FRAME_LOG_EVERY=8
16
- export LTXV_DEBUG=1
 
17
 
 
 
18
 
19
- # --- Garante que Diretórios Existam ---
20
- mkdir -p "$OUTPUT_ROOT" "$HF_HOME"
 
 
21
 
 
 
 
 
 
 
22
 
23
- # 1) Builder (garante Apex/Flash e deps CUDA)
24
- #echo "🛠️ Iniciando o builder.sh para compilar/instalar dependências CUDA..."
25
- #if [ -f "/app/builder.sh" ]; then
26
- # /bin/bash /app/builder.sh
27
- # echo "✅ Builder finalizado."
28
- #else
29
- # echo "⚠️ Aviso: builder.sh não encontrado. Pulando etapa de compilação de dependências."
30
- #fi
31
 
32
- python setup.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- cp -rfv /app/LTX-Video/ /data/
 
 
 
35
 
36
- export OUTPUT_ROOT="${OUTPUT_ROOT:-/app/outputs}"
37
- export INPUT_ROOT="${INPUT_ROOT:-/app/inputs}"
38
 
39
- mkdir -p "$OUTPUT_ROOT" "$INPUT_ROOT"
40
- echo "[aduc][start] Verificando ambiente como usuário: $(whoami)"
41
-
42
- # Env da UI
43
- export GRADIO_SERVER_NAME="0.0.0.0"
44
- export GRADIO_SERVER_PORT="${PORT:-7860}"
45
- export GRADIO_ENABLE_QUEUE="True"
46
-
47
- echo "[ltx][start] Lançando app_ltx.py..."
48
- # Executa diretamente o python.
49
- exec python app.py
 
1
+ #!/bin/bash
 
2
 
3
+ # ==============================================================================
4
+ # GERENCIAMENTO DE LOGS NA INICIALIZAÇÃO
5
+ # ==============================================================================
6
+ mkdir /data/logs
7
+ LOG_FILE="/data/logs/session.log"
8
 
9
+ # Verifica se o arquivo de log da sessão anterior existe e não está vazio
10
+ if [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then
11
+ echo "[STARTUP] Log da sessão anterior encontrado. Preparando para upload."
12
 
13
+ # Cria um nome de arquivo com timestamp para o upload
14
+ TODAY=$(date +%Y-%m-%d)
15
+ TIMESTAMP=$(date +%H-%M-%S)
16
+ UPLOAD_FILENAME="log-${TIMESTAMP}.txt"
17
+ export REPO_PATH="logs/${TODAY}/${UPLOAD_FILENAME}"
18
 
19
+ # Move o log antigo para um local temporário para evitar que a aplicação comece a escrever nele
20
+ TEMP_LOG_PATH="/data/previous_session.log"
21
+ mv "$LOG_FILE" "$TEMP_LOG_PATH"
22
+
23
+ echo "[STARTUP] Fazendo upload de '$TEMP_LOG_PATH' para o repositório em '$REPO_PATH'..."
24
 
25
+ # Executa o script de upload do Python em segundo plano para não bloquear a inicialização
26
+ # O token HF_TOKEN deve estar definido como uma variável de ambiente no seu contêiner
27
+ python - <<'PY' &
28
+ import os
29
+ import time
30
+ from huggingface_hub import HfApi, HfFolder
31
 
32
+ # Adiciona uma pequena espera para garantir que a rede esteja pronta
33
+ time.sleep(5)
34
 
35
+ repo = os.environ.get("SELF_HF_REPO_ID", "eeuuia/Tmp")
36
+ token = os.getenv("HF_TOKEN")
37
+ log_to_upload = "/data/previous_session.log"
38
+ repo_path = os.getenv("REPO_PATH",'logs/log.log')
39
 
40
+ if not token:
41
+ print("[UPLOAD_SCRIPT] AVISO: HF_TOKEN ausente; upload do log desabilitado.")
42
+ # Limpa o arquivo temporário mesmo assim
43
+ if os.path.exists(log_to_upload):
44
+ os.remove(log_to_upload)
45
+ exit()
46
 
47
+ if not repo_path:
48
+ print("[UPLOAD_SCRIPT] ERRO: REPO_PATH não definido.")
49
+ exit()
 
 
 
 
 
50
 
51
+ try:
52
+ print(f"[UPLOAD_SCRIPT] Iniciando upload para {repo}...")
53
+ api = HfApi(token=token)
54
+ api.upload_file(
55
+ path_or_fileobj=log_to_upload,
56
+ path_in_repo=repo_path,
57
+ repo_id=repo,
58
+ repo_type="model",
59
+ )
60
+ print(f"[UPLOAD_SCRIPT] Upload de log concluído com sucesso para: {repo_path}")
61
+ finally:
62
+ # Garante que o arquivo de log temporário seja sempre removido após a tentativa de upload
63
+ if os.path.exists(log_to_upload):
64
+ os.remove(log_to_upload)
65
+ print("[UPLOAD_SCRIPT] Arquivo de log temporário limpo.")
66
+ PY
67
+
68
+ else
69
+ echo "[STARTUP] Nenhum log da sessão anterior encontrado. Iniciando com um log limpo."
70
+ fi
71
 
72
+ # ==============================================================================
73
+ # INICIALIZAÇÃO DA APLICAÇÃO PRINCIPAL
74
+ # ==============================================================================
75
+ echo "[STARTUP] Iniciando a aplicação principal Gradio (app.py)..."
76
 
77
+ # Executa o setup.py primeiro para garantir que as dependências estão prontas
78
+ python /app/setup.py
79
 
80
+ # Inicia a aplicação Gradio
81
+ # O `exec` substitui o processo do shell pelo processo do python,
82
+ # o que é uma boa prática para scripts de inicialização de contêineres.
83
+ exec python /app/app.py