adbrasi commited on
Commit
1465d9c
·
verified ·
1 Parent(s): 594a577

Upload wanVideo2_2.sh

Browse files
Files changed (1) hide show
  1. wanVideo2_2.sh +481 -0
wanVideo2_2.sh ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # setup_comfyui_wan22_fixed.sh
3
+ # Script corrigido 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
+ HF_TOKEN="${HF_TOKEN:-}" # Token opcional do HuggingFace para login
30
+
31
+ # Configurações de performance
32
+ export MAX_JOBS=32
33
+ export NVCC_APPEND_FLAGS="--threads 8"
34
+ export UV_SYSTEM_PYTHON=1
35
+ export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True"
36
+ export HF_HUB_ENABLE_HF_TRANSFER=1
37
+ export HF_TRANSFER_CONCURRENCY=16
38
+ export EXT_PARALLEL=4
39
+
40
+ # -----------------------------
41
+ # Lista de downloads
42
+ # -----------------------------
43
+ # Formato: "URL|TIPO|NOME_ARQUIVO_OPCIONAL"
44
+ readonly DOWNLOAD_FILES=(
45
+ # Wan 2.2 models
46
+ "hf://Kijai/WanVideo_comfy/Wan22-Lightning/Wan2.2-Lightning_T2V-v1.1-A14B-4steps-lora_HIGH_fp16.safetensors|loras|Wan2.2-Lightning_T2V-v1.1-A14B-4steps-lora_HIGH_fp16.safetensors"
47
+ "hf://Kijai/WanVideo_comfy/Wan22-Lightning/Wan2.2-Lightning_T2V-v1.1-A14B-4steps-lora_LOW_fp16.safetensors|loras|Wan2.2-Lightning_T2V-v1.1-A14B-4steps-lora_LOW_fp16.safetensors"
48
+ #sdasd
49
+ "hf://Kijai/WanVideo_comfy_fp8_scaled/I2V/Wan2_2-I2V-A14B-HIGH_fp8_e5m2_scaled_KJ.safetensors|diffusion_models|Wan2_2-I2V-A14B-HIGH_fp8_e5m2_scaled_KJ.safetensors"
50
+ "hf://Kijai/WanVideo_comfy_fp8_scaled/I2V/Wan2_2-I2V-A14B-LOW_fp8_e5m2_scaled_KJ.safetensors|diffusion_models|Wan2_2-I2V-A14B-LOW_fp8_e5m2_scaled_KJ.safetensors"
51
+ "hf://Kijai/WanVideo_comfy/Wan22-Lightning/Wan2.2-Lightning_I2V-A14B-4steps-lora_HIGH_fp16.safetensors|loras|Wan2.2-Lightning_I2V-A14B-4steps-lora_HIGH_fp16.safetensors"
52
+ "hf://Kijai/WanVideo_comfy/Wan22-Lightning/Wan2.2-Lightning_I2V-A14B-4steps-lora_LOW_fp16.safetensors|loras|Wan2.2-Lightning_I2V-A14B-4steps-lora_LOW_fp16.safetensors"
53
+ "hf://Kijai/WanVideo_comfy/Wan2_1_VAE_fp32.safetensors|vae|Wan2_1_VAE_fp32.safetensors"
54
+ "hf://Kijai/WanVideo_comfy/umt5-xxl-enc-bf16.safetensors|text_encoders|umt5-xxl-enc-bf16.safetensors"
55
+ # Wan 2.1 clip vision
56
+ "hf://Kijai/WanVideo_comfy/open-clip-xlm-roberta-large-vit-huge-14_visual_fp32.safetensors|clip_vision|open-clip-xlm-roberta-large-vit-huge-14_visual_fp32.safetensors"
57
+ "hf://Comfy-Org/Wan_2.1_ComfyUI_repackaged/split_files/clip_vision/clip_vision_h.safetensors|clip_vision|clip_vision_h.safetensors"
58
+ # ControlNet e outros modelos
59
+ "https://huggingface.co/Kijai/WanVideo_comfy/resolve/main/taew2_1.safetensors|vae_approx|taew2_1.safetensors"
60
+ "https://huggingface.co/ABDALLALSWAITI/Upscalers/resolve/main/anime/2x-AnimeSharpV2_MoSR_Soft.pth|upscale_models|2x-AnimeSharpV2_MoSR_Soft.pth"
61
+ )
62
+
63
+ # Custom nodes para instalar
64
+ readonly CUSTOM_NODES=(
65
+ "https://github.com/kijai/ComfyUI-Florence2"
66
+ "https://github.com/kijai/ComfyUI-WanVideoWrapper"
67
+ "https://github.com/Fannovel16/ComfyUI-Frame-Interpolation"
68
+ "https://github.com/kijai/ComfyUI-GIMM-VFI"
69
+ "https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite"
70
+ "https://github.com/kijai/ComfyUI-KJNodes"
71
+ "https://github.com/Fannovel16/comfyui_controlnet_aux"
72
+ "https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit"
73
+ "https://github.com/shiimizu/ComfyUI_smZNodes"
74
+ "https://github.com/CoreyCorza/ComfyUI-CRZnodes"
75
+ "https://github.com/yuvraj108c/ComfyUI-Dwpose-Tensorrt"
76
+ "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes"
77
+ "https://github.com/grmchn/ComfyUI-ProportionChanger"
78
+ )
79
+
80
+ # -----------------------------
81
+ # Funções auxiliares
82
+ # -----------------------------
83
+ command_exists() {
84
+ command -v "$1" >/dev/null 2>&1
85
+ }
86
+
87
+ # Adicionar token do Civitai se necessário
88
+ add_civitai_token() {
89
+ local url="$1"
90
+ if [[ "$url" == *"civitai.com/api/download"* ]] && [[ "$url" != *"token="* ]]; then
91
+ echo "${url}&token=${CIVITAI_TOKEN}"
92
+ else
93
+ echo "$url"
94
+ fi
95
+ }
96
+
97
+ # Download HuggingFace usando hf com hf_transfer
98
+ download_hf() {
99
+ local repo="$1"
100
+ local file_path="$2"
101
+ local target_dir="$3"
102
+ local filename="$4"
103
+
104
+ # Se filename não foi fornecido, extrair do caminho
105
+ if [ -z "$filename" ]; then
106
+ filename=$(basename "$file_path")
107
+ fi
108
+
109
+ local target_file="$target_dir/$filename"
110
+
111
+ # Se arquivo já existe e tem tamanho razoável, pular
112
+ if [ -f "$target_file" ] && [ $(stat -c%s "$target_file" 2>/dev/null || echo 0) -gt 1000000 ]; then
113
+ log_success "Arquivo já existe: $filename"
114
+ return 0
115
+ fi
116
+
117
+ log_info "Baixando de HF: $filename"
118
+ log_info " Repo: $repo"
119
+ log_info " Path: $file_path"
120
+
121
+ # Criar diretório temporário para download
122
+ local temp_dir=$(mktemp -d)
123
+
124
+ # Tentar primeiro com 'hf download' (novo comando)
125
+ local download_success=false
126
+
127
+ if command_exists hf; then
128
+ if HF_HUB_ENABLE_HF_TRANSFER=1 hf download "$repo" "$file_path" \
129
+ --local-dir "$temp_dir" \
130
+ --local-dir-use-symlinks False 2>/dev/null; then
131
+ download_success=true
132
+ fi
133
+ fi
134
+
135
+ # Se 'hf' não funcionou, tentar com huggingface-cli
136
+ if [ "$download_success" = false ] && command_exists huggingface-cli; then
137
+ log_warn "Tentando com huggingface-cli..."
138
+ if HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$repo" "$file_path" \
139
+ --local-dir "$temp_dir" \
140
+ --local-dir-use-symlinks False 2>/dev/null; then
141
+ download_success=true
142
+ fi
143
+ fi
144
+
145
+ if [ "$download_success" = true ]; then
146
+ # Procurar o arquivo baixado (pode estar em subdiretórios)
147
+ local downloaded_file=$(find "$temp_dir" -type f \( -name "*.safetensors" -o -name "*.pth" -o -name "*.pt" -o -name "*.bin" \) 2>/dev/null | head -1)
148
+
149
+ if [ -n "$downloaded_file" ]; then
150
+ # Mover para o destino correto com o nome correto
151
+ mv "$downloaded_file" "$target_file"
152
+ rm -rf "$temp_dir"
153
+ log_success "Download concluído: $filename"
154
+ return 0
155
+ else
156
+ log_error "Arquivo baixado mas não encontrado em $temp_dir"
157
+ fi
158
+ fi
159
+
160
+ rm -rf "$temp_dir"
161
+ log_error "Falha ao baixar: $filename"
162
+ return 1
163
+ }
164
+
165
+ # Download genérico com aria2c, wget ou curl
166
+ download_file() {
167
+ local url="$1"
168
+ local target_dir="$2"
169
+ local filename="$3"
170
+
171
+ # Adicionar token Civitai se necessário
172
+ url=$(add_civitai_token "$url")
173
+
174
+ # Se arquivo já existe e tem tamanho razoável, pular
175
+ if [ -n "$filename" ] && [ -f "$target_dir/$filename" ] && [ $(stat -c%s "$target_dir/$filename" 2>/dev/null || echo 0) -gt 1000000 ]; then
176
+ log_success "Arquivo já existe: $filename"
177
+ return 0
178
+ fi
179
+
180
+ log_info "Baixando: ${filename:-$(basename "$url" | cut -d'?' -f1)}"
181
+
182
+ # Tentar com aria2c primeiro (mais rápido)
183
+ if command_exists aria2c; then
184
+ local aria_opts="-c -s 16 -x 16 -k 1M --console-log-level=warn --summary-interval=10"
185
+ if [ -n "$filename" ]; then
186
+ aria2c $aria_opts --dir="$target_dir" --out="$filename" "$url" && return 0
187
+ else
188
+ aria2c $aria_opts --dir="$target_dir" "$url" && return 0
189
+ fi
190
+ fi
191
+
192
+ # Fallback para wget
193
+ if command_exists wget; then
194
+ if [ -n "$filename" ]; then
195
+ wget -q --show-progress -c -O "$target_dir/$filename" "$url" && return 0
196
+ else
197
+ wget -q --show-progress -c --content-disposition -P "$target_dir" "$url" && return 0
198
+ fi
199
+ fi
200
+
201
+ # Último recurso: curl
202
+ if command_exists curl; then
203
+ if [ -n "$filename" ]; then
204
+ curl -L -# -C - -o "$target_dir/$filename" "$url" && return 0
205
+ else
206
+ local headers=$(curl -sI -L "$url")
207
+ local detected_name=$(echo "$headers" | grep -i "content-disposition" | sed -n 's/.*filename="\([^"]*\)".*/\1/p' | tr -d '\r')
208
+ if [ -z "$detected_name" ]; then
209
+ detected_name="downloaded_$(date +%s).safetensors"
210
+ fi
211
+ curl -L -# -C - -o "$target_dir/$detected_name" "$url" && return 0
212
+ fi
213
+ fi
214
+
215
+ log_error "Falha ao baixar: $url"
216
+ return 1
217
+ }
218
+
219
+ # Processar lista de downloads
220
+ process_downloads() {
221
+ local failed_count=0
222
+
223
+ for entry in "${DOWNLOAD_FILES[@]}"; do
224
+ IFS='|' read -r url type filename <<< "$entry"
225
+
226
+ # Limpar espaços
227
+ url=$(echo "$url" | xargs)
228
+ type=$(echo "$type" | xargs)
229
+ filename=$(echo "$filename" | xargs)
230
+
231
+ # Determinar diretório de destino
232
+ local target_dir="$MODELS_DIR"
233
+ case "$type" in
234
+ checkpoints) target_dir="$MODELS_DIR/checkpoints" ;;
235
+ diffusion_models) target_dir="$MODELS_DIR/diffusion_models" ;;
236
+ loras) target_dir="$MODELS_DIR/loras" ;;
237
+ vae) target_dir="$MODELS_DIR/vae" ;;
238
+ vae_approx) target_dir="$MODELS_DIR/vae_approx" ;;
239
+ text_encoders) target_dir="$MODELS_DIR/text_encoders" ;;
240
+ clip_vision) target_dir="$MODELS_DIR/clip_vision" ;;
241
+ controlnet) target_dir="$MODELS_DIR/controlnet" ;;
242
+ upscale_models) target_dir="$MODELS_DIR/upscale_models" ;;
243
+ *) target_dir="$MODELS_DIR/$type" ;;
244
+ esac
245
+
246
+ # Criar diretório se não existir
247
+ mkdir -p "$target_dir"
248
+
249
+ # Processar URL
250
+ if [[ "$url" == hf://* ]]; then
251
+ # HuggingFace download
252
+ url="${url#hf://}" # Remove prefixo hf://
253
+
254
+ # Separar repo e caminho do arquivo
255
+ local repo=$(echo "$url" | cut -d'/' -f1-2)
256
+ local file_path=$(echo "$url" | cut -d'/' -f3-)
257
+
258
+ download_hf "$repo" "$file_path" "$target_dir" "$filename" || ((failed_count++))
259
+ else
260
+ # Download normal (HTTP/HTTPS)
261
+ download_file "$url" "$target_dir" "$filename" || ((failed_count++))
262
+ fi
263
+ done
264
+
265
+ return $failed_count
266
+ }
267
+
268
+ # Clonar ou atualizar repositório git
269
+ clone_or_update() {
270
+ local url="$1"
271
+ local dest="$2"
272
+ local node_name=$(basename "$dest")
273
+
274
+ # Timeout de 60 segundos para operações git
275
+ if [ -d "$dest/.git" ]; then
276
+ log_info "Atualizando $node_name..."
277
+ timeout 60 git -C "$dest" pull --ff-only 2>/dev/null || {
278
+ log_warn "Timeout ou erro ao atualizar $node_name"
279
+ return 0 # Não falhar, apenas avisar
280
+ }
281
+ else
282
+ log_info "Clonando $node_name..."
283
+ timeout 60 git clone --recursive --depth 1 "$url" "$dest" 2>/dev/null || {
284
+ log_warn "Falha ao clonar $node_name"
285
+ return 0 # Não falhar, apenas avisar
286
+ }
287
+ fi
288
+
289
+ # Instalar requirements se existir (com timeout)
290
+ if [ -f "$dest/requirements.txt" ]; then
291
+ timeout 120 python3 -m pip install --no-warn-script-location -q -r "$dest/requirements.txt" 2>/dev/null || {
292
+ log_warn "Falha ao instalar requirements para $node_name"
293
+ }
294
+ fi
295
+
296
+ return 0
297
+ }
298
+
299
+ # -----------------------------
300
+ # Instalação principal
301
+ # -----------------------------
302
+ echo ""
303
+ log_info "========================================="
304
+ log_info " ComfyUI + Wan 2.2 Setup (Fixed v2)"
305
+ log_info "========================================="
306
+ echo ""
307
+
308
+ # [1] Verificar e instalar dependências
309
+ log_info "[1/8] Verificando e instalando dependências..."
310
+
311
+ # Instalar aria2c do sistema se não existir
312
+ if ! command_exists aria2c; then
313
+ log_info "Instalando aria2c do sistema..."
314
+ apt-get update -qq && apt-get install -y -qq aria2 2>/dev/null
315
+ fi
316
+
317
+ for cmd in python3 git wget curl; do
318
+ if ! command_exists "$cmd"; then
319
+ log_error "Dependência faltando: $cmd"
320
+ exit 1
321
+ fi
322
+ done
323
+ log_success "Dependências OK"
324
+
325
+ # [2] Atualizar pip e instalar ferramentas
326
+ log_info "[2/8] Preparando ferramentas Python..."
327
+ python3 -m pip install --upgrade pip wheel setuptools -q
328
+
329
+ # Instalar huggingface_hub com CLI e hf_transfer para velocidade máxima
330
+ python3 -m pip install --upgrade "huggingface_hub[cli,hf_transfer]>=0.26.0" comfy-cli -q
331
+
332
+ # Configurar token HF se disponível (opcional)
333
+ HF_TOKEN="${HF_TOKEN:-}"
334
+ if [ -n "$HF_TOKEN" ]; then
335
+ if huggingface-cli login --token "$HF_TOKEN" 2>/dev/null; then
336
+ log_success "Login HF configurado"
337
+ else
338
+ log_warn "Falha ao configurar login HF, continuando sem autenticação"
339
+ fi
340
+ fi
341
+
342
+ # Verificar comandos disponíveis
343
+ if command_exists hf; then
344
+ log_success "Comando 'hf' disponível (recomendado)"
345
+ elif command_exists huggingface-cli; then
346
+ log_warn "Usando 'huggingface-cli' (deprecated, mas funcional)"
347
+ else
348
+ log_error "Nenhum comando HF disponível!"
349
+ fi
350
+
351
+ log_success "Ferramentas instaladas"
352
+
353
+ # [3] Instalar PyTorch com CUDA 12.8
354
+ log_info "[3/8] Instalando PyTorch com CUDA 12.8..."
355
+ python3 -m pip install --upgrade torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
356
+ log_success "PyTorch com CUDA 12.8 instalado"
357
+
358
+ # [4] Instalar ComfyUI
359
+ log_info "[4/8] Instalando ComfyUI..."
360
+ if [ -f "$COMFY_DIR/main.py" ]; then
361
+ log_warn "ComfyUI já existe, pulando instalação base"
362
+ else
363
+ comfy --skip-prompt install --fast-deps --nvidia
364
+
365
+ # Verificar instalação
366
+ if [ ! -f "$COMFY_DIR/main.py" ]; then
367
+ log_error "ComfyUI não foi instalado corretamente!"
368
+ exit 1
369
+ fi
370
+ fi
371
+ log_success "ComfyUI instalado em: $COMFY_DIR"
372
+
373
+ # [5] Instalar SageAttention (wheel pré-compilada)
374
+ log_info "[5/8] Instalando SageAttention..."
375
+ if command_exists nvcc || python3 -c "import torch; print(torch.cuda.is_available())" 2>/dev/null | grep -q "True"; then
376
+ log_info "Instalando SageAttention pré-compilada..."
377
+ python3 -m pip install "https://huggingface.co/adbrasi/comfywheel/resolve/main/sageattention-2.2.0-cp311-cp311-linux_x86_64.whl" -q
378
+
379
+ # Verificar instalação
380
+ if python3 -c "import sageattention" 2>/dev/null; then
381
+ log_success "SageAttention instalado com sucesso"
382
+ else
383
+ log_warn "SageAttention instalado mas não pôde ser importado"
384
+ fi
385
+ else
386
+ log_warn "CUDA não detectado, pulando SageAttention"
387
+ fi
388
+
389
+ # [6] Baixar modelos
390
+ log_info "[6/8] Baixando modelos..."
391
+ mkdir -p "$MODELS_DIR"/{diffusion_models,loras,vae,vae_approx,text_encoders,clip_vision,controlnet,upscale_models,checkpoints}
392
+
393
+ # Verificar ferramentas de download
394
+ if command_exists aria2c; then
395
+ log_success "Usando aria2c para downloads (rápido)"
396
+ else
397
+ log_warn "aria2c não encontrado, usando wget/curl (mais lento)"
398
+ fi
399
+
400
+ # Processar downloads
401
+ if process_downloads; then
402
+ log_success "Todos os modelos baixados com sucesso"
403
+ else
404
+ log_warn "Alguns downloads falharam, mas continuando..."
405
+ fi
406
+
407
+ # [7] Instalar custom nodes
408
+ log_info "[7/8] Instalando custom nodes..."
409
+ CN_DIR="$COMFY_DIR/custom_nodes"
410
+ mkdir -p "$CN_DIR"
411
+
412
+ # Instalar nodes sequencialmente para evitar travamentos
413
+ for repo_url in "${CUSTOM_NODES[@]}"; do
414
+ node_name=$(basename "$repo_url")
415
+ clone_or_update "$repo_url" "$CN_DIR/$node_name"
416
+ done
417
+
418
+ log_success "Custom nodes instalados"
419
+
420
+ # [8] Verificação final
421
+ echo ""
422
+ log_info "[8/8] Verificando instalação..."
423
+
424
+ # Verificar arquivos principais (ajustado para os modelos que você está baixando)
425
+ check_critical_files() {
426
+ local files=(
427
+ "$COMFY_DIR/main.py"
428
+ "$MODELS_DIR/diffusion_models/Wan2_1-I2V-14B-720P_fp8_e4m3fn.safetensors"
429
+ "$MODELS_DIR/vae/wan_2.1_vae.safetensors"
430
+ "$MODELS_DIR/text_encoders/umt5_xxl_fp16.safetensors"
431
+ "$MODELS_DIR/clip_vision/clip_vision_h.safetensors"
432
+ )
433
+
434
+ local missing=0
435
+ for file in "${files[@]}"; do
436
+ if [ -f "$file" ]; then
437
+ log_success "✓ $(basename "$file")"
438
+ else
439
+ log_warn "✗ $(basename "$file") não encontrado (opcional)"
440
+ fi
441
+ done
442
+
443
+ # Listar modelos baixados
444
+ echo ""
445
+ log_info "Modelos disponíveis:"
446
+ for dir in diffusion_models loras vae vae_approx text_encoders clip_vision controlnet upscale_models checkpoints; do
447
+ if [ -d "$MODELS_DIR/$dir" ]; then
448
+ local count=$(find "$MODELS_DIR/$dir" -type f \( -name "*.safetensors" -o -name "*.pth" -o -name "*.pt" \) 2>/dev/null | wc -l)
449
+ if [ $count -gt 0 ]; then
450
+ log_success " $dir: $count arquivo(s)"
451
+ fi
452
+ fi
453
+ done
454
+
455
+ return 0
456
+ }
457
+
458
+ if check_critical_files; then
459
+ log_success "Instalação concluída com sucesso!"
460
+ echo ""
461
+ log_info "========================================="
462
+ log_info "Iniciando ComfyUI..."
463
+ log_info "URL: http://localhost:$COMFY_PORT"
464
+ log_info "========================================="
465
+
466
+ # Tentar usar SageAttention se disponível
467
+ SAGE_FLAG=""
468
+ if python3 -c "import sageattention" 2>/dev/null; then
469
+ SAGE_FLAG="--use-sage-attention"
470
+ log_info "SageAttention habilitado"
471
+ fi
472
+
473
+ cd "$COMFY_DIR"
474
+ exec comfy launch -- $SAGE_FLAG --listen "$COMFY_HOST" --port "$COMFY_PORT"
475
+ else
476
+ log_error "Alguns arquivos não foram encontrados, mas a instalação pode funcionar."
477
+ log_info "Iniciando ComfyUI mesmo assim..."
478
+
479
+ cd "$COMFY_DIR"
480
+ exec comfy launch -- --listen "$COMFY_HOST" --port "$COMFY_PORT"
481
+ fi