|
#!/bin/bash |
|
|
|
|
|
|
|
|
|
|
|
|
|
set -e |
|
set -o pipefail |
|
|
|
|
|
|
|
|
|
|
|
|
|
readonly INSTALL_BASE_DIR="$(pwd)" |
|
readonly WORKSPACE_DIR="$INSTALL_BASE_DIR/ComfyUI" |
|
readonly WORKFLOW_FILENAME="workflow.json" |
|
readonly WORKFLOW_FILE="$INSTALL_BASE_DIR/$WORKFLOW_FILENAME" |
|
readonly LOG_FILE="$INSTALL_BASE_DIR/install.log" |
|
|
|
|
|
readonly WORKFLOW_URL="https://huggingface.co/adbrasi/akarris_trainer/resolve/main/Wan_GenerationBase.json" |
|
|
|
|
|
|
|
|
|
|
|
log_info() { |
|
local msg="[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1" |
|
echo "$msg" | tee -a "$LOG_FILE" >&2 |
|
} |
|
|
|
log_warning() { |
|
local msg="[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" |
|
echo "$msg" | tee -a "$LOG_FILE" >&2 |
|
} |
|
|
|
log_error() { |
|
local msg="[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" |
|
echo "$msg" | tee -a "$LOG_FILE" >&2 |
|
} |
|
|
|
command_exists() { |
|
command -v "$1" >/dev/null 2>&1 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
check_requirements() { |
|
log_info "Verificando requisitos do sistema..." |
|
|
|
local missing_deps=() |
|
|
|
if ! command_exists python3; then |
|
missing_deps+=("python3") |
|
fi |
|
|
|
if ! command_exists git; then |
|
missing_deps+=("git") |
|
fi |
|
|
|
if ! command_exists gcc; then |
|
missing_deps+=("gcc/build-essential") |
|
fi |
|
|
|
if ! command_exists nvcc; then |
|
log_warning "CUDA toolkit (nvcc) não encontrado. A compilação do SageAttention pode falhar." |
|
fi |
|
|
|
if [ ${#missing_deps[@]} -gt 0 ]; then |
|
log_error "Dependências faltando: ${missing_deps[*]}" |
|
log_error "Por favor, instale as dependências e execute o script novamente." |
|
exit 1 |
|
fi |
|
|
|
|
|
local python_version=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') |
|
log_info "Python version: $python_version" |
|
|
|
if ! python3 -c 'import sys; exit(0 if sys.version_info >= (3,8) else 1)'; then |
|
log_error "Python 3.8 ou superior é necessário" |
|
exit 1 |
|
fi |
|
|
|
log_info "Todos os requisitos básicos estão presentes." |
|
} |
|
|
|
|
|
|
|
|
|
|
|
cleanup_existing_installation() { |
|
log_info "Verificando instalações existentes em: $WORKSPACE_DIR" |
|
|
|
if [ -d "$WORKSPACE_DIR" ]; then |
|
log_warning "Diretório existente encontrado: $WORKSPACE_DIR" |
|
read -p "Deseja remover a instalação existente? (s/n): " -n 1 -r |
|
echo |
|
if [[ $REPLY =~ ^[Ss]$ ]]; then |
|
log_info "Removendo a instalação existente..." |
|
rm -rf "$WORKSPACE_DIR" |
|
log_info "Diretório removido." |
|
else |
|
log_error "Instalação cancelada pelo usuário." |
|
exit 1 |
|
fi |
|
else |
|
log_info "Nenhuma instalação anterior encontrada." |
|
fi |
|
} |
|
|
|
|
|
|
|
|
|
|
|
install_comfy_cli() { |
|
log_info "Instalando/atualizando comfy-cli..." |
|
|
|
python3 -m pip install --upgrade pip |
|
python3 -m pip install --upgrade comfy-cli || { |
|
log_error "Falha ao instalar comfy-cli" |
|
return 1 |
|
} |
|
|
|
|
|
if [ -d "$HOME/.local/bin" ] && [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then |
|
export PATH="$HOME/.local/bin:$PATH" |
|
log_info "Adicionado $HOME/.local/bin ao PATH." |
|
fi |
|
|
|
if ! command_exists comfy; then |
|
log_error "Comando 'comfy' não encontrado no PATH." |
|
return 1 |
|
fi |
|
|
|
log_info "comfy-cli instalado: $(comfy --version 2>/dev/null || echo 'versão desconhecida')" |
|
return 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
install_comfyui() { |
|
log_info "Instalando ComfyUI em: $WORKSPACE_DIR" |
|
|
|
|
|
if ! comfy --workspace "$WORKSPACE_DIR" --skip-prompt install --nvidia; then |
|
log_error "Falha ao instalar ComfyUI" |
|
return 1 |
|
fi |
|
|
|
log_info "ComfyUI instalado com sucesso." |
|
return 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
install_hf_tools() { |
|
log_info "Instalando HuggingFace Hub e hf_transfer..." |
|
|
|
python3 -m pip install -U "huggingface_hub[cli,hf_transfer]" || { |
|
log_error "Falha ao instalar ferramentas HuggingFace" |
|
return 1 |
|
} |
|
|
|
|
|
export HF_HUB_ENABLE_HF_TRANSFER=1 |
|
|
|
log_info "HuggingFace tools instalados com sucesso." |
|
return 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
install_sageattention() { |
|
log_info "Instalando SageAttention 2.2.0 com 2++ (compilação otimizada)..." |
|
|
|
|
|
|
|
|
|
log_info "Instalando PyTorch 2.7.0 com CUDA 12.8..." |
|
|
|
python3 -m pip install torch==2.7.0 torchvision==0.22.0 torchaudio==2.7.0 --index-url https://download.pytorch.org/whl/cu128 || { |
|
log_error "Falha ao instalar PyTorch com CUDA 12.8" |
|
return 1 |
|
} |
|
|
|
|
|
log_info "Verificando instalação do PyTorch..." |
|
python3 -c "import torch; print(f'PyTorch version: {torch.__version__}'); print(f'CUDA available: {torch.cuda.is_available()}'); print(f'CUDA version: {torch.version.cuda if torch.cuda.is_available() else \"N/A\"}')" 2>&1 | tee -a "$LOG_FILE" |
|
|
|
local sage_dir="$INSTALL_BASE_DIR/SageAttention" |
|
|
|
|
|
if [ -d "$sage_dir" ]; then |
|
log_info "Removendo instalação anterior do SageAttention..." |
|
rm -rf "$sage_dir" |
|
fi |
|
|
|
|
|
log_info "Instalando dependências do SageAttention..." |
|
python3 -m pip install 'triton>=3.0.0,<3.1.0' packaging ninja || { |
|
log_error "Falha ao instalar dependências do SageAttention" |
|
return 1 |
|
} |
|
|
|
|
|
log_info "Clonando repositório SageAttention..." |
|
if ! git clone https://github.com/thu-ml/SageAttention.git "$sage_dir"; then |
|
log_error "Falha ao clonar repositório SageAttention" |
|
return 1 |
|
fi |
|
|
|
cd "$sage_dir" |
|
|
|
|
|
log_info "Configurando ambiente de compilação otimizada..." |
|
export EXT_PARALLEL=4 |
|
export NVCC_APPEND_FLAGS="--threads 8" |
|
export MAX_JOBS=32 |
|
export TORCH_CUDA_ARCH_LIST="8.9" |
|
|
|
|
|
if command_exists nvidia-smi; then |
|
local cuda_capability=$(nvidia-smi --query-gpu=compute_cap --format=csv,noheader | head -n1 | tr -d '.') |
|
if [ -n "$cuda_capability" ]; then |
|
log_info "Detectada capacidade CUDA: $cuda_capability" |
|
if [ "$cuda_capability" != "89" ]; then |
|
export TORCH_CUDA_ARCH_LIST="$TORCH_CUDA_ARCH_LIST;${cuda_capability:0:1}.${cuda_capability:1}" |
|
log_info "TORCH_CUDA_ARCH_LIST: $TORCH_CUDA_ARCH_LIST" |
|
fi |
|
fi |
|
fi |
|
|
|
|
|
log_info "Compilando SageAttention (5-10 minutos)..." |
|
if ! python3 setup.py install >> "$LOG_FILE" 2>&1; then |
|
log_error "Falha ao compilar SageAttention. Verifique $LOG_FILE" |
|
cd "$INSTALL_BASE_DIR" |
|
return 1 |
|
fi |
|
|
|
cd "$INSTALL_BASE_DIR" |
|
log_info "SageAttention 2.2.0 instalado com sucesso!" |
|
return 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
download_workflow() { |
|
log_info "Baixando o workflow..." |
|
|
|
|
|
if command_exists wget; then |
|
wget -U "Mozilla/5.0" -O "$WORKFLOW_FILE" "$WORKFLOW_URL" 2>&1 | tee -a "$LOG_FILE" |
|
elif command_exists curl; then |
|
curl -L -H "User-Agent: Mozilla/5.0" -o "$WORKFLOW_FILE" "$WORKFLOW_URL" 2>&1 | tee -a "$LOG_FILE" |
|
else |
|
log_error "wget ou curl não encontrado" |
|
return 1 |
|
fi |
|
|
|
if [ -f "$WORKFLOW_FILE" ] && [ -s "$WORKFLOW_FILE" ]; then |
|
log_info "Workflow baixado com sucesso." |
|
return 0 |
|
else |
|
log_error "Falha ao baixar o workflow." |
|
return 1 |
|
fi |
|
} |
|
|
|
|
|
|
|
|
|
|
|
download_models() { |
|
log_info "Iniciando download dos modelos Wan 2.2..." |
|
|
|
|
|
local dirs=( |
|
"$WORKSPACE_DIR/models/diffusion_models" |
|
"$WORKSPACE_DIR/models/loras" |
|
"$WORKSPACE_DIR/models/text_encoders" |
|
"$WORKSPACE_DIR/models/vae" |
|
"$WORKSPACE_DIR/models/clip_vision" |
|
) |
|
|
|
for dir in "${dirs[@]}"; do |
|
mkdir -p "$dir" |
|
log_info "Diretório criado/verificado: $dir" |
|
done |
|
|
|
|
|
export HF_HUB_ENABLE_HF_TRANSFER=1 |
|
|
|
|
|
log_info "Baixando modelos de difusão..." |
|
|
|
|
|
hf download "Comfy-Org/Wan_2.2_ComfyUI_Repackaged" \ |
|
"split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors" \ |
|
"split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors" \ |
|
--local-dir "$WORKSPACE_DIR/models" \ |
|
--cache-dir "$WORKSPACE_DIR/models/.cache" 2>&1 | tee -a "$LOG_FILE" |
|
|
|
log_info "Baixando LoRAs..." |
|
|
|
|
|
hf download "Comfy-Org/Wan_2.2_ComfyUI_Repackaged" \ |
|
"split_files/loras/wan2.2_i2v_lightx2v_4steps_lora_v1_high_noise.safetensors" \ |
|
"split_files/loras/wan2.2_i2v_lightx2v_4steps_lora_v1_low_noise.safetensors" \ |
|
"split_files/loras/wan2.2_t2v_lightx2v_4steps_lora_v1.1_high_noise.safetensors" \ |
|
"split_files/loras/wan2.2_t2v_lightx2v_4steps_lora_v1.1_low_noise.safetensors" \ |
|
--local-dir "$WORKSPACE_DIR/models" \ |
|
--cache-dir "$WORKSPACE_DIR/models/.cache" 2>&1 | tee -a "$LOG_FILE" |
|
|
|
log_info "Baixando Text Encoders..." |
|
|
|
|
|
hf download "Comfy-Org/Wan_2.2_ComfyUI_Repackaged" \ |
|
"split_files/text_encoders/umt5_xxl_fp16.safetensors" \ |
|
"split_files/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors" \ |
|
--local-dir "$WORKSPACE_DIR/models" \ |
|
--cache-dir "$WORKSPACE_DIR/models/.cache" 2>&1 | tee -a "$LOG_FILE" |
|
|
|
log_info "Baixando VAE..." |
|
|
|
|
|
hf download "Comfy-Org/Wan_2.1_ComfyUI_repackaged" \ |
|
"split_files/vae/wan_2.1_vae.safetensors" \ |
|
--local-dir "$WORKSPACE_DIR/models" \ |
|
--cache-dir "$WORKSPACE_DIR/models/.cache" 2>&1 | tee -a "$LOG_FILE" |
|
|
|
log_info "Baixando CLIP Vision..." |
|
|
|
|
|
hf download "Comfy-Org/Wan_2.1_ComfyUI_repackaged" \ |
|
"split_files/clip_vision/clip_vision_h.safetensors" \ |
|
--local-dir "$WORKSPACE_DIR/models" \ |
|
--cache-dir "$WORKSPACE_DIR/models/.cache" 2>&1 | tee -a "$LOG_FILE" |
|
|
|
|
|
log_info "Organizando arquivos de modelos..." |
|
|
|
|
|
if [ -d "$WORKSPACE_DIR/models/split_files/diffusion_models" ]; then |
|
mv "$WORKSPACE_DIR/models/split_files/diffusion_models/"*.safetensors "$WORKSPACE_DIR/models/diffusion_models/" 2>/dev/null || true |
|
fi |
|
|
|
|
|
if [ -d "$WORKSPACE_DIR/models/split_files/loras" ]; then |
|
mv "$WORKSPACE_DIR/models/split_files/loras/"*.safetensors "$WORKSPACE_DIR/models/loras/" 2>/dev/null || true |
|
fi |
|
|
|
|
|
if [ -d "$WORKSPACE_DIR/models/split_files/text_encoders" ]; then |
|
mv "$WORKSPACE_DIR/models/split_files/text_encoders/"*.safetensors "$WORKSPACE_DIR/models/text_encoders/" 2>/dev/null || true |
|
fi |
|
|
|
|
|
if [ -d "$WORKSPACE_DIR/models/split_files/vae" ]; then |
|
mv "$WORKSPACE_DIR/models/split_files/vae/"*.safetensors "$WORKSPACE_DIR/models/vae/" 2>/dev/null || true |
|
fi |
|
|
|
|
|
if [ -d "$WORKSPACE_DIR/models/split_files/clip_vision" ]; then |
|
mv "$WORKSPACE_DIR/models/split_files/clip_vision/"*.safetensors "$WORKSPACE_DIR/models/clip_vision/" 2>/dev/null || true |
|
fi |
|
|
|
|
|
rm -rf "$WORKSPACE_DIR/models/split_files" 2>/dev/null || true |
|
|
|
|
|
log_info "Verificando modelos baixados:" |
|
for dir in "${dirs[@]}"; do |
|
if [ -d "$dir" ]; then |
|
local count=$(ls -1 "$dir"/*.safetensors 2>/dev/null | wc -l) |
|
log_info " $(basename $(dirname "$dir"))/$(basename "$dir"): $count arquivo(s)" |
|
|
|
|
|
for file in "$dir"/*.safetensors; do |
|
if [ -f "$file" ]; then |
|
local size=$(du -h "$file" | cut -f1) |
|
log_info " - $(basename "$file") ($size)" |
|
fi |
|
done |
|
fi |
|
done |
|
|
|
return 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
install_custom_nodes_manually() { |
|
log_info "Instalando custom nodes manualmente..." |
|
|
|
local custom_nodes_dir="$WORKSPACE_DIR/custom_nodes" |
|
|
|
|
|
local custom_nodes=( |
|
"https://github.com/kijai/ComfyUI-WanVideoWrapper" |
|
"https://github.com/kijai/ComfyUI-MelBandRoFormer" |
|
"https://github.com/kijai/ComfyUI-KJNodes" |
|
"https://github.com/kijai/ComfyUI-Florence2" |
|
"https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite" |
|
"https://github.com/Fannovel16/ComfyUI-Frame-Interpolation" |
|
"https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit" |
|
"https://github.com/rdancer/ComfyUI_Florence2SAM2" |
|
"https://github.com/1038lab/ComfyUI-RMBG" |
|
"https://github.com/fpgaminer/joycaption_comfyui" |
|
"https://github.com/MieMieeeee/ComfyUI-CaptionThis" |
|
"https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes" |
|
"https://github.com/LAOGOU-666/Comfyui-Memory_Cleanup" |
|
"https://github.com/chrisgoringe/cg-use-everywhere" |
|
"https://github.com/pythongosssss/ComfyUI-Custom-Scripts" |
|
"https://github.com/chibiace/ComfyUI-Chibi-Nodes" |
|
"https://github.com/ptmaster/comfyui-audio-speed" |
|
"https://github.com/filliptm/ComfyUI_Fill-Nodes" |
|
"https://github.com/justUmen/Bjornulf_custom_nodes" |
|
"https://github.com/raindrop313/ComfyUI-WanVideoStartEndFrames" |
|
"https://github.com/ShmuelRonen/ComfyUI_wav2lip" |
|
"https://github.com/crystian/ComfyUI-Crystools" |
|
"https://github.com/bash-j/mikey_nodes" |
|
) |
|
|
|
cd "$custom_nodes_dir" |
|
|
|
for node_url in "${custom_nodes[@]}"; do |
|
local node_name=$(basename "$node_url" .git) |
|
log_info "Instalando: $node_name" |
|
|
|
|
|
if [ -d "$node_name" ]; then |
|
log_info " Removendo versão anterior..." |
|
rm -rf "$node_name" |
|
fi |
|
|
|
|
|
if git clone --depth 1 "$node_url" "$node_name" 2>&1 | tee -a "$LOG_FILE"; then |
|
log_info " Clone concluído: $node_name" |
|
|
|
|
|
if [ -f "$node_name/requirements.txt" ]; then |
|
log_info " Instalando dependências de $node_name..." |
|
python3 -m pip install -r "$node_name/requirements.txt" 2>&1 | tee -a "$LOG_FILE" || { |
|
log_warning " Algumas dependências de $node_name falharam" |
|
} |
|
fi |
|
|
|
|
|
if [ -f "$node_name/install.py" ]; then |
|
log_info " Executando install.py de $node_name..." |
|
cd "$node_name" |
|
python3 install.py 2>&1 | tee -a "$LOG_FILE" || { |
|
log_warning " install.py de $node_name retornou erro" |
|
} |
|
cd .. |
|
fi |
|
else |
|
log_warning " Falha ao clonar: $node_name" |
|
fi |
|
done |
|
|
|
cd "$INSTALL_BASE_DIR" |
|
log_info "Instalação de custom nodes concluída!" |
|
} |
|
|
|
|
|
|
|
|
|
|
|
verify_installation() { |
|
log_info "Verificando a instalação..." |
|
|
|
local issues=() |
|
|
|
|
|
if [ ! -d "$WORKSPACE_DIR" ]; then |
|
issues+=("Diretório ComfyUI não encontrado") |
|
fi |
|
|
|
|
|
if [ ! -f "$WORKFLOW_FILE" ]; then |
|
issues+=("Arquivo de workflow não encontrado") |
|
fi |
|
|
|
|
|
log_info "Verificando modelos instalados:" |
|
|
|
local expected_models=( |
|
"diffusion_models:2" |
|
"loras:4" |
|
"text_encoders:2" |
|
"vae:1" |
|
"clip_vision:1" |
|
) |
|
|
|
for expectation in "${expected_models[@]}"; do |
|
IFS=':' read -r dir_name expected_count <<< "$expectation" |
|
local dir="$WORKSPACE_DIR/models/$dir_name" |
|
|
|
if [ -d "$dir" ]; then |
|
local count=$(ls -1 "$dir"/*.safetensors 2>/dev/null | wc -l) |
|
log_info " $dir_name: $count arquivo(s) (esperado: $expected_count)" |
|
|
|
if [ $count -lt $expected_count ]; then |
|
issues+=("Faltam modelos em $dir_name ($count/$expected_count)") |
|
fi |
|
else |
|
issues+=("Diretório não existe: $dir_name") |
|
fi |
|
done |
|
|
|
|
|
log_info "Verificando PyTorch e CUDA:" |
|
if python3 -c "import torch; assert torch.cuda.is_available()" 2>/dev/null; then |
|
log_info "✓ PyTorch com CUDA instalado corretamente" |
|
else |
|
log_warning "PyTorch instalado mas CUDA não está disponível" |
|
fi |
|
|
|
|
|
if ! python3 -c "import sageattention" 2>/dev/null; then |
|
log_warning "SageAttention não está instalado (opcional)" |
|
else |
|
log_info "✓ SageAttention instalado corretamente" |
|
fi |
|
|
|
if [ ${#issues[@]} -gt 0 ]; then |
|
log_error "Problemas encontrados na instalação:" |
|
for issue in "${issues[@]}"; do |
|
log_error " ✗ $issue" |
|
done |
|
return 1 |
|
fi |
|
|
|
log_info "✓ Instalação verificada com sucesso!" |
|
return 0 |
|
} |
|
|
|
|
|
|
|
|
|
|
|
launch_comfyui() { |
|
log_info "=================================================" |
|
log_info "Instalação concluída com sucesso!" |
|
log_info "=================================================" |
|
log_info "" |
|
log_info "Iniciando ComfyUI..." |
|
log_info " Porta: 8818" |
|
log_info " Workspace: $WORKSPACE_DIR" |
|
log_info " Workflow: $WORKFLOW_FILE" |
|
log_info "" |
|
log_info "Para usar o workflow:" |
|
log_info " 1. Acesse http://127.0.0.1:8818" |
|
log_info " 2. Arraste o arquivo '$WORKFLOW_FILENAME' na interface" |
|
log_info "" |
|
log_info "Pressione Ctrl+C para parar o servidor" |
|
log_info "=================================================" |
|
|
|
|
|
local sage_args="" |
|
if python3 -c "import sageattention" 2>/dev/null; then |
|
sage_args="--use-sage-attention" |
|
log_info "SageAttention habilitado!" |
|
fi |
|
|
|
|
|
exec comfy --workspace "$WORKSPACE_DIR" launch -- \ |
|
--fast \ |
|
--listen 0.0.0.0 \ |
|
--port 8818 \ |
|
$sage_args \ |
|
--preview-method latent2rgb |
|
} |
|
|
|
|
|
|
|
|
|
|
|
main() { |
|
|
|
echo "=== Instalação ComfyUI iniciada em $(date) ===" > "$LOG_FILE" |
|
|
|
log_info "=================================================" |
|
log_info "Instalador ComfyUI com Wan 2.2 - v3.1" |
|
log_info "Com PyTorch 2.7.0 + CUDA 12.8" |
|
log_info "=================================================" |
|
|
|
|
|
check_requirements || exit 1 |
|
|
|
|
|
cleanup_existing_installation |
|
|
|
|
|
install_comfy_cli || exit 1 |
|
|
|
|
|
install_hf_tools || exit 1 |
|
|
|
|
|
install_comfyui || exit 1 |
|
|
|
|
|
download_workflow || log_warning "Workflow não foi baixado" |
|
|
|
|
|
install_custom_nodes_manually |
|
|
|
|
|
log_info "=================================================" |
|
log_info "Iniciando processos paralelos:" |
|
log_info " 1. Instalação do PyTorch + SageAttention (10-15 min)" |
|
log_info " 2. Download dos modelos Wan 2.2" |
|
log_info "=================================================" |
|
|
|
|
|
install_sageattention & |
|
local sage_pid=$! |
|
|
|
|
|
download_models & |
|
local models_pid=$! |
|
|
|
|
|
log_info "Aguardando conclusão dos processos paralelos..." |
|
log_info "Monitore o progresso em: $LOG_FILE" |
|
|
|
local both_done=false |
|
local sage_done=false |
|
local models_done=false |
|
|
|
while [ "$both_done" = false ]; do |
|
|
|
if [ "$sage_done" = false ]; then |
|
if ! ps -p $sage_pid > /dev/null 2>&1; then |
|
wait $sage_pid |
|
local sage_exit=$? |
|
sage_done=true |
|
if [ $sage_exit -eq 0 ]; then |
|
log_info "✓ PyTorch + SageAttention instalado com sucesso!" |
|
else |
|
log_warning "⚠ PyTorch/SageAttention pode não ter sido instalado corretamente" |
|
fi |
|
fi |
|
fi |
|
|
|
|
|
if [ "$models_done" = false ]; then |
|
if ! ps -p $models_pid > /dev/null 2>&1; then |
|
wait $models_pid |
|
local models_exit=$? |
|
models_done=true |
|
if [ $models_exit -eq 0 ]; then |
|
log_info "✓ Downloads dos modelos concluídos!" |
|
else |
|
log_warning "⚠ Alguns modelos podem não ter sido baixados" |
|
fi |
|
fi |
|
fi |
|
|
|
|
|
if [ "$sage_done" = true ] && [ "$models_done" = true ]; then |
|
both_done=true |
|
else |
|
sleep 10 |
|
if [ "$sage_done" = false ] && ps -p $sage_pid > /dev/null 2>&1; then |
|
echo -n "." |
|
fi |
|
if [ "$models_done" = false ] && ps -p $models_pid > /dev/null 2>&1; then |
|
echo -n "." |
|
fi |
|
fi |
|
done |
|
|
|
echo "" |
|
log_info "Todos os processos paralelos foram concluídos!" |
|
|
|
|
|
verify_installation || { |
|
log_error "A instalação teve problemas. Verifique o log em: $LOG_FILE" |
|
log_error "Você pode tentar executar o script novamente." |
|
exit 1 |
|
} |
|
|
|
|
|
launch_comfyui |
|
} |
|
|
|
|
|
|
|
|
|
|
|
cleanup_on_exit() { |
|
log_info "Interrompendo instalação..." |
|
|
|
jobs -p | xargs -r kill 2>/dev/null |
|
exit 1 |
|
} |
|
|
|
|
|
trap cleanup_on_exit INT TERM |
|
|
|
|
|
main "$@" |