From dc802b5b38932e72a2f919e484d0c05f568b4851 Mon Sep 17 00:00:00 2001 From: DirectX Date: Thu, 23 Apr 2026 20:41:00 +0300 Subject: [PATCH 1/4] minimal-linux-install.sh and linux-run.sh for already installed conda, node, etc. --- .../__pycache__/__init__.cpython-312.pyc | Bin 169 -> 188 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 176 -> 195 bytes .../mlx/__pycache__/__init__.cpython-312.pyc | Bin 1113 -> 1132 bytes .../__pycache__/dit_generate.cpython-312.pyc | Bin 16748 -> 16767 bytes download_model.sh | 81 ++++++ install.sh | 232 +++++++++++++++++ minimal-install-linux.sh | 233 ++++++++++++++++++ python_backend.txt | 1 + reinstall.sh | 112 +++++++++ run-dev.sh | 125 ++++++++++ run-linux.sh | 109 ++++++++ run-no-lm.sh | 94 +++++++ run.sh | 93 +++++++ update.sh | 90 +++++++ 14 files changed, 1170 insertions(+) create mode 100755 download_model.sh create mode 100755 install.sh create mode 100755 minimal-install-linux.sh create mode 100644 python_backend.txt create mode 100755 reinstall.sh create mode 100755 run-dev.sh create mode 100755 run-linux.sh create mode 100755 run-no-lm.sh create mode 100755 run.sh create mode 100755 update.sh diff --git a/ACE-Step-1.5/acestep/models/__pycache__/__init__.cpython-312.pyc b/ACE-Step-1.5/acestep/models/__pycache__/__init__.cpython-312.pyc index 5b7ab36c6a584431e4a8a6eb53bf621eb0e4f647..763db4a0ca3fe9d66b19e0bade8d0f9e5f38bf02 100644 GIT binary patch delta 106 zcmZ3b>KSU)|pB%?G* w-zBpM$c@lBCnyHhl^EAKv8~HYH~?&Oo*#*K#Zfat8Q>fY5|Za eP07qh@D24$V-k~7i-B@6x%nxnImIy(`*i`$upNc~ diff --git a/ACE-Step-1.5/acestep/models/common/__pycache__/__init__.cpython-312.pyc b/ACE-Step-1.5/acestep/models/common/__pycache__/__init__.cpython-312.pyc index ae6a2980a8119f6e3e8784aaeea325326a1d210a..3aed22cbc55c908b54d334134216cfeb5984fbfd 100644 GIT binary patch delta 111 zcmdnMc$ks`JnnxyZN zSp?)p=sP;Q>IRpj766ITl+1ht-%!s~KQTGA7$~Qoo1c=JQ>>qypPQSXr$4b-7XZ*T BC1(Ht delta 92 zcmX@ixPg)TG%qg~0}wp&zd4cH*wx>~Dkh*PKPxr4q&OzT)i)r<(b-iuxFodzNR*~z j<|FuqdZsan$*ILaxtQGil+>K!nB@H2-2A+liPLleSz#ZG diff --git a/ACE-Step-1.5/acestep/models/mlx/__pycache__/__init__.cpython-312.pyc b/ACE-Step-1.5/acestep/models/mlx/__pycache__/__init__.cpython-312.pyc index db0e0162d3759149d9f9056d442badcb35817ef7..10ccfa5d2c3e14fb15747c55ac2922855f7cf560 100644 GIT binary patch delta 113 zcmcb~@rHxb>KI3~o^Hz3B**;O~VB((rY ll%{0nBlw1TrZI`hsl`CKnB4r7)STj&+?~vm6}{qte>7) zl2MwZ?~+*rf pY5|ZaP07qh@D24$V-k~7i-B@6x%nxnImI!#ITbOR+qr(20RUMCB7^_{ diff --git a/download_model.sh b/download_model.sh new file mode 100755 index 0000000..d4e76a7 --- /dev/null +++ b/download_model.sh @@ -0,0 +1,81 @@ +#!/bin/bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +export HF_HOME="$SCRIPT_DIR/models" +export HUGGINGFACE_HUB_CACHE="$SCRIPT_DIR/models" +export HF_HUB_ENABLE_HF_TRANSFER=1 + +if [ ! -f "venv/bin/python" ]; then + echo "ERROR: Python venv not found! Run install.sh first." + exit 1 +fi + +PYTHON="$SCRIPT_DIR/venv/bin/python" + +echo "========================================" +echo " ACE-Step Studio - Download Models" +echo "========================================" +echo "" +echo "Select model to download:" +echo "" +echo " 1. XL Turbo - 18.8 GB, fast, 8 steps" +echo " 2. XL SFT - 18.8 GB, best quality, 50 steps" +echo " 3. XL Turbo BF16 - 7.5 GB, compact, less VRAM" +echo " 4. Download all three" +echo "" +read -rp "Enter number 1-4: " MODEL_CHOICE + +case "$MODEL_CHOICE" in + 1) + echo "" + echo "Downloading ACE-Step XL Turbo..." + "$PYTHON" -m huggingface_hub.commands.huggingface_cli download \ + ACE-Step/acestep-v15-xl-turbo \ + --local-dir "ACE-Step-1.5/checkpoints/acestep-v15-xl-turbo" + ;; + 2) + echo "" + echo "Downloading ACE-Step XL SFT..." + "$PYTHON" -m huggingface_hub.commands.huggingface_cli download \ + ACE-Step/acestep-v15-xl-sft \ + --local-dir "ACE-Step-1.5/checkpoints/acestep-v15-xl-sft" + ;; + 3) + echo "" + echo "Downloading ACE-Step XL Turbo BF16..." + "$PYTHON" -m huggingface_hub.commands.huggingface_cli download \ + marcorez8/acestep-v15-xl-turbo-bf16 \ + --local-dir "ACE-Step-1.5/checkpoints/acestep-v15-xl-turbo-bf16" + ;; + 4) + echo "" + echo "Downloading all three models..." + echo "" + echo "[1/3] XL Turbo..." + "$PYTHON" -m huggingface_hub.commands.huggingface_cli download \ + ACE-Step/acestep-v15-xl-turbo \ + --local-dir "ACE-Step-1.5/checkpoints/acestep-v15-xl-turbo" + echo "" + echo "[2/3] XL SFT..." + "$PYTHON" -m huggingface_hub.commands.huggingface_cli download \ + ACE-Step/acestep-v15-xl-sft \ + --local-dir "ACE-Step-1.5/checkpoints/acestep-v15-xl-sft" + echo "" + echo "[3/3] XL Turbo BF16..." + "$PYTHON" -m huggingface_hub.commands.huggingface_cli download \ + marcorez8/acestep-v15-xl-turbo-bf16 \ + --local-dir "ACE-Step-1.5/checkpoints/acestep-v15-xl-turbo-bf16" + ;; + *) + echo "Invalid choice!" + exit 1 + ;; +esac + +echo "" +echo "========================================" +echo " Download complete!" +echo "========================================" diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..b98893c --- /dev/null +++ b/install.sh @@ -0,0 +1,232 @@ +#!/bin/bash +set -euo pipefail + +echo "========================================" +echo " ACE-Step Studio - Install" +echo "========================================" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +export TMPDIR="$SCRIPT_DIR/temp" +mkdir -p downloads temp models cache app/data app/server/public/audio + +OS="$(uname -s)" +ARCH="$(uname -m)" + +# ============================================================ +# Step 1: GPU / compute backend selection +# ============================================================ +echo "" + +if [ "$OS" = "Darwin" ]; then + echo "Select your compute backend:" + echo "" + echo " 1. Apple Silicon (MPS)" + echo " 2. CPU only" + echo "" + read -rp "Enter number (1-2): " GPU_CHOICE + case "$GPU_CHOICE" in + 1) CUDA_VERSION="mps"; CUDA_NAME="Apple Silicon (MPS)";; + 2) CUDA_VERSION="cpu"; CUDA_NAME="CPU only";; + *) echo "Invalid choice!"; exit 1;; + esac +else + echo "Select your GPU:" + echo "" + echo " 1. NVIDIA GTX 10xx (Pascal)" + echo " 2. NVIDIA RTX 20xx (Turing)" + echo " 3. NVIDIA RTX 30xx (Ampere)" + echo " 4. NVIDIA RTX 40xx (Ada Lovelace)" + echo " 5. NVIDIA RTX 50xx (Blackwell)" + echo " 6. CPU only (no GPU)" + echo "" + read -rp "Enter number (1-6): " GPU_CHOICE + case "$GPU_CHOICE" in + 1) CUDA_VERSION="cu118"; CUDA_NAME="CUDA 11.8 (GTX 10xx)";; + 2) CUDA_VERSION="cu126"; CUDA_NAME="CUDA 12.6 (RTX 20xx)";; + 3) CUDA_VERSION="cu126"; CUDA_NAME="CUDA 12.6 (RTX 30xx)";; + 4) CUDA_VERSION="cu128"; CUDA_NAME="CUDA 12.8 (RTX 40xx)";; + 5) CUDA_VERSION="cu128"; CUDA_NAME="CUDA 12.8 (RTX 50xx)";; + 6) CUDA_VERSION="cpu"; CUDA_NAME="CPU only";; + *) echo "Invalid choice!"; exit 1;; + esac +fi + +TORCH_VERSION="2.7.1" +TORCHAUDIO_VERSION="2.7.1" + +echo "" +echo "Selected: $CUDA_NAME" +echo "" + +# ============================================================ +# Step 2: Python virtual environment +# ============================================================ +if [ -f "venv/bin/python" ]; then + echo "[OK] Python venv already exists" +else + echo "[1/7] Setting up Python virtual environment..." + PYTHON_CMD="" + for py in python3.12 python3.11 python3.10 python3; do + if command -v "$py" &>/dev/null; then + PYTHON_CMD="$py" + break + fi + done + if [ -z "$PYTHON_CMD" ]; then + echo "ERROR: Python 3.10+ not found! Install Python 3.12 first." + echo " Linux: sudo apt install python3.12 python3.12-venv" + echo " Mac: brew install python@3.12" + exit 1 + fi + "$PYTHON_CMD" -m venv venv + echo "[OK] Python venv created using $PYTHON_CMD" +fi + +PYTHON="$SCRIPT_DIR/venv/bin/python" + +# ============================================================ +# Step 3: pip +# ============================================================ +echo "[2/7] Upgrading pip..." +"$PYTHON" -m pip install --upgrade pip --quiet + +# ============================================================ +# Step 4: PyTorch +# ============================================================ +echo "[3/7] Installing PyTorch $TORCH_VERSION ($CUDA_NAME)..." +if [ "$OS" = "Darwin" ]; then + "$PYTHON" -m pip install \ + torch==$TORCH_VERSION torchaudio==$TORCHAUDIO_VERSION torchvision +else + "$PYTHON" -m pip install \ + torch==$TORCH_VERSION torchaudio==$TORCHAUDIO_VERSION torchvision \ + --index-url "https://download.pytorch.org/whl/$CUDA_VERSION" +fi + +# ============================================================ +# Step 5: ACE-Step dependencies +# ============================================================ +echo "[4/7] Installing ACE-Step dependencies..." +"$PYTHON" -m pip install hatchling editables + +"$PYTHON" -m pip install \ + -e ACE-Step-1.5/acestep/third_parts/nano-vllm/ + +"$PYTHON" -m pip install \ + "transformers>=4.51.0,<4.58.0" diffusers gradio==6.2.0 \ + matplotlib scipy soundfile loguru einops accelerate fastapi diskcache \ + "uvicorn[standard]" numba vector-quantize-pytorch torchcodec \ + "torchao>=0.16.0,<0.17.0" toml peft modelscope tensorboard \ + typer-slim hf_transfer hf_xet lightning lycoris-lora safetensors xxhash + +if [ "$CUDA_VERSION" != "cpu" ] && [ "$CUDA_VERSION" != "mps" ]; then + echo "Installing Triton for torch.compile..." + "$PYTHON" -m pip install "triton>=3.0.0,<3.4" +fi + +if [ "$CUDA_VERSION" = "cu128" ] && [ "$OS" != "Darwin" ]; then + echo "Installing Flash Attention 2..." + "$PYTHON" -m pip install flash-attn --no-build-isolation || \ + echo "WARNING: Flash Attention failed to install. Continuing without it." +fi + +"$PYTHON" -m pip install -e ACE-Step-1.5/ --no-deps + +# ============================================================ +# Step 6: Node.js +# ============================================================ +NODE_VERSION="22.18.0" + +if [ -f "node/bin/node" ]; then + echo "[OK] Node.js already installed" +else + echo "[5/7] Downloading Node.js 22 LTS..." + mkdir -p node + + if [ "$OS" = "Darwin" ]; then + if [ "$ARCH" = "arm64" ]; then + NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-darwin-arm64.tar.gz" + else + NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-darwin-x64.tar.gz" + fi + curl -fL "$NODE_URL" -o downloads/node.tar.gz + tar -xzf downloads/node.tar.gz -C node/ --strip-components=1 + else + NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" + curl -fL "$NODE_URL" -o downloads/node.tar.xz + tar -xJf downloads/node.tar.xz -C node/ --strip-components=1 + fi + echo "[OK] Node.js 22 LTS installed" +fi + +export PATH="$SCRIPT_DIR/node/bin:$PATH" + +# ============================================================ +# Step 7: npm dependencies +# ============================================================ +echo "[6/7] Installing npm dependencies..." + +echo " Installing frontend deps..." +cd "$SCRIPT_DIR/app" +"$SCRIPT_DIR/node/bin/npm" install + +echo " Installing server deps..." +cd "$SCRIPT_DIR/app/server" +"$SCRIPT_DIR/node/bin/npm" install + +# ============================================================ +# Step 8: Build frontend +# ============================================================ +echo "[7/7] Building frontend..." +cd "$SCRIPT_DIR/app" +"$SCRIPT_DIR/node/bin/npx" vite build + +# ============================================================ +# Step 9: FFmpeg +# ============================================================ +cd "$SCRIPT_DIR" + +if [ -f "ffmpeg/ffmpeg" ]; then + echo "[OK] FFmpeg already installed" +elif command -v ffmpeg &>/dev/null; then + echo "[OK] FFmpeg found in system PATH" +else + echo "Downloading FFmpeg..." + mkdir -p ffmpeg + + if [ "$OS" = "Darwin" ]; then + if [ "$ARCH" = "arm64" ]; then + FFMPEG_URL="https://evermeet.cx/ffmpeg/getrelease/ffmpeg/zip" + else + FFMPEG_URL="https://evermeet.cx/ffmpeg/getrelease/ffmpeg/zip" + fi + curl -fL "$FFMPEG_URL" -o downloads/ffmpeg.zip + unzip -q downloads/ffmpeg.zip -d ffmpeg/ + chmod +x ffmpeg/ffmpeg + else + FFMPEG_URL="https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz" + curl -fL "$FFMPEG_URL" -o downloads/ffmpeg.tar.xz + mkdir -p downloads/ffmpeg-extract + tar -xJf downloads/ffmpeg.tar.xz -C downloads/ffmpeg-extract/ --strip-components=1 + cp downloads/ffmpeg-extract/bin/ffmpeg ffmpeg/ffmpeg + cp downloads/ffmpeg-extract/bin/ffprobe ffmpeg/ffprobe + rm -rf downloads/ffmpeg-extract + chmod +x ffmpeg/ffmpeg ffmpeg/ffprobe + fi + echo "[OK] FFmpeg installed" +fi + +# ============================================================ +# Save GPU config +# ============================================================ +echo "$CUDA_VERSION" > cuda_version.txt + +echo "" +echo "========================================" +echo " Installation complete!" +echo "" +echo " To start: ./run.sh" +echo " Models download automatically on first run." +echo "========================================" diff --git a/minimal-install-linux.sh b/minimal-install-linux.sh new file mode 100755 index 0000000..1e8d57a --- /dev/null +++ b/minimal-install-linux.sh @@ -0,0 +1,233 @@ +#!/bin/bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "===========================================" +echo " ACE-Step Studio - Minimal Linux Install" +echo "===========================================" +echo "" + +# ================================================================ +# Phase 1: Dependency checks (collect ALL issues before failing) +# ================================================================ +ERRORS=() +WARNINGS=() + +# --- CUDA drivers --- +if command -v nvidia-smi &>/dev/null; then + CUDA_DRIVER="$(nvidia-smi --query-gpu=driver_version --format=csv,noheader 2>/dev/null | head -1 || true)" + CUDA_VERSION_DETECTED="$(nvidia-smi | grep -oP 'CUDA Version: \K[0-9.]+' 2>/dev/null || true)" + echo "[OK] NVIDIA driver: $CUDA_DRIVER (CUDA $CUDA_VERSION_DETECTED)" +else + WARNINGS+=("nvidia-smi not found - GPU acceleration unavailable. PyTorch will run on CPU.") + CUDA_VERSION_DETECTED="" +fi + +# --- conda --- +CONDA_CMD="" +if command -v conda &>/dev/null; then + CONDA_CMD="conda" + echo "[OK] conda: $(conda --version)" +elif command -v mamba &>/dev/null; then + CONDA_CMD="mamba" + echo "[OK] mamba: $(mamba --version | head -1)" +else + ERRORS+=("conda/mamba not found. Install Miniconda: https://docs.conda.io/en/latest/miniconda.html") +fi + +# --- Python (via conda env or system) --- +PYTHON="" +CONDA_ENV_NAME="acestep" +if [ -n "$CONDA_CMD" ]; then + if conda env list 2>/dev/null | grep -q "^${CONDA_ENV_NAME}[[:space:]]"; then + PYTHON="$(conda run -n "$CONDA_ENV_NAME" which python 2>/dev/null || true)" + if [ -n "$PYTHON" ]; then + PY_VER="$("$PYTHON" --version 2>&1)" + echo "[OK] conda env '$CONDA_ENV_NAME': $PY_VER" + fi + fi +fi +if [ -z "$PYTHON" ]; then + for py in python3.12 python3.11 python3.10; do + if command -v "$py" &>/dev/null; then + PYTHON="$(command -v "$py")" + echo "[OK] System Python: $("$PYTHON" --version)" + break + fi + done +fi +if [ -z "$PYTHON" ]; then + ERRORS+=("Python 3.10+ not found. Run: conda create -n acestep python=3.12") +fi + +# --- pip --- +if [ -n "$PYTHON" ] && ! "$PYTHON" -m pip --version &>/dev/null 2>&1; then + ERRORS+=("pip not available for $PYTHON. Run: $PYTHON -m ensurepip") +fi + +# --- Node.js --- +NODE_MIN=18 +if command -v node &>/dev/null; then + NODE_VER_FULL="$(node --version)" + NODE_MAJOR="${NODE_VER_FULL#v}" + NODE_MAJOR="${NODE_MAJOR%%.*}" + if [ "$NODE_MAJOR" -ge "$NODE_MIN" ]; then + echo "[OK] node: $NODE_VER_FULL" + else + ERRORS+=("Node.js $NODE_VER_FULL is too old (need v${NODE_MIN}+). Install: https://nodejs.org/en/download") + fi +else + ERRORS+=("node not found. Install: https://nodejs.org/en/download or sudo apt install nodejs npm") +fi + +# --- npm --- +if command -v npm &>/dev/null; then + echo "[OK] npm: $(npm --version)" +else + ERRORS+=("npm not found. Install alongside Node.js.") +fi + +# --- ffmpeg --- +if command -v ffmpeg &>/dev/null; then + FFMPEG_VER="$(ffmpeg -version 2>&1 | head -1 | grep -oP 'ffmpeg version \K\S+')" + echo "[OK] ffmpeg: $FFMPEG_VER" +else + WARNINGS+=("ffmpeg not found - video rendering will not work. Fix: sudo apt install ffmpeg") +fi + +# --- git --- +if command -v git &>/dev/null; then + echo "[OK] git: $(git --version)" +else + ERRORS+=("git not found. Fix: sudo apt install git") +fi + +# --- ACE-Step source --- +if [ ! -d "ACE-Step-1.5" ]; then + ERRORS+=("ACE-Step-1.5/ source directory not found in $SCRIPT_DIR") +fi + +# --- Print warnings --- +if [ ${#WARNINGS[@]} -gt 0 ]; then + echo "" + for w in "${WARNINGS[@]}"; do + echo " [WARN] $w" + done +fi + +# --- Abort on errors --- +if [ ${#ERRORS[@]} -gt 0 ]; then + echo "" + echo "==========================================" + echo " Missing dependencies - cannot proceed:" + echo "==========================================" + for e in "${ERRORS[@]}"; do + echo " [MISSING] $e" + done + echo "" + echo "Install the above, then re-run this script." + exit 1 +fi + +echo "" +echo "All required dependencies found. Proceeding with install..." +echo "" + +# ============================================================ +# Phase 2: Conda environment +# ============================================================ +if ! conda env list 2>/dev/null | grep -q "^${CONDA_ENV_NAME}[[:space:]]"; then + echo "[1/4] Creating conda environment '$CONDA_ENV_NAME' (Python 3.12)..." + $CONDA_CMD create -y -n "$CONDA_ENV_NAME" python=3.12 + echo "[OK] Conda env created" +else + echo "[1/4] Conda env '$CONDA_ENV_NAME' already exists" +fi + +PYTHON="$(conda run -n "$CONDA_ENV_NAME" which python)" + +# ============================================================ +# Phase 3: Python packages +# ============================================================ +echo "[2/4] Installing Python packages..." + +# Detect CUDA version for PyTorch index +if [ -n "$CUDA_VERSION_DETECTED" ]; then + CUDA_MAJOR="${CUDA_VERSION_DETECTED%%.*}" + CUDA_MINOR="$(echo "$CUDA_VERSION_DETECTED" | cut -d. -f2)" + CUDA_NUM="${CUDA_MAJOR}${CUDA_MINOR}" + if [ "$CUDA_NUM" -ge 128 ]; then TORCH_INDEX="cu128" + elif [ "$CUDA_NUM" -ge 126 ]; then TORCH_INDEX="cu126" + elif [ "$CUDA_NUM" -ge 118 ]; then TORCH_INDEX="cu118" + else TORCH_INDEX="cpu" + fi +else + TORCH_INDEX="cpu" +fi + +echo " PyTorch index: $TORCH_INDEX" + +conda run -n "$CONDA_ENV_NAME" pip install --upgrade pip --quiet + +conda run -n "$CONDA_ENV_NAME" pip install \ + torch==2.7.1 torchaudio==2.7.1 torchvision \ + --index-url "https://download.pytorch.org/whl/$TORCH_INDEX" + +conda run -n "$CONDA_ENV_NAME" pip install hatchling editables + +conda run -n "$CONDA_ENV_NAME" pip install \ + -e ACE-Step-1.5/acestep/third_parts/nano-vllm/ --quiet + +conda run -n "$CONDA_ENV_NAME" pip install \ + "transformers>=4.51.0,<4.58.0" diffusers gradio==6.2.0 \ + matplotlib scipy soundfile loguru einops accelerate fastapi diskcache \ + "uvicorn[standard]" numba vector-quantize-pytorch torchcodec \ + "torchao>=0.16.0,<0.17.0" toml peft modelscope tensorboard \ + typer-slim hf_transfer hf_xet lightning lycoris-lora safetensors xxhash + +if [ "$TORCH_INDEX" != "cpu" ]; then + conda run -n "$CONDA_ENV_NAME" pip install "triton>=3.0.0,<3.4" || \ + echo " [WARN] triton install failed - torch.compile will be unavailable" +fi + +conda run -n "$CONDA_ENV_NAME" pip install -e ACE-Step-1.5/ --no-deps + +echo "[OK] Python packages installed" + +# ============================================================ +# Phase 4: npm dependencies + frontend build +# ============================================================ +echo "[3/4] Installing npm dependencies..." + +mkdir -p app/data app/server/public/audio + +cd "$SCRIPT_DIR/app" +npm install + +cd "$SCRIPT_DIR/app/server" +npm install + +echo "[4/4] Building frontend..." +cd "$SCRIPT_DIR/app" +npx vite build + +# ============================================================ +# Save config +# ============================================================ +cd "$SCRIPT_DIR" +echo "$TORCH_INDEX" > cuda_version.txt +echo "conda:$CONDA_ENV_NAME" > python_backend.txt + +echo "" +echo "========================================" +echo " Install complete!" +echo "" +echo " Conda env : $CONDA_ENV_NAME" +echo " PyTorch : $TORCH_INDEX" +echo "" +echo " To start : conda run -n $CONDA_ENV_NAME bash run.sh" +echo " Or activate first:" +echo " conda activate $CONDA_ENV_NAME && ./run.sh" +echo "========================================" diff --git a/python_backend.txt b/python_backend.txt new file mode 100644 index 0000000..1f330bc --- /dev/null +++ b/python_backend.txt @@ -0,0 +1 @@ +conda:acestep diff --git a/reinstall.sh b/reinstall.sh new file mode 100755 index 0000000..078f33f --- /dev/null +++ b/reinstall.sh @@ -0,0 +1,112 @@ +#!/bin/bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "========================================" +echo " ACE-Step Studio - Clean Reinstall" +echo "========================================" +echo "" +echo " This will DELETE and reinstall:" +echo " - venv/ (Python + all packages)" +echo " - node/ (Node.js runtime)" +echo " - app/node_modules (npm packages)" +echo " - app/server/node_modules" +echo " - app/dist (frontend build)" +echo " - downloads/ (cached installers)" +echo "" +echo " This will KEEP (safe):" +echo " - models/ (downloaded models)" +echo " - output/ (generated audio)" +echo " - cache/ (HF cache with models)" +echo " - app/data/ (database, settings)" +echo " - app/server/public/audio/ (saved songs)" +echo " - datasets/ (training data)" +echo " - ffmpeg/ (ffmpeg binary)" +echo " - lora_output/ (trained LoRAs)" +echo " - ACE-Step-1.5/ (source code, not deps)" +echo " - cuda_version.txt (GPU config)" +echo "" + +read -rp "Type YES to continue: " CONFIRM +if [ "$CONFIRM" != "YES" ]; then + echo "Cancelled." + exit 0 +fi + +echo "" +echo "============================================================" +echo " Cleaning software directories..." +echo "============================================================" + +echo "IMPORTANT: Close ACE-Step Studio (run.sh) before continuing!" +echo "If the app is running, files may be locked and cleanup will fail." +echo "" + +if [ -d "venv" ]; then + echo "Removing venv/..." + rm -rf venv + echo " [OK] venv removed" +fi + +if [ -d "node" ]; then + echo "Removing node/..." + rm -rf node + echo " [OK] node removed" +fi + +if [ -d "app/node_modules" ]; then + echo "Removing app/node_modules/..." + rm -rf app/node_modules + echo " [OK] app/node_modules removed" +fi + +if [ -d "app/server/node_modules" ]; then + echo "Removing app/server/node_modules/..." + rm -rf app/server/node_modules + echo " [OK] app/server/node_modules removed" +fi + +if [ -d "app/dist" ]; then + echo "Removing app/dist/..." + rm -rf app/dist + echo " [OK] app/dist removed" +fi + +if [ -d "downloads" ]; then + echo "Removing downloads/..." + rm -rf downloads + echo " [OK] downloads removed" +fi + +[ -f "app/package-lock.json" ] && rm -f app/package-lock.json +[ -f "app/server/package-lock.json" ] && rm -f app/server/package-lock.json + +# ============================================================ +# Pull latest code before installing +# ============================================================ +if command -v git &>/dev/null && [ -d ".git" ]; then + echo "" + echo "Pulling latest code..." + git stash 2>/dev/null || true + git pull + git stash pop 2>/dev/null || true + echo " [OK] Code updated" +fi + +if [ -f "cuda_version.txt" ]; then + SAVED_CUDA="$(cat cuda_version.txt)" + echo "" + echo "NOTE: Your previous GPU config was: $SAVED_CUDA" + echo " install.sh will ask you to select GPU again." + echo " Choose the same option to keep your config." +fi + +echo "" +echo "============================================================" +echo " Starting fresh install..." +echo "============================================================" +echo "" + +bash "$SCRIPT_DIR/install.sh" diff --git a/run-dev.sh b/run-dev.sh new file mode 100755 index 0000000..98ba057 --- /dev/null +++ b/run-dev.sh @@ -0,0 +1,125 @@ +#!/bin/bash +set -euo pipefail + +echo "========================================" +echo " ACE-Step Studio" +echo "========================================" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# === Checks === +if [ ! -f "venv/bin/python" ]; then + echo "ERROR: Python venv not found! Run install.sh first" + exit 1 +fi +if [ ! -f "node/bin/node" ]; then + echo "ERROR: Node.js not found! Run install.sh first" + exit 1 +fi +if [ ! -d "ACE-Step-1.5" ]; then + echo "ERROR: ACE-Step-1.5 not found!" + exit 1 +fi + +# === Environment isolation === +export TMPDIR="$SCRIPT_DIR/temp" +mkdir -p "$TMPDIR" + +export HF_HOME="$SCRIPT_DIR/models" +export HUGGINGFACE_HUB_CACHE="$SCRIPT_DIR/models" +export TRANSFORMERS_CACHE="$SCRIPT_DIR/models" +export HF_HUB_ENABLE_HF_TRANSFER=1 +mkdir -p "$HF_HOME" + +export TORCH_HOME="$SCRIPT_DIR/models/torch" +mkdir -p "$TORCH_HOME" + +export XDG_CACHE_HOME="$SCRIPT_DIR/cache" +mkdir -p "$XDG_CACHE_HOME" + +if [ -f "$SCRIPT_DIR/ffmpeg/ffmpeg" ]; then + export PATH="$SCRIPT_DIR/ffmpeg:$PATH" +fi + +export PYTHONIOENCODING=utf-8 +export PYTHONUNBUFFERED=1 +export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True + +export PATH="$SCRIPT_DIR/node/bin:$PATH" + +# === Default model === +export DEFAULT_MODEL="acestep-v15-xl-turbo" +export ACESTEP_API_URL="http://localhost:8001" +export ACESTEP_PATH="$SCRIPT_DIR/ACE-Step-1.5" +export PYTHON_PATH="$SCRIPT_DIR/venv/bin/python" + +if [ -f "cuda_version.txt" ]; then + CUDA_VERSION="$(cat cuda_version.txt)" + echo "GPU: $CUDA_VERSION" +fi + +# === Install npm deps if needed === +if [ ! -d "app/node_modules" ]; then + echo "Installing npm dependencies..." + cd app + "$SCRIPT_DIR/node/bin/npm" install + cd "$SCRIPT_DIR" +fi + +# === Create output dirs === +mkdir -p app/data app/server/public/audio + +echo "" +echo "Starting 3 services:" +echo " [1] Gradio pipeline (port 8001)" +echo " [2] Express backend (port 3001)" +echo " [3] Vite frontend (port 3000)" +echo "" + +# === Cleanup on exit === +GRADIO_PID="" +EXPRESS_PID="" + +cleanup() { + echo "" + echo "Shutting down..." + [ -n "$GRADIO_PID" ] && kill "$GRADIO_PID" 2>/dev/null || true + [ -n "$EXPRESS_PID" ] && kill "$EXPRESS_PID" 2>/dev/null || true + echo "Done." +} +trap cleanup EXIT INT TERM + +# === Start Gradio pipeline === +echo "Starting Gradio pipeline with $DEFAULT_MODEL..." +cd "$SCRIPT_DIR/ACE-Step-1.5" +"$SCRIPT_DIR/venv/bin/python" -m acestep.acestep_v15_pipeline \ + --config_path "$DEFAULT_MODEL" \ + --port 8001 \ + --init_service true \ + --init_llm true & +GRADIO_PID=$! + +echo "Waiting for Gradio to initialize..." +sleep 5 + +# === Start Express backend === +echo "Starting Express backend..." +cd "$SCRIPT_DIR/app/server" +"$SCRIPT_DIR/node/bin/node" \ + "$SCRIPT_DIR/app/server/node_modules/tsx/dist/cli.mjs" \ + src/index.ts & +EXPRESS_PID=$! + +sleep 2 + +# === Start Vite frontend (foreground) === +echo "" +echo "========================================" +echo " UI will open at http://localhost:3000" +echo " Press Ctrl+C to stop all services" +echo "========================================" +echo "" + +cd "$SCRIPT_DIR/app" +"$SCRIPT_DIR/node/bin/npx" vite --open diff --git a/run-linux.sh b/run-linux.sh new file mode 100755 index 0000000..e665b66 --- /dev/null +++ b/run-linux.sh @@ -0,0 +1,109 @@ +#!/bin/bash +set -euo pipefail + +echo "========================================" +echo " ACE-Step Studio (Single Terminal)" +echo "========================================" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# === Resolve Python backend === +CONDA_ENV_NAME="acestep" +if [ -f "python_backend.txt" ]; then + BACKEND="$(cat python_backend.txt)" + if [[ "$BACKEND" == conda:* ]]; then + CONDA_ENV_NAME="${BACKEND#conda:}" + fi +fi + +# === Checks === +if ! conda env list 2>/dev/null | grep -q "^${CONDA_ENV_NAME}[[:space:]]"; then + echo "ERROR: conda env '$CONDA_ENV_NAME' not found! Run minimal-install-linux.sh first" + exit 1 +fi + +PYTHON="$(conda run -n "$CONDA_ENV_NAME" which python 2>/dev/null || true)" +if [ -z "$PYTHON" ]; then + echo "ERROR: Python not found in conda env '$CONDA_ENV_NAME'" + exit 1 +fi + +if ! command -v node &>/dev/null; then + echo "ERROR: node not found! Install Node.js 18+ from https://nodejs.org" + exit 1 +fi + +if [ ! -d "ACE-Step-1.5" ]; then + echo "ERROR: ACE-Step-1.5 not found!" + exit 1 +fi + +# === Environment isolation === +export TMPDIR="$SCRIPT_DIR/temp" +mkdir -p "$TMPDIR" + +export HF_HOME="$SCRIPT_DIR/models" +export HUGGINGFACE_HUB_CACHE="$SCRIPT_DIR/models" +export TRANSFORMERS_CACHE="$SCRIPT_DIR/models" +export HF_HUB_ENABLE_HF_TRANSFER=1 +mkdir -p "$HF_HOME" + +export TORCH_HOME="$SCRIPT_DIR/models/torch" +mkdir -p "$TORCH_HOME" + +export XDG_CACHE_HOME="$SCRIPT_DIR/cache" +mkdir -p "$XDG_CACHE_HOME" + +if [ -f "$SCRIPT_DIR/ffmpeg/ffmpeg" ]; then + export PATH="$SCRIPT_DIR/ffmpeg:$PATH" +fi + +export PYTHONIOENCODING=utf-8 +export PYTHONUNBUFFERED=1 +export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True + +# === Pipeline config === +export PYTHON_PATH="$PYTHON" +export ACESTEP_PATH="$SCRIPT_DIR/ACE-Step-1.5" +export DEFAULT_MODEL="marcorez8/acestep-v15-xl-turbo-bf16" +export MANAGE_PIPELINE=true + +if [ -f "cuda_version.txt" ]; then + CUDA_VERSION="$(cat cuda_version.txt)" + echo "GPU: $CUDA_VERSION" +fi + +# === Install npm deps if needed === +if [ ! -d "app/node_modules" ]; then + echo "Installing npm dependencies..." + npm install --prefix "$SCRIPT_DIR/app" +fi + +if [ ! -d "app/server/node_modules" ]; then + echo "Installing server npm dependencies..." + npm install --prefix "$SCRIPT_DIR/app/server" +fi + +# === Build frontend if dist/ missing === +if [ ! -d "app/dist" ]; then + echo "Building frontend..." + npx --prefix "$SCRIPT_DIR/app" vite build +fi + +# === Create output dirs === +mkdir -p app/data app/server/public/audio + +echo "" +echo "========================================" +echo " Single terminal mode" +echo " Express + Pipeline + Frontend" +echo " UI: http://localhost:3001" +echo " Press Ctrl+C to stop" +echo "========================================" +echo "" + +# === Start Express (manages everything, opens browser when pipeline ready) === +node \ + "$SCRIPT_DIR/app/server/node_modules/tsx/dist/cli.mjs" \ + "$SCRIPT_DIR/app/server/src/index.ts" diff --git a/run-no-lm.sh b/run-no-lm.sh new file mode 100755 index 0000000..8ea1c58 --- /dev/null +++ b/run-no-lm.sh @@ -0,0 +1,94 @@ +#!/bin/bash +set -euo pipefail + +echo "========================================" +echo " ACE-Step Studio (NO LM mode)" +echo "========================================" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# === Checks === +if [ ! -f "venv/bin/python" ]; then + echo "ERROR: Python venv not found! Run install.sh first" + exit 1 +fi +if [ ! -f "node/bin/node" ]; then + echo "ERROR: Node.js not found! Run install.sh first" + exit 1 +fi +if [ ! -d "ACE-Step-1.5" ]; then + echo "ERROR: ACE-Step-1.5 not found!" + exit 1 +fi + +# === Environment isolation === +export TMPDIR="$SCRIPT_DIR/temp" +mkdir -p "$TMPDIR" + +export HF_HOME="$SCRIPT_DIR/models" +export HUGGINGFACE_HUB_CACHE="$SCRIPT_DIR/models" +export TRANSFORMERS_CACHE="$SCRIPT_DIR/models" +export HF_HUB_ENABLE_HF_TRANSFER=1 +mkdir -p "$HF_HOME" + +export TORCH_HOME="$SCRIPT_DIR/models/torch" +mkdir -p "$TORCH_HOME" + +export XDG_CACHE_HOME="$SCRIPT_DIR/cache" +mkdir -p "$XDG_CACHE_HOME" + +if [ -f "$SCRIPT_DIR/ffmpeg/ffmpeg" ]; then + export PATH="$SCRIPT_DIR/ffmpeg:$PATH" +fi + +export PYTHONIOENCODING=utf-8 +export PYTHONUNBUFFERED=1 +export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True + +export PATH="$SCRIPT_DIR/node/bin:$PATH" + +# === Pipeline config === +export PYTHON_PATH="$SCRIPT_DIR/venv/bin/python" +export ACESTEP_PATH="$SCRIPT_DIR/ACE-Step-1.5" +export DEFAULT_MODEL="marcorez8/acestep-v15-xl-turbo-bf16" +export MANAGE_PIPELINE=true +export INIT_LLM=false + +if [ -f "cuda_version.txt" ]; then + CUDA_VERSION="$(cat cuda_version.txt)" + echo "GPU: $CUDA_VERSION" +fi + +# === Install npm deps if needed === +if [ ! -d "app/node_modules" ]; then + echo "Installing npm dependencies..." + cd app + "$SCRIPT_DIR/node/bin/npm" install + cd "$SCRIPT_DIR" +fi + +# === Build frontend if dist/ missing === +if [ ! -d "app/dist" ]; then + echo "Building frontend..." + cd app + "$SCRIPT_DIR/node/bin/npx" vite build + cd "$SCRIPT_DIR" +fi + +# === Create output dirs === +mkdir -p app/data app/server/public/audio + +echo "" +echo "========================================" +echo " NO LM mode (more VRAM for DiT)" +echo " Express + Pipeline + Frontend" +echo " UI: http://localhost:3001" +echo " Press Ctrl+C to stop" +echo "========================================" +echo "" + +# === Start Express (manages everything, opens browser when pipeline ready) === +"$SCRIPT_DIR/node/bin/node" \ + "$SCRIPT_DIR/app/server/node_modules/tsx/dist/cli.mjs" \ + "$SCRIPT_DIR/app/server/src/index.ts" diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..712848c --- /dev/null +++ b/run.sh @@ -0,0 +1,93 @@ +#!/bin/bash +set -euo pipefail + +echo "========================================" +echo " ACE-Step Studio (Single Terminal)" +echo "========================================" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# === Checks === +if [ ! -f "venv/bin/python" ]; then + echo "ERROR: Python venv not found! Run install.sh first" + exit 1 +fi +if [ ! -f "node/bin/node" ]; then + echo "ERROR: Node.js not found! Run install.sh first" + exit 1 +fi +if [ ! -d "ACE-Step-1.5" ]; then + echo "ERROR: ACE-Step-1.5 not found!" + exit 1 +fi + +# === Environment isolation === +export TMPDIR="$SCRIPT_DIR/temp" +mkdir -p "$TMPDIR" + +export HF_HOME="$SCRIPT_DIR/models" +export HUGGINGFACE_HUB_CACHE="$SCRIPT_DIR/models" +export TRANSFORMERS_CACHE="$SCRIPT_DIR/models" +export HF_HUB_ENABLE_HF_TRANSFER=1 +mkdir -p "$HF_HOME" + +export TORCH_HOME="$SCRIPT_DIR/models/torch" +mkdir -p "$TORCH_HOME" + +export XDG_CACHE_HOME="$SCRIPT_DIR/cache" +mkdir -p "$XDG_CACHE_HOME" + +if [ -f "$SCRIPT_DIR/ffmpeg/ffmpeg" ]; then + export PATH="$SCRIPT_DIR/ffmpeg:$PATH" +fi + +export PYTHONIOENCODING=utf-8 +export PYTHONUNBUFFERED=1 +export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True + +export PATH="$SCRIPT_DIR/node/bin:$PATH" + +# === Pipeline config === +export PYTHON_PATH="$SCRIPT_DIR/venv/bin/python" +export ACESTEP_PATH="$SCRIPT_DIR/ACE-Step-1.5" +export DEFAULT_MODEL="marcorez8/acestep-v15-xl-turbo-bf16" +export MANAGE_PIPELINE=true + +if [ -f "cuda_version.txt" ]; then + CUDA_VERSION="$(cat cuda_version.txt)" + echo "GPU: $CUDA_VERSION" +fi + +# === Install npm deps if needed === +if [ ! -d "app/node_modules" ]; then + echo "Installing npm dependencies..." + cd app + "$SCRIPT_DIR/node/bin/npm" install + cd "$SCRIPT_DIR" +fi + +# === Build frontend if dist/ missing === +if [ ! -d "app/dist" ]; then + echo "Building frontend..." + cd app + "$SCRIPT_DIR/node/bin/npx" vite build + cd "$SCRIPT_DIR" +fi + +# === Create output dirs === +mkdir -p app/data app/server/public/audio + +echo "" +echo "========================================" +echo " Single terminal mode" +echo " Express + Pipeline + Frontend" +echo " UI: http://localhost:3001" +echo " Press Ctrl+C to stop" +echo "========================================" +echo "" + +# === Start Express (manages everything, opens browser when pipeline ready) === +"$SCRIPT_DIR/node/bin/node" \ + "$SCRIPT_DIR/app/server/node_modules/tsx/dist/cli.mjs" \ + "$SCRIPT_DIR/app/server/src/index.ts" diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..4462457 --- /dev/null +++ b/update.sh @@ -0,0 +1,90 @@ +#!/bin/bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "========================================" +echo " ACE-Step Studio - Update" +echo "========================================" + +if ! command -v git &>/dev/null; then + echo "ERROR: Git not found! https://git-scm.com/downloads" + exit 1 +fi + +# ============================================================ +# Step 1: Pull latest code +# ============================================================ +if [ -d ".git" ]; then + echo "" + echo "[1/5] Updating ACE-Step Studio..." + git stash 2>/dev/null || true + git pull + git stash pop 2>/dev/null || true +else + echo "[1/5] No git repo, skipping code update" +fi + +# ============================================================ +# Step 2: Update Python deps +# ============================================================ +if [ -f "venv/bin/python" ]; then + PYTHON="$SCRIPT_DIR/venv/bin/python" + echo "" + echo "[2/5] Updating Python dependencies..." + "$PYTHON" -m pip install --upgrade pip + + if [ -d "ACE-Step-1.5/acestep/third_parts/nano-vllm" ]; then + "$PYTHON" -m pip install -e ACE-Step-1.5/acestep/third_parts/nano-vllm/ + fi + + "$PYTHON" -m pip install --upgrade \ + "transformers>=4.51.0,<4.58.0" diffusers gradio==6.2.0 \ + matplotlib scipy soundfile loguru einops accelerate fastapi diskcache \ + "uvicorn[standard]" numba vector-quantize-pytorch torchcodec \ + "torchao>=0.16.0,<0.17.0" toml peft modelscope tensorboard \ + typer-slim hf_transfer hf_xet lightning lycoris-lora safetensors xxhash + + "$PYTHON" -m pip install -e ACE-Step-1.5/ --no-deps +else + echo "[2/5] Python venv not found, skipping. Run install.sh first!" +fi + +# ============================================================ +# Step 3-5: Update npm deps + rebuild frontend +# ============================================================ +if [ -f "node/bin/node" ]; then + export PATH="$SCRIPT_DIR/node/bin:$PATH" + + echo "" + echo "[3/5] Updating frontend dependencies..." + if [ -f "app/package.json" ]; then + cd "$SCRIPT_DIR/app" + "$SCRIPT_DIR/node/bin/npm" install + cd "$SCRIPT_DIR" + fi + + echo "" + echo "[4/5] Updating server dependencies..." + if [ -f "app/server/package.json" ]; then + cd "$SCRIPT_DIR/app/server" + "$SCRIPT_DIR/node/bin/npm" install + cd "$SCRIPT_DIR" + fi + + echo "" + echo "[5/5] Rebuilding frontend..." + if [ -f "app/vite.config.ts" ]; then + cd "$SCRIPT_DIR/app" + "$SCRIPT_DIR/node/bin/npx" vite build + cd "$SCRIPT_DIR" + fi +else + echo "[3-5/5] Node.js not found, skipping npm steps. Run install.sh first!" +fi + +echo "" +echo "========================================" +echo " Update complete!" +echo "========================================" From 1fd309f573866f76473c906ab511179897888d32 Mon Sep 17 00:00:00 2001 From: DirectX Date: Thu, 23 Apr 2026 21:06:20 +0300 Subject: [PATCH 2/4] fixes to Gradio run issues --- app/server/src/services/gradio-client.ts | 6 ++++++ app/server/src/services/pipeline-manager.ts | 13 ++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/server/src/services/gradio-client.ts b/app/server/src/services/gradio-client.ts index 51822a1..5051e94 100644 --- a/app/server/src/services/gradio-client.ts +++ b/app/server/src/services/gradio-client.ts @@ -1,5 +1,6 @@ import { Client } from "@gradio/client"; import { config } from '../config/index.js'; +import { pipelineManager } from './pipeline-manager.js'; let clientInstance: Client | null = null; let connectionPromise: Promise | null = null; @@ -9,6 +10,11 @@ let connectionPromise: Promise | null = null; * Caches the connection for reuse across requests. */ export async function getGradioClient(): Promise { + const { state, message } = pipelineManager.getStatus(); + if (state !== 'ready') { + throw new Error(`Pipeline is not ready (${state}): ${message}`); + } + if (clientInstance) return clientInstance; if (connectionPromise) return connectionPromise; diff --git a/app/server/src/services/pipeline-manager.ts b/app/server/src/services/pipeline-manager.ts index d3121df..3248127 100644 --- a/app/server/src/services/pipeline-manager.ts +++ b/app/server/src/services/pipeline-manager.ts @@ -92,7 +92,7 @@ class PipelineManager { this.process = spawn(pythonPath, args, { cwd: aceStepDir, windowsHide: true, - stdio: ['ignore', 'pipe', 'inherit'], // stderr=inherit for tqdm progress bars + stdio: ['ignore', 'pipe', 'pipe'], // pipe stderr so we can detect Gradio ready signal env: { ...process.env, PYTHONUNBUFFERED: '1', @@ -109,7 +109,13 @@ class PipelineManager { this.parseStdout(text); }); - // stderr is inherited — writes directly to console (tqdm works) + // Pipe stderr: forward to process.stderr (tqdm still visible) and parse for readiness + this.process.stderr!.on('data', (data: Buffer) => { + const text = data.toString(); + process.stderr.write(text); + this.parseStdout(text); // Gradio 6 prints "Running on local URL:" to stderr + this.parseStderr(text); + }); this.process.on('exit', (code, signal) => { console.log(`[Pipeline] Process exited: code=${code} signal=${signal}`); @@ -173,7 +179,7 @@ class PipelineManager { if (text.includes('Initializing 5Hz LM') || text.includes('loading 5Hz LM tokenizer')) { this.message = 'Loading language model...'; } - if (text.includes('Running on local URL') || text.includes('Running on')) { + if (text.includes('Running on local URL') || text.includes('Uvicorn running on')) { this.onReady(); } } @@ -190,6 +196,7 @@ class PipelineManager { } private onReady() { + if (this.state === 'ready') return; this.state = 'ready'; this.message = 'Pipeline running'; this.startedAt = Date.now(); From b17a0e67fdb85602bd073c1633f4d6072df29cbe Mon Sep 17 00:00:00 2001 From: DirectX Date: Thu, 23 Apr 2026 21:27:38 +0300 Subject: [PATCH 3/4] proper .gitignore for __pycache__ --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 49b363f..e9f5e39 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ python/ node/ node_modules/ /models/ -__pycache__/ +**/__pycache__/ cache/ temp/ downloads/ From 89634f13a4a5f625d3f1d970b7c47136c81aed25 Mon Sep 17 00:00:00 2001 From: DirectX Date: Thu, 23 Apr 2026 21:34:44 +0300 Subject: [PATCH 4/4] Fixes t o.inner gitignore --- ACE-Step-1.5/.gitignore | 2 +- .../models/__pycache__/__init__.cpython-312.pyc | Bin 188 -> 0 bytes .../common/__pycache__/__init__.cpython-312.pyc | Bin 195 -> 0 bytes .../__pycache__/apg_guidance.cpython-312.pyc | Bin 11262 -> 0 bytes .../configuration_acestep_v15.cpython-312.pyc | Bin 11564 -> 0 bytes .../mlx/__pycache__/__init__.cpython-312.pyc | Bin 1132 -> 0 bytes .../__pycache__/dit_generate.cpython-312.pyc | Bin 16767 -> 0 bytes 7 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 ACE-Step-1.5/acestep/models/__pycache__/__init__.cpython-312.pyc delete mode 100644 ACE-Step-1.5/acestep/models/common/__pycache__/__init__.cpython-312.pyc delete mode 100644 ACE-Step-1.5/acestep/models/common/__pycache__/apg_guidance.cpython-312.pyc delete mode 100644 ACE-Step-1.5/acestep/models/common/__pycache__/configuration_acestep_v15.cpython-312.pyc delete mode 100644 ACE-Step-1.5/acestep/models/mlx/__pycache__/__init__.cpython-312.pyc delete mode 100644 ACE-Step-1.5/acestep/models/mlx/__pycache__/dit_generate.cpython-312.pyc diff --git a/ACE-Step-1.5/.gitignore b/ACE-Step-1.5/.gitignore index 3cf4712..f20aa41 100644 --- a/ACE-Step-1.5/.gitignore +++ b/ACE-Step-1.5/.gitignore @@ -10,7 +10,7 @@ data/ *.wav # Byte-compiled / optimized / DLL files -__pycache__/ +**/_pycache__/ *.py[codz] *$py.class diff --git a/ACE-Step-1.5/acestep/models/__pycache__/__init__.cpython-312.pyc b/ACE-Step-1.5/acestep/models/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 763db4a0ca3fe9d66b19e0bade8d0f9e5f38bf02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmX@j%ge<81k&EGGN%IR#~=J+maEG)dnjvk1tI(06op)eSC5EdUawDVg~QzM-C}eqwTJF;GrF xH$Npcr&vEeJ~J<~BtBlRpz;=n4N$N&C)KWq6=)YD5Ep|OADI~$8H<>KEC9+eFs}dr diff --git a/ACE-Step-1.5/acestep/models/common/__pycache__/__init__.cpython-312.pyc b/ACE-Step-1.5/acestep/models/common/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 3aed22cbc55c908b54d334134216cfeb5984fbfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 195 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 C3|SZe diff --git a/ACE-Step-1.5/acestep/models/common/__pycache__/configuration_acestep_v15.cpython-312.pyc b/ACE-Step-1.5/acestep/models/common/__pycache__/configuration_acestep_v15.cpython-312.pyc deleted file mode 100644 index eeb0206feae3d9116881942a141d9b512a6801cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11564 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 NGPIKZ0938`zX1jy3E2Pu diff --git a/ACE-Step-1.5/acestep/models/mlx/__pycache__/dit_generate.cpython-312.pyc b/ACE-Step-1.5/acestep/models/mlx/__pycache__/dit_generate.cpython-312.pyc deleted file mode 100644 index f2dd3242003aec1427222e0285c44e93919339d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16767 zcmb_@32+-%c3|T^34#Z}n`~YZA(9}eTNHIrJS6I%Em4wX$}$MDnf_gj|&cs{F%pOG_shP=E zD*N7VGyu}1t=-DE`SJT7@4x^4`|rR1-qU|6C@@lxs!sjN<2Xi9|9~HIYR?otw<{^? zF2zucVwM_}eifq%_*Tv;y{b`_S3RosYDP6)?WoqP8`UYKKKfAu^ijKf} zHDi~7=YCo9eTDQjTEM6o&9rjVGDR`k?JoYMByf zw@VPeDrZ`lQr0lz%&kB!F}5x0?W~q9Wy&U%WVUjcSI3qDW&}s6mb6r` zo6bx|S3!?z_^W}x+OO!b#e#O4793RP&gdF z#KjLgG@`oSGr^1M)1Ck?>R+1UJ$|2iR@9uIpPOYx%>^HPI~1ate}nOg8g_n`XGNae-G0$xh8$&`7V-Da!umM^XmWn2K@gcx#r;!hn`@}SpjXX6tgnSaD%ui z%xW;JgG}ye!HOcxN-(owR*qREX0?#XJqxg+5VK;;2y{G967*^)iJHK)XOb5UyvNH1 zcy=xznmoQqmUBrTT8`!CIp2f|`pQWU1^oW}+i=Wp;XzjfRf6K?pYWMuNl}7AKB7Uj zpynC{H6yXI>S_y2UnQt#@*!p*-_QIiC>UedFh=oC6|c#3fOZ)^qrM7QaAmw!ZksX4 zrQ9#0iBR{UA0`FmyRa!F?bUvO)burwbeoOM!3L~B)KpTq?tbcyWONRyt)S1t4)`bt6cRLxKw-v+y>OiL zy$Ew5B!FTgP&9&`;B_!U1r2#?LJlS=Ou?E=-_YmQbej?k5sJ+GbvtFop7%4{p`du= zT#_Obo(Y_J1SqP2zo6#2T+(GrQ0FLc{{S|-&+na^=UJMchQADZ(}9U;mH}ZxPx?8U z@k~z62SCu!0k?N<*5jLU8jUohSEgAXJvNqi62``8Pk^4|{MS4T%g}Bg1MM=@fYdtd z_pxoXo1XCdc#m)1KOZ2#0B&H;J;CPY21rw^kLBDvfNJr&`H5+mn;`n~!g)V8F-?!V z18lq3&#<%fI6LjW=JC&S4kv+k9@aCik?g?;eL0&AIt$x@CVmo?Jj~ z%2VNc-8*|_a<^wRL-#5EJUxzgkcs|wxB;q!##|QM;gaU#2IUp3v zWC+#EO$E9M6eJswCEav?maH;?q!zlxEe)oxdE5Y;bl<_#9dt`qYYX{m?{e(m9e}H} zR0Jx+2z1l(EkRGr2YA1io`t)E_D|-ztkTQ z+vw{+c>g?4^PJm*+(&n2);;{oe}%-M#QG%))y1AH6=>Ew$1l+CNgh_jv0h+E7`VuC z{=h-lUHo9!N%#CLFA@DvbKsXK_!paUAZA(L6hD2anV}EUJ39};{PVsEH}LG#L`F!$ z0E$w>A6_w^O;lwhYC^U9uGK_qT+_A-~$MWrvG`OW7_X! zI~dmI33R~unPDgRK*toUe15#6-^0P@rHmR!Rw)t;nK8J5uim1BEE|6P!B737jLzWyge0)c-o*#a znTAXvN{B;Ukn4c#h4FnIN8^3|n-KNqs+Hacn(q(&xrOUQ7*29@4mCS>PSTuz-iHE; z_tQSs%>m_*^E`~q49>1ehf!4H$q`j^{y9+v%phuK{Zmt*VCk;AIUlfrsPcMzV&TQ! z(?k6^5h7|hw{MCS%~CxPFe75&20`O6lBII>fEw2TnOMkYH^N0G*6{&S;PAyDYP}#9 zSVmNML>1@0E?WGYXUYT0po^?40E|YB;UOf6&`z{%y3HJ1;M7j|3rxet0j1V9NqU#AvXTFkp9?eziU~tB1#K>rPFk!o#u5Ahf ze)fc}HhwVC*!|$mM`!=~?T?+iR!%)}9!*(#lg^{dMd3j7Y^-X@l`3pXIFE)^2}^I< zWR3RS?s;}>AXPm0w~Y_ZM)$3yk^{SO<%eTm}1bY)Gr zP?{-SQ5&{=Y%Tfr>D0EvPpn76nzX4RcHyz9A-m2~k6uq)8GmA)__)%s+?=fJgt4Z| zgu3##pVd?L*A&0~OivXaQ~dT9#e)I7qW`X_s{f$+huXpcO8rB+d_bcXEmQLz#_gM6 zVfWpj(_6eC2z>m!7j#Rw`9up`FOZ|c-7-2%OA2b6-ppOzA(Tp$<`w@6{%>Nn+y)Pf9TY4Ec zJn62n^vjaS2a$9zC`~b^ljSf;W$4>Ze3bdfX2q$b5kzR(m*6J zV`G_nHUkY+HdM!04mx-NwtLnO7oYnERCduVvc}gDVBeT$fdk>*2i8MP&w-MWXk6re z$DZUQ$wgft+OR`_36TrsPC!0C24P2u2|_! z+4m+3_lDK!rk1cJx{%b@uj*_u#baGXy3~I6_|oy%`FQ`m%TKG@lhy4j2Ojc?>h@Ii z=~U^NupwPmad&ZPG2ZaUZ6CBPFQgg{JUIO5)x@h;l4q_Y55Ar%bA`<~-E6Y3A*^0C z6i3JJPAyHv7M2er>vlh_J&>$D@L(Y^@=BuiK&tjq%KmENwXvjqENO6uj-{=oQEtg_ z=k3Vb@u3Im@Y|`vLl2e7!egNm=^|T9zf>1G32Td4mWz_*JCyyz3mot%W%td%Y3WkR_U$2Tm82NZVlc#e(S`op<5?& z_r>kwcwaDTG&=@uU{@&S5eiAy6r4TxdSx_1@gIN@G1m@Xy6lW=ba_LtLkzVGP8+Vb8tqXR@z#d0u>B%TU1+hk0cD_VLU?%(WmTN%a&lH1Yk>fM@dy}cpv-^~9 z(IacK2v!J|n?+mnvdF9U!Ob766biTOS-7re72NL%v=iL!hY~T?2CJcDA-02>h=D1@ zTmOcFQv){`8Rfj<_CRES+X|2DP7yq6p=T5@Mho4BB-9G!GiZg|kYwrx>tGz(^EM=* zT&SB;GK!C^*`7$b&3aY{6&re12$eUxw#29MEAgSXn59ynH_TEgRNb^~(Ys2h+R(cS zXr%N|NUz(2f;xojuHLX{_?$tD=7tpM7pjGtNtL{#!Fu0sd3;8YB&d0OO^_thiuVvJ&-WKi)4}_`k z@$k^3hOq-4?cx5gIc$PjLwFFJNo7#yg!U8Rli|{E3G^z5nvNHg$DK??u#4X%FNxnH zmxOIHu1uv+^ih>e%YG`VxRQV~vr}jmb`t5hOV}xFzxo=SoD!icP{dRRyFk9Eh00*L zPzBO@$IW%?3+{lEzLi{P6gq}K_#jXMGEfsIfpD$);{fof8f z2W>CF*(2;FFB*L3v~Gb>YYwBR!nXq{2=l=dgpT`wC+>nSP(x<_7OZw3c{QQT_$oa1 zXIFKA;Bg>}NB0(Zbm#E+ioNI-y1%p+-NA!oFAfU(Hrb1wE%%})HzV1L9${Y=>mITf zJwi9^SjK)I>|ttwqCMnw3%eaW1S>lve>!9BhkS>}1NbzXBB&mtw>Vu9vsk@ohY!e(ZRtoA>2qp+R-f~2h@BE!qx~{lR z-B7(sT~|1o=DR`7KR53qE){&6%(CDJLUTjT0RUF~IbwmQ{Tb&o-8XogmW@^!gTwi0 zFe$+QXehupy6m_?3&A8jyzvbNUW6f@c27*Ob9{jI&3os-KF@LP1u*x+vkBf>;O8;o z+j)`$uZ3)HfTv#otsdhG1o|}il)%aDAigEZ?YaRNKkWuzLB=zY>5k4OoB+VMC$6G# zBLjX@2Ms>i8J4_CyTPad1nKvj@0TjjhvkEZBbrOlF#*mcH(HXfv!1DGK9F;*Z1Gy0 z>!vRsYonpnb-Io2zalLb3>08hU~>;vx`hxZ&%yJhmt_Xh`8K-m#i4xZ`P>aAZ+J!1 zJO&gH)Bxb#-2f3hTRy)hkiVC?)!~!7n+8KS16ze3bPGJI+la5}GL)`>n~0;))t9$~ z{1=tp2+OzYr)t>a5j z+~Z*N_&O+?*+;rzA#lX*WT}X(f zl^mN6I9u6$N6cUZMh1}q0gz@sMj8SBdX|AGBR>Ze=Frs$bi(65G0VEa|4xJR6+#5^ z_A+aOTJM{HGXj3YIa+R(0V8jp-U-r#^MWrHta)hh=KbrC^Y~y2sSAj2)(u8wq%~X` zoia&@TbTH49Z-Ey@)Wy?D{mbr@P_^(^zJS=mawjQkkf!aIOBnUaKoS+$&=DDs$d|L zt!dr#F>v-V;5`Rg_`orkvBc%ChHwC0c0f7|I*>vbkjR)2@$DD}LCA`$M^FC1nO?eO zZ0s6O9|BK)`=nzB6kF-Z9SCEcFCSsN$g1g1XD2ST)47ulc>R93jSwgBlcW3C&n;}_ zcE^}9nTs312#RjPjFFXahjjO3!Z#XFp2E!(-~-r*oFZ{*o+%$f(Clzc_JMmn(95H> z7FOK{o5(I!UhpCBgQ*-YiG0SUw=b4#chUnl<^Wk}gS!Gl0Yrt9gI5Iwwta?O3||JY z?Qs2Gp-%ws$^cNf`TXF!&q5|UGSWW)w==|Lfv{m|$rS9Q2fAr-4yCxmZU&7Oo zBCdLef;)xfF36yarlNHoMT`nV+vex!j7RUil8T^bO(7@+6?g-|$M})*e#R3>UZfiE zGit!Ar5YamP$w3wv*L?-`7RcXa>>PswoUH>v2cSx7c~>eL81Yoaa^SMAvn)ONg?kS!rFmmR|09P@LZ8c(5yNuZ*)_=+rh#WFUMjs#r5prS>pbxuN&s z?%a0uXM=rkZux2fwGmaw+(ps?o1DiW`3;}}f$IRcqB-D@Ls-zIMJ^zQgf%(WZ6zKe zvX$>a;X9hURKz%wdAvbIHVM=Wa>s@wnTID8V5-ivLg<_BrX|A;8bN~$A)6)y^&~u1 zpv{0zSgB1=NAzYiA*;arV=_}4*hUMXe_CmrL$z2p0?Z5grxeP?Vib_%UYurU!F}l@ zqK2CXBq4A{JqcM)DC8{pA_%R|)gE*Qv#pqHoxmVj!}h~$=-2ixJjA!@Jj zE;x*$1!S5;Ji-s6mI0T~QXk*Gyl18P zLCJ&3RLQ`@#YD;3g!$~VnihzlNZTsYW!341=5%#Ky0|)BRUch^T()z$B|iH_p}y9b z)K`YJQR7-MWwl2a6NU8&eLZ2%bwNxR7fP4~-IL$Z0<-7>N&&pp0-X4W8X`5}D+18~ zP*O#-f?`5>LwU6lD5Z&L$ZxR^Hd+8S$P0i17K!L1hWly&3JIV=yF%|>kyJ^|J`*F{P0VwR*&kJqol8W$|bZKR5cdRdZ8eFXQ>exu^d~`N! zN}FopHBU^(5<8DUzFJtG(3gLqqDq_ML(6YI7=ARID!H66Urv(-X)7{@Ab?I$*{wh> zA?H@l2@&n)XEzhtkUyRP0kaIa7Cy=vDDG!YK5pKokl>`F`DU|#uesV~Mb6IPVi8)bKt%-AG!v+d zmjp(Tin`2e?7XPL7y~rmi6z-?Bm$CXwqkXz67CyvA>_3d@_ruT1+t1THw%DZ63cqs zSyFN&RoPL;oqLIZoxynK4#oa@X>{R1PSk-TUIFvf>N13$MP zyQ)Dc^~1mK03BS^5ObMm9_PU3G~o_F2&bP5V=oh^P7s<3nj=JvX(h9as71Dde=K73 zfW9i3thn9STMI%BUN{`a0E#NG){uxmZZCf7GMA!g7`TC!I?&@eRHHbwdx~nj>bP5E zoYxIXmv7E-O1d#!*l7$iH)i9QO<+c2R*xBKo04#5u*70UME4YyrZMwiHiOw!%#hCH zG)U(HiN}2inP`%BgjhmEEhvGm=>T^VTMW{N3-m&w1i-K2yr}3C4Ow%HSU`&GjX97C zaEh(#K5?XmSiVFJ80GkYs0a{Jafb{JCLu7bS$?%}UNGgsQYG7)7s=@L!IB2J+y2kG$_o@5ZlxW0e5IOL`2g0z| zVPY`#iF$$<#=saP0+S*bC?HT8;%B%!xP*U)8M$cjjwSMpdml?nn8hIr;2UF15?)|; z0Lz0^mVf1zulqfkNs_u{-(1RZe-D!(O9p-yuFik`7l^64p@5*OpQ^i7btO-#oJpPY zV@r9WYR}5-%Ik@~i%(veNnE^|xH_At@TM%jgx`#kb4{rzx}^9gm8!tFR6$2* zFl{v7X^FHXN}5x~ZK1x^qvMIAzNqr9eo3FGIQYccli+WJhSK{+68l`?bJED2PYQM= zSWjqh)mRnlO&V)MeQA9~tUjr)4)x|rYg)=u9h*oN)ITmbp4fKq;qJt?3Rdxgt}mA!x2^ZlMw`O$Dex~SxC?NV*rzFd=__dRe&Yg0u> z!`igPddC;>#U|prVx!CMurFol46D+n(u9dl*VVuO_Pw{47alnNW5-{0r0Py4%+(0n za?i4CNbKrMZ0~>66|7kZXFcfCvA zKkQpp{QJR_y)~-(ieV2%5;g6qn%*BS?_Da$q>(q@ZTX-rt@lyz@d^M#fwYg-;zIq<0UiTz^eB?w54zLc^yg@!&U zwnaUOhP_Gq-c<3v&?z8_y)rcXOjr7aQfsiUS+xdBx~A^^(R-uIhE&bY@G!D31aT+I zho6{V`qWD4tq{By(X6(0C)$oBt=pbhTOO&ynpJ}Z!ul-5q2s?+TQm)86lA}q^_q%L zDad|ZYSmP%QILJn1Pi@eu~hMHRp?~8rUBxfKPfGL&lX!q!7HY-@6l^dOGgu>qhWoz zv@w1nS=t^p0Fq{ibA%x3WNUA_*^w|epdwt@l&)xqYC($zDi@X}3h8I%&Qy74R09gZ z?(Q&m=dH+FF%E*orw-ws+}jvZy|MEN!;jIUYG4J@$L2R&7o3ODl>GUQ60`h6jIMSQb0IJn*=> z3-_QdZco~_N0sS{s`tz8mC1a$Jf5oPf+g0~$B!-BKRA`F>xi0h^YQg(eqwEg)tptl zqKGNU!7#7PCbsuIs*hQol%Gz#HXYT#dvDpcqJ5x!sCsxIRdZ^|7*$0t$PiTDHb1k| z@sjvt%HAGTJ+tpv-nC+WFrKpaMpb}TWldZeANfEJ4@^M9Rus@M+$YU+S=*FI>4lM*$it83pMx;ON+x-D7VwtVi-E`4|@RlPTA z06;MhtQ}^yf7tV&JGo;ZX&YEVQhyy)0HKE1wR^2eTXR&oDiivhQ>(?Lw{>el1!cRe z_~NLNvXHI+*A=o9sIGb?ds6L8H?^;rl1&Hkn@+0h)AjA4li|0L>e^3WKS0dJir+N@*viJV zo&Hp#GHcf;l}7uUFJ4kp){4(4mBEs^3DVZnk0yStQWjV~qagb~Ybt2_=KzMd{it@^ zEA`aVdc!4?>gf*qC9Nv0)j-*y;xIaKc-WyFM#Tq``lzF5nEOL0WtzwXWcWF0#9Dj{ zNOi-5gB%*^xSz?HqgvGAKTH7&3iqc_37WwI+7UT?6mt0V=HMwsad0_OoDMS3ZqWJ4 z{QxUaw-XIu06s1K+ZMgc<#U6**Cpwo_pwh8X5E;f16$Ngg3psDswDRpSlf>oKG;Q_ zkCAj#6*$O5^|;?ZD{B4YXpSb=G#A9KotQbXzrF{IB4Ca^%>4>J74R4627A+*N}*7E z-a;t~e?pmlM(z1AwdWtG;-6BsRYPUC?5UwLX{e0tPZ^p*+SRh!xHe(mo}fxT(^A&D zkohyUrbHPk{LD%jdp=VtjHeWzsTIbSPYqhEUMr{?tIYh0>X!yfQD(Hg_eH!pu~z^^$4wQWbby6#g`t>OUmv{kO@u%xGK zHL>$c!)pfoGD7|5q{nFm)!vmZuSu8KrDB>6z=O*d$ zx^#0(y1wbt*4NYu?P@Lk{>;6ZH4T2iR3J}`_l#>g@~NlFYhoku#@MB$x7Q4$%1D_? z;NQ2D#F+T5d!ATrvZN(xbgY?3qnRqPuN9D@g)$ed6_TQrvX+x|7m?3mdEq7GvlLfn zBSkw^-4s9e$0t8HnXKwqDM bS+_>Wv(|