Upload wanVideo2_2.sh
Browse files- 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
|