Qwen-Image-Edit-App / setup_runpod.py
sdfafdfsdf's picture
Add Consistency LoRA to download list
cf017c8 verified
#!/usr/bin/env python3
"""
RunPod Fresh Setup Script for Qwen Image Edit
==============================================
Downloads everything from YOUR OWN HuggingFace repos:
- App code: sdfafdfsdf/Qwen-Image-Edit-App
- Models: sdfafdfsdf/Phr00t-Qwen-Rapid-AIO (20GB)
sdfafdfsdf/Qwen-Image-Edit-2511 (16GB)
sdfafdfsdf/BFS-Best-Face-Swap (1.3GB)
sdfafdfsdf/Qwen-Image-Edit-2511-Multiple-Angles-LoRA (282MB)
sdfafdfsdf/vllm-flash-attn3 (807MB)
Usage:
1. Upload this script to your RunPod
2. Run: python3 setup_runpod.py
3. The app will auto-start at the end
Set your HF token as an environment variable before running:
export HF_TOKEN="hf_your_token_here"
Or pass it as a command line argument:
python3 setup_runpod.py --token hf_your_token_here
"""
import os
import sys
import subprocess
import argparse
import time
# ═══════════════════════════════════════════════════════
# CONFIGURATION — Change these if you rename your repos
# ═══════════════════════════════════════════════════════
HF_USERNAME = "sdfafdfsdf"
# App code repo (small files: app.py, qwenimage/, camera_control_ui, etc.)
APP_REPO = f"{HF_USERNAME}/Qwen-Image-Edit-App"
# Model repos (large files: transformer weights, VAE, text encoder, etc.)
MODEL_REPOS = [
f"{HF_USERNAME}/Phr00t-Qwen-Rapid-AIO", # 20GB - AIO transformer
f"{HF_USERNAME}/Qwen-Image-Edit-2511", # 16GB - Pipeline (VAE, text encoder)
f"{HF_USERNAME}/BFS-Best-Face-Swap", # 1.3GB - Face swap LoRA
f"{HF_USERNAME}/Qwen-Image-Edit-2511-Multiple-Angles-LoRA", # 282MB - Angles LoRA
f"{HF_USERNAME}/vllm-flash-attn3", # 807MB - Flash attention kernel
f"{HF_USERNAME}/QIE_2511_Consistency_Lora", # Consistency LoRA
]
# Directories
WORKSPACE_DIR = "/workspace"
APP_DIR = os.path.join(WORKSPACE_DIR, "Qwen-Image-Edit")
VENV_DIR = os.path.join(WORKSPACE_DIR, "venv")
CACHE_DIR = os.path.join(WORKSPACE_DIR, "cache")
HF_HOME = os.path.join(CACHE_DIR, "huggingface")
PIP_CACHE = os.path.join(CACHE_DIR, "pip")
TMP_DIR = os.path.join(WORKSPACE_DIR, "tmp")
# ═══════════════════════════════════════════════════════
# HELPERS
# ═══════════════════════════════════════════════════════
def log(msg, level="INFO"):
"""Print a formatted log message."""
icons = {"INFO": "ℹ️ ", "OK": "✅", "WARN": "⚠️ ", "ERR": "❌", "DL": "📦", "RUN": "🚀"}
icon = icons.get(level, " ")
print(f"{icon} {msg}")
def run(command, cwd=None, env_extra=None, check=True):
"""Run a shell command, stream output, return exit code."""
log(f"Running: {command}", "RUN")
env = os.environ.copy()
env["TMPDIR"] = TMP_DIR
env["PIP_CACHE_DIR"] = PIP_CACHE
env["HF_HOME"] = HF_HOME
if env_extra:
env.update(env_extra)
proc = subprocess.Popen(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
text=True, cwd=cwd, env=env
)
for line in proc.stdout:
print(line, end="")
proc.wait()
if proc.returncode != 0 and check:
log(f"Command failed (exit {proc.returncode}): {command}", "ERR")
return proc.returncode
def ensure_dirs():
"""Create all necessary directories."""
for d in [APP_DIR, VENV_DIR, CACHE_DIR, HF_HOME, PIP_CACHE, TMP_DIR]:
os.makedirs(d, exist_ok=True)
# ═══════════════════════════════════════════════════════
# STEP 1: Download app code
# ═══════════════════════════════════════════════════════
def download_app_code(token):
"""Download app code from your HF repo."""
log(f"Downloading app code from {APP_REPO}...", "DL")
pip = os.path.join(VENV_DIR, "bin", "pip")
python = os.path.join(VENV_DIR, "bin", "python")
# Use huggingface_hub to download
run(f"""{python} -c "
from huggingface_hub import snapshot_download
snapshot_download(
repo_id='{APP_REPO}',
repo_type='model',
local_dir='{APP_DIR}',
token='{token}'
)
print('App code downloaded successfully!')
" """)
if os.path.exists(os.path.join(APP_DIR, "app.py")):
log("App code downloaded successfully!", "OK")
else:
log("App code download may have failed — app.py not found!", "ERR")
sys.exit(1)
# ═══════════════════════════════════════════════════════
# STEP 2: Download heavy models
# ═══════════════════════════════════════════════════════
def download_models(token):
"""Download all model repos (cached in HF_HOME)."""
python = os.path.join(VENV_DIR, "bin", "python")
for repo in MODEL_REPOS:
log(f"Downloading model: {repo}...", "DL")
run(f"""{python} -c "
from huggingface_hub import snapshot_download
snapshot_download(
repo_id='{repo}',
repo_type='model',
token='{token}'
)
print('Downloaded: {repo}')
" """)
log("All models downloaded!", "OK")
# ═══════════════════════════════════════════════════════
# STEP 3: Set up Python venv
# ═══════════════════════════════════════════════════════
def setup_venv():
"""Create virtual environment if it doesn't exist."""
if not os.path.exists(os.path.join(VENV_DIR, "bin", "python")):
log("Creating virtual environment...", "INFO")
run(f"python3 -m venv {VENV_DIR}")
else:
log("Virtual environment already exists.", "OK")
# Upgrade pip
pip = os.path.join(VENV_DIR, "bin", "pip")
run(f"{pip} install --upgrade pip")
# ═══════════════════════════════════════════════════════
# STEP 4: Install dependencies
# ═══════════════════════════════════════════════════════
def install_dependencies():
"""Install Python packages from requirements.txt."""
pip = os.path.join(VENV_DIR, "bin", "pip")
req_file = os.path.join(APP_DIR, "requirements.txt")
if os.path.exists(req_file):
log("Installing dependencies from requirements.txt...", "DL")
run(f"{pip} install -r {req_file}")
log("Dependencies installed!", "OK")
else:
log("No requirements.txt found!", "WARN")
# Ensure huggingface_hub is available (needed for model downloads)
run(f"{pip} install huggingface_hub")
# ═══════════════════════════════════════════════════════
# STEP 5: Start the app
# ═══════════════════════════════════════════════════════
def start_app():
"""Start the Gradio app."""
python = os.path.join(VENV_DIR, "bin", "python")
app_py = os.path.join(APP_DIR, "app.py")
if not os.path.exists(app_py):
log("app.py not found, cannot start!", "ERR")
return
log("Starting the Gradio app...", "RUN")
env_extra = {
"PYTHONPATH": APP_DIR,
"PYTHONUNBUFFERED": "1",
}
# Run in foreground so user can see output
run(f"{python} {app_py}", cwd=APP_DIR, env_extra=env_extra, check=False)
# ═══════════════════════════════════════════════════════
# MAIN
# ═══════════════════════════════════════════════════════
def main():
parser = argparse.ArgumentParser(description="Setup Qwen Image Edit on a fresh RunPod")
parser.add_argument("--token", type=str, default=None,
help="HuggingFace token (or set HF_TOKEN env var)")
parser.add_argument("--skip-models", action="store_true",
help="Skip model downloads (if already cached)")
parser.add_argument("--skip-app", action="store_true",
help="Skip app code download (if already present)")
parser.add_argument("--skip-deps", action="store_true",
help="Skip dependency installation")
parser.add_argument("--no-start", action="store_true",
help="Don't auto-start the app after setup")
args = parser.parse_args()
# Get token
token = args.token or os.environ.get("HF_TOKEN", "")
if not token:
log("No HuggingFace token provided!", "ERR")
log("Set HF_TOKEN environment variable or pass --token", "INFO")
sys.exit(1)
print("=" * 60)
print(" Qwen Image Edit — Fresh RunPod Setup")
print("=" * 60)
start_time = time.time()
# Step 0: Create directories
log("Creating directories...")
ensure_dirs()
# Step 1: Set up venv (needed before downloading, since we use huggingface_hub)
log("Setting up Python virtual environment...")
setup_venv()
# Step 2: Install huggingface_hub first (needed for downloads)
pip = os.path.join(VENV_DIR, "bin", "pip")
run(f"{pip} install huggingface_hub")
# Step 3: Download app code
if not args.skip_app:
download_app_code(token)
else:
log("Skipping app code download (--skip-app)", "INFO")
# Step 4: Install full dependencies
if not args.skip_deps:
install_dependencies()
else:
log("Skipping dependency installation (--skip-deps)", "INFO")
# Step 5: Download models
if not args.skip_models:
download_models(token)
else:
log("Skipping model downloads (--skip-models)", "INFO")
elapsed = time.time() - start_time
minutes = int(elapsed // 60)
seconds = int(elapsed % 60)
print("")
print("=" * 60)
log(f"Setup completed in {minutes}m {seconds}s!", "OK")
print("=" * 60)
# Step 6: Start the app
if not args.no_start:
start_app()
else:
log("Skipping app start (--no-start). To start manually:", "INFO")
log(f" bash /workspace/start_app.sh", "INFO")
if __name__ == "__main__":
main()