adbrasi commited on
Commit
d27dbec
·
verified ·
1 Parent(s): 6d9590d

Upload setup_comfy_wanDANCE.sh

Browse files
Files changed (1) hide show
  1. setup_comfy_wanDANCE.sh +458 -0
setup_comfy_wanDANCE.sh ADDED
@@ -0,0 +1,458 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/resolve/main/Wan2_1-I2V-14B-720P_fp8_e4m3fn.safetensors|diffusion_models|Wan2_1-I2V-14B-720P_fp8_e4m3fn.safetensors"
47
+ "hf://Kijai/WanVideo_comfy/resolve/main/Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank256_bf16.safetensors|loras|lightx2v_I2V_14B_480p_cfg_step_distill_rank256_bf16.safetensors"
48
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/vae/wan_2.1_vae.safetensors|vae|"
49
+ "hf://Comfy-Org/Wan_2.2_ComfyUI_Repackaged/split_files/text_encoders/umt5_xxl_fp16.safetensors|text_encoders|"
50
+ # Wan 2.1 clip vision
51
+ "hf://Comfy-Org/Wan_2.1_ComfyUI_repackaged/split_files/clip_vision/clip_vision_h.safetensors|clip_vision|"
52
+ # ControlNet models/vae_approx.
53
+ "https://huggingface.co/Kijai/WanVideo_comfy/resolve/main/taew2_1.safetensors|vae_approx|taew2_1.safetensors"
54
+ "https://huggingface.co/Kijai/WanVideo_comfy/resolve/main/UniAnimate-Wan2.1-14B-Lora-12000-fp16.safetensors|loras|UniAnimate-Wan2.1-14B-Lora-12000-fp16.safetensors"
55
+ "hf://xinsir/controlnet-union-sdxl-1.0/diffusion_pytorch_model_promax.safetensors|controlnet|controlnet-union.safetensors"
56
+ "https://huggingface.co/ABDALLALSWAITI/Upscalers/resolve/main/anime/2x-AnimeSharpV2_MoSR_Soft.pth|upscale_models|2x-AnimeSharpV2_MoSR_Soft.pth"
57
+ # Civitai model
58
+ "https://civitai.com/api/download/models/2122278?type=Model&format=SafeTensor&size=pruned&fp=fp16|checkpoints|raehoshiIllustXL_v60.safetensors"
59
+ )
60
+
61
+ # Custom nodes para instalar
62
+ readonly CUSTOM_NODES=(
63
+ "https://github.com/kijai/ComfyUI-Florence2"
64
+ "https://github.com/kijai/ComfyUI-WanVideoWrapper"
65
+ "https://github.com/Fannovel16/ComfyUI-Frame-Interpolation"
66
+ "https://github.com/kijai/ComfyUI-GIMM-VFI"
67
+ "https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite"
68
+ "https://github.com/kijai/ComfyUI-KJNodes"
69
+ "https://github.com/Fannovel16/comfyui_controlnet_aux"
70
+ "https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit"
71
+ "https://github.com/shiimizu/ComfyUI_smZNodes"
72
+ "https://github.com/CoreyCorza/ComfyUI-CRZnodes"
73
+ "https://github.com/yuvraj108c/ComfyUI-Dwpose-Tensorrt"
74
+ "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes"
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 huggingface-cli com hf_transfer
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 já 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
+ # Usar huggingface-cli com hf_transfer habilitado para velocidade máxima
118
+ if HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$repo" "$file_path" \
119
+ --local-dir "$target_dir" \
120
+ --local-dir-use-symlinks False \
121
+ --resume-download 2>/dev/null; then
122
+
123
+ # Verificar se arquivo foi baixado
124
+ if [ -f "$target_file" ]; then
125
+ log_success "Download concluído: $filename"
126
+ return 0
127
+ fi
128
+
129
+ # Procurar arquivo em subdiretórios se não estiver no local esperado
130
+ local downloaded_file=$(find "$target_dir" -name "$filename" -type f 2>/dev/null | head -1)
131
+ if [ -n "$downloaded_file" ] && [ "$downloaded_file" != "$target_file" ]; then
132
+ mv "$downloaded_file" "$target_file"
133
+ log_success "Download concluído e movido: $filename"
134
+ return 0
135
+ fi
136
+ fi
137
+
138
+ log_error "Falha ao baixar: $filename"
139
+ return 1
140
+ }
141
+
142
+ # Download genérico com aria2c, wget ou curl
143
+ download_file() {
144
+ local url="$1"
145
+ local target_dir="$2"
146
+ local filename="$3"
147
+
148
+ # Adicionar token Civitai se necessário
149
+ url=$(add_civitai_token "$url")
150
+
151
+ # Se arquivo já existe e tem tamanho razoável, pular
152
+ if [ -n "$filename" ] && [ -f "$target_dir/$filename" ] && [ $(stat -c%s "$target_dir/$filename" 2>/dev/null || echo 0) -gt 1000000 ]; then
153
+ log_success "Arquivo já existe: $filename"
154
+ return 0
155
+ fi
156
+
157
+ log_info "Baixando: ${filename:-$(basename "$url" | cut -d'?' -f1)}"
158
+
159
+ # Tentar com aria2c primeiro (mais rápido)
160
+ if command_exists aria2c; then
161
+ local aria_opts="-c -s 16 -x 16 -k 1M --console-log-level=warn --summary-interval=10"
162
+ if [ -n "$filename" ]; then
163
+ aria2c $aria_opts --dir="$target_dir" --out="$filename" "$url" && return 0
164
+ else
165
+ aria2c $aria_opts --dir="$target_dir" "$url" && return 0
166
+ fi
167
+ fi
168
+
169
+ # Fallback para wget
170
+ if command_exists wget; then
171
+ if [ -n "$filename" ]; then
172
+ wget -q --show-progress -c -O "$target_dir/$filename" "$url" && return 0
173
+ else
174
+ wget -q --show-progress -c --content-disposition -P "$target_dir" "$url" && return 0
175
+ fi
176
+ fi
177
+
178
+ # Último recurso: curl
179
+ if command_exists curl; then
180
+ if [ -n "$filename" ]; then
181
+ curl -L -# -C - -o "$target_dir/$filename" "$url" && return 0
182
+ else
183
+ local headers=$(curl -sI -L "$url")
184
+ local detected_name=$(echo "$headers" | grep -i "content-disposition" | sed -n 's/.*filename="\([^"]*\)".*/\1/p' | tr -d '\r')
185
+ if [ -z "$detected_name" ]; then
186
+ detected_name="downloaded_$(date +%s).safetensors"
187
+ fi
188
+ curl -L -# -C - -o "$target_dir/$detected_name" "$url" && return 0
189
+ fi
190
+ fi
191
+
192
+ log_error "Falha ao baixar: $url"
193
+ return 1
194
+ }
195
+
196
+ # Processar lista de downloads
197
+ process_downloads() {
198
+ local failed_count=0
199
+
200
+ for entry in "${DOWNLOAD_FILES[@]}"; do
201
+ IFS='|' read -r url type filename <<< "$entry"
202
+
203
+ # Limpar espaços
204
+ url=$(echo "$url" | xargs)
205
+ type=$(echo "$type" | xargs)
206
+ filename=$(echo "$filename" | xargs)
207
+
208
+ # Determinar diretório de destino
209
+ local target_dir="$MODELS_DIR"
210
+ case "$type" in
211
+ checkpoints) target_dir="$MODELS_DIR/checkpoints" ;;
212
+ loras) target_dir="$MODELS_DIR/loras" ;;
213
+ vae) target_dir="$MODELS_DIR/vae" ;;
214
+ vae_approx) target_dir="$MODELS_DIR/vae_approx" ;;
215
+ text_encoders) target_dir="$MODELS_DIR/text_encoders" ;;
216
+ clip_vision) target_dir="$MODELS_DIR/clip_vision" ;;
217
+ controlnet) target_dir="$MODELS_DIR/controlnet" ;;
218
+ upscale_models) target_dir="$MODELS_DIR/upscale_models" ;;
219
+ *) target_dir="$MODELS_DIR/$type" ;;
220
+ esac
221
+
222
+ # Criar diretório se não existir
223
+ mkdir -p "$target_dir"
224
+
225
+ # Processar URL
226
+ if [[ "$url" == hf://* ]]; then
227
+ # HuggingFace download
228
+ url="${url#hf://}" # Remove prefixo hf://
229
+ repo=$(echo "$url" | cut -d'/' -f1-2)
230
+ file_path=$(echo "$url" | cut -d'/' -f3-)
231
+
232
+ download_hf "$repo" "$file_path" "$target_dir" "$filename" || ((failed_count++))
233
+ else
234
+ # Download normal (HTTP/HTTPS)
235
+ download_file "$url" "$target_dir" "$filename" || ((failed_count++))
236
+ fi
237
+ done
238
+
239
+ # Limpar arquivos órfãos em split_files (se existirem)
240
+ if [ -d "$MODELS_DIR/diffusion_models/split_files" ]; then
241
+ log_info "Movendo arquivos de split_files para diretórios corretos..."
242
+ find "$MODELS_DIR" -path "*/split_files/*" -name "*.safetensors" | while read -r file; do
243
+ local base_dir=$(dirname "$(dirname "$file")")
244
+ local target_name=$(basename "$file")
245
+ if [ ! -f "$base_dir/$target_name" ]; then
246
+ mv "$file" "$base_dir/" 2>/dev/null && log_success "Movido: $target_name"
247
+ fi
248
+ done
249
+ # Remover diretórios split_files vazios
250
+ find "$MODELS_DIR" -type d -name "split_files" -empty -delete 2>/dev/null
251
+ fi
252
+
253
+ return $failed_count
254
+ }
255
+
256
+ # Clonar ou atualizar repositório git
257
+ clone_or_update() {
258
+ local url="$1"
259
+ local dest="$2"
260
+ local node_name=$(basename "$dest")
261
+
262
+ # Timeout de 60 segundos para operações git
263
+ if [ -d "$dest/.git" ]; then
264
+ log_info "Atualizando $node_name..."
265
+ timeout 60 git -C "$dest" pull --ff-only 2>/dev/null || {
266
+ log_warn "Timeout ou erro ao atualizar $node_name"
267
+ return 0 # Não falhar, apenas avisar
268
+ }
269
+ else
270
+ log_info "Clonando $node_name..."
271
+ timeout 60 git clone --recursive --depth 1 "$url" "$dest" 2>/dev/null || {
272
+ log_warn "Falha ao clonar $node_name"
273
+ return 0 # Não falhar, apenas avisar
274
+ }
275
+ fi
276
+
277
+ # Instalar requirements se existir (com timeout)
278
+ if [ -f "$dest/requirements.txt" ]; then
279
+ timeout 120 python3 -m pip install --no-warn-script-location -q -r "$dest/requirements.txt" 2>/dev/null || {
280
+ log_warn "Falha ao instalar requirements para $node_name"
281
+ }
282
+ fi
283
+
284
+ return 0
285
+ }
286
+
287
+ # -----------------------------
288
+ # Instalação principal
289
+ # -----------------------------
290
+ echo ""
291
+ log_info "========================================="
292
+ log_info " ComfyUI + Wan 2.2 Setup (Fixed)"
293
+ log_info "========================================="
294
+ echo ""
295
+
296
+ # [1] Verificar e instalar dependências
297
+ log_info "[1/8] Verificando e instalando dependências..."
298
+
299
+ # Instalar aria2c do sistema se não existir
300
+ if ! command_exists aria2c; then
301
+ log_info "Instalando aria2c do sistema..."
302
+ apt-get update -qq && apt-get install -y -qq aria2 2>/dev/null
303
+ fi
304
+
305
+ for cmd in python3 git wget curl; do
306
+ if ! command_exists "$cmd"; then
307
+ log_error "Dependência faltando: $cmd"
308
+ exit 1
309
+ fi
310
+ done
311
+ log_success "Dependências OK"
312
+
313
+ # [2] Atualizar pip e instalar ferramentas
314
+ log_info "[2/8] Preparando ferramentas Python..."
315
+ python3 -m pip install --upgrade pip wheel setuptools -q
316
+
317
+ # Instalar huggingface_hub com CLI e hf_transfer para velocidade máxima
318
+ python3 -m pip install --upgrade "huggingface_hub[cli]>=0.26.0" hf_transfer comfy-cli -q
319
+
320
+ # Configurar token HF se disponível (opcional)
321
+ HF_TOKEN="${HF_TOKEN:-}"
322
+ if [ -n "$HF_TOKEN" ]; then
323
+ if huggingface-cli login --token "$HF_TOKEN" 2>/dev/null; then
324
+ log_success "Login HF configurado"
325
+ else
326
+ log_warn "Falha ao configurar login HF, continuando sem autenticação"
327
+ fi
328
+ fi
329
+
330
+ # Verificar se hf está disponível
331
+ if command_exists huggingface-cli; then
332
+ log_success "huggingface-cli disponível"
333
+ else
334
+ log_warn "huggingface-cli não encontrado"
335
+ fi
336
+
337
+ log_success "Ferramentas instaladas"
338
+
339
+ # [3] Instalar PyTorch com CUDA 12.8
340
+ log_info "[3/8] Instalando PyTorch com CUDA 12.8..."
341
+ python3 -m pip install --upgrade torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128
342
+ log_success "PyTorch com CUDA 12.8 instalado"
343
+
344
+ # [4] Instalar ComfyUI
345
+ log_info "[4/8] Instalando ComfyUI..."
346
+ if [ -f "$COMFY_DIR/main.py" ]; then
347
+ log_warn "ComfyUI já existe, pulando instalação base"
348
+ else
349
+ comfy --skip-prompt install --fast-deps --nvidia
350
+
351
+ # Verificar instalação
352
+ if [ ! -f "$COMFY_DIR/main.py" ]; then
353
+ log_error "ComfyUI não foi instalado corretamente!"
354
+ exit 1
355
+ fi
356
+ fi
357
+ log_success "ComfyUI instalado em: $COMFY_DIR"
358
+
359
+ # [5] Instalar SageAttention (wheel pré-compilada)
360
+ log_info "[5/8] Instalando SageAttention..."
361
+ if command_exists nvcc || python3 -c "import torch; print(torch.cuda.is_available())" 2>/dev/null | grep -q "True"; then
362
+ log_info "Instalando SageAttention pré-compilada..."
363
+ python3 -m pip install "https://huggingface.co/adbrasi/comfywheel/resolve/main/sageattention-2.2.0-cp311-cp311-linux_x86_64.whl" -q
364
+
365
+ # Verificar instalação
366
+ if python3 -c "import sageattention" 2>/dev/null; then
367
+ log_success "SageAttention instalado com sucesso"
368
+ else
369
+ log_warn "SageAttention instalado mas não pôde ser importado"
370
+ fi
371
+ else
372
+ log_warn "CUDA não detectado, pulando SageAttention"
373
+ fi
374
+
375
+ # [6] Baixar modelos
376
+ log_info "[6/8] Baixando modelos..."
377
+ mkdir -p "$MODELS_DIR"/{diffusion_models,loras,vae,text_encoders,clip_vision,controlnet,upscale_models}
378
+
379
+ # Verificar ferramentas de download
380
+ if command_exists aria2c; then
381
+ log_success "Usando aria2c para downloads (rápido)"
382
+ else
383
+ log_warn "aria2c não encontrado, usando wget/curl (mais lento)"
384
+ fi
385
+
386
+ # Processar downloads
387
+ if process_downloads; then
388
+ log_success "Todos os modelos baixados com sucesso"
389
+ else
390
+ log_warn "Alguns downloads falharam, mas continuando..."
391
+ fi
392
+
393
+ # [7] Instalar custom nodes
394
+ log_info "[7/8] Instalando custom nodes..."
395
+ CN_DIR="$COMFY_DIR/custom_nodes"
396
+ mkdir -p "$CN_DIR"
397
+
398
+ # Instalar nodes sequencialmente para evitar travamentos
399
+ for repo_url in "${CUSTOM_NODES[@]}"; do
400
+ node_name=$(basename "$repo_url")
401
+ clone_or_update "$repo_url" "$CN_DIR/$node_name"
402
+ done
403
+
404
+ log_success "Custom nodes instalados"
405
+
406
+ # [8] Verificação final
407
+ echo ""
408
+ log_info "[8/8] Verificando instalação..."
409
+
410
+ # Verificar arquivos principais
411
+ check_critical_files() {
412
+ local files=(
413
+ "$COMFY_DIR/main.py"
414
+ "$MODELS_DIR/diffusion_models/wan2.2_fun_control_low_noise_14B_fp8_scaled.safetensors"
415
+ "$MODELS_DIR/diffusion_models/wan2.2_fun_control_high_noise_14B_fp8_scaled.safetensors"
416
+ "$MODELS_DIR/vae/wan_2.1_vae.safetensors"
417
+ "$MODELS_DIR/text_encoders/umt5_xxl_fp16.safetensors"
418
+ )
419
+
420
+ local missing=0
421
+ for file in "${files[@]}"; do
422
+ if [ -f "$file" ]; then
423
+ log_success "✓ $(basename "$file")"
424
+ else
425
+ log_error "✗ $(basename "$file") não encontrado"
426
+ ((missing++))
427
+ fi
428
+ done
429
+
430
+ return $missing
431
+ }
432
+
433
+ if check_critical_files; then
434
+ log_success "Instalação concluída com sucesso!"
435
+ echo ""
436
+ log_info "========================================="
437
+ log_info "Iniciando ComfyUI..."
438
+ log_info "URL: http://localhost:$COMFY_PORT"
439
+ log_info "========================================="
440
+
441
+ # Tentar usar SageAttention se disponível
442
+ SAGE_FLAG=""
443
+ if python3 -c "import sageattention" 2>/dev/null; then
444
+ SAGE_FLAG="--use-sage-attention"
445
+ log_info "SageAttention habilitado"
446
+ fi
447
+
448
+ cd "$COMFY_DIR"
449
+ exec comfy launch -- $SAGE_FLAG --listen "$COMFY_HOST" --port "$COMFY_PORT"
450
+ else
451
+ log_error "Arquivos críticos faltando. Verifique os erros acima."
452
+
453
+ # Mostrar onde os arquivos podem estar
454
+ log_info "Procurando arquivos mal posicionados..."
455
+ find "$MODELS_DIR" -name "*.safetensors" -type f | head -20
456
+
457
+ exit 1
458
+ fi