adbrasi commited on
Commit
72c1f8d
·
verified ·
1 Parent(s): 8a2fc0f

Update setup_comfyui_wan22.sh

Browse files
Files changed (1) hide show
  1. setup_comfyui_wan22.sh +313 -492
setup_comfyui_wan22.sh CHANGED
@@ -1,590 +1,411 @@
1
  #!/usr/bin/env bash
2
- # setup_comfyui_wan22_verbose.sh
3
- # Script com logs completos para instalação do ComfyUI com Wan 2.2
4
- # Requisitos: Linux + Python3 + git + (opcional) NVCC/CUDA para SageAttention
5
 
6
- set -Eeuo pipefail
7
- trap 'rc=$?; echo -e "\033[31m[ERRO]\033[0m Linha $LINENO: \"$BASH_COMMAND\" saiu com código $rc"; exit $rc' ERR
8
 
9
  # -----------------------------
10
- # Cores para melhor visualização
11
  # -----------------------------
12
  RED='\033[0;31m'
13
  GREEN='\033[0;32m'
14
  YELLOW='\033[1;33m'
15
  BLUE='\033[0;34m'
16
- CYAN='\033[0;36m'
17
- MAGENTA='\033[0;35m'
18
- NC='\033[0m' # No Color
19
 
20
  log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
21
  log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
22
  log_warn() { echo -e "${YELLOW}[!]${NC} $1"; }
23
  log_error() { echo -e "${RED}[✗]${NC} $1"; }
24
- log_debug() { echo -e "${CYAN}[DEBUG]${NC} $1"; }
25
- log_cmd() { echo -e "${MAGENTA}[CMD]${NC} $1"; }
26
 
27
  # -----------------------------
28
- # Configuráveis
29
  # -----------------------------
30
- # IMPORTANTE: comfy-cli SEMPRE instala em /root/comfy/ComfyUI
31
- COMFY_DIR="/root/comfy/ComfyUI" # Caminho fixo onde comfy-cli instala
32
  COMFY_HOST="${COMFY_HOST:-0.0.0.0}"
33
  COMFY_PORT="${COMFY_PORT:-8818}"
34
-
35
- # Repositórios no HF
36
- REPO_22="Comfy-Org/Wan_2.2_ComfyUI_Repackaged"
37
- REPO_21="Comfy-Org/Wan_2.1_ComfyUI_repackaged"
38
- REPO_CN="xinsir/controlnet-union-sdxl-1.0"
39
-
40
- # Token do Civitai
41
  CIVITAI_TOKEN="${CIVITAI_TOKEN:-4fcb2834969399006a736ee402b061e5}"
42
 
43
- # Configurações de performance
 
 
 
 
44
  export HF_HUB_ENABLE_HF_TRANSFER=1
45
- export HF_TRANSFER_CONCURRENCY=16 # Aumentado para melhor performance
46
 
47
  # -----------------------------
48
- # Detectar capacidades do CUDA
49
  # -----------------------------
50
- detect_cuda_capabilities() {
51
- if command -v nvidia-smi >/dev/null 2>&1; then
52
- log_info "Detectando capacidades do CUDA..."
53
-
54
- # Obter informações da GPU
55
- GPU_NAME=$(nvidia-smi --query-gpu=name --format=csv,noheader | head -n1)
56
- GPU_MEMORY=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | head -n1)
57
- GPU_COUNT=$(nvidia-smi --query-gpu=count --format=csv,noheader | wc -l)
58
-
59
- log_debug "GPU: $GPU_NAME ($GPU_MEMORY MB) x$GPU_COUNT"
60
-
61
- # Detectar compute capability
62
- if command -v nvcc >/dev/null 2>&1; then
63
- CUDA_VERSION=$(nvcc --version | grep "release" | awk '{print $6}' | cut -d',' -f1)
64
- log_debug "CUDA Version: $CUDA_VERSION"
65
-
66
- # Obter compute capability via nvidia-ml-py se disponível
67
- COMPUTE_CAP=$(python3 -c "
68
- try:
69
- import pynvml
70
- pynvml.nvmlInit()
71
- handle = pynvml.nvmlDeviceGetHandleByIndex(0)
72
- major, minor = pynvml.nvmlDeviceGetCudaComputeCapability(handle)
73
- print(f'{major}.{minor}')
74
- except:
75
- print('unknown')
76
- " 2>/dev/null || echo "unknown")
77
-
78
- if [ "$COMPUTE_CAP" != "unknown" ]; then
79
- log_debug "Compute Capability: $COMPUTE_CAP"
80
- fi
81
-
82
- # Determinar MAX_JOBS baseado na GPU e memória
83
- # RTX 4090/A100: 128 SMs -> pode usar 32 jobs
84
- # RTX 3090: 82 SMs -> pode usar 24 jobs
85
- # RTX 3080: 68 SMs -> pode usar 16 jobs
86
- # Regra geral: ~4 jobs por GB de VRAM, máximo 32
87
-
88
- if [ "$GPU_MEMORY" -gt 0 ]; then
89
- SUGGESTED_JOBS=$((GPU_MEMORY / 1024 / 4)) # 4 jobs por GB
90
- if [ $SUGGESTED_JOBS -gt 32 ]; then
91
- SUGGESTED_JOBS=32 # Limite do CUDA
92
- elif [ $SUGGESTED_JOBS -lt 4 ]; then
93
- SUGGESTED_JOBS=4 # Mínimo razoável
94
- fi
95
-
96
- # Para GPUs conhecidas, usar valores otimizados
97
- if [[ "$GPU_NAME" == *"4090"* ]] || [[ "$GPU_NAME" == *"A100"* ]]; then
98
- SUGGESTED_JOBS=32
99
- SUGGESTED_THREADS=16
100
- elif [[ "$GPU_NAME" == *"3090"* ]] || [[ "$GPU_NAME" == *"A6000"* ]]; then
101
- SUGGESTED_JOBS=24
102
- SUGGESTED_THREADS=12
103
- elif [[ "$GPU_NAME" == *"3080"* ]] || [[ "$GPU_NAME" == *"A5000"* ]]; then
104
- SUGGESTED_JOBS=16
105
- SUGGESTED_THREADS=8
106
- else
107
- SUGGESTED_THREADS=$((SUGGESTED_JOBS / 2))
108
- fi
109
-
110
- export MAX_JOBS=$SUGGESTED_JOBS
111
- export NVCC_APPEND_FLAGS="--threads $SUGGESTED_THREADS"
112
- export EXT_PARALLEL=$((SUGGESTED_JOBS / 2))
113
-
114
- log_success "Configuração CUDA otimizada:"
115
- log_debug " MAX_JOBS=$MAX_JOBS"
116
- log_debug " NVCC threads=$SUGGESTED_THREADS"
117
- log_debug " EXT_PARALLEL=$EXT_PARALLEL"
118
- fi
119
- fi
120
- else
121
- log_warn "nvidia-smi não encontrado, usando configuração padrão"
122
- fi
123
- }
124
-
125
- # Detecção de CPU cores para compilação
126
- CPU_CORES=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
127
- log_debug "CPU Cores detectados: $CPU_CORES"
128
-
129
- # Configuração inicial baseada em CPU (será sobrescrita pela detecção CUDA se disponível)
130
- if [ $CPU_CORES -gt 32 ]; then
131
- export MAX_JOBS=${MAX_JOBS:-32}
132
- export EXT_PARALLEL=${EXT_PARALLEL:-16}
133
- export NVCC_APPEND_FLAGS=${NVCC_APPEND_FLAGS:-"--threads 16"}
134
- COMPILE_JOBS=32
135
- else
136
- HALF_CORES=$((CPU_CORES / 2))
137
- export MAX_JOBS=${MAX_JOBS:-$HALF_CORES}
138
- export EXT_PARALLEL=${EXT_PARALLEL:-4}
139
- export NVCC_APPEND_FLAGS=${NVCC_APPEND_FLAGS:-"--threads 8"}
140
- COMPILE_JOBS=$HALF_CORES
141
- fi
142
-
143
- # Detectar e otimizar para CUDA
144
- detect_cuda_capabilities
145
 
146
- export UV_SYSTEM_PYTHON=1
147
- export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True"
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
  # -----------------------------
150
- # Setup inicial
151
  # -----------------------------
152
- TMPDL="$(mktemp -d)"
153
- cleanup() {
154
- log_info "Limpando arquivos temporários..."
155
- rm -rf "$TMPDL"
156
  }
157
- trap cleanup EXIT
158
 
159
- # Verificação de dependências
160
- need() {
161
- if ! command -v "$1" >/dev/null 2>&1; then
162
- log_error "Falta dependência: $1"
163
- log_info "Instale com: apt-get install $1"
164
- exit 1
 
165
  fi
166
  }
167
 
168
- log_info "Verificando dependências..."
169
- need python3
170
- need git
171
- need wget
172
- need curl
173
-
174
- # -----------------------------
175
- # Funções auxiliares
176
- # -----------------------------
177
- clone_or_update() {
178
- local url="$1" dest="$2"
179
- local repo_name=$(basename "$dest")
180
 
181
- if [ -d "$dest/.git" ]; then
182
- log_info "Atualizando $repo_name..."
183
- log_cmd "git -C \"$dest\" pull --ff-only"
184
- git -C "$dest" pull --ff-only || true
185
- else
186
- log_info "Clonando $repo_name..."
187
- log_cmd "git clone --recursive --depth 1 \"$url\" \"$dest\""
188
- git clone --recursive --depth 1 "$url" "$dest"
189
  fi
190
 
191
- if [ -f "$dest/requirements.txt" ]; then
192
- log_debug "Instalando requirements para $repo_name..."
193
- python3 -m pip install --no-warn-script-location -r "$dest/requirements.txt"
 
 
 
194
  fi
195
- }
196
-
197
- # Função para download com HF Transfer ou fallback
198
- hf_download_with_fallback() {
199
- local repo="$1"
200
- shift # Remove primeiro argumento
201
- local files=("$@") # Resto são os arquivos
202
- local output_dir="$TMPDL/$(basename $repo)"
203
 
204
- # Tentar primeiro com HF Transfer
 
 
205
  if python3 -c "import hf_transfer" 2>/dev/null; then
206
- log_info " → Usando HF Transfer (rápido) para $repo..."
207
- log_cmd "HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download \"$repo\" ..."
208
-
209
- HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$repo" \
210
- "${files[@]}" \
211
- --local-dir "$output_dir" \
212
  --local-dir-use-symlinks False \
213
- --resume-download || {
214
- log_warn " HF Transfer falhou, tentando método padrão..."
215
- HF_HUB_ENABLE_HF_TRANSFER=0 huggingface-cli download "$repo" \
216
- "${files[@]}" \
217
- --local-dir "$output_dir" \
218
- --local-dir-use-symlinks False \
219
- --resume-download
220
  }
221
- else
222
- log_info " → Usando download padrão para $repo..."
223
- huggingface-cli download "$repo" \
224
- "${files[@]}" \
225
- --local-dir "$output_dir" \
226
- --local-dir-use-symlinks False \
227
- --resume-download
228
  fi
229
- }
230
-
231
- # -----------------------------
232
- # Instalação principal
233
- # -----------------------------
234
- echo ""
235
- log_info "========================================="
236
- log_info " ComfyUI + Wan 2.2 Setup (Verbose)"
237
- log_info " CPU: $CPU_CORES cores | Compile Jobs: $COMPILE_JOBS"
238
- log_info " CUDA MAX_JOBS: ${MAX_JOBS:-não detectado}"
239
- log_info " ComfyUI Dir: $COMFY_DIR"
240
- log_info "========================================="
241
- echo ""
242
-
243
- # [1/8] Atualizar pip e instalar ferramentas essenciais
244
- log_info "[1/8] Atualizando pip e instalando ferramentas..."
245
- log_cmd "python3 -m pip install --upgrade pip wheel setuptools"
246
- python3 -m pip install --upgrade pip wheel setuptools
247
-
248
- # Instalar HF Transfer primeiro para downloads mais rápidos
249
- log_cmd "python3 -m pip install --upgrade hf_transfer"
250
- python3 -m pip install --upgrade hf_transfer || true
251
-
252
- # Depois instalar o resto
253
- log_cmd "python3 -m pip install --upgrade comfy-cli huggingface_hub>=0.23.0 aria2"
254
- python3 -m pip install --upgrade comfy-cli "huggingface_hub>=0.23.0" aria2
255
- log_success "Ferramentas instaladas"
256
-
257
- # [2/8] Instalar ComfyUI
258
- log_info "[2/8] Instalando ComfyUI (GPU NVIDIA, fast deps)..."
259
-
260
- # Verificar se ComfyUI já existe no caminho correto
261
- if [ -f "$COMFY_DIR/main.py" ] && [ -d "$COMFY_DIR/models" ]; then
262
- log_warn "ComfyUI já existe em $COMFY_DIR, pulando instalação base"
263
- else
264
- log_info "Instalando ComfyUI (será instalado em /root/comfy/ComfyUI)..."
265
 
266
- # Remove instalação parcial se existir
267
- [ -d "$COMFY_DIR" ] && rm -rf "$COMFY_DIR"
268
-
269
- # Instala ComfyUI (sempre vai para /root/comfy/ComfyUI)
270
- log_cmd "comfy --skip-prompt install --fast-deps --nvidia"
271
- comfy --skip-prompt install --fast-deps --nvidia
272
-
273
- # Verifica se instalou no local correto
274
- if [ ! -f "$COMFY_DIR/main.py" ]; then
275
- log_error "ComfyUI não foi encontrado em $COMFY_DIR após instalação!"
276
- log_info "Verificando outros locais possíveis..."
277
-
278
- # Tentar encontrar onde foi instalado
279
- for possible_path in "/root/comfy/ComfyUI" "$HOME/comfy/ComfyUI" "/workspace/ComfyUI"; do
280
- if [ -f "$possible_path/main.py" ]; then
281
- log_info "ComfyUI encontrado em: $possible_path"
282
- COMFY_DIR="$possible_path"
283
- break
284
- fi
285
- done
286
-
287
- if [ ! -f "$COMFY_DIR/main.py" ]; then
288
- log_error "Não foi possível encontrar ComfyUI instalado!"
289
- exit 1
290
  fi
291
- fi
292
- fi
293
-
294
- # Criar estrutura de diretórios
295
- MODELS_DIR="$COMFY_DIR/models"
296
- log_info "Criando estrutura de diretórios em $MODELS_DIR..."
297
- mkdir -p "$MODELS_DIR"/{diffusion_models,loras,vae,text_encoders,clip_vision,controlnet}
298
- mkdir -p "$COMFY_DIR/custom_nodes"
299
- mkdir -p "$TMPDL"/{wan22,wan21,controlnet}
300
-
301
- log_success "ComfyUI pronto em: $COMFY_DIR"
302
-
303
- # [3/8] Baixar modelos Wan 2.2
304
- log_info "[3/8] Iniciando download dos modelos Wan 2.2..."
305
- (
306
- set -Eeuo pipefail
307
-
308
- hf_download_with_fallback "$REPO_22" \
309
- "split_files/diffusion_models/wan2.2_fun_control_low_noise_14B_fp8_scaled.safetensors" \
310
- "split_files/diffusion_models/wan2.2_fun_control_high_noise_14B_fp8_scaled.safetensors" \
311
- "split_files/loras/wan2.2_i2v_lightx2v_4steps_lora_v1_high_noise.safetensors" \
312
- "split_files/loras/wan2.2_i2v_lightx2v_4steps_lora_v1_low_noise.safetensors" \
313
- "split_files/vae/wan_2.1_vae.safetensors" \
314
- "split_files/text_encoders/umt5_xxl_fp16.safetensors"
315
-
316
- # Copiar para destino
317
- log_debug "Copiando modelos Wan 2.2 para $MODELS_DIR..."
318
- cp -fv "$TMPDL/wan22/split_files/diffusion_models/"*.safetensors "$MODELS_DIR/diffusion_models/" 2>/dev/null || true
319
- cp -fv "$TMPDL/wan22/split_files/loras/"*.safetensors "$MODELS_DIR/loras/" 2>/dev/null || true
320
- cp -fv "$TMPDL/wan22/split_files/vae/"*.safetensors "$MODELS_DIR/vae/" 2>/dev/null || true
321
- cp -fv "$TMPDL/wan22/split_files/text_encoders/"*.safetensors "$MODELS_DIR/text_encoders/" 2>/dev/null || true
322
 
323
- log_success " Modelos Wan 2.2 baixados"
324
- ) &
325
- WAN22_PID=$!
326
 
327
- # [4/8] Baixar Wan 2.1 clip vision
328
- log_info "[4/8] Baixando Wan 2.1 clip vision..."
329
- (
330
- set -Eeuo pipefail
331
-
332
- hf_download_with_fallback "$REPO_21" \
333
- "split_files/clip_vision/clip_vision_h.safetensors"
334
 
335
- log_debug "Copiando clip vision para $MODELS_DIR/clip_vision..."
336
- cp -fv "$TMPDL/wan21/split_files/clip_vision/"*.safetensors "$MODELS_DIR/clip_vision/" 2>/dev/null || true
337
 
338
- log_success " Clip vision baixado"
339
- ) &
340
- WAN21_PID=$!
341
-
342
- # [5/8] Baixar ControlNet
343
- log_info "[5/8] Baixando ControlNet Union..."
344
- (
345
- set -Eeuo pipefail
346
 
347
- hf_download_with_fallback "$REPO_CN" \
348
- "diffusion_pytorch_model_promax.safetensors"
349
 
350
- log_debug "Copiando ControlNet para $MODELS_DIR/controlnet..."
351
- # O arquivo pode estar direto no diretório ou em subdiretório
352
- if [ -f "$TMPDL/controlnet/diffusion_pytorch_model_promax.safetensors" ]; then
353
- cp -fv "$TMPDL/controlnet/diffusion_pytorch_model_promax.safetensors" \
354
- "$MODELS_DIR/controlnet/controlnet-union.safetensors"
355
- elif [ -f "$TMPDL/xinsir/controlnet-union-sdxl-1.0/diffusion_pytorch_model_promax.safetensors" ]; then
356
- cp -fv "$TMPDL/xinsir/controlnet-union-sdxl-1.0/diffusion_pytorch_model_promax.safetensors" \
357
- "$MODELS_DIR/controlnet/controlnet-union.safetensors"
358
- else
359
- # Procurar o arquivo em qualquer lugar do diretório temporário
360
- FOUND_FILE=$(find "$TMPDL" -name "diffusion_pytorch_model_promax.safetensors" -type f | head -n1)
361
- if [ -n "$FOUND_FILE" ]; then
362
- log_debug "ControlNet encontrado em: $FOUND_FILE"
363
- cp -fv "$FOUND_FILE" "$MODELS_DIR/controlnet/controlnet-union.safetensors"
364
  else
365
- log_warn "ControlNet não encontrado no diretório temporário"
366
  fi
367
  fi
368
 
369
- log_success " ControlNet baixado"
370
- ) &
371
- CN_PID=$!
372
-
373
- # [6/8] Baixar modelo do Civitai
374
- log_info "[6/8] Baixando modelo do Civitai..."
375
- (
376
- set -Eeuo pipefail
377
-
378
- cd "$MODELS_DIR/loras"
379
 
380
- # URL correta completa
381
- CIVITAI_URL="https://civitai.com/api/download/models/2122278?type=Model&format=SafeTensor&size=pruned&fp=fp16&token=${CIVITAI_TOKEN}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
 
383
- log_debug "Baixando de: $CIVITAI_URL"
 
 
 
 
 
 
384
 
385
- # Usar curl direto pois wget está falhando com nomes longos
386
- # Primeiro obter o nome real do arquivo
387
- log_debug "Obtendo nome do arquivo..."
388
- HEADERS=$(curl -sI -L --max-time 30 "$CIVITAI_URL")
389
- FILENAME=$(echo "$HEADERS" | grep -i "content-disposition" | sed -n 's/.*filename="\([^"]*\)".*/\1/p' | tr -d '\r')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
 
391
- if [ -z "$FILENAME" ]; then
392
- # Tentar outro padrão de header
393
- FILENAME=$(echo "$HEADERS" | grep -i "content-disposition" | sed -n "s/.*filename='\([^']*\)'.*/\1/p" | tr -d '\r')
394
- fi
 
 
 
395
 
396
- if [ -z "$FILENAME" ]; then
397
- # Se ainda não conseguiu, usar nome padrão baseado no ID do modelo
398
- FILENAME="civitai_model_2122278.safetensors"
399
- log_warn "Não foi possível detectar nome do arquivo, usando: $FILENAME"
400
  else
401
- log_success "Nome do arquivo detectado: $FILENAME"
 
402
  fi
403
 
404
- # Baixar o arquivo
405
- log_cmd "curl -L --progress-bar \"$CIVITAI_URL\" -o \"$FILENAME\""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406
 
407
- if curl -L \
408
- --retry 3 \
409
- --connect-timeout 60 \
410
- --max-time 1800 \
411
- --progress-bar \
412
- -o "$FILENAME" \
413
- "$CIVITAI_URL"; then
414
- log_success " Modelo Civitai baixado: $FILENAME"
415
- else
416
- log_error " Falha ao baixar modelo Civitai"
417
  fi
418
- ) &
419
- CIVITAI_PID=$!
420
 
421
- # [7/8] Instalar SageAttention (em paralelo com downloads)
422
- log_info "[7/8] Preparando SageAttention (paralelo com downloads)..."
423
  (
424
- set -Eeuo pipefail
425
-
426
- # Verificar se CUDA está disponível
427
- if command -v nvcc >/dev/null 2>&1; then
428
- log_info " CUDA detectado, instalando triton e preparando SageAttention..."
429
- log_info " Usando configuração otimizada: MAX_JOBS=$MAX_JOBS, EXT_PARALLEL=$EXT_PARALLEL"
430
-
431
- # Instalar triton primeiro
432
- log_cmd "python3 -m pip install \"triton>=3.0.0\""
433
- python3 -m pip install "triton>=3.0.0"
434
 
435
- # Instalar pynvml para melhor detecção de GPU (ignorar warning de deprecation)
436
- log_cmd "python3 -m pip install nvidia-ml-py"
437
- python3 -m pip install nvidia-ml-py 2>&1 | grep -v "FutureWarning" || true
438
-
439
- # Clonar SageAttention
440
- SAGE_DIR="$TMPDL/SageAttention"
441
- if [ ! -d "$SAGE_DIR" ]; then
442
- log_cmd "git clone --depth 1 https://github.com/thu-ml/SageAttention.git \"$SAGE_DIR\""
443
- git clone --depth 1 https://github.com/thu-ml/SageAttention.git "$SAGE_DIR"
444
- fi
445
 
446
  cd "$SAGE_DIR"
 
447
 
448
- # Compilar com configurações otimizadas
449
- log_info " Compilando SageAttention com MAX_JOBS=$MAX_JOBS..."
450
- log_debug " NVCC flags: $NVCC_APPEND_FLAGS"
451
-
452
- # Mostrar output completo da compilação
453
- log_cmd "python3 setup.py install"
454
- python3 setup.py install 2>&1 | grep -v "SetuptoolsDeprecationWarning" | grep -v "FutureWarning" || true
455
-
456
- log_success " SageAttention instalado"
457
  else
458
- log_warn " CUDA não detectado, pulando SageAttention"
459
  fi
460
  ) &
461
  SAGE_PID=$!
462
 
463
- # Aguardar downloads principais
464
- log_info "Aguardando downloads principais (em paralelo com SageAttention)..."
465
- wait $WAN22_PID $WAN21_PID $CN_PID $CIVITAI_PID
466
-
467
- # [8/8] Instalar custom nodes (após downloads, mas ainda em paralelo com SageAttention)
468
- log_info "[8/8] Instalando custom nodes..."
469
- (
470
- set -Eeuo pipefail
471
- CN_DIR="$COMFY_DIR/custom_nodes"
472
-
473
- # Verificar se o diretório existe
474
- if [ ! -d "$CN_DIR" ]; then
475
- log_error "Diretório custom_nodes não existe! Criando..."
476
- mkdir -p "$CN_DIR"
477
- fi
478
-
479
- declare -A REPOS=(
480
- ["https://github.com/kijai/ComfyUI-Florence2"]="ComfyUI-Florence2"
481
- ["https://github.com/kijai/ComfyUI-WanVideoWrapper"]="ComfyUI-WanVideoWrapper"
482
- ["https://github.com/Fannovel16/ComfyUI-Frame-Interpolation"]="ComfyUI-Frame-Interpolation"
483
- ["https://github.com/kijai/ComfyUI-GIMM-VFI"]="ComfyUI-GIMM-VFI"
484
- ["https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite"]="ComfyUI-VideoHelperSuite"
485
- ["https://github.com/kijai/ComfyUI-KJNodes"]="ComfyUI-KJNodes"
486
- ["https://github.com/Fannovel16/comfyui_controlnet_aux"]="comfyui_controlnet_aux"
487
- ["https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit"]="comfyui-WhiteRabbit"
488
- ["https://github.com/LucipherDev/ComfyUI-AniDoc"]="ComfyUI-AniDoc"
489
- ["https://github.com/shiimizu/ComfyUI_smZNodes"]="ComfyUI_smZNodes"
490
- ["https://github.com/yuvraj108c/ComfyUI-Dwpose-Tensorrt"]="ComfyUI-Dwpose-Tensorrt"
491
- ["https://github.com/grmchn/ComfyUI-ProportionChanger"]="ComfyUI-ProportionChanger"
492
- )
493
-
494
- # Clonar todos em paralelo
495
- for url in "${!REPOS[@]}"; do
496
- node_name="${REPOS[$url]}"
497
- node_path="$CN_DIR/$node_name"
498
- clone_or_update "$url" "$node_path" &
499
- done
500
- wait
501
-
502
- log_success " Custom nodes instalados"
503
- )
504
-
505
- # Aguardar SageAttention terminar
506
- log_info "Aguardando conclusão da instalação do SageAttention..."
507
- wait $SAGE_PID
508
 
509
- # Verificar instalação
510
- log_info "Verificando instalação..."
511
- ERROR_COUNT=0
 
 
 
 
512
 
513
- check_file() {
514
- if [ -f "$1" ]; then
515
- SIZE=$(du -h "$1" | cut -f1)
516
- log_success " ✓ $(basename "$1") ($SIZE)"
517
- return 0
518
- else
519
- log_error " ✗ $(basename "$1") não encontrado"
520
- ((ERROR_COUNT++))
521
- return 1
522
- fi
523
- }
524
 
525
- # Verificar ComfyUI
526
- log_debug "Verificando ComfyUI..."
527
- check_file "$COMFY_DIR/main.py"
 
528
 
529
- # Verificar modelos principais
530
- log_info "Verificando modelos baixados..."
531
- check_file "$MODELS_DIR/diffusion_models/wan2.2_fun_control_low_noise_14B_fp8_scaled.safetensors"
532
- check_file "$MODELS_DIR/diffusion_models/wan2.2_fun_control_high_noise_14B_fp8_scaled.safetensors"
533
- check_file "$MODELS_DIR/vae/wan_2.1_vae.safetensors"
534
- check_file "$MODELS_DIR/text_encoders/umt5_xxl_fp16.safetensors"
535
- check_file "$MODELS_DIR/clip_vision/clip_vision_h.safetensors"
536
- check_file "$MODELS_DIR/controlnet/controlnet-union.safetensors"
537
 
538
- # Verificar se algum modelo Civitai foi baixado
539
- log_debug "Verificando modelos Civitai em $MODELS_DIR/loras..."
540
- CIVITAI_FILES=$(ls -1 "$MODELS_DIR/loras/"*.safetensors 2>/dev/null || true)
541
- CIVITAI_COUNT=$(echo "$CIVITAI_FILES" | grep -c safetensors || echo 0)
542
 
543
- if [ "$CIVITAI_COUNT" -gt 0 ]; then
544
- log_success " ✓ $CIVITAI_COUNT modelo(s) Civitai encontrado(s):"
545
- echo "$CIVITAI_FILES" | while read file; do
546
- [ -n "$file" ] && log_debug " - $(basename "$file") ($(du -h "$file" | cut -f1))"
547
- done
548
- else
549
- log_warn " ⚠ Nenhum modelo Civitai encontrado (não crítico)"
550
- fi
551
 
552
- # Relatório final
553
  echo ""
554
  log_info "========================================="
555
- if [ $ERROR_COUNT -eq 0 ]; then
556
- log_success "Instalação concluída com sucesso!"
557
- log_info "ComfyUI instalado em: $COMFY_DIR"
 
 
 
 
 
 
 
 
558
 
559
- # Sempre usar flag do SageAttention (ComfyUI ignora se não estiver instalado)
560
- SAGE_FLAG="--use-sage-attention"
561
- log_info "Flag SageAttention habilitada (será usada se disponível)"
 
 
 
 
 
 
562
 
563
- # Mostrar informações do sistema
564
- log_debug "Configuração final:"
565
- log_debug " CPU: $CPU_CORES cores"
566
- if command -v nvidia-smi >/dev/null 2>&1; then
567
- log_debug " GPU: $(nvidia-smi --query-gpu=name --format=csv,noheader | head -n1)"
568
- log_debug " VRAM: $(nvidia-smi --query-gpu=memory.total --format=csv,noheader | head -n1)"
569
- fi
570
 
571
  echo ""
572
  log_info "Iniciando ComfyUI..."
 
573
 
574
- # Tentar obter IP local
575
- LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
576
- if [ -n "$LOCAL_IP" ]; then
577
- log_info "URL Local: http://$LOCAL_IP:$COMFY_PORT"
 
578
  fi
579
- log_info "URL: http://localhost:$COMFY_PORT"
580
- echo ""
581
 
582
- # Mudar para o diretório do ComfyUI e executar
583
  cd "$COMFY_DIR"
584
- log_cmd "comfy launch -- $SAGE_FLAG --listen \"$COMFY_HOST\" --port \"$COMFY_PORT\""
585
  exec comfy launch -- $SAGE_FLAG --listen "$COMFY_HOST" --port "$COMFY_PORT"
586
  else
587
- log_error "Instalação completada com $ERROR_COUNT erro(s)"
588
- log_info "Verifique os erros acima e execute o script novamente"
589
  exit 1
590
  fi
 
1
  #!/usr/bin/env bash
2
+ # setup_comfyui_wan22_clean.sh
3
+ # Script limpo e funcional para instalação do ComfyUI com Wan 2.2
 
4
 
5
+ set -euo pipefail
 
6
 
7
  # -----------------------------
8
+ # Cores para output
9
  # -----------------------------
10
  RED='\033[0;31m'
11
  GREEN='\033[0;32m'
12
  YELLOW='\033[1;33m'
13
  BLUE='\033[0;34m'
14
+ NC='\033[0m'
 
 
15
 
16
  log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
17
  log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
18
  log_warn() { echo -e "${YELLOW}[!]${NC} $1"; }
19
  log_error() { echo -e "${RED}[✗]${NC} $1"; }
 
 
20
 
21
  # -----------------------------
22
+ # Configuração
23
  # -----------------------------
24
+ COMFY_DIR="/root/comfy/ComfyUI"
25
+ MODELS_DIR="$COMFY_DIR/models"
26
  COMFY_HOST="${COMFY_HOST:-0.0.0.0}"
27
  COMFY_PORT="${COMFY_PORT:-8818}"
 
 
 
 
 
 
 
28
  CIVITAI_TOKEN="${CIVITAI_TOKEN:-4fcb2834969399006a736ee402b061e5}"
29
 
30
+ # Configurações de performance (fixas, sem detecção complexa)
31
+ export MAX_JOBS=16
32
+ export NVCC_APPEND_FLAGS="--threads 8"
33
+ export UV_SYSTEM_PYTHON=1
34
+ export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True"
35
  export HF_HUB_ENABLE_HF_TRANSFER=1
36
+ export HF_TRANSFER_CONCURRENCY=16
37
 
38
  # -----------------------------
39
+ # Lista de downloads
40
  # -----------------------------
41
+ # Formato: "URL|TIPO|NOME_ARQUIVO_OPCIONAL"
42
+ # TIPO pode ser: checkpoints, loras, vae, text_encoders, clip_vision, controlnet, upscale_models
43
+ readonly DOWNLOAD_FILES=(
44
+ # Wan 2.2 models
45
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/diffusion_models/wan2.2_fun_control_low_noise_14B_fp8_scaled.safetensors|checkpoints|"
46
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/diffusion_models/wan2.2_fun_control_high_noise_14B_fp8_scaled.safetensors|checkpoints|"
47
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/loras/wan2.2_i2v_lightx2v_4steps_lora_v1_high_noise.safetensors|loras|"
48
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/loras/wan2.2_i2v_lightx2v_4steps_lora_v1_low_noise.safetensors|loras|"
49
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/vae/wan_2.1_vae.safetensors|vae|"
50
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/text_encoders/umt5_xxl_fp16.safetensors|text_encoders|"
51
+
52
+ # Wan 2.1 clip vision
53
+ "hf://Comfy-Org/Wan_2.1_ComfyUI_repackaged/split_files/clip_vision/clip_vision_h.safetensors|clip_vision|"
54
+
55
+ # ControlNet
56
+ "hf://xinsir/controlnet-union-sdxl-1.0/diffusion_pytorch_model_promax.safetensors|controlnet|controlnet-union.safetensors"
57
+
58
+ # Civitai model
59
+ "https://civitai.com/api/download/models/2122278?type=Model&format=SafeTensor&size=pruned&fp=fp16|loras|"
60
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ # Custom nodes para instalar
63
+ readonly CUSTOM_NODES=(
64
+ "https://github.com/kijai/ComfyUI-Florence2"
65
+ "https://github.com/kijai/ComfyUI-WanVideoWrapper"
66
+ "https://github.com/Fannovel16/ComfyUI-Frame-Interpolation"
67
+ "https://github.com/kijai/ComfyUI-GIMM-VFI"
68
+ "https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite"
69
+ "https://github.com/kijai/ComfyUI-KJNodes"
70
+ "https://github.com/Fannovel16/comfyui_controlnet_aux"
71
+ "https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit"
72
+ "https://github.com/LucipherDev/ComfyUI-AniDoc"
73
+ "https://github.com/shiimizu/ComfyUI_smZNodes"
74
+ "https://github.com/yuvraj108c/ComfyUI-Dwpose-Tensorrt"
75
+ "https://github.com/grmchn/ComfyUI-ProportionChanger"
76
+ )
77
 
78
  # -----------------------------
79
+ # Funções auxiliares
80
  # -----------------------------
81
+ command_exists() {
82
+ command -v "$1" >/dev/null 2>&1
 
 
83
  }
 
84
 
85
+ # Adicionar token do Civitai se necessário
86
+ add_civitai_token() {
87
+ local url="$1"
88
+ if [[ "$url" == *"civitai.com/api/download"* ]] && [[ "$url" != *"token="* ]]; then
89
+ echo "${url}&token=${CIVITAI_TOKEN}"
90
+ else
91
+ echo "$url"
92
  fi
93
  }
94
 
95
+ # Download HuggingFace usando HF Transfer ou huggingface-cli
96
+ download_hf() {
97
+ local repo="$1"
98
+ local file_path="$2"
99
+ local target_dir="$3"
100
+ local filename="$4"
 
 
 
 
 
 
101
 
102
+ # Extrair nome do arquivo se não fornecido
103
+ if [ -z "$filename" ]; then
104
+ filename=$(basename "$file_path")
 
 
 
 
 
105
  fi
106
 
107
+ local target_file="$target_dir/$filename"
108
+
109
+ # Se arquivo existe e tem tamanho razoável, pular
110
+ if [ -f "$target_file" ] && [ $(stat -c%s "$target_file" 2>/dev/null || echo 0) -gt 1000000 ]; then
111
+ log_success "Arquivo já existe: $filename"
112
+ return 0
113
  fi
 
 
 
 
 
 
 
 
114
 
115
+ log_info "Baixando de HF: $filename"
116
+
117
+ # Tentar com HF Transfer primeiro
118
  if python3 -c "import hf_transfer" 2>/dev/null; then
119
+ HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$repo" "$file_path" \
120
+ --local-dir "$target_dir" \
 
 
 
 
121
  --local-dir-use-symlinks False \
122
+ --resume-download 2>/dev/null && {
123
+ # Renomear se necessário
124
+ if [ "$filename" != "$(basename "$file_path")" ]; then
125
+ mv "$target_dir/$file_path" "$target_file" 2>/dev/null || true
126
+ fi
127
+ return 0
 
128
  }
 
 
 
 
 
 
 
129
  fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ # Fallback para método padrão
132
+ huggingface-cli download "$repo" "$file_path" \
133
+ --local-dir "$target_dir" \
134
+ --local-dir-use-symlinks False \
135
+ --resume-download && {
136
+ # Renomear se necessário
137
+ if [ "$filename" != "$(basename "$file_path")" ]; then
138
+ mv "$target_dir/$file_path" "$target_file" 2>/dev/null || true
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  fi
140
+ return 0
141
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
+ return 1
144
+ }
 
145
 
146
+ # Download genérico com aria2c, wget ou curl
147
+ download_file() {
148
+ local url="$1"
149
+ local target_dir="$2"
150
+ local filename="$3"
 
 
151
 
152
+ # Adicionar token Civitai se necessário
153
+ url=$(add_civitai_token "$url")
154
 
155
+ # Se arquivo já existe e tem tamanho razoável, pular
156
+ if [ -n "$filename" ] && [ -f "$target_dir/$filename" ] && [ $(stat -c%s "$target_dir/$filename" 2>/dev/null || echo 0) -gt 1000000 ]; then
157
+ log_success "Arquivo já existe: $filename"
158
+ return 0
159
+ fi
 
 
 
160
 
161
+ log_info "Baixando: ${filename:-$(basename "$url" | cut -d'?' -f1)}"
 
162
 
163
+ # Tentar com aria2c primeiro (mais rápido)
164
+ if command_exists aria2c; then
165
+ local aria_opts="-c -s 16 -x 16 -k 1M --console-log-level=warn --summary-interval=10"
166
+ if [ -n "$filename" ]; then
167
+ aria2c $aria_opts --dir="$target_dir" --out="$filename" "$url" && return 0
 
 
 
 
 
 
 
 
 
168
  else
169
+ aria2c $aria_opts --dir="$target_dir" "$url" && return 0
170
  fi
171
  fi
172
 
173
+ # Fallback para wget
174
+ if command_exists wget; then
175
+ if [ -n "$filename" ]; then
176
+ wget -q --show-progress -c -O "$target_dir/$filename" "$url" && return 0
177
+ else
178
+ wget -q --show-progress -c --content-disposition -P "$target_dir" "$url" && return 0
179
+ fi
180
+ fi
 
 
181
 
182
+ # Último recurso: curl
183
+ if command_exists curl; then
184
+ if [ -n "$filename" ]; then
185
+ curl -L -# -C - -o "$target_dir/$filename" "$url" && return 0
186
+ else
187
+ # Tentar obter nome do arquivo do header
188
+ local headers=$(curl -sI -L "$url")
189
+ local detected_name=$(echo "$headers" | grep -i "content-disposition" | sed -n 's/.*filename="\([^"]*\)".*/\1/p' | tr -d '\r')
190
+
191
+ if [ -z "$detected_name" ]; then
192
+ detected_name="downloaded_$(date +%s).safetensors"
193
+ fi
194
+
195
+ curl -L -# -C - -o "$target_dir/$detected_name" "$url" && return 0
196
+ fi
197
+ fi
198
 
199
+ log_error "Falha ao baixar: $url"
200
+ return 1
201
+ }
202
+
203
+ # Processar lista de downloads
204
+ process_downloads() {
205
+ local failed_count=0
206
 
207
+ for entry in "${DOWNLOAD_FILES[@]}"; do
208
+ IFS='|' read -r url type filename <<< "$entry"
209
+
210
+ # Limpar espaços
211
+ url=$(echo "$url" | xargs)
212
+ type=$(echo "$type" | xargs)
213
+ filename=$(echo "$filename" | xargs)
214
+
215
+ # Determinar diretório de destino
216
+ local target_dir="$MODELS_DIR"
217
+ case "$type" in
218
+ checkpoints) target_dir="$MODELS_DIR/diffusion_models" ;;
219
+ loras) target_dir="$MODELS_DIR/loras" ;;
220
+ vae) target_dir="$MODELS_DIR/vae" ;;
221
+ text_encoders) target_dir="$MODELS_DIR/text_encoders" ;;
222
+ clip_vision) target_dir="$MODELS_DIR/clip_vision" ;;
223
+ controlnet) target_dir="$MODELS_DIR/controlnet" ;;
224
+ upscale_models) target_dir="$MODELS_DIR/upscale_models" ;;
225
+ *) target_dir="$MODELS_DIR/$type" ;;
226
+ esac
227
+
228
+ # Criar diretório se não existir
229
+ mkdir -p "$target_dir"
230
+
231
+ # Processar URL
232
+ if [[ "$url" == hf://* ]]; then
233
+ # HuggingFace download
234
+ url="${url#hf://}" # Remove prefixo hf://
235
+
236
+ # Separar repo e caminho
237
+ repo=$(echo "$url" | cut -d'/' -f1-2)
238
+ file_path=$(echo "$url" | cut -d'/' -f3-)
239
+
240
+ download_hf "$repo" "$file_path" "$target_dir" "$filename" || ((failed_count++))
241
+ else
242
+ # Download normal (HTTP/HTTPS)
243
+ download_file "$url" "$target_dir" "$filename" || ((failed_count++))
244
+ fi
245
+ done
246
 
247
+ return $failed_count
248
+ }
249
+
250
+ # Clonar ou atualizar repositório git
251
+ clone_or_update() {
252
+ local url="$1"
253
+ local dest="$2"
254
 
255
+ if [ -d "$dest/.git" ]; then
256
+ log_info "Atualizando $(basename "$dest")..."
257
+ git -C "$dest" pull --ff-only 2>/dev/null || true
 
258
  else
259
+ log_info "Clonando $(basename "$dest")..."
260
+ git clone --recursive --depth 1 "$url" "$dest" 2>/dev/null || return 1
261
  fi
262
 
263
+ # Instalar requirements se existir
264
+ if [ -f "$dest/requirements.txt" ]; then
265
+ python3 -m pip install --no-warn-script-location -q -r "$dest/requirements.txt" 2>/dev/null || true
266
+ fi
267
+ }
268
+
269
+ # -----------------------------
270
+ # Instalação principal
271
+ # -----------------------------
272
+ echo ""
273
+ log_info "========================================="
274
+ log_info " ComfyUI + Wan 2.2 Setup (Clean)"
275
+ log_info "========================================="
276
+ echo ""
277
+
278
+ # [1] Verificar dependências
279
+ log_info "[1/6] Verificando dependências..."
280
+ for cmd in python3 git wget curl; do
281
+ if ! command_exists "$cmd"; then
282
+ log_error "Dependência faltando: $cmd"
283
+ exit 1
284
+ fi
285
+ done
286
+ log_success "Dependências OK"
287
+
288
+ # [2] Atualizar pip e instalar ferramentas
289
+ log_info "[2/6] Preparando ferramentas Python..."
290
+ python3 -m pip install --upgrade pip wheel setuptools -q
291
+ python3 -m pip install --upgrade comfy-cli "huggingface_hub>=0.23.0" hf_transfer aria2 -q
292
+ log_success "Ferramentas instaladas"
293
+
294
+ # [3] Instalar ComfyUI
295
+ log_info "[3/6] Instalando ComfyUI..."
296
+ if [ -f "$COMFY_DIR/main.py" ]; then
297
+ log_warn "ComfyUI já existe, pulando instalação base"
298
+ else
299
+ comfy --skip-prompt install --fast-deps --nvidia
300
 
301
+ # Verificar instalação
302
+ if [ ! -f "$COMFY_DIR/main.py" ]; then
303
+ log_error "ComfyUI não foi instalado corretamente!"
304
+ exit 1
 
 
 
 
 
 
305
  fi
306
+ fi
307
+ log_success "ComfyUI instalado em: $COMFY_DIR"
308
 
309
+ # [4] Instalar SageAttention (em background)
310
+ log_info "[4/6] Instalando SageAttention..."
311
  (
312
+ if command_exists nvcc; then
313
+ python3 -m pip install "triton>=3.0.0" nvidia-ml-py -q
 
 
 
 
 
 
 
 
314
 
315
+ SAGE_DIR="/tmp/SageAttention"
316
+ rm -rf "$SAGE_DIR"
317
+ git clone --depth 1 https://github.com/thu-ml/SageAttention.git "$SAGE_DIR" 2>/dev/null
 
 
 
 
 
 
 
318
 
319
  cd "$SAGE_DIR"
320
+ python3 setup.py install --quiet 2>/dev/null
321
 
322
+ log_success "SageAttention instalado"
 
 
 
 
 
 
 
 
323
  else
324
+ log_warn "CUDA não detectado, pulando SageAttention"
325
  fi
326
  ) &
327
  SAGE_PID=$!
328
 
329
+ # [5] Baixar modelos
330
+ log_info "[5/6] Baixando modelos..."
331
+ mkdir -p "$MODELS_DIR"/{diffusion_models,loras,vae,text_encoders,clip_vision,controlnet,upscale_models}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
+ # Verificar se aria2c está disponível
334
+ if command_exists aria2c; then
335
+ log_success "Usando aria2c para downloads (rápido)"
336
+ else
337
+ log_warn "aria2c não encontrado, usando wget/curl (mais lento)"
338
+ log_info "Instale aria2c para downloads mais rápidos: apt-get install aria2"
339
+ fi
340
 
341
+ # Processar downloads
342
+ if process_downloads; then
343
+ log_success "Todos os modelos baixados com sucesso"
344
+ else
345
+ log_warn "Alguns downloads falharam, mas continuando..."
346
+ fi
 
 
 
 
 
347
 
348
+ # [6] Instalar custom nodes
349
+ log_info "[6/6] Instalando custom nodes..."
350
+ CN_DIR="$COMFY_DIR/custom_nodes"
351
+ mkdir -p "$CN_DIR"
352
 
353
+ for repo_url in "${CUSTOM_NODES[@]}"; do
354
+ node_name=$(basename "$repo_url")
355
+ clone_or_update "$repo_url" "$CN_DIR/$node_name" &
356
+ done
357
+ wait
 
 
 
358
 
359
+ log_success "Custom nodes instalados"
 
 
 
360
 
361
+ # Aguardar SageAttention
362
+ wait $SAGE_PID 2>/dev/null || true
 
 
 
 
 
 
363
 
364
+ # Verificação final
365
  echo ""
366
  log_info "========================================="
367
+ log_info "Verificando instalação..."
368
+
369
+ # Verificar arquivos principais
370
+ check_critical_files() {
371
+ local files=(
372
+ "$COMFY_DIR/main.py"
373
+ "$MODELS_DIR/diffusion_models/wan2.2_fun_control_low_noise_14B_fp8_scaled.safetensors"
374
+ "$MODELS_DIR/diffusion_models/wan2.2_fun_control_high_noise_14B_fp8_scaled.safetensors"
375
+ "$MODELS_DIR/vae/wan_2.1_vae.safetensors"
376
+ "$MODELS_DIR/text_encoders/umt5_xxl_fp16.safetensors"
377
+ )
378
 
379
+ local missing=0
380
+ for file in "${files[@]}"; do
381
+ if [ -f "$file" ]; then
382
+ log_success "✓ $(basename "$file")"
383
+ else
384
+ log_error "✗ $(basename "$file") não encontrado"
385
+ ((missing++))
386
+ fi
387
+ done
388
 
389
+ return $missing
390
+ }
391
+
392
+ if check_critical_files; then
393
+ log_success "Instalação concluída com sucesso!"
 
 
394
 
395
  echo ""
396
  log_info "Iniciando ComfyUI..."
397
+ log_info "URL: http://localhost:$COMFY_PORT"
398
 
399
+ # Tentar usar SageAttention se disponível
400
+ SAGE_FLAG=""
401
+ if python3 -c "import sageattention" 2>/dev/null; then
402
+ SAGE_FLAG="--use-sage-attention"
403
+ log_info "SageAttention habilitado"
404
  fi
 
 
405
 
 
406
  cd "$COMFY_DIR"
 
407
  exec comfy launch -- $SAGE_FLAG --listen "$COMFY_HOST" --port "$COMFY_PORT"
408
  else
409
+ log_error "Arquivos críticos faltando. Verifique os erros acima."
 
410
  exit 1
411
  fi