Spaces:
Paused
Paused
Upload 6 files
Browse files- Dockerfile +85 -148
- app_vince.py +194 -0
- builder.sh +205 -0
- info.sh +113 -0
- requirements.txt +36 -51
- start.sh +67 -89
Dockerfile
CHANGED
|
@@ -1,93 +1,70 @@
|
|
| 1 |
# =============================================================================
|
| 2 |
-
#
|
| 3 |
-
#
|
| 4 |
-
# Otimizado para Hugging Face Spaces com 8x NVIDIA L40S GPUs
|
| 5 |
# =============================================================================
|
| 6 |
-
|
| 7 |
-
# Base CUDA 12.8.0
|
| 8 |
FROM nvidia/cuda:12.8.0-devel-ubuntu22.04
|
| 9 |
|
| 10 |
-
# =============================================================================
|
| 11 |
-
# METADADOS
|
| 12 |
-
# =============================================================================
|
| 13 |
LABEL maintainer="Carlos Rodrigues dos Santos & Development Partner"
|
| 14 |
-
LABEL description="
|
| 15 |
-
LABEL version="4.
|
| 16 |
LABEL cuda_version="12.8.0"
|
| 17 |
LABEL python_version="3.10"
|
| 18 |
LABEL pytorch_version="2.8.0+cu128"
|
| 19 |
LABEL gpu_optimized_for="8x_NVIDIA_L40S"
|
| 20 |
|
| 21 |
-
#
|
| 22 |
-
ENV
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
ENV CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
|
|
|
|
|
|
|
| 25 |
ENV CUDA_DEVICE_MAX_CONNECTIONS=32
|
| 26 |
-
|
| 27 |
-
# Cache e Memory Management
|
| 28 |
-
# Unificar PYTORCH_CUDA_ALLOC_CONF em uma linha
|
| 29 |
-
ENV PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512,garbage_collection_threshold:0.8
|
| 30 |
ENV CUDA_MODULE_LOADING=LAZY
|
| 31 |
-
ENV CUDA_DEVICE_MAX_CONNECTIONS=32
|
| 32 |
-
ENV CUDA_DEVICE_ORDER=PCI_BUS_ID
|
| 33 |
-
|
| 34 |
-
|
| 35 |
|
| 36 |
-
#
|
| 37 |
-
ENV
|
| 38 |
-
ENV CUDA_CACHE_DISABLE=0
|
| 39 |
-
ENV TORCH_HOME=/app/.cache/torch
|
| 40 |
-
ENV HF_HOME=/app/.cache/huggingface
|
| 41 |
-
ENV HF_DATASETS_CACHE=/app/.cache/datasets
|
| 42 |
|
| 43 |
-
#
|
| 44 |
ENV PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512,garbage_collection_threshold:0.8
|
| 45 |
-
ENV CUDA_LAUNCH_BLOCKING=0
|
| 46 |
-
ENV CUDA_DEVICE_ORDER=PCI_BUS_ID
|
| 47 |
|
| 48 |
-
#
|
| 49 |
-
ENV
|
| 50 |
-
|
| 51 |
-
ENV MODEL_CACHE_STRATEGY=aggressive
|
| 52 |
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
| 55 |
ENV HF_HOME=/app/.cache/huggingface
|
|
|
|
| 56 |
ENV TRANSFORMERS_CACHE=/app/.cache/transformers
|
| 57 |
ENV DIFFUSERS_CACHE=/app/.cache/diffusers
|
| 58 |
-
ENV HF_DATASETS_CACHE=/app/.cache/datasets
|
| 59 |
ENV HF_HUB_ENABLE_HF_TRANSFER=1
|
| 60 |
ENV TOKENIZERS_PARALLELISM=false
|
| 61 |
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
#
|
| 79 |
-
|
| 80 |
-
ENV MAX_JOBS=90
|
| 81 |
-
|
| 82 |
-
# Caminhos da Aplicação
|
| 83 |
-
ENV APP_HOME=/app
|
| 84 |
-
WORKDIR $APP_HOME
|
| 85 |
-
|
| 86 |
-
# =============================================================================
|
| 87 |
-
# PACOTES DO SISTEMA E PYTHON 3.10
|
| 88 |
-
# =============================================================================
|
| 89 |
-
RUN apt-get update && \
|
| 90 |
-
apt-get install -y --no-install-recommends \
|
| 91 |
build-essential cmake git git-lfs curl wget ffmpeg ninja-build \
|
| 92 |
python3.10 python3.10-dev python3.10-distutils python3-pip \
|
| 93 |
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
@@ -96,105 +73,65 @@ RUN ln -sf /usr/bin/python3.10 /usr/bin/python3 && \
|
|
| 96 |
ln -sf /usr/bin/python3.10 /usr/bin/python && \
|
| 97 |
python3 -m pip install --upgrade pip
|
| 98 |
|
| 99 |
-
# =============================================================================
|
| 100 |
-
# INSTALAÇÃO DE BIBLIOTECAS DE ALTA PERFORMANCE
|
| 101 |
-
# =============================================================================
|
| 102 |
-
|
| 103 |
-
# 1. Instala PyTorch 2.8.0 e ferramentas de build
|
| 104 |
-
RUN pip -v install \
|
| 105 |
-
torch>=2.8.0+cu128 \
|
| 106 |
-
torchvision \
|
| 107 |
-
torchaudio \
|
| 108 |
-
--index-url https://download.pytorch.org/whl/cu128
|
| 109 |
|
| 110 |
-
RUN pip install \
|
| 111 |
-
packaging \
|
| 112 |
-
ninja \
|
| 113 |
-
cmake \
|
| 114 |
-
pybind11 \
|
| 115 |
-
scikit-build \
|
| 116 |
-
cython \
|
| 117 |
-
hf_transfer \
|
| 118 |
-
numpy==1.24.4
|
| 119 |
|
| 120 |
|
| 121 |
-
# =============================================================================
|
| 122 |
-
# CLONAGEM E INSTALAÇÃO DOS REPOSITÓRIOS DA APLICAÇÃO
|
| 123 |
-
# =============================================================================
|
| 124 |
|
| 125 |
-
|
| 126 |
-
#
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
RUN git clone https://github.com/bytedance-seed/VINCIE.git && \
|
| 132 |
-
#cd VINCIE && pip install -v -r requirements.txt && cd .. && \
|
| 133 |
-
#echo "Copiando módulos do SeedVR para /app/..." && \
|
| 134 |
-
#cp /VINCIE/generate.py /app/VINCIE/ 2>/dev/null || echo "vincie_service.py não encontrado"
|
| 135 |
-
#cp -r VINCIE /app/VINCIE && \
|
| 136 |
-
#cp -r VINCIE/projects /app/projects && \
|
| 137 |
-
#cp -r VINCIE/data /app/data && \
|
| 138 |
cp -r VINCIE/configs/. /app/configs/
|
| 139 |
-
|
| 140 |
|
| 141 |
-
#
|
| 142 |
RUN git clone https://github.com/bytedance-seed/SeedVR.git && \
|
| 143 |
-
|
| 144 |
-
#echo "Copiando módulos do SeedVR para /app/..." && \
|
| 145 |
-
#cp -r SeedVR/common /app/common && \
|
| 146 |
-
#cp -r SeedVR/projects /app/projects && \
|
| 147 |
-
#cp -r SeedVR/data /app/data && \
|
| 148 |
-
cp -r SeedVR/configs_3b /app/configs_3b
|
| 149 |
-
|
| 150 |
|
| 151 |
-
# MMAudio
|
| 152 |
RUN git clone https://github.com/hkchengrex/MMAudio.git && \
|
| 153 |
-
|
| 154 |
-
echo "Copiando 'mmaudio' para /app/mmaudio..." && \
|
| 155 |
-
cp -r MMAudio/mmaudio /app/mmaudio
|
| 156 |
|
| 157 |
-
# LTX-Video
|
| 158 |
RUN git clone https://github.com/Lightricks/LTX-Video.git && \
|
| 159 |
-
|
| 160 |
-
echo "Copiando 'ltx_video' para /app/ltx_video..." && \
|
| 161 |
-
cp -r LTX-Video/ltx_video /app/ltx_video
|
| 162 |
-
|
| 163 |
-
# opcionais
|
| 164 |
-
RUN pip uninstall -y bitsandbytes triton && \
|
| 165 |
-
pip install -v bitsandbytes --index-url https://pypi.org/simple/ && \
|
| 166 |
-
pip install -v triton
|
| 167 |
-
|
| 168 |
-
# =============================================================================
|
| 169 |
-
# INSTALAÇÃO DO RESTANTE DAS DEPENDÊNCIAS
|
| 170 |
-
# =============================================================================
|
| 171 |
-
COPY requirements.txt .
|
| 172 |
-
|
| 173 |
-
# Instala os pacotes restantes do requirements.txt
|
| 174 |
-
# A linha do flash-attention no arquivo será ignorada se já estiver instalado, mas é bom limpá-la.
|
| 175 |
-
RUN pip install -r requirements.txt
|
| 176 |
|
|
|
|
|
|
|
|
|
|
| 177 |
|
| 178 |
-
#
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
|
| 183 |
-
#
|
| 184 |
-
# COPIA O CÓDIGO DA APLICAÇÃO E CONFIGURA PERMISSÕES
|
| 185 |
-
# =============================================================================
|
| 186 |
COPY . .
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
mkdir -p /app && chown -R appuser:appuser /app
|
| 191 |
|
| 192 |
USER appuser
|
| 193 |
|
| 194 |
-
#
|
| 195 |
-
# PONTO DE ENTRADA
|
| 196 |
-
# =============================================================================
|
| 197 |
-
RUN chmod +x ./start.sh
|
| 198 |
-
|
| 199 |
ENTRYPOINT ["./start.sh"]
|
| 200 |
-
CMD ["gradio"]
|
|
|
|
| 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 CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
|
| 23 |
+
ENV TORCH_CUDA_ARCH_LIST="8.9"
|
| 24 |
+
ENV CUDA_DEVICE_ORDER=PCI_BUS_ID
|
| 25 |
ENV CUDA_DEVICE_MAX_CONNECTIONS=32
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
ENV CUDA_MODULE_LOADING=LAZY
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
+
# Threads
|
| 29 |
+
ENV OMP_NUM_THREADS=8 MKL_NUM_THREADS=8 MAX_JOBS=48
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
|
| 31 |
+
# Alloc/caches
|
| 32 |
ENV PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:512,garbage_collection_threshold:0.8
|
| 33 |
+
ENV CUDA_LAUNCH_BLOCKING=0 CUDA_CACHE_MAXSIZE=2147483648 CUDA_CACHE_DISABLE=0
|
|
|
|
| 34 |
|
| 35 |
+
# NCCL single-node sane defaults (use IB=1/IFNAME em clusters com IB)
|
| 36 |
+
ENV NCCL_DEBUG=INFO NCCL_ASYNC_ERROR_HANDLING=1 NCCL_P2P_DISABLE=0 NCCL_IB_DISABLE=1 \
|
| 37 |
+
NCCL_MIN_NCHANNELS=8 NCCL_NTHREADS=256 NCCL_SOCKET_IFNAME=lo
|
|
|
|
| 38 |
|
| 39 |
+
# Hugging Face caches
|
| 40 |
+
ENV APP_HOME=/app
|
| 41 |
+
WORKDIR $APP_HOME
|
| 42 |
+
ENV TORCH_HOME=/app/.cache/torch
|
| 43 |
ENV HF_HOME=/app/.cache/huggingface
|
| 44 |
+
ENV HF_DATASETS_CACHE=/app/.cache/datasets
|
| 45 |
ENV TRANSFORMERS_CACHE=/app/.cache/transformers
|
| 46 |
ENV DIFFUSERS_CACHE=/app/.cache/diffusers
|
|
|
|
| 47 |
ENV HF_HUB_ENABLE_HF_TRANSFER=1
|
| 48 |
ENV TOKENIZERS_PARALLELISM=false
|
| 49 |
|
| 50 |
+
# FlashAttention / SDPA defaults
|
| 51 |
+
ENV FLASH_ATTENTION_DISABLE=0 \
|
| 52 |
+
FLASH_ATTENTION_FORCE_FP16=1 \
|
| 53 |
+
ATTN_FORCE_F16=1 \
|
| 54 |
+
ENABLE_FLASH_SDP=1 \
|
| 55 |
+
ENABLE_MEMORY_EFFICIENT_SDP=1 \
|
| 56 |
+
ENABLE_MATH_SDP=0 \
|
| 57 |
+
XFORMERS_FORCE_DISABLE=1 \
|
| 58 |
+
TORCH_DTYPE=bfloat16 \
|
| 59 |
+
NVIDIA_TF32_OVERRIDE=0 \
|
| 60 |
+
FA_LOG_LEVEL=WARNING
|
| 61 |
+
|
| 62 |
+
# Link de modelos
|
| 63 |
+
ENV MODELS_DIR=/app/models
|
| 64 |
+
RUN mkdir -p /home/user/.cache/models && ln -sf /home/user/.cache/models /app/models
|
| 65 |
+
|
| 66 |
+
# ---------------- Sistema & Python ----------------
|
| 67 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
build-essential cmake git git-lfs curl wget ffmpeg ninja-build \
|
| 69 |
python3.10 python3.10-dev python3.10-distutils python3-pip \
|
| 70 |
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
|
|
| 73 |
ln -sf /usr/bin/python3.10 /usr/bin/python && \
|
| 74 |
python3 -m pip install --upgrade pip
|
| 75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
+
|
| 81 |
+
# ---------------- PyTorch cu128 (pinado) ----------------
|
| 82 |
+
RUN pip install --index-url https://download.pytorch.org/whl/cu128 \
|
| 83 |
+
torch==2.8.0+cu128 torchvision==0.23.0+cu128 torchaudio==2.8.0+cu128
|
| 84 |
+
|
| 85 |
+
# ---------------- Toolchain, Triton, FA2 (sem bnb) ----------------
|
| 86 |
+
RUN pip install packaging ninja cmake pybind11 scikit-build cython hf_transfer numpy==1.24.4
|
| 87 |
+
|
| 88 |
+
# Triton 3.x (sem triton.ops)
|
| 89 |
+
RUN pip uninstall -y triton || true && \
|
| 90 |
+
pip install -v --no-build-isolation triton==3.4.0
|
| 91 |
+
|
| 92 |
+
# FlashAttention 2.8.x
|
| 93 |
+
RUN pip install flash-attn==2.8.3 --no-build-isolation || \
|
| 94 |
+
pip install flash-attn==2.8.2 --no-build-isolation || \
|
| 95 |
+
pip install flash-attn==2.8.1 --no-build-isolation || \
|
| 96 |
+
pip install flash-attn==2.8.0.post2 --no-build-isolation
|
| 97 |
+
|
| 98 |
+
# Diffusers/Transformers estáveis (sem dev)
|
| 99 |
+
RUN pip install --no-cache-dir diffusers==0.31.0 transformers==4.44.2 accelerate==0.34.2 omegaconf==2.3.0
|
| 100 |
+
|
| 101 |
+
# Opcional: seu fork de otimizações
|
| 102 |
+
# RUN pip install -U git+https://github.com/carlex22/diffusers-aduc-sdr
|
| 103 |
+
|
| 104 |
+
# ---------------- Repositórios auxiliares ----------------
|
| 105 |
RUN git clone https://github.com/bytedance-seed/VINCIE.git && \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
cp -r VINCIE/configs/. /app/configs/
|
|
|
|
| 107 |
|
| 108 |
+
# Exemplos adicionais (descomente se precisar)
|
| 109 |
RUN git clone https://github.com/bytedance-seed/SeedVR.git && \
|
| 110 |
+
cp -r SeedVR/configs_3b /app/configs_3b
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
|
|
|
| 112 |
RUN git clone https://github.com/hkchengrex/MMAudio.git && \
|
| 113 |
+
cp -r MMAudio/mmaudio /app/mmaudio
|
|
|
|
|
|
|
| 114 |
|
|
|
|
| 115 |
RUN git clone https://github.com/Lightricks/LTX-Video.git && \
|
| 116 |
+
cp -r LTX-Video/ltx_video /app/ltx_video
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
+
# ---------------- Dependências da aplicação ----------------
|
| 119 |
+
COPY requirements.txt ./requirements.txt
|
| 120 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
| 121 |
|
| 122 |
+
# Scripts e configs
|
| 123 |
+
COPY info.sh ./info.sh
|
| 124 |
+
COPY start.sh ./start.sh
|
| 125 |
+
COPY /configs ./configs
|
| 126 |
|
| 127 |
+
# ---------------- Código e permissões ----------------
|
|
|
|
|
|
|
| 128 |
COPY . .
|
| 129 |
+
RUN useradd -m -u 1000 -s /bin/bash appuser && \
|
| 130 |
+
chown -R appuser:appuser /app && \
|
| 131 |
+
chmod 0755 /app/start.sh /app/info.sh || true
|
|
|
|
| 132 |
|
| 133 |
USER appuser
|
| 134 |
|
| 135 |
+
# ---------------- Entry ----------------
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
ENTRYPOINT ["./start.sh"]
|
| 137 |
+
CMD ["gradio"]
|
app_vince.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
VINCIE Service UI (Gradio) - Versão Final com Suporte a Multi-GPU
|
| 4 |
+
|
| 5 |
+
- Interface com 3 abas: Edição Multi-Turno, Texto-para-Vídeo e Composição Multi-Conceito.
|
| 6 |
+
- Controles avançados na UI, incluindo seleção de número de GPUs e tamanho do lote (batch size).
|
| 7 |
+
- Configuração automática no carregamento da aplicação.
|
| 8 |
+
- Projetado para hardware de ponta como 8x L40S.
|
| 9 |
+
- Modelo funcional de referência: ByteDance-Seed/VINCIE.
|
| 10 |
+
- Interface desenvolvida por Carlex ([email protected]).
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
import os
|
| 14 |
+
from pathlib import Path
|
| 15 |
+
from typing import List, Tuple, Optional
|
| 16 |
+
import gradio as gr
|
| 17 |
+
|
| 18 |
+
# Adapte este import para o layout do seu projeto, se necessário.
|
| 19 |
+
from services.vincie import VincieService
|
| 20 |
+
|
| 21 |
+
# --- Instanciação do Serviço e Constantes ---
|
| 22 |
+
svc = VincieService()
|
| 23 |
+
DEFAULT_NEGATIVE_PROMPT = "Worst quality, Normal quality, Low quality, Low res, Blurry, Jpeg artifacts, Grainy, text, logo, watermark, banner, extra digits, signature, subtitling, Bad anatomy, Bad proportions, Deformed, Disconnected limbs, Disfigured, Extra arms, Extra limbs, Extra hands, Fused fingers, Gross proportions, Long neck, Malformed limbs, Mutated, Mutated hands, Mutated limbs, Missing arms, Missing fingers, Poorly drawn hands, Poorly drawn face, Nsfw, Uncensored, Cleavage, Nude, Nipples, Overexposed, Plain background, Grainy, Underexposed, Deformed structures"
|
| 24 |
+
|
| 25 |
+
# --- Funções Helper ---
|
| 26 |
+
def setup_auto() -> str:
|
| 27 |
+
"""
|
| 28 |
+
Executa uma configuração idempotente no carregamento da interface.
|
| 29 |
+
Retorna uma string de status para a UI.
|
| 30 |
+
"""
|
| 31 |
+
try:
|
| 32 |
+
svc.ensure_repo()
|
| 33 |
+
svc.ensure_model()
|
| 34 |
+
return "Configuração concluída com sucesso: repositório e checkpoint estão prontos."
|
| 35 |
+
except Exception as e:
|
| 36 |
+
# Fornece um feedback de erro mais detalhado para depuração
|
| 37 |
+
import traceback
|
| 38 |
+
print(traceback.format_exc())
|
| 39 |
+
return f"A configuração encontrou um erro: {e}"
|
| 40 |
+
|
| 41 |
+
def _list_media(out_dir: Path, max_images: int = 24) -> Tuple[List[str], Optional[str]]:
|
| 42 |
+
"""
|
| 43 |
+
Enumera as imagens resultantes e o vídeo mais recente de um diretório de saída.
|
| 44 |
+
"""
|
| 45 |
+
img_globs = ("*.png", "*.jpg", "*.jpeg", "*.webp")
|
| 46 |
+
# Usa rglob para encontrar imagens em subdiretórios e ordena por tempo de modificação
|
| 47 |
+
images = sorted(
|
| 48 |
+
[p for pat in img_globs for p in out_dir.rglob(pat)],
|
| 49 |
+
key=lambda p: p.stat().st_mtime
|
| 50 |
+
)
|
| 51 |
+
image_paths = [str(p) for p in images[-max_images:]]
|
| 52 |
+
videos = sorted(out_dir.rglob("*.mp4"), key=lambda p: p.stat().st_mtime)
|
| 53 |
+
video_path = str(videos[-1]) if videos else None
|
| 54 |
+
return image_paths, video_path
|
| 55 |
+
|
| 56 |
+
# --- Funções Handler da UI (com todos os parâmetros) ---
|
| 57 |
+
def ui_multi_turn(input_image, turns_text, negative_prompt, seed, steps, cfg_scale, resolution, use_vae_slicing, num_gpus, batch_size):
|
| 58 |
+
"""Handler para a aba de Edição Multi-Turno."""
|
| 59 |
+
if not input_image:
|
| 60 |
+
return [], None, "Por favor, forneça uma imagem de entrada."
|
| 61 |
+
if not turns_text or not turns_text.strip():
|
| 62 |
+
return [], None, "Por favor, forneça as instruções de edição (uma por linha)."
|
| 63 |
+
|
| 64 |
+
turns = [ln.strip() for ln in turns_text.splitlines() if ln.strip()]
|
| 65 |
+
try:
|
| 66 |
+
out_dir = svc.multi_turn_edit(
|
| 67 |
+
input_image, turns,
|
| 68 |
+
negative_prompt=negative_prompt, seed=int(seed), steps=int(steps),
|
| 69 |
+
cfg_scale=float(cfg_scale), resolution=int(resolution), use_vae_slicing=use_vae_slicing,
|
| 70 |
+
num_gpus=int(num_gpus), batch_size=int(batch_size)
|
| 71 |
+
)
|
| 72 |
+
imgs, vid = _list_media(Path(out_dir))
|
| 73 |
+
return imgs, vid, f"Saídas salvas em: {out_dir}"
|
| 74 |
+
except Exception as e:
|
| 75 |
+
import traceback
|
| 76 |
+
print(traceback.format_exc())
|
| 77 |
+
return [], None, f"Erro na geração: {e}"
|
| 78 |
+
|
| 79 |
+
def ui_text_to_video(input_image, prompt, negative_prompt, seed, steps, cfg_scale, resolution, fps, use_vae_slicing, num_gpus, batch_size):
|
| 80 |
+
"""Handler para a aba de Texto-para-Vídeo."""
|
| 81 |
+
if not input_image:
|
| 82 |
+
return None, "Por favor, forneça uma imagem de entrada (frame inicial)."
|
| 83 |
+
if not prompt or not prompt.strip():
|
| 84 |
+
return None, "Por favor, forneça um prompt para o vídeo."
|
| 85 |
+
|
| 86 |
+
try:
|
| 87 |
+
out_dir = svc.text_to_video(
|
| 88 |
+
input_image, prompt,
|
| 89 |
+
negative_prompt=negative_prompt, seed=int(seed), steps=int(steps),
|
| 90 |
+
cfg_scale=float(cfg_scale), resolution=int(resolution), fps=int(fps), use_vae_slicing=use_vae_slicing,
|
| 91 |
+
num_gpus=int(num_gpus), batch_size=int(batch_size)
|
| 92 |
+
)
|
| 93 |
+
_, vid = _list_media(Path(out_dir))
|
| 94 |
+
return vid, f"Vídeo salvo em: {out_dir}"
|
| 95 |
+
except Exception as e:
|
| 96 |
+
import traceback
|
| 97 |
+
print(traceback.format_exc())
|
| 98 |
+
return None, f"Erro na geração: {e}"
|
| 99 |
+
|
| 100 |
+
def ui_multi_concept(files, descs_text, final_prompt):
|
| 101 |
+
"""Handler para a aba de Composição Multi-Conceito."""
|
| 102 |
+
if not files: return [], None, "Por favor, faça o upload das imagens de conceito."
|
| 103 |
+
if not descs_text: return [], None, "Por favor, forneça as descrições (uma por linha)."
|
| 104 |
+
if not final_prompt: return [], None, "Por favor, forneça um prompt final."
|
| 105 |
+
|
| 106 |
+
descs = [ln.strip() for ln in descs_text.splitlines() if ln.strip()]
|
| 107 |
+
if len(descs) != len(files): return [], None, f"O número de descrições ({len(descs)}) deve ser igual ao de imagens ({len(files)})."
|
| 108 |
+
|
| 109 |
+
try:
|
| 110 |
+
out_dir = svc.multi_concept_compose(files, descs, final_prompt)
|
| 111 |
+
imgs, vid = _list_media(Path(out_dir))
|
| 112 |
+
return imgs, vid, f"Saídas salvas em: {out_dir}"
|
| 113 |
+
except Exception as e:
|
| 114 |
+
import traceback
|
| 115 |
+
print(traceback.format_exc())
|
| 116 |
+
return [], None, f"Erro na geração: {e}"
|
| 117 |
+
|
| 118 |
+
# --- Definição da Interface Gradio Completa ---
|
| 119 |
+
with gr.Blocks(title="VINCIE Service", theme=gr.themes.Soft()) as demo:
|
| 120 |
+
gr.Markdown("# VINCIE Service — Geração Distribuída com Controles Avançados")
|
| 121 |
+
gr.Markdown("- **Interface por:** Carlex ([email protected] | GitHub: carlex22)")
|
| 122 |
+
with gr.Row():
|
| 123 |
+
setup_out = gr.Textbox(label="Status da Configuração", interactive=False)
|
| 124 |
+
|
| 125 |
+
with gr.Tab("Edição Multi-Turno"):
|
| 126 |
+
with gr.Row():
|
| 127 |
+
img_mt = gr.Image(type="filepath", label="Imagem de Entrada")
|
| 128 |
+
with gr.Column():
|
| 129 |
+
turns_mt = gr.Textbox(lines=5, label="Instruções de Edição (uma por linha)", placeholder="Ex: adicione um chapéu azul\nagora, mude o fundo para uma praia")
|
| 130 |
+
with gr.Accordion("Configurações Avançadas e de Desempenho", open=True):
|
| 131 |
+
with gr.Row():
|
| 132 |
+
num_gpus_mt = gr.Slider(label="Número de GPUs", minimum=1, maximum=8, step=1, value=8, info="Use >1 para acelerar a geração com torchrun.")
|
| 133 |
+
batch_size_mt = gr.Number(label="Batch Size por GPU", value=1, precision=0, info="Para Multi-GPU, o lote total será (GPUs x Batch Size).")
|
| 134 |
+
resolution_mt = gr.Slider(label="Resolução", minimum=256, maximum=1024, step=128, value=512, info="Maior resolução exige mais VRAM e tempo.")
|
| 135 |
+
use_vae_slicing_mt = gr.Checkbox(label="Usar VAE Slicing (Economiza VRAM)", value=True)
|
| 136 |
+
neg_prompt_mt = gr.Textbox(lines=3, label="Prompt Negativo", value=DEFAULT_NEGATIVE_PROMPT)
|
| 137 |
+
seed_mt = gr.Number(label="Seed (Semente)", value=1, precision=0)
|
| 138 |
+
steps_mt = gr.Slider(label="Passos de Inferência", minimum=10, maximum=100, step=1, value=50, info="Menos passos = mais rápido.")
|
| 139 |
+
cfg_mt = gr.Slider(label="Escala de Orientação (CFG)", minimum=1.0, maximum=20.0, step=0.5, value=7.5, info="Quão forte o modelo segue o prompt.")
|
| 140 |
+
run_mt = gr.Button("Executar Edição Multi-Turno", variant="primary")
|
| 141 |
+
gallery_mt = gr.Gallery(label="Imagens Geradas", columns=4, height="auto")
|
| 142 |
+
video_mt = gr.Video(label="Vídeo da Sequência (se disponível)")
|
| 143 |
+
status_mt = gr.Textbox(label="Status da Saída", interactive=False)
|
| 144 |
+
run_mt.click(ui_multi_turn,
|
| 145 |
+
inputs=[img_mt, turns_mt, neg_prompt_mt, seed_mt, steps_mt, cfg_mt, resolution_mt, use_vae_slicing_mt, num_gpus_mt, batch_size_mt],
|
| 146 |
+
outputs=[gallery_mt, video_mt, status_mt])
|
| 147 |
+
|
| 148 |
+
with gr.Tab("Texto-para-Vídeo"):
|
| 149 |
+
with gr.Row():
|
| 150 |
+
img_vid = gr.Image(type="filepath", label="Frame Inicial")
|
| 151 |
+
with gr.Column():
|
| 152 |
+
prompt_vid = gr.Textbox(lines=2, label="Prompt do Vídeo", placeholder="Ex: um gato andando pela sala")
|
| 153 |
+
with gr.Accordion("Configurações Avançadas e de Desempenho", open=True):
|
| 154 |
+
with gr.Row():
|
| 155 |
+
num_gpus_vid = gr.Slider(label="Número de GPUs", minimum=1, maximum=8, step=1, value=8, info="Use >1 para acelerar a geração com torchrun.")
|
| 156 |
+
batch_size_vid = gr.Number(label="Batch Size por GPU", value=1, precision=0, info="Para Multi-GPU, o lote total será (GPUs x Batch Size).")
|
| 157 |
+
resolution_vid = gr.Slider(label="Resolução", minimum=256, maximum=1024, step=128, value=512)
|
| 158 |
+
fps_vid = gr.Slider(label="Frames por Segundo (FPS)", minimum=1, maximum=24, step=1, value=2)
|
| 159 |
+
use_vae_slicing_vid = gr.Checkbox(label="Usar VAE Slicing (Economiza VRAM)", value=True)
|
| 160 |
+
neg_prompt_vid = gr.Textbox(lines=3, label="Prompt Negativo", value=DEFAULT_NEGATIVE_PROMPT)
|
| 161 |
+
seed_vid = gr.Number(label="Seed (Semente)", value=1, precision=0)
|
| 162 |
+
steps_vid = gr.Slider(label="Passos de Inferência", minimum=10, maximum=100, step=1, value=50)
|
| 163 |
+
cfg_vid = gr.Slider(label="Escala de Orientação (CFG)", minimum=1.0, maximum=20.0, step=0.5, value=7.5)
|
| 164 |
+
run_vid = gr.Button("Gerar Vídeo", variant="primary")
|
| 165 |
+
video_vid = gr.Video(label="Vídeo Gerado")
|
| 166 |
+
status_vid = gr.Textbox(label="Status da Saída", interactive=False)
|
| 167 |
+
run_vid.click(ui_text_to_video,
|
| 168 |
+
inputs=[img_vid, prompt_vid, neg_prompt_vid, seed_vid, steps_vid, cfg_vid, resolution_vid, fps_vid, use_vae_slicing_vid, num_gpus_vid, batch_size_vid],
|
| 169 |
+
outputs=[video_vid, status_vid])
|
| 170 |
+
|
| 171 |
+
with gr.Tab("Composição Multi-Conceito"):
|
| 172 |
+
gr.Markdown("Nota: A composição multi-conceito está atualmente configurada para rodar em uma única GPU para garantir estabilidade.")
|
| 173 |
+
with gr.Row():
|
| 174 |
+
with gr.Column(scale=1):
|
| 175 |
+
files_mc = gr.File(file_count="multiple", type="filepath", label="1. Imagens de Conceito")
|
| 176 |
+
with gr.Column(scale=2):
|
| 177 |
+
descs_mc = gr.Textbox(lines=5, label="2. Descrições (uma por linha, na mesma ordem)", placeholder="Ex: <IMG1>: uma foto de um pai\n<IMG2>: uma foto de uma mãe...")
|
| 178 |
+
final_prompt_mc = gr.Textbox(lines=3, label="3. Prompt Final de Composição", placeholder="Ex: Baseado em <IMG0>, <IMG1>..., uma família sorrindo em um retrato...")
|
| 179 |
+
run_mc = gr.Button("Executar Composição", variant="primary")
|
| 180 |
+
gallery_mc = gr.Gallery(label="Imagens Geradas", columns=4, height="auto")
|
| 181 |
+
video_mc = gr.Video(label="Vídeo da Sequência (se disponível)")
|
| 182 |
+
status_mc = gr.Textbox(label="Status da Saída", interactive=False)
|
| 183 |
+
run_mc.click(ui_multi_concept,
|
| 184 |
+
inputs=[files_mc, descs_mc, final_prompt_mc],
|
| 185 |
+
outputs=[gallery_mc, video_mc, status_mc])
|
| 186 |
+
|
| 187 |
+
# Gatilho de configuração automática no carregamento
|
| 188 |
+
demo.load(fn=setup_auto, outputs=setup_out)
|
| 189 |
+
|
| 190 |
+
if __name__ == "__main__":
|
| 191 |
+
demo.launch(
|
| 192 |
+
server_name="0.0.0.0",
|
| 193 |
+
server_port=int(os.getenv("PORT", "7860")),
|
| 194 |
+
)
|
builder.sh
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
echo "🚀 Builder (Apex + Q8) — roda em runtime com GPU visível"
|
| 5 |
+
|
| 6 |
+
# ===== Config e diretórios =====
|
| 7 |
+
export SELF_HF_REPO_ID="${SELF_HF_REPO_ID:-carlex3321/aduc-sdr}" # Model repo no HF com wheels
|
| 8 |
+
export HF_HOME="${HF_HOME:-/app/model_cache}"
|
| 9 |
+
export HF_HUB_CACHE="${HF_HUB_CACHE:-$HF_HOME/hub}"
|
| 10 |
+
export TORCH_HOME="${TORCH_HOME:-$HF_HOME/torch}"
|
| 11 |
+
export HF_HUB_ENABLE_HF_TRANSFER="${HF_HUB_ENABLE_HF_TRANSFER:-1}"
|
| 12 |
+
export PATH="$HOME/.local/bin:$PATH"
|
| 13 |
+
|
| 14 |
+
mkdir -p /app/wheels /app/cuda_cache "$HF_HOME" "$TORCH_HOME" /app/wheels/src
|
| 15 |
+
chmod -R 777 /app/wheels || true
|
| 16 |
+
export CUDA_CACHE_PATH="/app/cuda_cache"
|
| 17 |
+
|
| 18 |
+
if [ -f "/NGC-DL-CONTAINER-LICENSE" ]; then
|
| 19 |
+
cp -f /NGC-DL-CONTAINER-LICENSE /app/wheels/NGC-DL-CONTAINER-LICENSE || true
|
| 20 |
+
fi
|
| 21 |
+
|
| 22 |
+
# ===== Dependências mínimas =====
|
| 23 |
+
python -m pip install -v -U pip build setuptools wheel hatchling hatch-vcs scikit-build-core cmake ninja packaging "huggingface_hub[hf_transfer]" || true
|
| 24 |
+
|
| 25 |
+
# ===== Tags de ambiente (Python/CUDA/Torch) =====
|
| 26 |
+
PY_TAG="$(python -c 'import sys; print(f"cp{sys.version_info[0]}{sys.version_info[1]}")' 2>/dev/null || echo cp310)"
|
| 27 |
+
TORCH_VER="$(python - <<'PY'
|
| 28 |
+
try:
|
| 29 |
+
import torch, re
|
| 30 |
+
v = torch.__version__
|
| 31 |
+
print(re.sub(r'\+.*$', '', v))
|
| 32 |
+
except Exception:
|
| 33 |
+
print("unknown")
|
| 34 |
+
PY
|
| 35 |
+
)"
|
| 36 |
+
CU_TAG="$(python - <<'PY'
|
| 37 |
+
try:
|
| 38 |
+
import torch
|
| 39 |
+
cu = getattr(torch.version, "cuda", None)
|
| 40 |
+
print("cu"+cu.replace(".","")) if cu else print("")
|
| 41 |
+
except Exception:
|
| 42 |
+
print("")
|
| 43 |
+
PY
|
| 44 |
+
)"
|
| 45 |
+
echo "[env] PY_TAG=${PY_TAG} TORCH_VER=${TORCH_VER} CU_TAG=${CU_TAG}"
|
| 46 |
+
|
| 47 |
+
# ===== Checkers =====
|
| 48 |
+
check_apex() {
|
| 49 |
+
python - <<'PY'
|
| 50 |
+
try:
|
| 51 |
+
from apex.normalization import FusedLayerNorm, FusedRMSNorm
|
| 52 |
+
import importlib; importlib.import_module("fused_layer_norm_cuda")
|
| 53 |
+
ok = True
|
| 54 |
+
except Exception:
|
| 55 |
+
ok = False
|
| 56 |
+
raise SystemExit(0 if ok else 1)
|
| 57 |
+
PY
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
check_q8() {
|
| 61 |
+
python - <<'PY'
|
| 62 |
+
import importlib.util
|
| 63 |
+
spec = importlib.util.find_spec("ltx_q8_kernels") or importlib.util.find_spec("q8_kernels")
|
| 64 |
+
raise SystemExit(0 if spec else 1)
|
| 65 |
+
PY
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
# ===== Download do Hub =====
|
| 69 |
+
install_from_hf () {
|
| 70 |
+
local PKG="$1" # 'apex' ou 'q8_kernels'
|
| 71 |
+
echo "[hub] Verificando wheel de ${PKG} no repositório ${SELF_HF_REPO_ID}"
|
| 72 |
+
python - "$PKG" "$PY_TAG" "$CU_TAG" <<'PY' || exit 0
|
| 73 |
+
import os, sys
|
| 74 |
+
from huggingface_hub import HfApi, hf_hub_download, HfFolder
|
| 75 |
+
|
| 76 |
+
pkg, py_tag, cu_tag = sys.argv[1], sys.argv[2], sys.argv[3]
|
| 77 |
+
repo = os.environ.get("SELF_HF_REPO_ID","carlex3321/aduc-sdr")
|
| 78 |
+
api = HfApi(token=os.getenv("HF_TOKEN") or HfFolder.get_token())
|
| 79 |
+
try:
|
| 80 |
+
files = api.list_repo_files(repo_id=repo, repo_type="model")
|
| 81 |
+
except Exception:
|
| 82 |
+
raise SystemExit(0)
|
| 83 |
+
|
| 84 |
+
cands = [f for f in files if f.endswith(".whl") and f.rsplit("/",1)[-1].startswith(pkg+"-") and py_tag in f]
|
| 85 |
+
pref = [f for f in cands if cu_tag and cu_tag in f] or cands
|
| 86 |
+
if not pref:
|
| 87 |
+
raise SystemExit(0)
|
| 88 |
+
|
| 89 |
+
target = sorted(pref, reverse=True)[0]
|
| 90 |
+
print(target)
|
| 91 |
+
path = hf_hub_download(repo_id=repo, filename=target, repo_type="model", local_dir="/app/wheels")
|
| 92 |
+
print(path)
|
| 93 |
+
PY
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
# ===== Builders =====
|
| 97 |
+
build_apex () {
|
| 98 |
+
local SRC="/app/wheels/src/apex"
|
| 99 |
+
echo "[build] Preparando fonte Apex em ${SRC}"
|
| 100 |
+
if [ -d "$SRC/.git" ]; then
|
| 101 |
+
git -C "$SRC" fetch --all -p || true
|
| 102 |
+
git -C "$SRC" reset --hard HEAD || true
|
| 103 |
+
git -C "$SRC" clean -fdx || true
|
| 104 |
+
else
|
| 105 |
+
rm -rf "$SRC"
|
| 106 |
+
git clone --depth 1 https://github.com/NVIDIA/apex "$SRC"
|
| 107 |
+
fi
|
| 108 |
+
echo "[build] Compilando Apex -> wheel"
|
| 109 |
+
export APEX_CPP_EXT=1 APEX_CUDA_EXT=1 APEX_ALL_CONTRIB_EXT=0
|
| 110 |
+
python -m pip wheel -v --no-build-isolation --no-deps "$SRC" -w /app/wheels || true
|
| 111 |
+
local W="$(ls -t /app/wheels/apex-*.whl 2>/dev/null | head -n1 || true)"
|
| 112 |
+
if [ -n "${W}" ]; then
|
| 113 |
+
python -m pip install -v -U --no-deps "${W}" || true
|
| 114 |
+
echo "[build] Apex instalado da wheel recém-compilada: ${W}"
|
| 115 |
+
else
|
| 116 |
+
echo "[build] Nenhuma wheel Apex gerada; instalando do source (pode falhar)"
|
| 117 |
+
python -m pip install -v --no-build-isolation "$SRC" || true
|
| 118 |
+
fi
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
Q8_REPO="${Q8_REPO:-https://github.com/Lightricks/LTX-Video-Q8-Kernels.git}"
|
| 122 |
+
Q8_COMMIT="${Q8_COMMIT:-f3066edea210082799ca5a2bbf9ef0321c5dd8fc}"
|
| 123 |
+
build_q8 () {
|
| 124 |
+
local SRC="/app/wheels/src/q8_kernels"
|
| 125 |
+
rm -rf "$SRC"
|
| 126 |
+
git clone --filter=blob:none "$Q8_REPO" "$SRC"
|
| 127 |
+
git -C "$SRC" checkout "$Q8_COMMIT"
|
| 128 |
+
git -C "$SRC" submodule update --init --recursive
|
| 129 |
+
echo "[build] Compilando Q8 Kernels -> wheel"
|
| 130 |
+
python -m pip wheel -v --no-build-isolation "$SRC" -w /app/wheels || true
|
| 131 |
+
local W="$(ls -t /app/wheels/q8_kernels-*.whl 2>/dev/null | head -n1 || true)"
|
| 132 |
+
if [ -n "${W}" ]; then
|
| 133 |
+
python -m pip install -v -U --no-deps "${W}" || true
|
| 134 |
+
echo "[build] Q8 instalado da wheel recém-compilada: ${W}"
|
| 135 |
+
else
|
| 136 |
+
echo "[build] Nenhuma wheel q8_kernels gerada; instalando do source (pode falhar)"
|
| 137 |
+
python -m pip install -v --no-build-isolation "$SRC" || true
|
| 138 |
+
fi
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
# ===== Pipeline genérico =====
|
| 142 |
+
ensure_pkg () {
|
| 143 |
+
local PKG="$1" # apex | q8_kernels
|
| 144 |
+
local CHECK_FN="$2" # check_apex | check_q8
|
| 145 |
+
local BUILD_FN="$3" # build_apex | build_q8
|
| 146 |
+
|
| 147 |
+
echo "[flow] === ${PKG} ==="
|
| 148 |
+
if ${CHECK_FN}; then
|
| 149 |
+
echo "[flow] ${PKG}: já instalado (import OK)"
|
| 150 |
+
return 0
|
| 151 |
+
fi
|
| 152 |
+
|
| 153 |
+
echo "[flow] ${PKG}: tentando wheel do Hub (${SELF_HF_REPO_ID})"
|
| 154 |
+
HF_OUT="$(install_from_hf "$PKG" || true)"
|
| 155 |
+
if [ -n "${HF_OUT:-}" ]; then
|
| 156 |
+
WHEEL_PATH="$(printf "%s\n" "${HF_OUT}" | tail -n1)"
|
| 157 |
+
echo "[hub] Baixado: ${WHEEL_PATH}"
|
| 158 |
+
python -m pip install -v -U --no-build-isolation "${WHEEL_PATH}" || true
|
| 159 |
+
if ${CHECK_FN}; then
|
| 160 |
+
echo "[flow] ${PKG}: sucesso via Hub (${WHEEL_PATH})"
|
| 161 |
+
return 0
|
| 162 |
+
else
|
| 163 |
+
echo "[flow] ${PKG}: import falhou após wheel do Hub; compilando"
|
| 164 |
+
fi
|
| 165 |
+
else
|
| 166 |
+
echo "[hub] Nenhuma wheel compatível encontrada para ${PKG}"
|
| 167 |
+
fi
|
| 168 |
+
|
| 169 |
+
echo "[flow] ${PKG}: compilando (fallback)"
|
| 170 |
+
${BUILD_FN}
|
| 171 |
+
if ${CHECK_FN}; then
|
| 172 |
+
echo "[flow] ${PKG}: sucesso após compilação"
|
| 173 |
+
return 0
|
| 174 |
+
fi
|
| 175 |
+
|
| 176 |
+
echo "[flow] ${PKG}: falhou após build; registrando logs e seguindo"
|
| 177 |
+
return 1
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
# ===== Execução: Apex e Q8 =====
|
| 181 |
+
ensure_pkg "apex" check_apex build_apex || true
|
| 182 |
+
ensure_pkg "q8_kernels" check_q8 build_q8 || true
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
python - <<'PY'
|
| 186 |
+
import os
|
| 187 |
+
from huggingface_hub import HfApi, HfFolder
|
| 188 |
+
repo=os.environ.get("SELF_HF_REPO_ID","carlex3321/aduc-sdr")
|
| 189 |
+
token=os.getenv("HF_TOKEN") or HfFolder.get_token()
|
| 190 |
+
if not token:
|
| 191 |
+
raise SystemExit("HF_TOKEN ausente; upload desabilitado")
|
| 192 |
+
api=HfApi(token=token)
|
| 193 |
+
api.upload_folder(
|
| 194 |
+
folder_path="/app/wheels",
|
| 195 |
+
repo_id=repo,
|
| 196 |
+
repo_type="model",
|
| 197 |
+
allow_patterns=["*.whl","NGC-DL-CONTAINER-LICENSE"],
|
| 198 |
+
ignore_patterns=["**/src/**","**/*.log","**/logs/**",".git/**"],
|
| 199 |
+
)
|
| 200 |
+
print("Upload concluído (wheels + licença).")
|
| 201 |
+
PY
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
chmod -R 777 /app/wheels || true
|
| 205 |
+
echo "✅ Builder finalizado."
|
info.sh
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
echo "================= RUNTIME CAPABILITIES ================="
|
| 5 |
+
nvidia-smi || true
|
| 6 |
+
echo "CUDA_HOME: ${CUDA_HOME:-/usr/local/cuda}"
|
| 7 |
+
echo "NVCC: $(nvcc --version 2>/dev/null | tail -n1 || echo 'N/A')"
|
| 8 |
+
echo
|
| 9 |
+
|
| 10 |
+
echo "[PyTorch / CUDA backend]"
|
| 11 |
+
python3 - <<'PY'
|
| 12 |
+
import json
|
| 13 |
+
try:
|
| 14 |
+
import torch
|
| 15 |
+
info = {
|
| 16 |
+
"torch": torch.__version__,
|
| 17 |
+
"cuda_available": torch.cuda.is_available(),
|
| 18 |
+
"cuda_device_count": torch.cuda.device_count(),
|
| 19 |
+
"cuda_runtime_version": getattr(torch.version, "cuda", None),
|
| 20 |
+
"cudnn_version": (torch.backends.cudnn.version() if torch.cuda.is_available() else None),
|
| 21 |
+
"tf32": (torch.backends.cuda.matmul.allow_tf32 if torch.cuda.is_available() else None),
|
| 22 |
+
"flash_sdp": (torch.backends.cuda.flash_sdp_enabled() if hasattr(torch.backends.cuda,"flash_sdp_enabled") else None),
|
| 23 |
+
"mem_efficient_sdp": (torch.backends.cuda.mem_efficient_sdp_enabled() if hasattr(torch.backends.cuda,"mem_efficient_sdp_enabled") else None),
|
| 24 |
+
"math_sdp": (torch.backends.cuda.math_sdp_enabled() if hasattr(torch.backends.cuda,"math_sdp_enabled") else None),
|
| 25 |
+
}
|
| 26 |
+
print(json.dumps(info, indent=2))
|
| 27 |
+
if torch.cuda.is_available():
|
| 28 |
+
for i in range(torch.cuda.device_count()):
|
| 29 |
+
print(f"GPU {i}: {torch.cuda.get_device_name(i)}")
|
| 30 |
+
except Exception as e:
|
| 31 |
+
print(f"[ERR torch] {type(e).__name__}: {e}")
|
| 32 |
+
PY
|
| 33 |
+
echo
|
| 34 |
+
|
| 35 |
+
echo "[Apex]"
|
| 36 |
+
python3 - <<'PY'
|
| 37 |
+
try:
|
| 38 |
+
import importlib
|
| 39 |
+
importlib.import_module("apex.normalization")
|
| 40 |
+
print("apex.normalization: OK")
|
| 41 |
+
except Exception as e:
|
| 42 |
+
print(f"Apex: ERR {type(e).__name__}: {e}")
|
| 43 |
+
PY
|
| 44 |
+
echo
|
| 45 |
+
|
| 46 |
+
echo "[FlashAttention]"
|
| 47 |
+
python3 - <<'PY'
|
| 48 |
+
try:
|
| 49 |
+
import flash_attn
|
| 50 |
+
print(f"flash_attn: OK (version={getattr(flash_attn,'__version__', 'unknown')})")
|
| 51 |
+
try:
|
| 52 |
+
import flash_attn_2_cuda
|
| 53 |
+
print("flash_attn_2_cuda: OK")
|
| 54 |
+
except Exception as e:
|
| 55 |
+
print(f"flash_attn_2_cuda: ERR {type(e).__name__}: {e}")
|
| 56 |
+
except Exception as e:
|
| 57 |
+
print(f"flash_attn: ERR {type(e).__name__}: {e}")
|
| 58 |
+
PY
|
| 59 |
+
echo
|
| 60 |
+
|
| 61 |
+
echo "[Triton]"
|
| 62 |
+
python3 - <<'PY'
|
| 63 |
+
try:
|
| 64 |
+
import triton
|
| 65 |
+
print(f"triton: OK (version={getattr(triton,'__version__','unknown')})")
|
| 66 |
+
try:
|
| 67 |
+
import triton.ops
|
| 68 |
+
print("triton.ops: legacy module present")
|
| 69 |
+
except ModuleNotFoundError:
|
| 70 |
+
print("triton.ops: not present (ok on Triton>=3.x)")
|
| 71 |
+
except Exception as e:
|
| 72 |
+
print(f"triton.ops: WARN {type(e).__name__}: {e}")
|
| 73 |
+
except Exception as e:
|
| 74 |
+
print(f"triton: ERR {type(e).__name__}: {e}")
|
| 75 |
+
PY
|
| 76 |
+
echo
|
| 77 |
+
|
| 78 |
+
echo "[BitsAndBytes (Q8/Q4)]"
|
| 79 |
+
python3 - <<'PY'
|
| 80 |
+
try:
|
| 81 |
+
import bitsandbytes as bnb
|
| 82 |
+
v = getattr(bnb, "__version__", "unknown")
|
| 83 |
+
print(f"bitsandbytes: OK (version={v})")
|
| 84 |
+
try:
|
| 85 |
+
import bitsandbytes.triton.int8_matmul_mixed_dequantize as q8
|
| 86 |
+
print("bnb.triton.int8_matmul_mixed_dequantize: OK")
|
| 87 |
+
except ModuleNotFoundError:
|
| 88 |
+
print("bnb.q8.triton: not present (disabled or no GPU build)")
|
| 89 |
+
except Exception as e:
|
| 90 |
+
print(f"bnb.q8.triton: WARN {type(e).__name__}: {e}")
|
| 91 |
+
except Exception as e:
|
| 92 |
+
print(f"bitsandbytes: ERR {type(e).__name__}: {e}")
|
| 93 |
+
PY
|
| 94 |
+
echo
|
| 95 |
+
|
| 96 |
+
echo "[Transformers / Diffusers / XFormers]"
|
| 97 |
+
python3 - <<'PY'
|
| 98 |
+
import importlib
|
| 99 |
+
def ver(name):
|
| 100 |
+
try:
|
| 101 |
+
m = importlib.import_module(name)
|
| 102 |
+
return getattr(m, "__version__", "unknown")
|
| 103 |
+
except Exception as e:
|
| 104 |
+
return f"ERR:{type(e).__name__}"
|
| 105 |
+
print("transformers:", ver("transformers"))
|
| 106 |
+
print("diffusers:", ver("diffusers"))
|
| 107 |
+
print("xformers:", ver("xformers"))
|
| 108 |
+
PY
|
| 109 |
+
echo
|
| 110 |
+
|
| 111 |
+
echo "[Distribuído / NCCL Env]"
|
| 112 |
+
env | egrep 'MASTER_|NCCL|CUDA_VISIBLE_DEVICES|TORCH_|ENABLE_' | sort
|
| 113 |
+
echo "================= END CAPABILITIES ================="
|
requirements.txt
CHANGED
|
@@ -1,65 +1,50 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
torchao
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
|
|
|
|
|
|
| 9 |
mediapy
|
|
|
|
|
|
|
| 10 |
OmegaConf
|
| 11 |
-
|
| 12 |
-
accelerate
|
| 13 |
-
safetensors
|
| 14 |
-
einops
|
| 15 |
-
decord
|
| 16 |
sentencepiece
|
| 17 |
-
#git+https://github.com/hkchengrex/MMAudio.git@main
|
| 18 |
-
#git+https://github.com/huggingface/diffusers.git@main
|
| 19 |
-
gradio>=5.23.1
|
| 20 |
gradio[oauth]
|
|
|
|
| 21 |
fastapi
|
| 22 |
uvicorn[standard]
|
| 23 |
-
pydantic
|
| 24 |
-
soundfile
|
| 25 |
tiktoken
|
| 26 |
transformers_stream_generator
|
| 27 |
rotary-embedding-torch
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
huggingface_hub
|
| 34 |
google-generativeai
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
parameterized
|
| 43 |
-
mediapy
|
| 44 |
-
black
|
| 45 |
-
flake8
|
| 46 |
-
isort
|
| 47 |
-
pre-commit
|
| 48 |
-
expecttest
|
| 49 |
-
hypothesis
|
| 50 |
-
numpy<2
|
| 51 |
-
ninja
|
| 52 |
-
psutil
|
| 53 |
-
packaging
|
| 54 |
-
#https://github.com/Dao-AILab/flash-attention/releases/download/v2.7.4.post1/flash_attn-2.7.4.post1+cu12torch2.6cxx11abiFALSE-cp310-cp310-linux_x86_64.whl
|
| 55 |
-
#https://huggingface.co/ByteDance-Seed/SeedVR2-3B/resolve/main/apex-0.1-cp310-cp310-linux_x86_64.whl
|
| 56 |
-
peft
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
#sentencepiece
|
| 60 |
-
peft
|
| 61 |
ftfy
|
| 62 |
-
#imageio-ffmpeg
|
| 63 |
-
#opencv-python
|
| 64 |
-
#torchao==0.11.0
|
| 65 |
easydict
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
opencv-python-headless
|
| 3 |
+
pillow>=10.4.0
|
| 4 |
+
numpy==1.24.4
|
|
|
|
| 5 |
|
| 6 |
+
safetensors>=0.4.5
|
| 7 |
+
einops>=0.8.0
|
| 8 |
+
pyyaml>=6.0.2
|
| 9 |
+
omegaconf==2.3.0
|
| 10 |
mediapy
|
| 11 |
+
librosa
|
| 12 |
+
moviepy
|
| 13 |
OmegaConf
|
| 14 |
+
beartype
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
sentencepiece
|
|
|
|
|
|
|
|
|
|
| 16 |
gradio[oauth]
|
| 17 |
+
mediapy
|
| 18 |
fastapi
|
| 19 |
uvicorn[standard]
|
|
|
|
|
|
|
| 20 |
tiktoken
|
| 21 |
transformers_stream_generator
|
| 22 |
rotary-embedding-torch
|
| 23 |
+
transformers
|
| 24 |
+
accelerate
|
| 25 |
+
safetensors
|
| 26 |
+
einops
|
| 27 |
+
decord
|
| 28 |
huggingface_hub
|
| 29 |
google-generativeai
|
| 30 |
+
gradio
|
| 31 |
+
tabulate
|
| 32 |
+
pydantic
|
| 33 |
+
soundfile
|
| 34 |
+
requests
|
| 35 |
+
hf_transfer
|
| 36 |
+
timm
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
ftfy
|
|
|
|
|
|
|
|
|
|
| 38 |
easydict
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
#vince
|
| 42 |
+
bitsandbytes
|
| 43 |
+
einop
|
| 44 |
+
numpy
|
| 45 |
+
rotary-embedding-torch
|
| 46 |
+
safetensors
|
| 47 |
+
sentencepiece
|
| 48 |
+
torch
|
| 49 |
+
torchvision
|
| 50 |
+
transformers
|
start.sh
CHANGED
|
@@ -1,97 +1,75 @@
|
|
| 1 |
-
#!/bin/bash
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
#
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
#
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
#
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
"
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
# Flag para rastrear se tudo está correto
|
| 60 |
-
ALL_REPOS_OK=true
|
| 61 |
-
|
| 62 |
-
for repo_dir in "${REPOS_TO_CHECK[@]}"; do
|
| 63 |
-
# Verifica se o diretório do repositório existe
|
| 64 |
-
if [ -d "$repo_dir" ]; then
|
| 65 |
-
echo " [✅ OK] Repositório encontrado: $repo_dir"
|
| 66 |
-
else
|
| 67 |
-
echo " [❌ ERRO] Repositório CRÍTICO não encontrado: $repo_dir"
|
| 68 |
-
echo " -> Isso indica uma falha durante o 'docker build'."
|
| 69 |
-
ALL_REPOS_OK=false
|
| 70 |
-
fi
|
| 71 |
-
done
|
| 72 |
-
|
| 73 |
-
# Se qualquer verificação falhou, o script para com uma mensagem de erro clara.
|
| 74 |
-
if [ "$ALL_REPOS_OK" = false ]; then
|
| 75 |
-
echo "----------------------------------------------------------------------"
|
| 76 |
-
echo "🔥 Falha na verificação de integridade! A aplicação não pode iniciar."
|
| 77 |
-
echo " Por favor, verifique os logs de build do Docker para encontrar a causa do erro na instalação."
|
| 78 |
-
exit 1
|
| 79 |
fi
|
| 80 |
|
| 81 |
-
|
| 82 |
-
|
|
|
|
| 83 |
|
| 84 |
|
| 85 |
-
|
| 86 |
-
echo "📦 Verificando e baixando os modelos de IA..."
|
| 87 |
-
# O script python cuidará da lógica de verificar se o download é necessário
|
| 88 |
-
#python3 download_models.py
|
| 89 |
-
echo "✅ Modelos prontos."
|
| 90 |
|
| 91 |
|
|
|
|
| 92 |
|
|
|
|
|
|
|
| 93 |
|
| 94 |
-
#
|
| 95 |
-
|
| 96 |
-
echo "🚀 Iniciando app.py..."
|
| 97 |
-
python3 -d /app/app_animatediff.py --listen --port ${PORT:-7860}
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
echo "======================================================="
|
| 5 |
+
echo " ADUC-SDR — Start (VINCIE/SeedVR, 8× L40S)"
|
| 6 |
+
echo "======================================================="
|
| 7 |
+
|
| 8 |
+
# ---------------------- Env base ----------------------
|
| 9 |
+
export CUDA_VISIBLE_DEVICES="${CUDA_VISIBLE_DEVICES:-0,1,2,3,4,5,6,7}"
|
| 10 |
+
export TORCH_DTYPE="${TORCH_DTYPE:-bfloat16}"
|
| 11 |
+
|
| 12 |
+
# SDPA/FA toggles
|
| 13 |
+
export ENABLE_FLASH_SDP="${ENABLE_FLASH_SDP:-1}"
|
| 14 |
+
export ENABLE_MEMORY_EFFICIENT_SDP="${ENABLE_MEMORY_EFFICIENT_SDP:-1}"
|
| 15 |
+
export ENABLE_MATH_SDP="${ENABLE_MATH_SDP:-0}"
|
| 16 |
+
export FLASH_ATTENTION_DISABLE="${FLASH_ATTENTION_DISABLE:-0}"
|
| 17 |
+
export XFORMERS_FORCE_DISABLE="${XFORMERS_FORCE_DISABLE:-1}"
|
| 18 |
+
|
| 19 |
+
# CUDA/NCCL/perf — single-node robust
|
| 20 |
+
export CUDA_MODULE_LOADING="${CUDA_MODULE_LOADING:-LAZY}"
|
| 21 |
+
export CUDA_DEVICE_MAX_CONNECTIONS="${CUDA_DEVICE_MAX_CONNECTIONS:-32}"
|
| 22 |
+
export CUDA_DEVICE_ORDER="${CUDA_DEVICE_ORDER:-PCI_BUS_ID}"
|
| 23 |
+
export PYTORCH_CUDA_ALLOC_CONF="${PYTORCH_CUDA_ALLOC_CONF:-max_split_size_mb:512,garbage_collection_threshold:0.8}"
|
| 24 |
+
export OMP_NUM_THREADS="${OMP_NUM_THREADS:-8}"
|
| 25 |
+
export MKL_NUM_THREADS="${MKL_NUM_THREADS:-8}"
|
| 26 |
+
export NCCL_DEBUG="${NCCL_DEBUG:-INFO}"
|
| 27 |
+
export NCCL_ASYNC_ERROR_HANDLING="${NCCL_ASYNC_ERROR_HANDLING:-1}"
|
| 28 |
+
export NCCL_P2P_DISABLE="${NCCL_P2P_DISABLE:-0}"
|
| 29 |
+
export NCCL_IB_DISABLE="${NCCL_IB_DISABLE:-1}"
|
| 30 |
+
export NCCL_SOCKET_IFNAME="${NCCL_SOCKET_IFNAME:-lo}"
|
| 31 |
+
export NCCL_BLOCKING_WAIT=1
|
| 32 |
+
export TORCH_NCCL_BLOCKING_WAIT=1
|
| 33 |
+
export NCCL_TIMEOUT="${NCCL_TIMEOUT:-600}"
|
| 34 |
+
|
| 35 |
+
# HF caches
|
| 36 |
+
export HF_HOME="${HF_HOME:-/app/.cache/huggingface}"
|
| 37 |
+
unset TRANSFORMERS_CACHE
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
# ---------------------- Builder (Apex + Q8) ----------------------
|
| 41 |
+
# Executa com GPU disponível; busca wheels no HF e compila se necessário (sem FlashAttention)
|
| 42 |
+
if nvidia-smi >/dev/null 2>&1; then
|
| 43 |
+
if [ "${DISABLE_BUILDER:-0}" = "0" ]; then
|
| 44 |
+
echo "🔧 Executando builder (Apex + Q8)..."
|
| 45 |
+
chmod +x /app/builder.sh || true
|
| 46 |
+
# Configuráveis:
|
| 47 |
+
SELF_HF_REPO_ID="carlex3321/aduc-sdr" # repo de wheels no HF
|
| 48 |
+
HF_UPLOAD_WHEELS=0 # publica wheels geradas
|
| 49 |
+
BUILDER_TIMEOUT_SEC=6000000 # tempo limite
|
| 50 |
+
#Q8_REPO / Q8_COMMIT # pin do LTX Q8
|
| 51 |
+
( timeout ${BUILDER_TIMEOUT_SEC:-60000} bash -lc "/app/builder.sh" ) || {
|
| 52 |
+
echo "⚠️ Builder excedeu tempo/retornou erro; prosseguindo com a aplicação."
|
| 53 |
+
}
|
| 54 |
+
else
|
| 55 |
+
echo "ℹ️ Builder desabilitado por DISABLE_BUILDER=1"
|
| 56 |
+
fi
|
| 57 |
+
else
|
| 58 |
+
echo "⚠️ GPU não visível; pulando builder (Apex/Q8)."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
fi
|
| 60 |
|
| 61 |
+
|
| 62 |
+
# ---------------------- Banner ----------------------
|
| 63 |
+
./info.sh || true
|
| 64 |
|
| 65 |
|
| 66 |
+
ls -la /app && ls -R /app | head -n 2000
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
|
| 69 |
+
echo "🚀 Subindo serviços..."
|
| 70 |
|
| 71 |
+
# Exemplo: subir UI mínima SD Img2Img (ajuste conforme seu app)
|
| 72 |
+
# python app_animatediff_min.py
|
| 73 |
|
| 74 |
+
# Ou subir VINCIE UI se for o caso
|
| 75 |
+
python app_vince.py
|
|
|
|
|
|