├── K3U_GUI.bat ├── README.md ├── K3U_emebeded_GUI.bat ├── k3u_config_file ├── k3u_Comfyui_Embedded.k3u ├── k3u_embedded_Wan_cu128.k3u ├── k3u_Comfyui_venv_StableNightly.k3u └── k3u_Comfyui_venv_allPyton.k3u ├── LICENSE └── k3u_installer_gui.py /K3U_GUI.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | REM Determine the current directory of the batch script 5 | set "SCRIPT_DIR=%~dp0" 6 | 7 | REM Define the name of the GUI Python script 8 | set "GUI_SCRIPT=%SCRIPT_DIR%k3u_installer_gui.py" 9 | 10 | echo Checking for GUI script: %GUI_SCRIPT% 11 | if not exist "%GUI_SCRIPT%" ( 12 | echo ERROR: GUI script '%GUI_SCRIPT%' not found. 13 | echo Make sure the Python script is located in this same folder. 14 | pause 15 | exit /b 1 16 | ) 17 | 18 | echo Starting K3U Installer GUI using system Python (from PATH)... 19 | echo Make sure the Python in PATH has Tkinter installed. 20 | echo. 21 | 22 | REM Run the GUI script using Python found in the system PATH 23 | python "%GUI_SCRIPT%" 24 | 25 | REM Alternative (more explicit on Windows, usually equivalent): 26 | REM python.exe "%GUI_SCRIPT%" 27 | 28 | echo. 29 | echo GUI script finished. 30 | pause 31 | 32 | endlocal 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 🌟 **K3U Installer v2 Beta** 2 | 3 | 🔧 Flexible & Visual ComfyUI Installer 4 | 5 | K3U Installer is a desktop GUI tool designed to simplify and automate the installation of ComfyUI with flexible setups. 6 | 7 | This is a configurable and scriptable installer that reads .k3u files to create full environments, clone repos, install PyTorch, CUDA, Triton, SageAttention, and more. 8 | Perfect for both first-time users and advanced developers who want version control and automation. 9 | 10 | 🖼️ What’s New in v2 Beta? 11 | Complete GUI redesign (Tkinter-based) 12 | 13 | Full automation for: 14 | 15 | Virtual environments (external_venv) 16 | 17 | Updates for embedded Python installs (embedded) 18 | 19 | Rich preview and logging system with real-time feedback 20 | 21 | Summary step with version choices (e.g. Triton Stable/Nightly, Sage v1/v2) 22 | 23 | Auto-creation of launch/update scripts (.bat) 24 | 25 | Prepackaged .k3u configurations for various Python/CUDA/PyTorch versions 26 | 27 | ⚙️ Features 28 | 🔧 Flexible JSON-based configs (.k3u) 29 | Define installation logic step-by-step. Includes variables, setup types, conditionals, and user choices. 30 | 31 | 🖥️ GUI-based installer (no terminal needed) 32 | Just double-click to run the GUI. Works with both: 33 | 34 | K3U_GUI.bat: Uses system Python 35 | 36 | K3U_emebeded_GUI.bat: Uses embedded Python (included separately) 37 | 38 | 📜 Setup scripts generator 39 | Automatically generates .bat files to run or update ComfyUI with custom options. 40 | 41 | 🧠 Advanced components supported 42 | 43 | Triton: choose between Stable/Nightly 44 | 45 | SageAttention: v1 (pip) or v2 (from source, requires PyTorch >=2.7) 46 | 47 | OnnxRuntime, Diffusers, Transformers, Accelerate, Ninja, etc. 48 | 49 | 📦 Included Configs (.k3u files): 50 | 51 | k3u_Comfyui_venv_StableNightly.k3u 52 | 53 | Full setups for Python 3.12, CUDA 12.4/12.6, PyTorch Stable/Nightly with choice of Triton/Sage. 54 | 55 | k3u_Comfyui_venv_allPyton.k3u 56 | 57 | Covers Python 3.10, 3.11, 3.12, 3.13 — various compatible toolchains. 58 | 59 | k3u_Comfyui_Embedded.k3u 60 | 61 | Designed to update ComfyUI installs that run with embedded Python. 62 | 63 | ▶️ How to Use 64 | Download or clone this repository 65 | 66 | Choose how to launch: 67 | 68 | K3U_GUI.bat (uses your Python from PATH) 69 | 70 | K3U_emebeded_GUI.bat (if you use embedded Python) 71 | 72 | Run the GUI and: 73 | 74 | Select base installation folder 75 | 76 | Select Python.exe (if required) 77 | 78 | Choose a .k3u configuration 79 | 80 | Choose the desired setup (e.g., Stable/Nightly + Triton/Sage options) 81 | 82 | Click "Summary and Start" to preview all actions 83 | 84 | Confirm and watch the logs and progress bar 85 | 86 | 🔍 Screenshots 87 | 88 | ![1](https://github.com/user-attachments/assets/ce2ce699-f44e-44a7-a3f5-40f3b6f6c469) 89 | 90 | ![2](https://github.com/user-attachments/assets/05391d97-b84f-4fc6-bd5e-0a43d62c6886) 91 | 92 | ![k3u](https://github.com/user-attachments/assets/d819a357-0430-4ef9-adfb-3945fb6d1653) 93 | 94 | ![k3u3](https://github.com/user-attachments/assets/dc045c3b-f84e-47fa-bfb3-88f90dd54bdc) 95 | 96 | 97 | Copyright [2025] Karma3u 98 | 📜 License 99 | Licensed under the Apache License 2.0. 100 | You are free to use, distribute, and modify this tool in personal and commercial projects. 101 | 102 | See LICENSE for full details. 103 | 104 | 💬 Feedback / Issues 105 | Found a bug? Have a suggestion? 106 | Please open an issue or contribute via pull requests. 107 | 108 | -------------------------------------------------------------------------------- /K3U_emebeded_GUI.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | REM --- Path Configuration --- 5 | REM Determine the current directory of the batch script 6 | set "SCRIPT_DIR=%~dp0" 7 | REM Remove trailing backslash (\) if present for consistency 8 | if "%SCRIPT_DIR:~-1%"=="\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%" 9 | 10 | REM Define the embedded Python directory and executable 11 | set "EMBEDDED_PYTHON_DIR=%SCRIPT_DIR%\python_embeded" 12 | set "EMBEDDED_PYTHON=%EMBEDDED_PYTHON_DIR%\python.exe" 13 | 14 | REM Define the path to the get-pip.py script 15 | set "GET_PIP_SCRIPT=%EMBEDDED_PYTHON_DIR%\get-pip.py" 16 | 17 | REM Define the name of the GUI Python script 18 | set "GUI_SCRIPT=%SCRIPT_DIR%\k3u_installer_gui.py" 19 | 20 | REM --- Check for Embedded Python --- 21 | echo Checking for Python executable: %EMBEDDED_PYTHON% 22 | if not exist "%EMBEDDED_PYTHON%" ( 23 | echo ERROR: Python executable not found in %EMBEDDED_PYTHON_DIR% 24 | echo Make sure the 'python_embeded' folder exists here and contains python.exe 25 | pause 26 | exit /b 1 27 | ) 28 | 29 | REM --- Install/Update Python Dependencies --- 30 | echo. 31 | echo Starting installation/update of dependencies for embedded Python... 32 | echo Target folder: %EMBEDDED_PYTHON_DIR% 33 | echo. 34 | 35 | REM 1. Install/Update pip using get-pip.py 36 | echo Checking for get-pip.py: %GET_PIP_SCRIPT% 37 | if not exist "%GET_PIP_SCRIPT%" ( 38 | echo ERROR: Script 'get-pip.py' not found in %EMBEDDED_PYTHON_DIR% 39 | echo Download it from https://bootstrap.pypa.io/get-pip.py and place it in that folder. 40 | pause 41 | exit /b 1 42 | ) 43 | echo Running get-pip.py to install/update pip... 44 | "%EMBEDDED_PYTHON%" "%GET_PIP_SCRIPT%" --target "%EMBEDDED_PYTHON_DIR%" --no-warn-script-location 45 | if errorlevel 1 ( 46 | echo ERROR: Failed during get-pip.py execution. 47 | pause 48 | exit /b 1 49 | ) 50 | 51 | REM 2. Install/Update setuptools 52 | echo Installing/Updating setuptools... 53 | "%EMBEDDED_PYTHON%" -m pip install --upgrade setuptools --target "%EMBEDDED_PYTHON_DIR%" --no-warn-script-location 54 | if errorlevel 1 ( 55 | echo ERROR: Failed during setuptools installation. 56 | pause 57 | exit /b 1 58 | ) 59 | 60 | REM 3. Install/Update tkinter-embed 61 | echo Installing/Updating tkinter-embed... 62 | "%EMBEDDED_PYTHON%" -m pip install --upgrade tkinter-embed --target "%EMBEDDED_PYTHON_DIR%" --no-warn-script-location 63 | if errorlevel 1 ( 64 | echo ERROR: Failed during tkinter-embed installation. 65 | pause 66 | exit /b 1 67 | ) 68 | 69 | echo. 70 | echo Dependency installation completed successfully. 71 | echo. 72 | 73 | REM Determine the current directory of the batch script 74 | set "SCRIPT_DIR=%~dp0" 75 | 76 | REM Define the relative path to the embedded Python 77 | set "EMBEDDED_PYTHON=%SCRIPT_DIR%python_embeded\python.exe" 78 | 79 | REM Define the name of the GUI Python script 80 | set "GUI_SCRIPT=%SCRIPT_DIR%k3u_installer_gui.py" 81 | 82 | echo Checking for Embedded Python executable: %EMBEDDED_PYTHON% 83 | if not exist "%EMBEDDED_PYTHON%" ( 84 | echo ERROR: Embedded Python executable not found. 85 | echo Make sure the 'python_embeded' folder exists here and contains python.exe 86 | pause 87 | exit /b 1 88 | ) 89 | 90 | echo Checking for GUI script: %GUI_SCRIPT% 91 | if not exist "%GUI_SCRIPT%" ( 92 | echo ERROR: GUI script '%GUI_SCRIPT%' not found. 93 | echo Make sure the Python script is in this same folder. 94 | pause 95 | exit /b 1 96 | ) 97 | 98 | echo Launching K3U Installer GUI using Embedded Python... 99 | echo. 100 | 101 | REM Run the GUI script using embedded Python 102 | "%EMBEDDED_PYTHON%" "%GUI_SCRIPT%" 103 | 104 | echo. 105 | echo GUI script has finished. 106 | pause 107 | 108 | endlocal 109 | -------------------------------------------------------------------------------- /k3u_config_file/k3u_Comfyui_Embedded.k3u: -------------------------------------------------------------------------------- 1 | { 2 | "k3u_type": "embedded", 3 | "placeholders_info": { 4 | "{INSTALL_PATH}": "Base folder where 'python_embeded' and 'ComfyUI' are located.", 5 | "{EMBEDDED_PYTHON_DIR}": "Embedded Python folder (derived: {INSTALL_PATH}\\python_embeded).", 6 | "{EMBEDDED_PYTHON_EXE}": "Embedded Python executable (derived: {EMBEDDED_PYTHON_DIR}\\python.exe).", 7 | "{COMFYUI_PATH}": "ComfyUI folder (derived: {INSTALL_PATH}\\ComfyUI)." 8 | }, 9 | "setups": { 10 | "Update_ComfyUI_EmbedPy312_CUDA126": { 11 | "description": "Update ComfyUI and dependencies for Python 3.12 Embedded and PyTorch (CUDA 12.6).", 12 | "info": "Assumes existence of python_embeded. Updates pip, PyTorch (CUDA 12.6), Triton, SageAttention, ComfyUI, nodes.", 13 | "python_version_target": "3.12", 14 | "cuda_version_target": "12.6", 15 | "steps": [ 16 | {"key": "prequire1", "step_data": [ 17 | {"name": "Check Embedded Python Existence", "command": "if exist \"{EMBEDDED_PYTHON_EXE}\" (echo OK) else (echo ERROR: Embedded Python not found in {EMBEDDED_PYTHON_EXE} && exit /b 1)"}, 18 | {"name": "Check ComfyUI Existence", "command": "if exist \"{COMFYUI_PATH}\\main.py\" (echo OK) else (echo WARNING: ComfyUI folder not found in {COMFYUI_PATH}, git pull will fail. && timeout /t 5)"}, 19 | {"name": "Check Curl", "command": "where curl"}, 20 | {"name": "Check Tar", "command": "where tar"}, 21 | {"name": "Check Git", "command": "where git"} 22 | ]}, 23 | {"key": "update_pip", "step_data": [ 24 | {"name": "Update Pip", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade pip"} 25 | ]}, 26 | {"key": "install_include_libs", "step_data": [ 27 | {"name": "Download Python 3.12 Include/Libs (zip)", "command": "curl -L \"https://github.com/woct0rdho/triton-windows/releases/download/v3.0.0-windows.post1/python_3.12.7_include_libs.zip\" -o \"{INSTALL_PATH}\\py_libs.zip\""}, 28 | {"name": "Extract Include/Libs", "command": "tar -xf \"{INSTALL_PATH}\\py_libs.zip\" -C \"{EMBEDDED_PYTHON_DIR}\""}, 29 | {"name": "Clean downloaded file (libs zip)", "command": "del \"{INSTALL_PATH}\\py_libs.zip\""} 30 | ]}, 31 | {"key": "install_base_deps", "step_data": [ 32 | {"name": "Install/Update Accelerate", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade \"accelerate >= 1.1.1\""}, 33 | {"name": "Install/Update Diffusers", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade \"diffusers >= 0.31.0\""}, 34 | {"name": "Install/Update Transformers", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade \"transformers >= 4.39.3\""} 35 | ]}, 36 | {"key": "install_pytorch", "step_data": [ 37 | {"name": "Install/Update PyTorch (CUDA 12.6)", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126"} 38 | ]}, 39 | {"key": "install_triton", "step_data": [ 40 | {"name": "Install/Update Triton 3.2.0 (Py3.12)", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp312-cp312-win_amd64.whl"}, 41 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 42 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 43 | ]}, 44 | {"key": "update_comfyui", "step_data": [ 45 | {"name": "Update ComfyUI Repository", "command": "cd /d \"{COMFYUI_PATH}\" && git fetch origin && git checkout master && git reset --hard origin/master"} 46 | ]}, 47 | {"key": "install_comfy_reqs", "step_data": [ 48 | {"name": "Install/Update ComfyUI requirements.txt", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade -r \"{COMFYUI_PATH}\\requirements.txt\""} 49 | ]}, 50 | {"key": "install_other_deps", "step_data": [ 51 | {"name": "Install/Update OnnxRuntime-GPU", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade onnxruntime-gpu"}, 52 | {"name": "Install/Update Wheel", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade wheel"}, 53 | {"name": "Install/Update Setuptools", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade setuptools"}, 54 | {"name": "Install/Update Packaging", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade packaging"}, 55 | {"name": "Install/Update Ninja", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade ninja"} 56 | ]}, 57 | {"key": "install_sage", "step_data": [ 58 | {"name": "Clone SageAttention (if it doesn't exist)", "command": "if not exist \"{INSTALL_PATH}\\temp_sage\" git clone https://github.com/thu-ml/SageAttention \"{INSTALL_PATH}\\temp_sage\""}, 59 | {"name": "Update SageAttention", "command": "if exist \"{INSTALL_PATH}\\temp_sage\\.git\" ( cd /d \"{INSTALL_PATH}\\temp_sage\" && git pull )"}, 60 | {"name": "Install/Update SageAttention", "command": "cd /d \"{INSTALL_PATH}\\temp_sage\" && \"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade ."}, 61 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{INSTALL_PATH}\\temp_sage\""} 62 | ]}, 63 | {"key": "update_nodes", "step_data": [ 64 | {"name": "Update/Clone ComfyUI-Manager", "command": "if exist \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\\.git\" ( cd /d \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\" && git pull ) else ( git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\" )"}, 65 | {"name": "Update/Clone ComfyUI-Crystools", "command": "if exist \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\\.git\" ( cd /d \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\" && git pull ) else ( git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\" )"} 66 | ]} 67 | ] 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /k3u_config_file/k3u_embedded_Wan_cu128.k3u: -------------------------------------------------------------------------------- 1 | { 2 | "k3u_type": "embedded", 3 | "placeholders_info": { 4 | "{INSTALL_PATH}": "Base folder where 'python_embeded' and the repository folder will be created.", 5 | "{EMBEDDED_PYTHON_DIR}": "Embedded Python folder (derived: {INSTALL_PATH}\\python_embeded).", 6 | "{EMBEDDED_PYTHON_EXE}": "Embedded Python executable (derived: {EMBEDDED_PYTHON_DIR}\\python.exe).", 7 | "{REPO_PATH}": "Path to the main repository folder (derived: {INSTALL_PATH}\\[repo_subdir])." 8 | }, 9 | "setups": { 10 | "ComfyUI_Embed_Custom_Py312_cu128": { 11 | "description": "Custom ComfyUI setup with Embedded Python 3.12, PyTorch Nightly (CUDA 12.8), Nightly Triton, Sage v1, and multiple custom nodes.", 12 | "info": "Installs VS Build Tools, PyTorch, Triton, Sage, ComfyUI, Manager, VHS, KJNodes, Essentials, Frame Interp, MultiGPU, AdaptiveGuidance, GGUF, WanVideoWrapper.", 13 | "python_version_target": "3.12", 14 | "cuda_version_target": "12.8", 15 | "pytorch_type": "Nightly", 16 | "repo_subdir": "ComfyUI", 17 | "steps": [ 18 | {"key": "prequire_system", "step_data": [ 19 | {"name": "Check Curl", "command": "where curl"}, 20 | {"name": "Check Tar", "command": "where tar"}, 21 | {"name": "Check Git", "command": "where git"}, 22 | {"name": "Check Winget", "command": "where winget"}, 23 | {"name": "Check cl.exe (Optional Pre-Check)", "command": "where cl.exe || echo Warning: cl.exe not found initially, will attempt VS Build Tools install."} 24 | ]}, 25 | {"key": "setup_embed_python", "step_data": [ 26 | {"name": "Create Embedded Python Folder (if needed)", "command": "if not exist \"{EMBEDDED_PYTHON_DIR}\" mkdir \"{EMBEDDED_PYTHON_DIR}\""}, 27 | {"name": "Download Python 3.12.4 Embedded (zip)", "command": "curl -L \"https://www.python.org/ftp/python/3.12.4/python-3.12.4-embed-amd64.zip\" -o \"{INSTALL_PATH}\\pyembed.zip\""}, 28 | {"name": "Extract Python Embedded", "command": "tar -xf \"{INSTALL_PATH}\\pyembed.zip\" -C \"{EMBEDDED_PYTHON_DIR}\""}, 29 | {"name": "Download get-pip.py", "command": "curl -L \"https://bootstrap.pypa.io/get-pip.py\" -o \"{INSTALL_PATH}\\get-pip.py\""}, 30 | {"name": "Install Pip", "command": "\"{EMBEDDED_PYTHON_EXE}\" \"{INSTALL_PATH}\\get-pip.py\""}, 31 | {"name": "Clean up downloaded files (zip, get-pip)", "command": "del \"{INSTALL_PATH}\\pyembed.zip\" \"{INSTALL_PATH}\\get-pip.py\""}, 32 | {"name": "Enable site-packages in ._pth file", "command": "(echo import site >> \"{EMBEDDED_PYTHON_DIR}\\python312._pth\")"}, 33 | {"name": "Upgrade Pip", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --upgrade pip"} 34 | ]}, 35 | {"key": "install_vs_tools", "step_data": [ 36 | {"name": "Install/Update VS 2022 Build Tools", "command": "winget install --id Microsoft.VisualStudio.2022.BuildTools -e --source winget --override \"--quiet --wait --norestart --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.20348\" || echo Note: Winget might report failure if tools are already installed/updated.", "message": "Installing VS Build Tools via winget (may take time)..."} 37 | ]}, 38 | {"key": "prequire_build", "step_data": [ 39 | {"name": "Verify C++ Compiler (cl.exe)", "command": "where cl.exe"} 40 | ]}, 41 | {"key": "install_pytorch", "step_data": [ 42 | {"name": "Install PyTorch Nightly (CUDA 12.8)", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install --force-reinstall torch==2.8.0.dev20250317+cu128 torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu128", "message":"Installing specific PyTorch Nightly build..."}, 43 | {"name": "Verify PyTorch Installation", "command": "\"{EMBEDDED_PYTHON_EXE}\" -c \"import torch; print(f'PyTorch Version: {torch.__version__}, CUDA Available: {torch.cuda.is_available()}, CUDA Version: {torch.version.cuda}')\""} 44 | ]}, 45 | {"key": "install_triton", "step_data": [ 46 | {"name": "Install Triton Nightly", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -U --pre triton-windows"}, 47 | {"name": "Clear Triton Cache (.triton)", "command": "if exist \"%USERPROFILE%\\.triton\\cache\" ( rmdir /s /q \"%USERPROFILE%\\.triton\\cache\" 2>nul && mkdir \"%USERPROFILE%\\.triton\\cache\" )"}, 48 | {"name": "Clear Triton Cache (torchinductor)", "command": "if exist \"%LOCALAPPDATA%\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"%LOCALAPPDATA%\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"%LOCALAPPDATA%\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 49 | ]}, 50 | {"key": "install_include_libs", "step_data": [ 51 | {"name": "Download Python 3.12 Include/Libs (zip)", "command": "curl -L \"https://github.com/woct0rdho/triton-windows/releases/download/v3.0.0-windows.post1/python_3.12.7_include_libs.zip\" -o \"{INSTALL_PATH}\\py_libs.zip\""}, 52 | {"name": "Extract Include/Libs", "command": "tar -xf \"{INSTALL_PATH}\\py_libs.zip\" -C \"{EMBEDDED_PYTHON_DIR}\""}, 53 | {"name": "Clean downloaded file (libs zip)", "command": "del \"{INSTALL_PATH}\\py_libs.zip\""} 54 | ]}, 55 | {"key": "install_sage1", "step_data": [ 56 | {"name": "Install SageAttention v1 (1.0.6)", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install sageattention==1.0.6"} 57 | ]}, 58 | {"key": "clone_comfyui", "step_data": [ 59 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{REPO_PATH}\""} 60 | ]}, 61 | {"key": "install_comfy_reqs", "step_data": [ 62 | {"name": "Install ComfyUI requirements.txt", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\requirements.txt\""} 63 | ]}, 64 | {"key": "clone_custom_nodes", "step_data": [ 65 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{REPO_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 66 | {"name": "Clone ComfyUI-VideoHelperSuite", "command": "git clone https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite \"{REPO_PATH}\\custom_nodes\\ComfyUI-VideoHelperSuite\""}, 67 | {"name": "Clone ComfyUI-KJNodes", "command": "git clone https://github.com/kijai/ComfyUI-KJNodes \"{REPO_PATH}\\custom_nodes\\ComfyUI-KJNodes\""}, 68 | {"name": "Clone ComfyUI_essentials", "command": "git clone https://github.com/cubiq/ComfyUI_essentials \"{REPO_PATH}\\custom_nodes\\ComfyUI_essentials\""}, 69 | {"name": "Clone ComfyUI-Frame-Interpolation", "command": "git clone https://github.com/Fannovel16/ComfyUI-Frame-Interpolation \"{REPO_PATH}\\custom_nodes\\ComfyUI-Frame-Interpolation\""}, 70 | {"name": "Clone ComfyUI-MultiGPU", "command": "git clone https://github.com/pollockjj/ComfyUI-MultiGPU \"{REPO_PATH}\\custom_nodes\\ComfyUI-MultiGPU\""}, 71 | {"name": "Clone ComfyUI-Adaptive-Guidance", "command": "git clone https://github.com/asagi4/ComfyUI-Adaptive-Guidance \"{REPO_PATH}\\custom_nodes\\ComfyUI-Adaptive-Guidance\""}, 72 | {"name": "Clone ComfyUI-GGUF", "command": "git clone https://github.com/city96/ComfyUI-GGUF \"{REPO_PATH}\\custom_nodes\\ComfyUI-GGUF\""}, 73 | {"name": "Clone ComfyUI-WanVideoWrapper", "command": "git clone https://github.com/kijai/ComfyUI-WanVideoWrapper \"{REPO_PATH}\\custom_nodes\\ComfyUI-WanVideoWrapper\""} 74 | ]}, 75 | {"key": "install_custom_node_reqs", "step_data": [ 76 | {"name": "Install ComfyUI-Manager Requirements", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI-Manager\\requirements.txt\""}, 77 | {"name": "Install ComfyUI-VideoHelperSuite Requirements", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI-VideoHelperSuite\\requirements.txt\""}, 78 | {"name": "Install ComfyUI-KJNodes Requirements", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI-KJNodes\\requirements.txt\""}, 79 | {"name": "Install ComfyUI_essentials Requirements", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI_essentials\\requirements.txt\""}, 80 | {"name": "Install ComfyUI-Frame-Interpolation Requirements (CuPy)", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI-Frame-Interpolation\\requirements-with-cupy.txt\""}, 81 | {"name": "Install ComfyUI-GGUF Requirements", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI-GGUF\\requirements.txt\""}, 82 | {"name": "Install ComfyUI-WanVideoWrapper Requirements", "command": "\"{EMBEDDED_PYTHON_EXE}\" -s -m pip install -r \"{REPO_PATH}\\custom_nodes\\ComfyUI-WanVideoWrapper\\requirements.txt\""} 83 | ]} 84 | ] 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /k3u_config_file/k3u_Comfyui_venv_StableNightly.k3u: -------------------------------------------------------------------------------- 1 | { 2 | "k3u_type": "external_venv", 3 | "placeholders_info": { 4 | "{INSTALL_PATH}": "Base folder where to clone ComfyUI.", 5 | "{PYTHON_EXE}": "External Python.exe path (provided by user).", 6 | "{VENV_PATH}": "Venv Path (derived: {INSTALL_PATH}\\ComfyUI\\venv).", 7 | "{VENV_PYTHON}": "Python.exe path in Venv (derived: {VENV_PATH}\\Scripts\\python.exe).", 8 | "{COMFYUI_PATH}": "ComfyUI Path (derived: {INSTALL_PATH}\\ComfyUI)." 9 | }, 10 | "setups": { 11 | "ComfyUI_Stable_Py312_CUDA124": { 12 | "description": "ComfyUI Installation (PyTorch Stable ~2.6) for Python 3.12 and CUDA 12.4.", 13 | "info": "Uses external Python 3.12, creates venv, installs PyTorch Stable (cu124), deps, Triton(choice), Sage(choice), Manager. Sage v2 OK.", 14 | "python_version_target": "3.12", 15 | "cuda_version_target": "12.4", 16 | "pytorch_type": "Stable", 17 | "steps": [ 18 | {"key": "start", "step_data": [ 19 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 20 | ]}, 21 | {"key": "prequire1", "step_data": [ 22 | {"name": "Check Python Version (3.12)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.12\""}, 23 | {"name": "Check CUDA Version (12.4)", "command": "nvcc --version | findstr /C:\"release 12.4,\""}, 24 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 25 | ]}, 26 | {"key": "create_venv", "step_data": [ 27 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 28 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 29 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 30 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 31 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 32 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 33 | ]}, 34 | {"key": "install_pytorch", "step_data": [ 35 | {"name": "Install PyTorch Stable (CUDA 12.4)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124"}, 36 | {"name": "Verify PyTorch Installation", "command": "\"{VENV_PYTHON}\" -c \"import torch; print(f'PyTorch Version: {torch.__version__}, CUDA Available: {torch.cuda.is_available()}, CUDA Version: {torch.version.cuda}')\""} 37 | ]}, 38 | {"key": "install_reqs", "step_data": [ 39 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 40 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 41 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 42 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 43 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 44 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 45 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 46 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 47 | {"name": "Install Specific Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install \"setuptools==70.2.0\""} 48 | ]}, 49 | {"key": "input1_triton", "step_data": { 50 | "question": "Choose the Triton version to install:", 51 | "choices": { 52 | "Stable": { "steps": [ 53 | {"name": "Install Triton Stable", "command": "\"{VENV_PYTHON}\" -m pip install triton-windows"}, 54 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 55 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 56 | ]}, 57 | "Nightly": { "steps": [ 58 | {"name": "Install Triton Nightly", "command": "\"{VENV_PYTHON}\" -m pip install -U --pre triton-windows"}, 59 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 60 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 61 | ]} 62 | } 63 | }}, 64 | {"key": "input2_sage", "step_data": { 65 | "question": "Choose SageAttention version (v2 requires PyTorch >=2.7):", 66 | "choices": { 67 | "v1": { "steps": [ 68 | {"name": "Install SageAttention v1 (1.0.6)", "command": "\"{VENV_PYTHON}\" -m pip install sageattention==1.0.6"} 69 | ]}, 70 | "v2": { "steps": [ 71 | {"name": "Clone SageAttention v2", "command": "git clone https://github.com/thu-ml/SageAttention \"{INSTALL_PATH}\\temp_sage\""}, 72 | {"name": "Install SageAttention v2", "command": "cd /d \"{INSTALL_PATH}\\temp_sage\" && \"{VENV_PYTHON}\" -m pip install ."}, 73 | {"name": "Clean SageAttention v2", "command": "rmdir /s /q \"{INSTALL_PATH}\\temp_sage\""} 74 | ]} 75 | } 76 | }}, 77 | {"key": "create_scripts", "step_data": [ 78 | {"name": "Create run_comfyui_fp16fast_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 79 | {"name": "Create run_comfyui_fp16fast_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 80 | {"name": "Create run_comfyui_fp16fast_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 81 | {"name": "Create run_comfyui_fp16fast_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 82 | {"name": "Create run_comfyui_fp16fast_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast fp16_accumulation >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 83 | {"name": "Create run_comfyui_fp16fast_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 84 | {"name": "Create run_comfyui_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 85 | {"name": "Create run_comfyui_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 86 | {"name": "Create run_comfyui_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 87 | {"name": "Create run_comfyui_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 88 | {"name": "Create run_comfyui_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 89 | {"name": "Create run_comfyui_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 90 | {"name": "Create Activate_Venv.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 91 | {"name": "Create Activate_Venv.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\\venv\" >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 92 | {"name": "Create Activate_Venv.bat (L3)", "command": "echo call .\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 93 | {"name": "Create Activate_Venv.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 94 | {"name": "Create Activate_Venv.bat (L5)", "command": "echo cmd.exe /k >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 95 | {"name": "Create Update_Comfy.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 96 | {"name": "Create Update_Comfy.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 97 | {"name": "Create Update_Comfy.bat (L3)", "command": "echo git pull >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 98 | {"name": "Create Update_Comfy.bat (L4)", "command": "echo pause >> \"{INSTALL_PATH}\\Update_Comfy.bat\""} 99 | ]}, 100 | {"key": "install_manager", "step_data": [ 101 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""} 102 | ]} 103 | ] 104 | }, 105 | "ComfyUI_Nightly_Py312_CUDA124": { 106 | "description": "ComfyUI Installation (PyTorch Nightly ~2.7) for Python 3.12 and CUDA 12.4.", 107 | "info": "Uses external Python 3.12, creates venv, installs PyTorch Nightly (cu124), deps, Triton(choice), Sage(choice), Manager. Sage v2 OK. FastFP16 not recommended (requires CUDA >=12.6).", 108 | "python_version_target": "3.12", 109 | "cuda_version_target": "12.4", 110 | "pytorch_type": "Nightly", 111 | "steps": [ 112 | {"key": "start", "step_data": [ 113 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 114 | ]}, 115 | {"key": "prequire1", "step_data": [ 116 | {"name": "Check Python Version (3.12)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.12\""}, 117 | {"name": "Check CUDA Version (12.4)", "command": "nvcc --version | findstr /C:\"release 12.4,\""}, 118 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 119 | ]}, 120 | {"key": "create_venv", "step_data": [ 121 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 122 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 123 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 124 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 125 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 126 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 127 | ]}, 128 | {"key": "install_pytorch", "step_data": [ 129 | {"name": "Install PyTorch Nightly (CUDA 12.4)", "command": "\"{VENV_PYTHON}\" -m pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu124"}, 130 | {"name": "Verify PyTorch Installation", "command": "\"{VENV_PYTHON}\" -c \"import torch; print(f'PyTorch Version: {torch.__version__}, CUDA Available: {torch.cuda.is_available()}, CUDA Version: {torch.version.cuda}')\""} 131 | ]}, 132 | {"key": "install_reqs", "step_data": [ 133 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 134 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 135 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 136 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 137 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 138 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 139 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 140 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 141 | {"name": "Install Specific Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install \"setuptools==70.2.0\""} 142 | ]}, 143 | {"key": "input1_triton", "step_data": { 144 | "question": "Choose the Triton version to install:", 145 | "choices": { 146 | "Stable": { "steps": [ 147 | {"name": "Install Triton Stable", "command": "\"{VENV_PYTHON}\" -m pip install triton-windows"}, 148 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 149 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 150 | ]}, 151 | "Nightly": { "steps": [ 152 | {"name": "Install Triton Nightly", "command": "\"{VENV_PYTHON}\" -m pip install -U --pre triton-windows"}, 153 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 154 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 155 | ]} 156 | } 157 | }}, 158 | {"key": "input2_sage", "step_data": { 159 | "question": "Choose SageAttention version (v2 requires PyTorch >=2.7):", 160 | "choices": { 161 | "v1": { "steps": [ 162 | {"name": "Install SageAttention v1 (1.0.6)", "command": "\"{VENV_PYTHON}\" -m pip install sageattention==1.0.6"} 163 | ]}, 164 | "v2": { "steps": [ 165 | {"name": "Clone SageAttention v2", "command": "git clone https://github.com/thu-ml/SageAttention \"{INSTALL_PATH}\\temp_sage\""}, 166 | {"name": "Install SageAttention v2", "command": "cd /d \"{INSTALL_PATH}\\temp_sage\" && \"{VENV_PYTHON}\" -m pip install ."}, 167 | {"name": "Clean SageAttention v2", "command": "rmdir /s /q \"{INSTALL_PATH}\\temp_sage\""} 168 | ]} 169 | } 170 | }}, 171 | {"key": "create_scripts", "step_data": [ 172 | {"name": "Create run_comfyui_fp16fast_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 173 | {"name": "Create run_comfyui_fp16fast_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 174 | {"name": "Create run_comfyui_fp16fast_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 175 | {"name": "Create run_comfyui_fp16fast_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 176 | {"name": "Create run_comfyui_fp16fast_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast fp16_accumulation >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 177 | {"name": "Create run_comfyui_fp16fast_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 178 | {"name": "Create run_comfyui_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 179 | {"name": "Create run_comfyui_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 180 | {"name": "Create run_comfyui_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 181 | {"name": "Create run_comfyui_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 182 | {"name": "Create run_comfyui_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 183 | {"name": "Create run_comfyui_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 184 | {"name": "Create Activate_Venv.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 185 | {"name": "Create Activate_Venv.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\\venv\" >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 186 | {"name": "Create Activate_Venv.bat (L3)", "command": "echo call .\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 187 | {"name": "Create Activate_Venv.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 188 | {"name": "Create Activate_Venv.bat (L5)", "command": "echo cmd.exe /k >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 189 | {"name": "Create Update_Comfy.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 190 | {"name": "Create Update_Comfy.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 191 | {"name": "Create Update_Comfy.bat (L3)", "command": "echo git pull >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 192 | {"name": "Create Update_Comfy.bat (L4)", "command": "echo pause >> \"{INSTALL_PATH}\\Update_Comfy.bat\""} 193 | ]}, 194 | {"key": "install_manager", "step_data": [ 195 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""} 196 | ]} 197 | ] 198 | }, 199 | "ComfyUI_Stable_Py312_CUDA126": { 200 | "description": "ComfyUI Installation (PyTorch Stable ~2.6) for Python 3.12 and CUDA 12.6.", 201 | "info": "Uses external Python 3.12, creates venv, installs PyTorch Stable (cu126), deps, Triton(choice), Sage(choice), Manager. Sage v2 OK. FastFP16 OK.", 202 | "python_version_target": "3.12", 203 | "cuda_version_target": "12.6", 204 | "pytorch_type": "Stable", 205 | "steps": [ 206 | {"key": "start", "step_data": [ 207 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 208 | ]}, 209 | {"key": "prequire1", "step_data": [ 210 | {"name": "Check Python Version (3.12)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.12\""}, 211 | {"name": "Check CUDA Version (12.6)", "command": "nvcc --version | findstr /C:\"release 12.6,\""}, 212 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 213 | ]}, 214 | {"key": "create_venv", "step_data": [ 215 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 216 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 217 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 218 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 219 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 220 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 221 | ]}, 222 | {"key": "install_pytorch", "step_data": [ 223 | {"name": "Install PyTorch Stable (CUDA 12.6)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126"}, 224 | {"name": "Verify PyTorch Installation", "command": "\"{VENV_PYTHON}\" -c \"import torch; print(f'PyTorch Version: {torch.__version__}, CUDA Available: {torch.cuda.is_available()}, CUDA Version: {torch.version.cuda}')\""} 225 | ]}, 226 | {"key": "install_reqs", "step_data": [ 227 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 228 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 229 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 230 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 231 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 232 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 233 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 234 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 235 | {"name": "Install Specific Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install \"setuptools==70.2.0\""} 236 | ]}, 237 | {"key": "input1_triton", "step_data": { 238 | "question": "Choose the Triton version to install:", 239 | "choices": { 240 | "Stable": { "steps": [ 241 | {"name": "Install Triton Stable", "command": "\"{VENV_PYTHON}\" -m pip install triton-windows"}, 242 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 243 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 244 | ]}, 245 | "Nightly": { "steps": [ 246 | {"name": "Install Triton Nightly", "command": "\"{VENV_PYTHON}\" -m pip install -U --pre triton-windows"}, 247 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 248 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 249 | ]} 250 | } 251 | }}, 252 | {"key": "input2_sage", "step_data": { 253 | "question": "Choose SageAttention version (v2 requires PyTorch >=2.7):", 254 | "choices": { 255 | "v1": { "steps": [ 256 | {"name": "Install SageAttention v1 (1.0.6)", "command": "\"{VENV_PYTHON}\" -m pip install sageattention==1.0.6"} 257 | ]}, 258 | "v2": { "steps": [ 259 | {"name": "Clone SageAttention v2", "command": "git clone https://github.com/thu-ml/SageAttention \"{INSTALL_PATH}\\temp_sage\""}, 260 | {"name": "Install SageAttention v2", "command": "cd /d \"{INSTALL_PATH}\\temp_sage\" && \"{VENV_PYTHON}\" -m pip install ."}, 261 | {"name": "Clean SageAttention v2", "command": "rmdir /s /q \"{INSTALL_PATH}\\temp_sage\""} 262 | ]} 263 | } 264 | }}, 265 | {"key": "create_scripts", "step_data": [ 266 | {"name": "Create run_comfyui_fp16fast_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 267 | {"name": "Create run_comfyui_fp16fast_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 268 | {"name": "Create run_comfyui_fp16fast_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 269 | {"name": "Create run_comfyui_fp16fast_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 270 | {"name": "Create run_comfyui_fp16fast_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast fp16_accumulation >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 271 | {"name": "Create run_comfyui_fp16fast_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 272 | {"name": "Create run_comfyui_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 273 | {"name": "Create run_comfyui_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 274 | {"name": "Create run_comfyui_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 275 | {"name": "Create run_comfyui_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 276 | {"name": "Create run_comfyui_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 277 | {"name": "Create run_comfyui_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 278 | {"name": "Create Activate_Venv.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 279 | {"name": "Create Activate_Venv.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\\venv\" >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 280 | {"name": "Create Activate_Venv.bat (L3)", "command": "echo call .\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 281 | {"name": "Create Activate_Venv.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 282 | {"name": "Create Activate_Venv.bat (L5)", "command": "echo cmd.exe /k >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 283 | {"name": "Create Update_Comfy.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 284 | {"name": "Create Update_Comfy.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 285 | {"name": "Create Update_Comfy.bat (L3)", "command": "echo git pull >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 286 | {"name": "Create Update_Comfy.bat (L4)", "command": "echo pause >> \"{INSTALL_PATH}\\Update_Comfy.bat\""} 287 | ]}, 288 | {"key": "install_manager", "step_data": [ 289 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""} 290 | ]} 291 | ] 292 | }, 293 | "ComfyUI_Nightly_Py312_CUDA126": { 294 | "description": "ComfyUI Installation (PyTorch Nightly ~2.8) for Python 3.12 and CUDA 12.6.", 295 | "info": "Uses external Python 3.12, creates venv, installs PyTorch Nightly (cu126), deps, Triton(choice), Sage(choice), Manager. Sage v2 OK. FastFP16 OK.", 296 | "python_version_target": "3.12", 297 | "cuda_version_target": "12.6", 298 | "pytorch_type": "Nightly", 299 | "steps": [ 300 | {"key": "start", "step_data": [ 301 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 302 | ]}, 303 | {"key": "prequire1", "step_data": [ 304 | {"name": "Check Python Version (3.12)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.12\""}, 305 | {"name": "Check CUDA Version (12.6)", "command": "nvcc --version | findstr /C:\"release 12.6,\""}, 306 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 307 | ]}, 308 | {"key": "create_venv", "step_data": [ 309 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 310 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 311 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 312 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 313 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 314 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 315 | ]}, 316 | {"key": "install_pytorch", "step_data": [ 317 | {"name": "Install PyTorch Nightly (CUDA 12.6)", "command": "\"{VENV_PYTHON}\" -m pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cu126"}, 318 | {"name": "Verify PyTorch Installation", "command": "\"{VENV_PYTHON}\" -c \"import torch; print(f'PyTorch Version: {torch.__version__}, CUDA Available: {torch.cuda.is_available()}, CUDA Version: {torch.version.cuda}')\""} 319 | ]}, 320 | {"key": "install_reqs", "step_data": [ 321 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 322 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 323 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 324 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 325 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 326 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 327 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 328 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 329 | {"name": "Install Specific Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install \"setuptools==70.2.0\""} 330 | ]}, 331 | {"key": "input1_triton", "step_data": { 332 | "question": "Choose the Triton version to install:", 333 | "choices": { 334 | "Stable": { "steps": [ 335 | {"name": "Install Triton Stable", "command": "\"{VENV_PYTHON}\" -m pip install triton-windows"}, 336 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 337 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 338 | ]}, 339 | "Nightly": { "steps": [ 340 | {"name": "Install Triton Nightly", "command": "\"{VENV_PYTHON}\" -m pip install -U --pre triton-windows"}, 341 | {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, 342 | {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} 343 | ]} 344 | } 345 | }}, 346 | {"key": "input2_sage", "step_data": { 347 | "question": "Choose SageAttention version (v2 requires PyTorch >=2.7):", 348 | "choices": { 349 | "v1": { "steps": [ 350 | {"name": "Install SageAttention v1 (1.0.6)", "command": "\"{VENV_PYTHON}\" -m pip install sageattention==1.0.6"} 351 | ]}, 352 | "v2": { "steps": [ 353 | {"name": "Clone SageAttention v2", "command": "git clone https://github.com/thu-ml/SageAttention \"{INSTALL_PATH}\\temp_sage\""}, 354 | {"name": "Install SageAttention v2", "command": "cd /d \"{INSTALL_PATH}\\temp_sage\" && \"{VENV_PYTHON}\" -m pip install ."}, 355 | {"name": "Clean SageAttention v2", "command": "rmdir /s /q \"{INSTALL_PATH}\\temp_sage\""} 356 | ]} 357 | } 358 | }}, 359 | {"key": "create_scripts", "step_data": [ 360 | {"name": "Create run_comfyui_fp16fast_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 361 | {"name": "Create run_comfyui_fp16fast_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 362 | {"name": "Create run_comfyui_fp16fast_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 363 | {"name": "Create run_comfyui_fp16fast_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 364 | {"name": "Create run_comfyui_fp16fast_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast fp16_accumulation >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 365 | {"name": "Create run_comfyui_fp16fast_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_fp16fast_sage.bat\""}, 366 | {"name": "Create run_comfyui_sage.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 367 | {"name": "Create run_comfyui_sage.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 368 | {"name": "Create run_comfyui_sage.bat (L3)", "command": "echo call venv\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 369 | {"name": "Create run_comfyui_sage.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 370 | {"name": "Create run_comfyui_sage.bat (L5)", "command": "echo .\\venv\\Scripts\\python.exe -s main.py --windows-standalone-build --use-sage-attention --fast >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 371 | {"name": "Create run_comfyui_sage.bat (L6)", "command": "echo pause >> \"{INSTALL_PATH}\\run_comfyui_sage.bat\""}, 372 | {"name": "Create Activate_Venv.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 373 | {"name": "Create Activate_Venv.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\\venv\" >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 374 | {"name": "Create Activate_Venv.bat (L3)", "command": "echo call .\\Scripts\\activate.bat >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 375 | {"name": "Create Activate_Venv.bat (L4)", "command": "echo echo Venv Activated >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 376 | {"name": "Create Activate_Venv.bat (L5)", "command": "echo cmd.exe /k >> \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 377 | {"name": "Create Update_Comfy.bat (L1)", "command": "echo @echo off > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 378 | {"name": "Create Update_Comfy.bat (L2)", "command": "echo cd /d \"{COMFYUI_PATH}\" >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 379 | {"name": "Create Update_Comfy.bat (L3)", "command": "echo git pull >> \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 380 | {"name": "Create Update_Comfy.bat (L4)", "command": "echo pause >> \"{INSTALL_PATH}\\Update_Comfy.bat\""} 381 | ]}, 382 | {"key": "install_manager", "step_data": [ 383 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""} 384 | ]} 385 | ] 386 | } 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /k3u_config_file/k3u_Comfyui_venv_allPyton.k3u: -------------------------------------------------------------------------------- 1 | { 2 | "k3u_type": "external_venv", 3 | "placeholders_info": { 4 | "{INSTALL_PATH}": "Base folder where to clone ComfyUI (provided by the user in the GUI).", 5 | "{PYTHON_EXE}": "Full path to the Python executable for this specific setup (e.g., C:\\Python310\\python.exe). MUST BE PROVIDED BY THE USER.", 6 | "{VENV_PATH}": "Path of the virtual environment (derived: {INSTALL_PATH}\\ComfyUI\\venv).", 7 | "{VENV_PYTHON}": "Path to the Python executable in the venv (derived: {VENV_PATH}\\Scripts\\python.exe).", 8 | "{COMFYUI_PATH}": "ComfyUI folder (derived: {INSTALL_PATH}\\ComfyUI)." 9 | }, 10 | "setups": { 11 | "ComfyUI_Py310_CUDA124": { 12 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.10 and CUDA 12.4.", 13 | "info": "Includes prerequisite checks for Python 3.10, CUDA 12.4 and cl.exe.", 14 | "python_version_target": "3.10", 15 | "cuda_version_target": "12.4", 16 | "steps": [ 17 | {"key": "start", "step_data": [ 18 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 19 | ]}, 20 | {"key": "prequire1", "step_data": [ 21 | {"name": "Check Python Version (3.10)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.10\""}, 22 | {"name": "Check CUDA Version (12.4)", "command": "nvcc --version | findstr /C:\"release 12.4,\""}, 23 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 24 | ]}, 25 | {"key": "install_part1", "step_data": [ 26 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 27 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 28 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 29 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 30 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 31 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 32 | ]}, 33 | {"key": "install_pytorch", "step_data": [ 34 | {"name": "Install PyTorch (CUDA 12.4)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124"} 35 | ]}, 36 | {"key": "install_part2", "step_data": [ 37 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 38 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 39 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 40 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 41 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 42 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 43 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 44 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 45 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 46 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 47 | ]}, 48 | {"key": "input1_triton", "step_data": { 49 | "question": "Choose Triton version (check PyTorch/Python 3.10 compatibility):", 50 | "choices": { 51 | "Triton_3.2.0": { "steps": [ {"name": "Install Triton 3.2.0 (Py3.10)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp310-cp310-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 52 | "Triton_3.1.0": { "steps": [ {"name": "Install Triton 3.1.0 (Py3.10)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.1.0-cp310-cp310-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 53 | "Triton_3.0.0": { "steps": [ {"name": "Install Triton 3.0.0 (Py3.10)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.0.0-cp310-cp310-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 54 | } 55 | }}, 56 | {"key": "post_part1", "step_data": [ 57 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 58 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 59 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 60 | ]}, 61 | {"key": "post_part2", "step_data": [ 62 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 63 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 64 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 65 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 66 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 67 | ]} 68 | ] 69 | }, 70 | "ComfyUI_Py310_CUDA126": { 71 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.10 and CUDA 12.6.", 72 | "info": "Includes prerequisite checks for Python 3.10, CUDA 12.6 and cl.exe.", 73 | "python_version_target": "3.10", 74 | "cuda_version_target": "12.6", 75 | "steps": [ 76 | {"key": "start", "step_data": [ 77 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 78 | ]}, 79 | {"key": "prequire1", "step_data": [ 80 | {"name": "Check Python Version (3.10)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.10\""}, 81 | {"name": "Check CUDA Version (12.6)", "command": "nvcc --version | findstr /C:\"release 12.6,\""}, 82 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 83 | ]}, 84 | {"key": "install_part1", "step_data": [ 85 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 86 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 87 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 88 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 89 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 90 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 91 | ]}, 92 | {"key": "install_pytorch", "step_data": [ 93 | {"name": "Install PyTorch (CUDA 12.6)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126"} 94 | ]}, 95 | {"key": "install_part2", "step_data": [ 96 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 97 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 98 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 99 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 100 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 101 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 102 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 103 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 104 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 105 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 106 | ]}, 107 | {"key": "input1_triton", "step_data": { 108 | "question": "Choose Triton version (check PyTorch/Python 3.10 compatibility):", 109 | "choices": { 110 | "Triton_3.2.0": { "steps": [ {"name": "Install Triton 3.2.0 (Py3.10)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp310-cp310-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 111 | "Triton_3.1.0": { "steps": [ {"name": "Install Triton 3.1.0 (Py3.10)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.1.0-cp310-cp310-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 112 | "Triton_3.0.0": { "steps": [ {"name": "Install Triton 3.0.0 (Py3.10)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.0.0-cp310-cp310-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 113 | } 114 | }}, 115 | {"key": "post_part1", "step_data": [ 116 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 117 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 118 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 119 | ]}, 120 | {"key": "post_part2", "step_data": [ 121 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 122 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 123 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 124 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 125 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 126 | ]} 127 | ] 128 | }, 129 | "ComfyUI_Py311_CUDA124": { 130 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.11 and CUDA 12.4.", 131 | "info": "Includes prerequisite checks for Python 3.11, CUDA 12.4 and cl.exe. Triton 3.2 not available.", 132 | "python_version_target": "3.11", 133 | "cuda_version_target": "12.4", 134 | "steps": [ 135 | {"key": "start", "step_data": [ 136 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 137 | ]}, 138 | {"key": "prequire1", "step_data": [ 139 | {"name": "Check Python Version (3.11)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.11\""}, 140 | {"name": "Check CUDA Version (12.4)", "command": "nvcc --version | findstr /C:\"release 12.4,\""}, 141 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 142 | ]}, 143 | {"key": "install_part1", "step_data": [ 144 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 145 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 146 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 147 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 148 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 149 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 150 | ]}, 151 | {"key": "install_pytorch", "step_data": [ 152 | {"name": "Install PyTorch (CUDA 12.4)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124"} 153 | ]}, 154 | {"key": "install_part2", "step_data": [ 155 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 156 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 157 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 158 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 159 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 160 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 161 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 162 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 163 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 164 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 165 | ]}, 166 | {"key": "input1_triton", "step_data": { 167 | "question": "Choose Triton version (check PyTorch/Python 3.11 compatibility):", 168 | "choices": { 169 | "Triton_3.1.0": { "steps": [ {"name": "Install Triton 3.1.0 (Py3.11)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.1.0-cp311-cp311-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 170 | "Triton_3.0.0": { "steps": [ {"name": "Install Triton 3.0.0 (Py3.11)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.0.0-cp311-cp311-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 171 | } 172 | }}, 173 | {"key": "post_part1", "step_data": [ 174 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 175 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 176 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 177 | ]}, 178 | {"key": "post_part2", "step_data": [ 179 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 180 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 181 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 182 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 183 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 184 | ]} 185 | ] 186 | }, 187 | "ComfyUI_Py311_CUDA126": { 188 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.11 and CUDA 12.6.", 189 | "info": "Includes prerequisite checks for Python 3.11, CUDA 12.6 and cl.exe. Triton 3.2 not available.", 190 | "python_version_target": "3.11", 191 | "cuda_version_target": "12.6", 192 | "steps": [ 193 | {"key": "start", "step_data": [ 194 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 195 | ]}, 196 | {"key": "prequire1", "step_data": [ 197 | {"name": "Check Python Version (3.11)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.11\""}, 198 | {"name": "Check CUDA Version (12.6)", "command": "nvcc --version | findstr /C:\"release 12.6,\""}, 199 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 200 | ]}, 201 | {"key": "install_part1", "step_data": [ 202 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 203 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 204 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 205 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 206 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 207 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 208 | ]}, 209 | {"key": "install_pytorch", "step_data": [ 210 | {"name": "Install PyTorch (CUDA 12.6)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126"} 211 | ]}, 212 | {"key": "install_part2", "step_data": [ 213 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 214 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 215 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 216 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 217 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 218 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 219 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 220 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 221 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 222 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 223 | ]}, 224 | {"key": "input1_triton", "step_data": { 225 | "question": "Choose Triton version (check PyTorch/Python 3.11 compatibility):", 226 | "choices": { 227 | "Triton_3.1.0": { "steps": [ {"name": "Install Triton 3.1.0 (Py3.11)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.1.0-cp311-cp311-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 228 | "Triton_3.0.0": { "steps": [ {"name": "Install Triton 3.0.0 (Py3.11)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.0.0-cp311-cp311-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 229 | } 230 | }}, 231 | {"key": "post_part1", "step_data": [ 232 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 233 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 234 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 235 | ]}, 236 | {"key": "post_part2", "step_data": [ 237 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 238 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 239 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 240 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 241 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 242 | ]} 243 | ] 244 | }, 245 | "ComfyUI_Py312_CUDA124": { 246 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.12 and CUDA 12.4.", 247 | "info": "Includes prerequisite checks for Python 3.12, CUDA 12.4 and cl.exe.", 248 | "python_version_target": "3.12", 249 | "cuda_version_target": "12.4", 250 | "steps": [ 251 | {"key": "start", "step_data": [ 252 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 253 | ]}, 254 | {"key": "prequire1", "step_data": [ 255 | {"name": "Check Python Version (3.12)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.12\""}, 256 | {"name": "Check CUDA Version (12.4)", "command": "nvcc --version | findstr /C:\"release 12.4,\""}, 257 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 258 | ]}, 259 | {"key": "install_part1", "step_data": [ 260 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 261 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 262 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 263 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 264 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 265 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 266 | ]}, 267 | {"key": "install_pytorch", "step_data": [ 268 | {"name": "Install PyTorch (CUDA 12.4)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124"} 269 | ]}, 270 | {"key": "install_part2", "step_data": [ 271 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 272 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 273 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 274 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 275 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 276 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 277 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 278 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 279 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 280 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 281 | ]}, 282 | {"key": "input1_triton", "step_data": { 283 | "question": "Choose Triton version (check PyTorch/Python 3.12 compatibility):", 284 | "choices": { 285 | "Triton_3.2.0": { "steps": [ {"name": "Install Triton 3.2.0 (Py3.12)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp312-cp312-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 286 | "Triton_3.1.0": { "steps": [ {"name": "Install Triton 3.1.0 (Py3.12)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.1.0-cp312-cp312-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 287 | "Triton_3.0.0": { "steps": [ {"name": "Install Triton 3.0.0 (Py3.12)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.0.0-cp312-cp312-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 288 | } 289 | }}, 290 | {"key": "post_part1", "step_data": [ 291 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 292 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 293 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 294 | ]}, 295 | {"key": "post_part2", "step_data": [ 296 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 297 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 298 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 299 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 300 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 301 | ]} 302 | ] 303 | }, 304 | "ComfyUI_Py312_CUDA126": { 305 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.12 and CUDA 12.6.", 306 | "info": "Includes prerequisite checks for Python 3.12, CUDA 12.6 and cl.exe.", 307 | "python_version_target": "3.12", 308 | "cuda_version_target": "12.6", 309 | "steps": [ 310 | {"key": "start", "step_data": [ 311 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 312 | ]}, 313 | {"key": "prequire1", "step_data": [ 314 | {"name": "Check Python Version (3.12)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.12\""}, 315 | {"name": "Check CUDA Version (12.6)", "command": "nvcc --version | findstr /C:\"release 12.6,\""}, 316 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 317 | ]}, 318 | {"key": "install_part1", "step_data": [ 319 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 320 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 321 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 322 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 323 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 324 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 325 | ]}, 326 | {"key": "install_pytorch", "step_data": [ 327 | {"name": "Install PyTorch (CUDA 12.6)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126"} 328 | ]}, 329 | {"key": "install_part2", "step_data": [ 330 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 331 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 332 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 333 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 334 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 335 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 336 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 337 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 338 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 339 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 340 | ]}, 341 | {"key": "input1_triton", "step_data": { 342 | "question": "Choose Triton version (check PyTorch/Python 3.12 compatibility):", 343 | "choices": { 344 | "Triton_3.2.0": { "steps": [ {"name": "Install Triton 3.2.0 (Py3.12)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp312-cp312-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 345 | "Triton_3.1.0": { "steps": [ {"name": "Install Triton 3.1.0 (Py3.12)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.1.0-cp312-cp312-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] }, 346 | "Triton_3.0.0": { "steps": [ {"name": "Install Triton 3.0.0 (Py3.12)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.1.0-windows.post9/triton-3.0.0-cp312-cp312-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 347 | } 348 | }}, 349 | {"key": "post_part1", "step_data": [ 350 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 351 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 352 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 353 | ]}, 354 | {"key": "post_part2", "step_data": [ 355 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 356 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 357 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 358 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 359 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 360 | ]} 361 | ] 362 | }, 363 | "ComfyUI_Py313_CUDA124": { 364 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.13 and CUDA 12.4.", 365 | "info": "Includes prerequisite checks for Python 3.13, CUDA 12.4 and cl.exe. Triton v3.1/v3.0 not available.", 366 | "python_version_target": "3.13", 367 | "cuda_version_target": "12.4", 368 | "steps": [ 369 | {"key": "start", "step_data": [ 370 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 371 | ]}, 372 | {"key": "prequire1", "step_data": [ 373 | {"name": "Check Python Version (3.13)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.13\""}, 374 | {"name": "Check CUDA Version (12.4)", "command": "nvcc --version | findstr /C:\"release 12.4,\""}, 375 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 376 | ]}, 377 | {"key": "install_part1", "step_data": [ 378 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 379 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 380 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 381 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 382 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 383 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 384 | ]}, 385 | {"key": "install_pytorch", "step_data": [ 386 | {"name": "Install PyTorch (CUDA 12.4)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124"} 387 | ]}, 388 | {"key": "install_part2", "step_data": [ 389 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 390 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 391 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 392 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 393 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 394 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 395 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 396 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 397 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 398 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 399 | ]}, 400 | {"key": "input1_triton", "step_data": { 401 | "question": "Choose Triton version (check PyTorch/Python 3.13 compatibility):", 402 | "choices": { 403 | "Triton_3.2.0": { "steps": [ {"name": "Install Triton 3.2.0 (Py3.13)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp313-cp313-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 404 | } 405 | }}, 406 | {"key": "post_part1", "step_data": [ 407 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 408 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 409 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 410 | ]}, 411 | {"key": "post_part2", "step_data": [ 412 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 413 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 414 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 415 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 416 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 417 | ]} 418 | ] 419 | }, 420 | "ComfyUI_Py313_CUDA126": { 421 | "description": "ComfyUI + Triton + SageAttention installation for Python 3.13 and CUDA 12.6.", 422 | "info": "Includes prerequisite checks for Python 3.13, CUDA 12.6 and cl.exe. Triton v3.1/v3.0 not available.", 423 | "python_version_target": "3.13", 424 | "cuda_version_target": "12.6", 425 | "steps": [ 426 | {"key": "start", "step_data": [ 427 | {"name": "Clone ComfyUI Repository", "command": "git clone https://github.com/comfyanonymous/ComfyUI \"{COMFYUI_PATH}\""} 428 | ]}, 429 | {"key": "prequire1", "step_data": [ 430 | {"name": "Check Python Version (3.13)", "command": "\"{PYTHON_EXE}\" --version | findstr /B /C:\"Python 3.13\""}, 431 | {"name": "Check CUDA Version (12.6)", "command": "nvcc --version | findstr /C:\"release 12.6,\""}, 432 | {"name": "Check C++ Compiler (cl.exe)", "command": "where cl.exe"} 433 | ]}, 434 | {"key": "install_part1", "step_data": [ 435 | {"name": "Create Virtual Environment", "command": "\"{PYTHON_EXE}\" -m venv \"{VENV_PATH}\""}, 436 | {"name": "Copy Python Headers", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\Include\" \"{VENV_PATH}\\Include\""}, 437 | {"name": "Copy Python Libs", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\libs\" \"{VENV_PATH}\\libs\""}, 438 | {"name": "Copy VC Runtime DLL 1", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140.dll\" \"{VENV_PATH}\\Scripts\\\""}, 439 | {"name": "Copy VC Runtime DLL 2", "command": "xcopy /E /I /Y \"{PYTHON_EXE}\\..\\vcruntime140_1.dll\" \"{VENV_PATH}\\Scripts\\\""}, 440 | {"name": "Update Pip", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade pip"} 441 | ]}, 442 | {"key": "install_pytorch", "step_data": [ 443 | {"name": "Install PyTorch (CUDA 12.6)", "command": "\"{VENV_PYTHON}\" -m pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126"} 444 | ]}, 445 | {"key": "install_part2", "step_data": [ 446 | {"name": "Install requirements.txt", "command": "\"{VENV_PYTHON}\" -m pip install -r \"{COMFYUI_PATH}\\requirements.txt\""}, 447 | {"name": "Install OnnxRuntime-GPU", "command": "\"{VENV_PYTHON}\" -m pip install onnxruntime-gpu"}, 448 | {"name": "Install Wheel", "command": "\"{VENV_PYTHON}\" -m pip install wheel"}, 449 | {"name": "Install Setuptools", "command": "\"{VENV_PYTHON}\" -m pip install setuptools"}, 450 | {"name": "Install Packaging", "command": "\"{VENV_PYTHON}\" -m pip install packaging"}, 451 | {"name": "Install Ninja", "command": "\"{VENV_PYTHON}\" -m pip install ninja"}, 452 | {"name": "Install Accelerate", "command": "\"{VENV_PYTHON}\" -m pip install \"accelerate >= 1.1.1\""}, 453 | {"name": "Install Diffusers", "command": "\"{VENV_PYTHON}\" -m pip install \"diffusers >= 0.31.0\""}, 454 | {"name": "Install Transformers", "command": "\"{VENV_PYTHON}\" -m pip install \"transformers >= 4.39.3\""}, 455 | {"name": "Update Setuptools (again)", "command": "\"{VENV_PYTHON}\" -m pip install --upgrade setuptools"} 456 | ]}, 457 | {"key": "input1_triton", "step_data": { 458 | "question": "Choose Triton version (check PyTorch/Python 3.13 compatibility):", 459 | "choices": { 460 | "Triton_3.2.0": { "steps": [ {"name": "Install Triton 3.2.0 (Py3.13)", "command": "\"{VENV_PYTHON}\" -m pip install https://github.com/woct0rdho/triton-windows/releases/download/v3.2.0-windows.post10/triton-3.2.0-cp313-cp313-win_amd64.whl"}, {"name": "Clean Triton cache (.triton)", "command": "if exist \"C:\\Users\\%USERNAME%\\.triton\\cache\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\.triton\\cache\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\.triton\\cache\" )"}, {"name": "Clean Triton cache (torchinductor)", "command": "if exist \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" ( rmdir /s /q \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" 2>nul && mkdir \"C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\torchinductor_%USERNAME%\\triton\" )"} ] } 461 | } 462 | }}, 463 | {"key": "post_part1", "step_data": [ 464 | {"name": "Clone SageAttention", "command": "git clone https://github.com/thu-ml/SageAttention \"{VENV_PATH}\\SageAttention\""}, 465 | {"name": "Install SageAttention", "command": "cd /d \"{VENV_PATH}\\SageAttention\" && \"{VENV_PYTHON}\" setup.py install"}, 466 | {"name": "Clean SageAttention", "command": "rmdir /s /q \"{VENV_PATH}\\SageAttention\""} 467 | ]}, 468 | {"key": "post_part2", "step_data": [ 469 | {"name": "Create Run_Comfyui.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo call venv\\Scripts\\activate.bat & echo echo Venv Activated & echo .\\venv\\Scripts\\python.exe -s main.py --fast --windows-standalone-build --use-pytorch-cross-attention & echo pause) > \"{INSTALL_PATH}\\Run_Comfyui.bat\""}, 470 | {"name": "Create Activate_Venv.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\\venv\" & echo call .\\Scripts\\activate.bat & echo echo Venv Activated & echo cmd.exe /k) > \"{INSTALL_PATH}\\Activate_Venv.bat\""}, 471 | {"name": "Create Update_Comfy.bat", "command": "(echo @echo off & echo cd /d \"{COMFYUI_PATH}\" & echo git pull & echo pause) > \"{INSTALL_PATH}\\Update_Comfy.bat\""}, 472 | {"name": "Clone ComfyUI-Manager", "command": "git clone https://github.com/ltdrdata/ComfyUI-Manager \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Manager\""}, 473 | {"name": "Clone ComfyUI-Crystools", "command": "git clone https://github.com/crystian/ComfyUI-Crystools \"{COMFYUI_PATH}\\custom_nodes\\ComfyUI-Crystools\""} 474 | ]} 475 | ] 476 | } 477 | } 478 | } 479 | -------------------------------------------------------------------------------- /k3u_installer_gui.py: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Karma3u 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import tkinter as tk 16 | from tkinter import ttk, filedialog, messagebox, scrolledtext 17 | import json 18 | import os 19 | import re 20 | import subprocess 21 | import threading 22 | import time # Import time for potential delays or checks 23 | import sys # To get platform for path separators 24 | 25 | class K3U_Installer_GUI: 26 | def __init__(self, master): 27 | self.master = master 28 | self.master.title("K3U Installer GUI") 29 | # Main window size 30 | self.main_width = 950 31 | self.main_height = 750 32 | self.master.geometry(f"{self.main_width}x{self.main_height}") 33 | 34 | # --- State Variables --- 35 | self.k3u_data = None 36 | self.selected_setup_key = None 37 | self.current_setup_data = None 38 | self.current_k3u_type = "external_venv" # Default type 39 | self.total_steps_for_progress = 0 40 | self.worker_thread = None 41 | self.user_inputs = {} # Stores user choices {input_key: selected_value_string} 42 | self._config_vars = {} # Stores tk.StringVar for config window {input_key: tk.StringVar} 43 | self.placeholders = {} # Stores resolved placeholder values 44 | self._flash_after_id = None # ID for the flashing animation timer 45 | self._is_flashing = False # Flag to control flashing state 46 | 47 | # --- Log File Setup --- 48 | self.log_file = "install_log.txt" 49 | try: 50 | # Clear log file on start 51 | with open(self.log_file, "w", encoding="utf-8") as f: 52 | f.write(f"=== Log Installazione K3U ({time.strftime('%Y-%m-%d %H:%M:%S')}) ===\n\n") 53 | except IOError as e: 54 | print(f"Errore apertura log file '{self.log_file}': {e}") 55 | messagebox.showwarning("Log Error", f"Unable to write to log file:\n{e}\nIl logging su file sarà disabilitato.") 56 | messagebox.showwarning("Log Error", "File logging will be disabled.") 57 | self.log_file = None # Disable file logging if opening failed 58 | 59 | self.setup_ui() 60 | 61 | def setup_ui(self): 62 | # --- Top Frame for Paths --- 63 | top_frame = ttk.Frame(self.master, padding="10") 64 | top_frame.pack(fill=tk.X) 65 | 66 | # --- Installation Path Frame --- 67 | path_frame = ttk.Frame(top_frame) 68 | path_frame.pack(fill=tk.X, pady=(0, 5)) 69 | ttk.Label(path_frame, text="Installation Base Path:", width=22, anchor="w").pack(side=tk.LEFT) 70 | self.install_path_var = tk.StringVar() 71 | self.path_entry = ttk.Entry(path_frame, textvariable=self.install_path_var, width=60) 72 | self.path_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True) 73 | self.browse_path_button = ttk.Button(path_frame, text="Browse 📁.", command=self.choose_install_path) 74 | self.browse_path_button.pack(side=tk.LEFT, padx=5) 75 | 76 | # --- Python Executable Frame (State depends on K3U type) --- 77 | python_frame = ttk.Frame(top_frame) 78 | python_frame.pack(fill=tk.X) 79 | self.python_label = ttk.Label(python_frame, text="Python exe. Target:", width=22, anchor="w") 80 | self.python_label.pack(side=tk.LEFT) 81 | self.python_exe_var = tk.StringVar() 82 | self.python_entry = ttk.Entry(python_frame, textvariable=self.python_exe_var, width=60) 83 | self.python_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True) 84 | self.browse_python_button = ttk.Button(python_frame, text="Browse 📁.", command=self.choose_python_exe) 85 | self.browse_python_button.pack(side=tk.LEFT, padx=5) 86 | self.python_label.config(state="normal") 87 | self.python_entry.config(state="normal") 88 | self.browse_python_button.config(state="normal") 89 | 90 | 91 | # --- K3U File Frame --- 92 | self.file_frame = ttk.Frame(self.master, padding="10") 93 | self.file_frame.pack(fill=tk.X) 94 | ttk.Label(self.file_frame, text="File K3U:", width=22, anchor="w").pack(side=tk.LEFT) # Added width for alignment 95 | self.file_path_var = tk.StringVar() 96 | self.file_entry = ttk.Entry(self.file_frame, textvariable=self.file_path_var, width=50) 97 | self.file_entry.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=5) 98 | self.browse_button = ttk.Button(self.file_frame, text="Browse 📁.", command=self.browse_file) 99 | self.browse_button.pack(side=tk.LEFT) 100 | 101 | # --- Setup Selection and Info Frame --- 102 | self.setup_frame = ttk.LabelFrame(self.master, text="Setup Selection", padding="10") 103 | self.setup_frame.pack(fill=tk.X, padx=10, pady=5) 104 | 105 | setup_select_frame = ttk.Frame(self.setup_frame) 106 | setup_select_frame.pack(fill=tk.X) 107 | ttk.Label(setup_select_frame, text="Available Setups:").pack(side=tk.LEFT) 108 | self.setup_var = tk.StringVar() 109 | self.setup_combobox = ttk.Combobox(setup_select_frame, textvariable=self.setup_var, state="disabled", width=40) 110 | self.setup_combobox.pack(side=tk.LEFT, padx=10) 111 | self.setup_combobox.bind("<>", self.on_setup_selected) 112 | 113 | # Description 114 | self.description_label = ttk.Label(self.setup_frame, text="Description:", font=('TkDefaultFont', 10, 'bold')) 115 | self.description_label.pack(fill=tk.X, pady=(10, 0), anchor='w') 116 | self.description_text = tk.StringVar() 117 | self.description_value = ttk.Label(self.setup_frame, textvariable=self.description_text, wraplength=self.main_width - 100, justify=tk.LEFT) 118 | self.description_value.pack(fill=tk.X, anchor='w') 119 | 120 | # Info 121 | self.info_label = ttk.Label(self.setup_frame, text="Info:", font=('TkDefaultFont', 10, 'bold')) 122 | self.info_label.pack(fill=tk.X, pady=(5, 0), anchor='w') 123 | self.info_text = tk.StringVar() 124 | self.info_value = ttk.Label(self.setup_frame, textvariable=self.info_text, wraplength=self.main_width - 100, justify=tk.LEFT) 125 | self.info_value.pack(fill=tk.X, anchor='w') 126 | 127 | # --- Log Area Frame --- 128 | self.log_frame = ttk.LabelFrame(self.master, text="Installation Log", padding="10") 129 | self.log_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) 130 | self.log_text = scrolledtext.ScrolledText(self.log_frame, wrap=tk.WORD, height=15, state="disabled", font=("Courier New", 9), bg="black", fg="lime") 131 | self.log_text.pack(fill=tk.BOTH, expand=True) 132 | # Configure tags for colored logging 133 | self.log_text.tag_config("ERROR", foreground="red", font=("Courier New", 9, "bold")) 134 | self.log_text.tag_config("WARNING", foreground="orange") 135 | self.log_text.tag_config("INFO", foreground="cyan") 136 | self.log_text.tag_config("SUCCESS", foreground="lightgreen") 137 | self.log_text.tag_config("STEP", foreground="yellow", font=("Courier New", 9, "bold")) 138 | self.log_text.tag_config("CMD", foreground="white") 139 | self.log_text.tag_config("OUTPUT", foreground="#cccccc") # Light gray for output 140 | 141 | 142 | # --- Progress Bar --- 143 | self.progress_var = tk.DoubleVar(value=0) 144 | self.progress_bar = ttk.Progressbar(self.master, maximum=100, variable=self.progress_var, mode='determinate') 145 | self.progress_bar.pack(fill=tk.X, padx=10, pady=(5, 0)) # Padding adjusted 146 | 147 | 148 | # --- Control Frame (Modified Layout) --- 149 | self.control_frame = ttk.Frame(self.master, padding="10") 150 | self.control_frame.pack(fill=tk.X, pady=(5, 10)) 151 | 152 | # Start Button (Left) 153 | self.start_button = ttk.Button(self.control_frame, text="Summary and Start", command=self.open_config_window, state="disabled") 154 | self.start_button.pack(side=tk.LEFT, padx=5) 155 | 156 | # Reset Button (Right) 157 | self.reset_button = ttk.Button(self.control_frame, text="Reset", command=self.reset_ui) 158 | self.reset_button.pack(side=tk.RIGHT, padx=5) 159 | 160 | # Status Display Frame (Middle, expands) - NEW 161 | self.status_display_frame = ttk.Frame(self.control_frame) 162 | # Packed later when needed (in start_flashing) 163 | # self.status_display_frame.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=10) 164 | 165 | # Flashing Indicator Label (inside status frame) - NEW 166 | self.flash_label = ttk.Label(self.status_display_frame, text="", width=3, font=("Courier New", 10, "bold")) 167 | self.flash_label.pack(side=tk.LEFT, padx=(0, 5)) 168 | 169 | # Status Text Label (inside status frame) - NEW 170 | self.status_label_var = tk.StringVar(value="") # Initially empty 171 | self.status_label = ttk.Label(self.status_display_frame, textvariable=self.status_label_var, anchor="w") 172 | self.status_label.pack(side=tk.LEFT, fill=tk.X, expand=True) 173 | 174 | 175 | # --- Methods for Status/Flashing --- 176 | 177 | def update_status_text(self, text): 178 | """Updates the status label text.""" 179 | try: 180 | self.status_label_var.set(text) 181 | except tk.TclError: 182 | # Handle error if the window/widget is destroyed during update 183 | print("Warning: Could not update status text (widget destroyed?).") 184 | 185 | 186 | def _animate_status(self, state=0): 187 | """Internal method to animate the flashing label.""" 188 | if not self._is_flashing: # Stop if flashing was cancelled 189 | self.flash_label.config(text="") 190 | return 191 | 192 | # Simple animation: [*] / [-] 193 | new_text = "[*]" if state == 0 else "[-]" 194 | foreground_color = "lime" if state == 0 else "orange" 195 | 196 | try: 197 | self.flash_label.config(text=new_text, foreground=foreground_color) 198 | # Schedule next frame 199 | self._flash_after_id = self.master.after(400, self._animate_status, 1 - state) 200 | except tk.TclError: 201 | # Handle error if the window/widget is destroyed during update 202 | print("Warning: Could not animate status (widget destroyed?).") 203 | self._is_flashing = False 204 | 205 | 206 | def start_flashing(self): 207 | """Starts the flashing animation and shows the status frame.""" 208 | if not self._is_flashing: 209 | self._is_flashing = True 210 | # Make the status frame visible by packing it 211 | # Pack reset button first to ensure it stays on the right 212 | self.reset_button.pack_forget() 213 | self.status_display_frame.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=10) 214 | self.reset_button.pack(side=tk.RIGHT, padx=5) # Re-pack reset button 215 | self.update_status_text("Avvio...") # Initial text 216 | self._animate_status(0) # Start animation 217 | 218 | def stop_flashing(self): 219 | """Stops the flashing animation and hides the status frame.""" 220 | if self._is_flashing: 221 | self._is_flashing = False 222 | if self._flash_after_id: 223 | try: 224 | self.master.after_cancel(self._flash_after_id) 225 | except tk.TclError: 226 | pass # Ignore if timer already cancelled or window destroyed 227 | self._flash_after_id = None 228 | try: 229 | self.flash_label.config(text="") # Clear flash label 230 | # Hide the status frame 231 | self.status_display_frame.pack_forget() 232 | except tk.TclError: 233 | pass # Ignore if widgets already destroyed 234 | 235 | # --- Rest of the methods --- 236 | 237 | def reset_ui(self): 238 | """Resets the UI elements to their initial state.""" 239 | if self.worker_thread and self.worker_thread.is_alive(): 240 | messagebox.showwarning("Attention", "Cannot reset while an installation is in progress.") 241 | return 242 | 243 | self.install_path_var.set("") 244 | self.python_exe_var.set("") 245 | self.file_path_var.set("") 246 | self.setup_var.set("") 247 | self.description_text.set("") 248 | self.info_text.set("") 249 | self.setup_combobox.set("") 250 | self.setup_combobox.config(state="disabled", values=[]) 251 | self.start_button.config(state="disabled") 252 | self.log_text.config(state="normal") 253 | self.log_text.delete('1.0', tk.END) 254 | self.log_text.config(state="disabled") 255 | self.progress_var.set(0) 256 | self.k3u_data = None 257 | self.selected_setup_key = None 258 | self.current_setup_data = None 259 | self.current_k3u_type = "external_venv" # Reset type 260 | self.user_inputs = {} 261 | self._config_vars = {} 262 | self.placeholders = {} 263 | # Stop flashing and clear status on reset 264 | self.stop_flashing() 265 | self.update_status_text("") # Clear status text too 266 | self.enable_controls() # Ensure controls are enabled after reset 267 | # Re-enable Python input by default on reset 268 | self.python_label.config(state="normal") 269 | self.python_entry.config(state="normal") 270 | self.browse_python_button.config(state="normal") 271 | self.log("UI Resettata.", tag="INFO") 272 | 273 | def log(self, message, tag=None, is_error=False): 274 | """Appends a message to the log text area and optionally to a file.""" 275 | if tag is None and is_error: 276 | tag = "ERROR" 277 | 278 | def append_log(): 279 | try: 280 | self.log_text.config(state="normal") 281 | if tag: 282 | self.log_text.insert(tk.END, message + "\n", tag) 283 | else: 284 | self.log_text.insert(tk.END, message + "\n") 285 | self.log_text.see(tk.END) 286 | self.log_text.config(state="disabled") 287 | except tk.TclError: 288 | print(f"Warning: Log widget destroyed, could not log: {message}") 289 | 290 | 291 | self.master.after(0, append_log) 292 | 293 | if self.log_file: 294 | try: 295 | with open(self.log_file, "a", encoding="utf-8") as f: 296 | timestamp = time.strftime('%H:%M:%S') 297 | log_prefix = f"[{timestamp}] " 298 | if tag: 299 | log_prefix += f"[{tag}] " 300 | f.write(log_prefix + message + "\n") 301 | except IOError as e: 302 | if not hasattr(self, '_log_file_error_shown'): 303 | print(f"Error writing log file '{self.log_file}': {e}") 304 | self._log_file_error_shown = True 305 | 306 | def browse_file(self): 307 | """Opens a dialog to select the K3U JSON file.""" 308 | if self.worker_thread and self.worker_thread.is_alive(): return 309 | filepath = filedialog.askopenfilename( 310 | title="Seleziona File K3U", 311 | filetypes=[("K3U files", "*.k3u"), ("JSON files", "*.json"), ("All files", "*.*")] 312 | ) 313 | if filepath: 314 | self.file_path_var.set(filepath) 315 | self.load_k3u_file() 316 | 317 | def choose_install_path(self): 318 | """Opens a dialog to select the base installation directory.""" 319 | if self.worker_thread and self.worker_thread.is_alive(): return 320 | path = filedialog.askdirectory(title="Scegli cartella base per l'installazione") 321 | if path: 322 | self.install_path_var.set(path) 323 | self.log(f"Base installation path set to: {path}", tag="INFO") 324 | 325 | def choose_python_exe(self): 326 | """Opens a dialog to select the target Python executable.""" 327 | if self.worker_thread and self.worker_thread.is_alive(): return 328 | filetypes = [("Python Executable", "python.exe"), ("All files", "*.*")] if sys.platform == "win32" else [("Python Executable", "python*"), ("All files", "*.*")] 329 | filepath = filedialog.askopenfilename( 330 | title="Select the target Python executable (if required by K3U)", 331 | filetypes=filetypes 332 | ) 333 | if filepath: 334 | self.python_exe_var.set(filepath) 335 | self.log(f"Python executable target set to: {filepath}", tag="INFO") 336 | 337 | 338 | def load_k3u_file(self): 339 | """Loads and parses the selected K3U JSON file and determines its type.""" 340 | filepath = self.file_path_var.get() 341 | if not filepath or not os.path.exists(filepath): 342 | messagebox.showerror("Errore", "Invalid or missing K3U file.") 343 | return 344 | 345 | try: 346 | with open(filepath, 'r', encoding='utf-8') as f: 347 | self.k3u_data = json.load(f) 348 | 349 | if "setups" not in self.k3u_data or not isinstance(self.k3u_data["setups"], dict) or not self.k3u_data["setups"]: 350 | messagebox.showerror("Errore", "The K3U file does not contain a valid or empty 'setups' section.") 351 | self.reset_ui() 352 | return 353 | 354 | self.current_k3u_type = self.k3u_data.get("k3u_type", "external_venv") 355 | self.log(f"Type K3U detected: {self.current_k3u_type}", tag="INFO") 356 | 357 | if self.current_k3u_type == "embedded": 358 | self.python_label.config(state="disabled") 359 | self.python_entry.config(state="disabled") 360 | self.browse_python_button.config(state="disabled") 361 | self.python_exe_var.set("") 362 | self.log("Input Python Target disabled (setup embedded).", tag="INFO") 363 | else: 364 | self.python_label.config(state="normal") 365 | self.python_entry.config(state="normal") 366 | self.browse_python_button.config(state="normal") 367 | self.log("Input Python Target enabled.", tag="INFO") 368 | 369 | 370 | keys = list(self.k3u_data["setups"].keys()) 371 | self.setup_combobox['values'] = keys 372 | self.setup_combobox.config(state="readonly") 373 | self.setup_combobox.set(keys[0]) 374 | self.on_setup_selected() 375 | self.log(f"File K3U uploaded: {filepath}", tag="SUCCESS") 376 | self.log(f"Available setups: {', '.join(keys)}", tag="INFO") 377 | 378 | except json.JSONDecodeError as e: 379 | err_msg = f"Error parsing the K3U file (invalid JSON):\n{e.msg}\nLinea: {e.lineno}, Colonna: {e.colno}" 380 | messagebox.showerror("Errore JSON", err_msg) 381 | self.reset_ui() 382 | except Exception as e: 383 | messagebox.showerror("Errore", f"Unexpected error while loading the K3U file.\n{e}") 384 | self.reset_ui() 385 | 386 | # get_step_order is no longer needed 387 | 388 | def on_setup_selected(self, event=None): 389 | """Updates UI elements when a setup is selected from the combobox.""" 390 | if not self.k3u_data: return 391 | 392 | self.log_text.config(state="normal") 393 | self.log_text.delete('1.0', tk.END) 394 | self.log_text.config(state="disabled") 395 | 396 | self.selected_setup_key = self.setup_var.get() 397 | setup = self.k3u_data["setups"].get(self.selected_setup_key) 398 | if not setup: 399 | messagebox.showerror("Internal Error", f"Setup '{self.selected_setup_key}' not found in the loaded data") 400 | return 401 | self.current_setup_data = setup 402 | 403 | self.description_text.set(setup.get("description", "No description provided.")) 404 | self.info_text.set(setup.get("info", "No additional information available..")) 405 | self.start_button.config(state="normal") 406 | 407 | self.log(f"--- Setup Preview: {self.selected_setup_key} ---", tag="INFO") 408 | 409 | steps = setup.get("steps", []) 410 | if not steps: 411 | self.log("(No steps defined for this setup!)", tag="WARNING") 412 | 413 | for step_info in steps: 414 | key = step_info.get("key", "CHIAVE_MANCANTE") 415 | step_data = step_info.get("step_data") 416 | self.log(f"[{key.upper()}]", tag="STEP") 417 | 418 | if isinstance(step_data, list): 419 | if not step_data: 420 | self.log(" (No action defined)") 421 | for item in step_data: 422 | if isinstance(item, dict): 423 | descr = item.get("name", "Unrecognized element.") 424 | cmd = item.get("command", "") 425 | # Log custom message if present for preview 426 | msg = item.get("message", "") 427 | log_extra = f" (Msg: {msg})" if msg else (f" (Cmd: {cmd[:60]}{'...' if len(cmd)>60 else ''})" if cmd else "") 428 | self.log(f" - {descr}{log_extra}") 429 | elif isinstance(item, str): 430 | self.log(f" - Comando: {item}") 431 | else: 432 | self.log(f" - Unrecognized element. {item}", tag="WARNING") 433 | 434 | elif isinstance(step_data, dict) and key.startswith("input"): 435 | question = step_data.get("question", f"Input requested for {key}") 436 | self.log(f" ? {question}") 437 | choices = step_data.get("choices", {}) 438 | if not choices: 439 | self.log(" (No selection defined!)", tag="WARNING") 440 | else: 441 | is_first = True 442 | for choice_key, choice_content in choices.items(): 443 | prefix = "[*]" if is_first else "[ ]" 444 | self.log(f" {prefix} {choice_key}") 445 | choice_steps = choice_content.get("steps", []) 446 | if choice_steps: 447 | for c_item in choice_steps: 448 | if isinstance(c_item, dict): 449 | c_descr = c_item.get("name", "Unnamed action") 450 | c_cmd = c_item.get("command", "") 451 | c_msg = c_item.get("message","") 452 | c_log_extra = f" (Msg: {c_msg})" if c_msg else (f" (Cmd: {c_cmd[:50]}{'...' if len(c_cmd)>50 else ''})" if c_cmd else "") 453 | self.log(f" -> {c_descr}{c_log_extra}") 454 | elif isinstance(c_item, str): 455 | self.log(f" -> Comando: {c_item}") 456 | is_first = False 457 | elif isinstance(step_data, dict): 458 | self.log(f" (Specific details for {key} not displayed in the preview)", tag="INFO") 459 | else: 460 | self.log(f" Type of data not recognized for the step '{key}': {type(step_data)}", tag="WARNING") 461 | self.log("--- End preview ---", tag="INFO") 462 | 463 | def open_config_window(self): 464 | """Opens a Toplevel window showing a summary of all steps 465 | and allowing configuration of input steps.""" 466 | if self.worker_thread and self.worker_thread.is_alive(): 467 | messagebox.showwarning("Attention", "Window not available during installation.") 468 | return 469 | if not self.current_setup_data: 470 | messagebox.showerror("Error", "No selected setup.") 471 | return 472 | 473 | config_win = tk.Toplevel(self.master) 474 | config_win.title("Summary and setup configuration") 475 | config_win.geometry(f"{self.main_width - 20}x{self.main_height - 70}") 476 | config_win.minsize(600, 400) 477 | config_win.resizable(True, True) 478 | 479 | config_win.grab_set() 480 | config_win.transient(self.master) 481 | 482 | ttk.Label(config_win, text=f"Plan for: {self.selected_setup_key}", font=("Arial", 12, "bold")).pack(pady=10) 483 | 484 | steps_frame = ttk.Frame(config_win) 485 | steps_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) 486 | 487 | canvas = tk.Canvas(steps_frame) 488 | scrollbar = ttk.Scrollbar(steps_frame, orient="vertical", command=canvas.yview) 489 | scrollable_frame = ttk.Frame(canvas, padding=(10, 5)) 490 | 491 | scrollable_frame.bind("", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) 492 | canvas_window = canvas.create_window((0, 0), window=scrollable_frame, anchor="nw") 493 | canvas.configure(yscrollcommand=scrollbar.set) 494 | 495 | def _configure_scrollable_frame(event): 496 | canvas.itemconfig(canvas_window, width=event.width) 497 | canvas.bind("", _configure_scrollable_frame) 498 | 499 | canvas.pack(side="left", fill="both", expand=True) 500 | scrollbar.pack(side="right", fill="y") 501 | 502 | self._config_vars.clear() 503 | setup_data = self.current_setup_data 504 | steps = setup_data.get("steps", []) 505 | 506 | style = ttk.Style() 507 | style.configure("Step.TLabel", font=("Arial", 10, "bold")) 508 | style.configure("Desc.TLabel", foreground="#333333") 509 | style.configure("InputQ.TLabel", font=("Arial", 10, "bold"), foreground="darkgreen") 510 | style.configure("Action.TLabel", foreground="gray", font=('TkDefaultFont', 8)) 511 | 512 | if not steps: 513 | ttk.Label(scrollable_frame, text="(No step defined for this setup!)").pack(anchor="w", padx=5) 514 | 515 | initial_wraplength = self.main_width - 80 516 | 517 | for step_info in steps: 518 | key = step_info.get("key", "CHIAVE_MANCANTE") 519 | step_data = step_info.get("step_data") 520 | 521 | ttk.Separator(scrollable_frame, orient='horizontal').pack(fill='x', pady=(10, 5), padx=5) 522 | ttk.Label(scrollable_frame, text=f"Step: {key.upper()}", style="Step.TLabel").pack(anchor="w", padx=5) 523 | 524 | if isinstance(step_data, list): 525 | if not step_data: 526 | ttk.Label(scrollable_frame, text="(No defined action)", style="Desc.TLabel", foreground="gray").pack(anchor="w", padx=20) 527 | for item_index, item in enumerate(step_data): 528 | display_text = f"{item_index+1}. " 529 | if isinstance(item, dict): 530 | descr = item.get("name", "Nameless action") 531 | display_text += f"{descr}" 532 | # Show custom message if available 533 | msg = item.get("message") 534 | if msg: display_text += f" -> {msg[:60]}{'...' if len(msg)>60 else ''}" 535 | elif isinstance(item, str): 536 | display_text += f"{item}" 537 | else: 538 | display_text += f"Element not recognized: {str(item)}" 539 | ttk.Label(scrollable_frame, text=display_text, style="Desc.TLabel", wraplength=initial_wraplength - 40).pack(anchor="w", padx=20, fill='x') 540 | 541 | elif isinstance(step_data, dict) and key.startswith("input"): 542 | question = step_data.get("question", f"Input required for {key}") 543 | choices = step_data.get("choices", {}) 544 | 545 | ttk.Label(scrollable_frame, text=question, style="InputQ.TLabel").pack(anchor="w", padx=5, pady=(5, 2)) 546 | 547 | if not choices: 548 | ttk.Label(scrollable_frame, text="(ATTENTION: No choice defined!)", foreground="red").pack(anchor="w", padx=20) 549 | continue 550 | 551 | default_value = list(choices.keys())[0] 552 | current_selection = self.user_inputs.get(key, default_value) 553 | var = tk.StringVar(value=current_selection) 554 | self._config_vars[key] = var 555 | 556 | for choice_key, choice_content in choices.items(): 557 | choice_frame = ttk.Frame(scrollable_frame) 558 | choice_frame.pack(anchor="w", fill="x", padx=15, pady=2) 559 | rb = ttk.Radiobutton(choice_frame, text=choice_key, variable=var, value=choice_key) 560 | rb.pack(side=tk.LEFT, anchor="nw", padx=(0, 5)) 561 | 562 | actions_frame = ttk.Frame(choice_frame) 563 | actions_frame.pack(side=tk.LEFT, fill=tk.X, expand=True) 564 | 565 | steps_in_choice = choice_content.get("steps", []) 566 | if steps_in_choice: 567 | steps_label_text = "Associated actions:\n" + "\n".join([ 568 | f" - {s.get('name', s if isinstance(s, str) else 'Action unknown')[:70]}{'...' if isinstance(s, dict) and len(s.get('name',''))>70 else ('...' if isinstance(s,str) and len(s)>70 else '')}" 569 | + (f" -> {s['message'][:50]}{'...' if len(s['message'])>50 else ''}" if isinstance(s, dict) and s.get('message') else "") # Show message hint 570 | for s in steps_in_choice 571 | ]) 572 | steps_label = ttk.Label(actions_frame, text=steps_label_text, style="Action.TLabel", justify=tk.LEFT, wraplength=initial_wraplength - 150) 573 | steps_label.pack(anchor="nw") 574 | else: 575 | ttk.Label(actions_frame, text="(No associated action)", style="Action.TLabel").pack(anchor="nw") 576 | 577 | elif isinstance(step_data, dict): 578 | ttk.Label(scrollable_frame, text="(Specific details not shown here)", foreground="gray").pack(anchor="w", padx=20) 579 | else: 580 | ttk.Label(scrollable_frame, text=f"(Type of data not recognizedo: {type(step_data)})", foreground="red").pack(anchor="w", padx=20) 581 | 582 | button_frame = ttk.Frame(config_win) 583 | button_frame.pack(pady=10, fill=tk.X, side=tk.BOTTOM) 584 | center_frame = ttk.Frame(button_frame) 585 | center_frame.pack() 586 | confirm_button = ttk.Button(center_frame, text="Confirm and start", 587 | command=lambda w=config_win: self.confirm_config_and_start(w)) 588 | confirm_button.pack(side=tk.LEFT, padx=10) 589 | cancel_button = ttk.Button(center_frame, text="Cancel", command=config_win.destroy) 590 | cancel_button.pack(side=tk.LEFT, padx=10) 591 | 592 | 593 | def confirm_config_and_start(self, config_window): 594 | """Saves selections from config window, prepares placeholders based on k3u_type, and starts the installation thread.""" 595 | self.user_inputs.clear() 596 | for key, var in self._config_vars.items(): 597 | self.user_inputs[key] = var.get() 598 | 599 | self.log("--- User configuration selected ---", tag="INFO") 600 | if not self._config_vars: 601 | self.log("(No input configurable for this setup)") 602 | else: 603 | for key, value in self.user_inputs.items(): 604 | self.log(f"Input '{key}': Scelta = {value}") 605 | self.log("-------------------------------------", tag="INFO") 606 | 607 | if config_window: 608 | config_window.grab_release() 609 | config_window.destroy() 610 | 611 | install_path = self.install_path_var.get() 612 | python_exe_target = self.python_exe_var.get() 613 | 614 | self.log(f"DEBUG: Raw value from install_path_var: '{install_path}'", tag="INFO") 615 | 616 | if not install_path: 617 | messagebox.showerror("Errore", "Base installation path not specified..") 618 | self.enable_controls() 619 | return 620 | parent_dir = os.path.dirname(install_path) 621 | if parent_dir and not os.path.isdir(parent_dir): 622 | messagebox.showerror("Errore", f"The parent directory of the installation path does not exist.:\n{parent_dir}") 623 | self.enable_controls() 624 | return 625 | if os.path.exists(install_path) and not os.path.isdir(install_path): 626 | messagebox.showerror("Errore", f"The base installation path exists but is not a folder.:\n{install_path}") 627 | self.enable_controls() 628 | return 629 | 630 | norm_install_path = os.path.normpath(install_path) 631 | self.log(f"DEBUG: Normalized install path value: '{norm_install_path}'", tag="INFO") 632 | comfyui_dir = os.path.join(norm_install_path, "ComfyUI") 633 | 634 | self.placeholders = { 635 | "{INSTALL_PATH}": norm_install_path, 636 | "{COMFYUI_PATH}": comfyui_dir 637 | } 638 | 639 | if self.current_k3u_type == "embedded": 640 | embed_dir = os.path.join(norm_install_path, "python_embeded") 641 | embed_python_exe = os.path.join(embed_dir, "python.exe") 642 | self.placeholders["{EMBEDDED_PYTHON_DIR}"] = embed_dir 643 | self.placeholders["{EMBEDDED_PYTHON_EXE}"] = embed_python_exe 644 | self.placeholders["{PYTHON_EXE}"] = "" 645 | 646 | elif self.current_k3u_type == "external_venv": 647 | if not python_exe_target: 648 | messagebox.showerror("Errore", "Python target executable not specified (required for setup external_venv).") 649 | self.enable_controls(); return 650 | if not os.path.isfile(python_exe_target): 651 | messagebox.showerror("Errore", f"Python target executable not found:\n{python_exe_target}") 652 | self.enable_controls(); return 653 | norm_python_exe_target = os.path.normpath(python_exe_target) 654 | venv_dir = os.path.join(comfyui_dir, "venv") 655 | venv_python = os.path.join(venv_dir, "Scripts", "python.exe") if sys.platform == "win32" else os.path.join(venv_dir, "bin", "python") 656 | self.placeholders["{PYTHON_EXE}"] = norm_python_exe_target 657 | self.placeholders["{VENV_PATH}"] = venv_dir 658 | self.placeholders["{VENV_PYTHON}"] = venv_python 659 | self.placeholders["{EMBEDDED_PYTHON_DIR}"] = "" 660 | self.placeholders["{EMBEDDED_PYTHON_EXE}"] = "" 661 | else: 662 | messagebox.showwarning("Attenzione", f"Tipo K3U '{self.current_k3u_type}' not recognized.I proceed like 'external_venv'.") 663 | self.current_k3u_type = "external_venv" 664 | if not python_exe_target or not os.path.isfile(python_exe_target): 665 | messagebox.showerror("Errore", "Executable Python Target not specified or not valid.") 666 | self.enable_controls(); return 667 | norm_python_exe_target = os.path.normpath(python_exe_target) 668 | venv_dir = os.path.join(comfyui_dir, "venv") 669 | venv_python = os.path.join(venv_dir, "Scripts", "python.exe") if sys.platform == "win32" else os.path.join(venv_dir, "bin", "python") 670 | self.placeholders["{PYTHON_EXE}"] = norm_python_exe_target 671 | self.placeholders["{VENV_PATH}"] = venv_dir 672 | self.placeholders["{VENV_PYTHON}"] = venv_python 673 | self.placeholders["{EMBEDDED_PYTHON_DIR}"] = "" 674 | self.placeholders["{EMBEDDED_PYTHON_EXE}"] = "" 675 | 676 | self.log("Placeholders impostati:", tag="INFO") 677 | for k,v in self.placeholders.items(): 678 | if v: self.log(f" {k} = {v}") 679 | 680 | # Start flashing and show status frame BEFORE disabling controls 681 | self.update_status_text("Avvio...") 682 | self.start_flashing() 683 | self.disable_controls() 684 | self.start_installation_thread() 685 | 686 | def disable_controls(self): 687 | """Disables UI controls during installation.""" 688 | self.start_button.config(state="disabled") 689 | self.reset_button.config(state="disabled") 690 | self.browse_button.config(state="disabled") 691 | self.browse_path_button.config(state="disabled") 692 | self.browse_python_button.config(state="disabled") 693 | self.setup_combobox.config(state="disabled") 694 | self.path_entry.config(state="disabled") 695 | self.python_entry.config(state="disabled") 696 | self.file_entry.config(state="disabled") 697 | 698 | def enable_controls(self): 699 | """Enables UI controls after installation or on error.""" 700 | self.start_button.config(state="normal" if self.current_setup_data else "disabled") 701 | self.reset_button.config(state="normal") 702 | self.browse_button.config(state="normal") 703 | self.browse_path_button.config(state="normal") 704 | # Enable/disable Python input based on last loaded k3u type 705 | python_input_state = "disabled" if self.current_k3u_type == "embedded" else "normal" 706 | self.browse_python_button.config(state=python_input_state) 707 | self.python_entry.config(state=python_input_state) 708 | self.python_label.config(state=python_input_state) 709 | 710 | self.setup_combobox.config(state="readonly" if self.k3u_data else "disabled") 711 | self.path_entry.config(state="normal") 712 | self.file_entry.config(state="normal") 713 | 714 | 715 | def start_installation_thread(self): 716 | """Prepares and starts the background thread for installation steps.""" 717 | if self.worker_thread is not None and self.worker_thread.is_alive(): 718 | messagebox.showwarning("Attention", "Un processo di installazione è già in corso.") 719 | self.enable_controls() 720 | return 721 | if not self.placeholders or not self.placeholders.get("{INSTALL_PATH}"): 722 | messagebox.showerror("Errore Interno", "Placeholders not correctly initialized before starting the thread.") 723 | self.enable_controls() 724 | # Stop flashing if validation failed after starting it 725 | self.stop_flashing() 726 | self.update_status_text("Error Placeholder") 727 | return 728 | 729 | self.total_steps_for_progress = self._calculate_total_steps() 730 | self.progress_var.set(0) 731 | 732 | self.log("\n=== Installation start ===", tag="INFO") 733 | self.log(f"Selected setup: {self.selected_setup_key} (Tipo: {self.current_k3u_type})") 734 | self.log(f"Basic installation route: {self.placeholders.get('{INSTALL_PATH}', 'N/D')}") 735 | if self.current_k3u_type == "embedded": 736 | self.log(f"Python Embedded Path: {self.placeholders.get('{EMBEDDED_PYTHON_EXE}', 'N/D')}") 737 | else: 738 | self.log(f"Python Target Path: {self.placeholders.get('{PYTHON_EXE}', 'N/D')}") 739 | 740 | if self.user_inputs: 741 | self.log("With the following options:") 742 | for k, v in self.user_inputs.items(): 743 | self.log(f" - {k}: {v}") 744 | 745 | self.worker_thread = threading.Thread(target=self._run_installation_steps, daemon=True) 746 | self.worker_thread.start() 747 | self.master.after(100, self._check_thread_completion) 748 | 749 | def _check_thread_completion(self): 750 | """Periodically checks if the worker thread has finished.""" 751 | if self.worker_thread is not None and self.worker_thread.is_alive(): 752 | self.master.after(100, self._check_thread_completion) 753 | else: 754 | # Stop flashing and update status when thread completes 755 | self.stop_flashing() 756 | # Final status message is set in _run_installation_steps 757 | # self.update_status_text("Completato/Fallito") # Set by thread end 758 | self.enable_controls() 759 | self.worker_thread = None 760 | final_progress = self.progress_var.get() 761 | # Log if incomplete only if some progress was made 762 | if final_progress < 100 and final_progress > 0: 763 | self.log("The installation process is finished (it could be incomplete or failed).", tag="WARNING") 764 | 765 | 766 | def _calculate_total_steps(self): 767 | """Calculates the total number of command items for the progress bar based on the 'steps' structure.""" 768 | count = 0 769 | if not self.current_setup_data or "steps" not in self.current_setup_data: 770 | return 1 771 | 772 | steps_list = self.current_setup_data.get("steps", []) 773 | 774 | temp_user_inputs = self.user_inputs.copy() 775 | if not temp_user_inputs: # Estimate using defaults if run before config 776 | for step_info in steps_list: 777 | key = step_info.get("key") 778 | step_data = step_info.get("step_data") 779 | if isinstance(step_data, dict) and key and key.startswith("input"): 780 | choices = step_data.get("choices", {}) 781 | if choices: 782 | default_choice = list(choices.keys())[0] 783 | temp_user_inputs[key] = default_choice 784 | 785 | for step_info in steps_list: 786 | key = step_info.get("key") 787 | step_data = step_info.get("step_data") 788 | commands_in_step = [] 789 | 790 | if isinstance(step_data, list): 791 | commands_in_step = step_data 792 | elif isinstance(step_data, dict) and key and key.startswith("input"): 793 | user_choice = temp_user_inputs.get(key) # Use temp map for calculation 794 | if user_choice: 795 | choice_data = step_data.get("choices", {}).get(user_choice, {}) 796 | commands_in_step = choice_data.get("steps", []) 797 | 798 | for item in commands_in_step: 799 | if isinstance(item, str) and item.strip(): 800 | count += 1 801 | elif isinstance(item, dict) and item.get("command", "").strip(): 802 | count += 1 803 | 804 | return count if count > 0 else 1 805 | 806 | 807 | def _substitute_placeholders(self, command_string): 808 | """Replaces all known placeholders in a command string.""" 809 | substituted_cmd = command_string 810 | try: 811 | if not self.placeholders: 812 | raise ValueError("Placeholders dictionary not initialized.") 813 | for key, value in sorted(self.placeholders.items(), key=lambda item: len(item[0]), reverse=True): 814 | str_value = str(value) if value is not None else "" 815 | if key.startswith("{") and key.endswith("}"): 816 | substituted_cmd = substituted_cmd.replace(key, str_value) 817 | except Exception as e: 818 | self.log(f"Error during replacement placeholder in '{command_string}': {e}", tag="ERROR") 819 | raise ValueError(f"Failed replacement placeholder for: {command_string}") from e 820 | return substituted_cmd 821 | 822 | 823 | def _run_installation_steps(self): 824 | """Executes the installation steps in the background thread using the 'steps' structure.""" 825 | current_step_count = 0 826 | success = True 827 | final_message = "Successful installation." 828 | final_tag = "SUCCESS" 829 | 830 | base_install_path = self.placeholders.get("{INSTALL_PATH}") 831 | comfyui_base_dir = self.placeholders.get("{COMFYUI_PATH}") 832 | 833 | if not base_install_path: 834 | self.log("Critical error: Placeholder {INSTALL_PATH} undefined.", tag="ERROR") 835 | final_message = "Internal error: missing basic installation route." 836 | final_tag = "ERROR"; success = False 837 | # Update status from thread using after() 838 | self.master.after(0, self.update_status_text, final_message) 839 | self.master.after(0, self.progress_var.set, 0) 840 | return # Stop thread execution 841 | 842 | 843 | try: 844 | # Initial status update from thread 845 | self.master.after(0, self.update_status_text, "In processing...") 846 | 847 | steps_list = self.current_setup_data.get("steps", []) 848 | for step_info in steps_list: 849 | if not success: break 850 | 851 | key = step_info.get("key", "CHIAVE_SCONOSCIUTA") 852 | step_data = step_info.get("step_data") 853 | self.log(f"\n--- Execution step: {key.upper()} ---", tag="STEP") 854 | 855 | commands_to_run = [] 856 | step_source_info = "" 857 | 858 | if isinstance(step_data, list): 859 | commands_to_run = step_data 860 | step_source_info = f"(da '{key}')" 861 | elif isinstance(step_data, dict) and key.startswith("input"): 862 | user_choice = self.user_inputs.get(key) 863 | if user_choice: 864 | step_source_info = f"(da Input '{key}', choice '{user_choice}')" 865 | self.log(f"I run through the user choice: {user_choice}") 866 | choice_data = step_data.get("choices", {}).get(user_choice, {}) 867 | commands_to_run = choice_data.get("steps", []) 868 | if not commands_to_run: 869 | self.log(f" (No step defined for the choice '{user_choice}')", tag="WARNING") 870 | else: 871 | self.log(f"ATTENTION: No user choice found for input '{key}', step saltato.", tag="WARNING") 872 | continue 873 | 874 | for item_index, item in enumerate(commands_to_run): 875 | if not success: break 876 | 877 | command_template = None 878 | name = None 879 | 880 | if isinstance(item, str) and item.strip(): 881 | command_template = item 882 | name = f"{key} - Comando {item_index+1}" 883 | elif isinstance(item, dict): 884 | command_template = item.get("command") 885 | name = item.get("name", f"{key} - Azione {item_index+1}") 886 | else: 887 | self.log(f"Invalid element ignored {step_source_info}: {item}", tag="WARNING") 888 | continue 889 | 890 | if not command_template or not command_template.strip(): 891 | self.log(f"Empty command ignored for '{name}' {step_source_info}", tag="WARNING") 892 | continue 893 | 894 | # Set status text before running command (use custom message if available) 895 | message = item.get("message") if isinstance(item, dict) else None 896 | default_status = f"Execution: {name}..." 897 | status_to_show = message if message else default_status 898 | if len(status_to_show) > 100: status_to_show = status_to_show[:97] + "..." 899 | self.master.after(0, self.update_status_text, status_to_show) 900 | 901 | 902 | try: 903 | final_command = self._substitute_placeholders(command_template) 904 | except ValueError as e: 905 | self.log(str(e), tag="ERROR") 906 | success = False; final_message = "Placeholder replacement error."; final_tag="ERROR"; break 907 | except Exception as e: 908 | self.log(f"Unexpected error during the replacement of the placeholders for [{name}]: {e}", tag="ERROR") 909 | self.log(f"Original command: {command_template}", tag="ERROR") 910 | success = False; final_message = "Placeholder replacement error."; final_tag="ERROR"; break 911 | 912 | self.log(f"--> Run [{name}] {step_source_info}:", tag="CMD") 913 | self.log(f" Command: {final_command}") 914 | 915 | # --- Determine and Validate CWD --- 916 | cwd_template = base_install_path 917 | try: 918 | resolved_comfyui_dir_template = self.placeholders.get("{COMFYUI_PATH}", base_install_path) 919 | resolved_comfyui_dir = self._substitute_placeholders(resolved_comfyui_dir_template) 920 | if os.path.isdir(resolved_comfyui_dir): 921 | cwd_template = resolved_comfyui_dir_template 922 | except Exception as e: 923 | self.log(f"ATTENTION: error in determining CWD default based on Comfyui: {e}", tag="WARNING") 924 | 925 | if "setup.py install" in final_command and "SageAttention" in name: 926 | cwd_template = os.path.join(base_install_path, "temp_sage") 927 | elif key in ["start", "setup_embed_python", "install_include_libs"] or "git clone" in command_template: 928 | cwd_template = base_install_path 929 | elif "custom_nodes" in command_template: 930 | nodes_dir_template = os.path.join(self.placeholders.get("{COMFYUI_PATH}", ""), "custom_nodes") 931 | try: 932 | resolved_nodes_dir = self._substitute_placeholders(nodes_dir_template) 933 | if os.path.isdir(resolved_nodes_dir): 934 | cwd_template = nodes_dir_template 935 | except: pass 936 | 937 | try: 938 | resolved_cwd = self._substitute_placeholders(cwd_template) 939 | resolved_cwd = os.path.normpath(resolved_cwd) 940 | except ValueError as e: 941 | self.log(f"Error while replacing Placeholder for CWD '{cwd_template}': {e}", tag="ERROR") 942 | success = False; final_message = "Error CWD."; final_tag="ERROR"; break 943 | except Exception as e: 944 | self.log(f"Unexpected error while replacing Placeholder for CWD '{cwd_template}': {e}", tag="ERROR") 945 | success = False; final_message = "Error Cwd."; final_tag="ERROR"; break 946 | 947 | if not os.path.isdir(resolved_cwd): 948 | fallback_cwd_template = self.placeholders.get('{INSTALL_PATH}', '.') 949 | try: 950 | resolved_fallback_cwd = self._substitute_placeholders(fallback_cwd_template) 951 | resolved_fallback_cwd = os.path.normpath(resolved_fallback_cwd) 952 | except Exception as e: 953 | self.log(f"Error while replacing Placeholder for Fallback CWD '{fallback_cwd_template}': {e}", tag="ERROR") 954 | success = False; final_message = "Error CWD Fallback."; final_tag="ERROR"; break 955 | 956 | self.log(f" ATTENTION: the work directory '{resolved_cwd}' (da '{cwd_template}') does not exist, use '{resolved_fallback_cwd}'.", tag="WARNING") 957 | resolved_cwd = resolved_fallback_cwd 958 | if not os.path.isdir(resolved_cwd): 959 | self.log(f" Error: also the Fallback Directory '{resolved_cwd}' it does not exist!", tag="ERROR") 960 | success = False; final_message = "Errore CWD Fallback."; final_tag="ERROR"; break 961 | 962 | 963 | # --- Execute Command --- 964 | try: 965 | process = subprocess.run( 966 | final_command, 967 | shell=True, 968 | cwd=resolved_cwd, 969 | capture_output=True, 970 | text=True, 971 | encoding='utf-8', 972 | errors='replace' 973 | ) 974 | 975 | if process.stdout and process.stdout.strip(): 976 | self.log(f" Output:\n{process.stdout.strip()}", tag="OUTPUT") 977 | if process.stderr and process.stderr.strip(): 978 | stderr_tag = "ERROR" if process.returncode != 0 else "WARNING" 979 | self.log(f" Error Output:\n{process.stderr.strip()}", tag=stderr_tag) 980 | 981 | if process.returncode != 0: 982 | self.log(f"Error: Command [{name}] Failed with code. {process.returncode}", tag="ERROR") 983 | success = False 984 | final_message = f"Command '{name}' Failed." 985 | final_tag = "ERROR" 986 | if key.startswith("prequire"): 987 | final_message = f"Prerequisite control '{name}' failed.Impossible to continue." 988 | break # Stop processing commands in this step 989 | else: 990 | self.log(f"<-- Command [{name}] completed.", tag="SUCCESS") 991 | 992 | except FileNotFoundError: 993 | cmd_part = final_command.split()[0] 994 | self.log(f"Error: Command or program not found: '{cmd_part}'. Make sure it is in the path or uses an absolute path.", tag="ERROR") 995 | success = False; final_message = "Command not found."; final_tag="ERROR"; break 996 | except subprocess.TimeoutExpired: 997 | self.log(f"Error: Timeout expired for the command [{name}]", tag="ERROR") 998 | success = False; final_message = "Timeout comando."; final_tag="ERROR"; break 999 | except Exception as e: 1000 | self.log(f"Unexpected error during the execution of [{name}] in CWD '{resolved_cwd}': {e}", tag="ERROR") 1001 | success = False; final_message = "Command execution error."; final_tag="ERROR"; break 1002 | 1003 | # --- Update Progress Bar --- 1004 | current_step_count += 1 1005 | progress = (current_step_count / self.total_steps_for_progress) * 100 if self.total_steps_for_progress > 0 else 100.0 1006 | self.master.after(0, self.progress_var.set, min(progress, 100.0)) 1007 | 1008 | # Reset status to generic "In Lavorazione" if no specific message for next command (optional) 1009 | # Or just let the next loop update it. Let's do that. 1010 | 1011 | 1012 | except OSError as e: 1013 | self.log(f"System error: {e}", tag="ERROR") 1014 | success = False 1015 | final_message = "Installation failed due to a system error." 1016 | final_tag = "ERROR" 1017 | except Exception as e: 1018 | self.log(f"Critical error in the installation process: {e}", tag="ERROR") 1019 | import traceback 1020 | self.log(f"Traceback:\n{traceback.format_exc()}", tag="ERROR") 1021 | success = False 1022 | final_message = "Failed installation due to an unexpected error." 1023 | final_tag = "ERROR" 1024 | 1025 | # --- Final Logging & Status Update --- 1026 | if not success and final_tag != "ERROR": # Catch cases where success is False but no specific message was set 1027 | final_message = "Installation finished with errors." 1028 | final_tag = "ERROR" 1029 | 1030 | self.log(f"\n=== {final_message} ===", tag=final_tag) 1031 | # Update status label one last time from the thread 1032 | self.master.after(0, self.update_status_text, final_message) 1033 | 1034 | final_progress_value = 100.0 if success else self.progress_var.get() 1035 | self.master.after(0, self.progress_var.set, final_progress_value) 1036 | 1037 | 1038 | # ================================== 1039 | # BLOCCO PRINCIPALE 1040 | # QUESTA RIGA DEVE AVERE ZERO INDENTAZIONE (Nessuno spazio/tab prima) 1041 | # ================================== 1042 | if __name__ == "__main__": 1043 | # Il codice qui sotto è indentato sotto l'if 1044 | root = tk.Tk() 1045 | try: 1046 | style = ttk.Style(root) 1047 | # Example theme setting (uncomment to try) 1048 | # available_themes = style.theme_names() 1049 | # print(available_themes) 1050 | # if 'vista' in available_themes: 1051 | # style.theme_use('vista') 1052 | # elif 'clam' in available_themes: 1053 | # style.theme_use('clam') 1054 | except tk.TclError: 1055 | print("ttk themes not available or failed to set.") 1056 | 1057 | app = K3U_Installer_GUI(root) # Crea l'istanza della classe definita sopra 1058 | root.mainloop() 1059 | # ================================== 1060 | # FINE FILE 1061 | # ================================== 1062 | --------------------------------------------------------------------------------