#!/bin/bash # ============================================================================ # Instalador Dinâmico para ComfyUI # Instala o ComfyUI e suas dependências no diretório atual. # ============================================================================ set -e set -o pipefail # ============================================================================ # CONFIGURAÇÕES GLOBAIS # ============================================================================ # URL do workflow a ser baixado readonly WORKFLOW_URL="https://huggingface.co/adbrasi/testedownload/resolve/main/modo%20balanco3.json" # --- Caminhos Dinâmicos --- # Define o diretório de instalação como o diretório atual onde o script é executado readonly INSTALL_BASE_DIR="$(pwd)" # O ComfyUI será instalado em uma subpasta "ComfyUI" readonly WORKSPACE_DIR="$INSTALL_BASE_DIR/ComfyUI" # O arquivo de workflow será salvo na raiz do diretório de instalação readonly WORKFLOW_FILENAME="workflow.json" readonly WORKFLOW_FILE="$INSTALL_BASE_DIR/$WORKFLOW_FILENAME" # ============================================================================ # FUNÇÕES DE UTILIDADE # ============================================================================ log_info() { echo "INFO: $1" >&2 } log_warning() { echo "WARNING: $1" >&2 } log_error() { echo "ERROR: $1" >&2 } command_exists() { command -v "$1" >/dev/null 2>&1 } # ============================================================================ # FUNÇÃO DE LIMPEZA # ============================================================================ 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" log_info "Removendo a instalação existente para evitar conflitos..." rm -rf "$WORKSPACE_DIR" log_info "Diretório removido." else log_info "Nenhuma instalação anterior encontrada no local. Continuando..." fi } # ============================================================================ # INSTALAÇÃO DO COMFY-CLI # ============================================================================ install_comfy_cli() { log_info "Instalando/atualizando comfy-cli..." python3 -m pip install --upgrade comfy-cli || { log_error "Falha ao instalar comfy-cli" exit 1 } # Verifica se o 'comfy' está no PATH if ! command_exists comfy; then if [ -d "$HOME/.local/bin" ] && [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then export PATH="$HOME/.local/bin:$PATH" log_info "Adicionado $HOME/.local/bin ao PATH para esta sessão." fi if ! command_exists comfy; then log_error "Comando 'comfy' não encontrado no PATH após a instalação." log_error "Verifique se '$HOME/.local/bin' está em seu PATH." exit 1 fi fi log_info "comfy-cli version: $(comfy --version 2>/dev/null || echo 'desconhecida')" } # ============================================================================ # INSTALAÇÃO DO COMFYUI # ============================================================================ install_comfyui() { log_info "Instalando ComfyUI em: $WORKSPACE_DIR" # Instala ComfyUI com dependências rápidas comfy --workspace "$WORKSPACE_DIR" --skip-prompt install --nvidia || { log_error "Falha ao instalar ComfyUI" exit 1 } log_info "ComfyUI instalado com sucesso." } # ============================================================================ # INSTALAÇÃO DO HUGGINGFACE HUB E HF_TRANSFER # ============================================================================ install_hf_tools() { log_info "Instalando HuggingFace Hub CLI e hf_transfer..." python3 -m pip install -U "huggingface_hub[cli]" || { log_error "Falha ao instalar huggingface_hub[cli]" exit 1 } python3 -m pip install hf_transfer || { log_error "Falha ao instalar hf_transfer" exit 1 } log_info "HuggingFace tools instalados com sucesso." } # ============================================================================ # DOWNLOAD DO WORKFLOW # ============================================================================ download_workflow() { log_info "Baixando o workflow de: $WORKFLOW_URL" log_info "Salvando como: $WORKFLOW_FILE" local success=false # Tenta diferentes métodos de download if command_exists wget; then if wget -q --show-progress -O "$WORKFLOW_FILE" "$WORKFLOW_URL"; then success=true fi elif command_exists curl; then if curl -L -o "$WORKFLOW_FILE" "$WORKFLOW_URL"; then success=true fi elif command_exists aria2c; then # aria2c precisa do nome do arquivo e diretório separados if aria2c -q -o "$(basename "$WORKFLOW_FILE")" -d "$(dirname "$WORKFLOW_FILE")" "$WORKFLOW_URL"; then success=true fi else log_error "Nenhuma ferramenta de download disponível (wget, curl ou aria2c)." exit 1 fi if ! $success; then log_error "Falha ao baixar o arquivo do workflow." exit 1 fi if [ ! -f "$WORKFLOW_FILE" ]; then log_error "O arquivo do workflow não foi baixado com sucesso." exit 1 fi log_info "Workflow baixado com sucesso." } # ============================================================================ # DEPENDÊNCIAS DO WORKFLOW # ============================================================================ install_workflow_dependencies() { log_info "Instalando dependências do workflow a partir de: $WORKFLOW_FILE" if [ ! -f "$WORKFLOW_FILE" ]; then log_error "Arquivo de workflow não encontrado: $WORKFLOW_FILE" exit 1 fi # Usa o workspace correto para instalar as dependências comfy --workspace "$WORKSPACE_DIR" node install-deps --workflow="$WORKFLOW_FILE" || { log_warning "Algumas dependências do workflow podem ter falhado ao instalar." log_info "Isso pode ser normal. O ComfyUI mostrará os nós ausentes ao iniciar." } log_info "Instalação de dependências do workflow concluída." } # ============================================================================ # INSTALAÇÃO DO CUSTOM NODE WANVIDEOWRAPPER # ============================================================================ install_wanvideo_wrapper() { log_info "Instalando custom node ComfyUI-WanVideoWrapper..." local custom_nodes_dir="$WORKSPACE_DIR/custom_nodes" local wrapper_dir="$custom_nodes_dir/ComfyUI-WanVideoWrapper" # Cria diretório de custom_nodes se não existir mkdir -p "$custom_nodes_dir" # Clone do repositório if [ -d "$wrapper_dir" ]; then log_warning "Diretório ComfyUI-WanVideoWrapper já existe, removendo..." rm -rf "$wrapper_dir" fi cd "$custom_nodes_dir" git clone https://github.com/kijai/ComfyUI-WanVideoWrapper.git || { log_error "Falha ao clonar ComfyUI-WanVideoWrapper" exit 1 } # Instala dependências if [ -f "$wrapper_dir/requirements.txt" ]; then log_info "Instalando dependências do ComfyUI-WanVideoWrapper..." python3 -m pip install -r "$wrapper_dir/requirements.txt" || { log_warning "Algumas dependências do WanVideoWrapper podem ter falhado" } fi # Volta para o diretório base cd "$INSTALL_BASE_DIR" log_info "ComfyUI-WanVideoWrapper instalado com sucesso." } # ============================================================================ # CRIAÇÃO DE DIRETÓRIOS DE MODELOS # ============================================================================ create_model_directories() { log_info "Criando diretórios para modelos..." mkdir -p "$WORKSPACE_DIR/models/diffusion_models" mkdir -p "$WORKSPACE_DIR/models/clip_vision" mkdir -p "$WORKSPACE_DIR/models/vae" mkdir -p "$WORKSPACE_DIR/models/text_encoders" mkdir -p "$WORKSPACE_DIR/models/loras" log_info "Diretórios de modelos criados." } # ============================================================================ # INSTALAÇÃO DO SAGEATTENTION (OTIMIZADO PARA EXECUTAR PRIMEIRO EM BACKGROUND) # ============================================================================ install_sageattention() { log_info "Iniciando instalação do SageAttention em background (otimizado)..." ( log_info "Clonando repositório SageAttention..." if [ -d "SageAttention" ]; then rm -rf SageAttention fi git clone https://github.com/thu-ml/SageAttention.git cd SageAttention log_info "Instalando SageAttention (isso pode demorar 5+ minutos)..." python3 setup.py install log_info "SageAttention instalado com sucesso!" # Criar arquivo de flag para indicar que a instalação terminou touch "$INSTALL_BASE_DIR/.sageattention_ready" ) & local sage_pid=$! log_info "Instalação do SageAttention iniciada em background. PID: $sage_pid" return 0 } # ============================================================================ # DOWNLOAD DE MODELOS COM HF_TRANSFER # ============================================================================ download_hf_models() { log_info "Iniciando downloads de modelos do HuggingFace em paralelo..." local pids=() # Downloads usando HuggingFace CLI local hf_cli_downloads=( "Comfy-Org/Wan_2.1_ComfyUI_repackaged:split_files/diffusion_models/wan2.1_i2v_720p_14B_fp16.safetensors:$WORKSPACE_DIR/models/diffusion_models/" "Comfy-Org/Wan_2.1_ComfyUI_repackaged:split_files/clip_vision/clip_vision_h.safetensors:$WORKSPACE_DIR/models/clip_vision/" "Comfy-Org/Wan_2.1_ComfyUI_repackaged:split_files/vae/wan_2.1_vae.safetensors:$WORKSPACE_DIR/models/vae/" ) # Downloads diretos via URL local direct_downloads=( "https://huggingface.co/Comfy-Org/Wan_2.1_ComfyUI_repackaged/resolve/main/split_files/text_encoders/umt5_xxl_fp16.safetensors:$WORKSPACE_DIR/models/text_encoders/" "https://huggingface.co/Kijai/WanVideo_comfy/resolve/main/Wan21_CausVid_14B_T2V_lora_rank32_v2.safetensors:$WORKSPACE_DIR/models/loras/" "https://huggingface.co/Kijai/WanVideo_comfy/resolve/main/Wan21_T2V_14B_lightx2v_cfg_step_distill_lora_rank32.safetensors:$WORKSPACE_DIR/models/loras/" ) # Processa downloads HF CLI for download in "${hf_cli_downloads[@]}"; do IFS=':' read -r repo file dest <<< "$download" log_info "Iniciando download HF: $repo/$file -> $dest" ( cd "$dest" HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$repo" "$file" --local-dir . --local-dir-use-symlinks False log_info "Concluído: $repo/$file" ) & pids+=($!) done # Processa downloads diretos for download in "${direct_downloads[@]}"; do IFS=':' read -r url dest <<< "$download" log_info "Iniciando download direto: $url -> $dest" ( cd "$dest" if command_exists wget; then wget "$url" --content-disposition elif command_exists curl; then curl -L -O "$url" else log_error "Nenhuma ferramenta de download disponível" exit 1 fi log_info "Concluído download direto: $url" ) & pids+=($!) done log_info "Downloads do HuggingFace iniciados em paralelo. PIDs: ${pids[*]}" return 0 } # ============================================================================ # DOWNLOAD DE MODELOS DO CIVITAI # ============================================================================ download_civitai_models() { log_info "Iniciando downloads do CivitAI em paralelo..." local civitai_downloads=( "https://civitai.com/api/download/models/1516994?type=Model&format=SafeTensor" ) local pids=() for url in "${civitai_downloads[@]}"; do log_info "Iniciando download: $url" # Download em background ( cd "$WORKSPACE_DIR/models/loras" wget "$url" --content-disposition log_info "Concluído download do CivitAI: $url" ) & pids+=($!) done log_info "Downloads do CivitAI iniciados. PIDs: ${pids[*]}" return 0 } # ============================================================================ # AGUARDAR DOWNLOADS # ============================================================================ wait_for_downloads() { log_info "Aguardando conclusão dos downloads..." # Aguarda todos os processos filhos (downloads) for job in $(jobs -p); do if kill -0 "$job" 2>/dev/null; then log_info "Aguardando processo: $job" wait "$job" fi done log_info "Todos os downloads foram concluídos." } # ============================================================================ # AGUARDAR SAGEATTENTION # ============================================================================ wait_for_sageattention() { log_info "Verificando instalação do SageAttention..." # Aguarda até que o arquivo de flag seja criado while [ ! -f "$INSTALL_BASE_DIR/.sageattention_ready" ]; do log_info "SageAttention ainda instalando... aguardando 30 segundos" sleep 30 done # Remove o arquivo de flag rm -f "$INSTALL_BASE_DIR/.sageattention_ready" log_info "SageAttention está pronto!" } # ============================================================================ # INICIAR O COMFYUI # ============================================================================ launch_comfyui() { log_info "Iniciando ComfyUI na porta 8818 com SageAttention e preview latent2rgb..." log_info "Workspace do ComfyUI: $WORKSPACE_DIR" log_info "Arquivo de workflow disponível em: $WORKFLOW_FILE" log_info "Para usar o workflow, arraste e solte o arquivo '$WORKFLOW_FILENAME' na interface do ComfyUI." log_info "Acesse o ComfyUI em: http://127.0.0.1:8818 (ou o IP da sua máquina)" # Inicia o ComfyUI com SageAttention e preview latent2rgb exec comfy --workspace "$WORKSPACE_DIR" launch -- --fast --listen 0.0.0.0 --port 8818 --use-sage-attention --preview-method latent2rgb } # ============================================================================ # EXECUÇÃO PRINCIPAL # ============================================================================ main() { # Passo 8: OTIMIZAÇÃO - Iniciar SageAttention PRIMEIRO (processo mais longo) log_info "=================================================" log_info "Iniciando SageAttention em background (processo mais longo - ~5+ minutos)..." log_info "Enquanto isso, continuaremos com as outras instalações..." log_info "=================================================" install_sageattention log_info "Iniciando instalação dinâmica do ComfyUI..." log_info "Diretório de instalação base: $INSTALL_BASE_DIR" log_info "=================================================" # Passo 1: Limpar instalações existentes no diretório alvo cleanup_existing_installation # Passo 2: Instalar comfy-cli install_comfy_cli # Passo 3: Instalar HuggingFace tools install_hf_tools # Passo 4: Instalar ComfyUI install_comfyui # Passo 5: Criar diretórios de modelos create_model_directories # Passo 6: Baixar o workflow download_workflow # Passo 7: Instalar dependências do workflow install_workflow_dependencies # Passo 9: Instalar custom node WanVideoWrapper install_wanvideo_wrapper # Passo 10: Iniciar downloads paralelos enquanto SageAttention instala log_info "=================================================" log_info "Iniciando downloads paralelos enquanto SageAttention instala..." log_info "=================================================" download_hf_models download_civitai_models # Passo 11: Aguardar downloads wait_for_downloads # Passo 12: Aguardar SageAttention (que provavelmente ainda estará rodando) wait_for_sageattention # Passo 13: Iniciar o ComfyUI log_info "=================================================" log_info "Instalação concluída com sucesso!" log_info "=================================================" launch_comfyui } # ============================================================================ # EXECUÇÃO DO SCRIPT # ============================================================================ # Captura interrupções (Ctrl+C) trap 'log_error "Script interrompido pelo usuário."; kill $(jobs -p) 2>/dev/null; exit 1' INT TERM # Executa a função principal main "$@"