This commit is contained in:
mike
2026-06-18 00:06:15 +02:00
parent 2d0322465d
commit 1dead1c666
32 changed files with 3332 additions and 65 deletions

72
a6000-comfy/bootstrap.sh Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/bash
# One-time (idempotent) host setup for the Qwen-Image-Edit service on the CUDA box.
# Runs as the service user (NO sudo). Safe to re-run: existing pieces are skipped.
#
# Builds, under $BASE (default ~/comfyui, outside the git repo):
# venv/ CUDA torch + ComfyUI deps (RTX A6000 / sm_86)
# ComfyUI/ latest master + ComfyUI-GGUF custom node
# ComfyUI/models/{unet,text_encoders,vae}/ the v23 Q8 GGUF + encoder + vae
#
# CUDA lifts every MI50 workaround: no rocm wheel, no v0.3.77 pin (that pin only
# existed because rocm-torch 2.3.1 lacks torch.library.custom_op), no lowvram.
set -e
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env.sh"
GGUF_NODE="$COMFY/custom_nodes/ComfyUI-GGUF"
echo "[bootstrap] BASE=$BASE VENV=$VENV"
mkdir -p "$BASE"
# --- ComfyUI (latest) -------------------------------------------------------
if [ ! -d "$COMFY/.git" ]; then
echo "[bootstrap] cloning ComfyUI (latest master) ..."
git clone --depth 1 https://github.com/comfyanonymous/ComfyUI.git "$COMFY"
fi
# --- venv + python deps -----------------------------------------------------
# Build from the real system interpreter, NOT whatever venv is currently active.
if [ ! -d "$VENV" ]; then
echo "[bootstrap] creating venv at $VENV ..."
/usr/bin/python3.13 -m venv "$VENV"
fi
source "$VENV/bin/activate"
python -m pip install --upgrade pip wheel
echo "[bootstrap] installing torch (CUDA cu124) ..."
# torchaudio MUST come from the cu124 index too. Latest ComfyUI imports torchaudio
# at startup (comfy/sd.py -> audio_vae); the PyPI default build links libcudart.so.13
# (CUDA 13) and crashes against our cu124 torch. The matching +cu124 build fixes it.
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
echo "[bootstrap] installing ComfyUI requirements ..."
pip install -r "$COMFY/requirements.txt"
# ComfyUI's requirements can re-pull a mismatched torchaudio from PyPI; re-pin it.
pip install torchaudio --index-url https://download.pytorch.org/whl/cu124
# --- ComfyUI-GGUF custom node ----------------------------------------------
if [ ! -d "$GGUF_NODE" ]; then
echo "[bootstrap] cloning ComfyUI-GGUF ..."
git clone --depth 1 https://github.com/city96/ComfyUI-GGUF.git "$GGUF_NODE"
fi
pip install -r "$GGUF_NODE/requirements.txt" || pip install gguf
# --- API deps ---------------------------------------------------------------
pip install fastapi "uvicorn[standard]" websocket-client python-multipart pillow requests
# --- models (resume-safe; skipped if already complete) ----------------------
# Identical files/URLs to tour-comfy/bootstrap.sh.
M="$COMFY/models"
mkdir -p "$M/unet" "$M/text_encoders" "$M/vae"
dl() { # url dest
if [ -s "$2" ]; then echo "[bootstrap] have $(basename "$2")"; return; fi
echo "[bootstrap] downloading $(basename "$2") ..."
wget -c -q --show-progress -O "$2" "$1"
}
dl "https://huggingface.co/Novice25/Qwen-Image-Edit-Rapid-AIO-GGUF/resolve/main/v23/Qwen-Rapid-NSFW-v23_Q8_0.gguf" \
"$M/unet/Qwen-Rapid-NSFW-v23_Q8_0.gguf"
dl "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/text_encoders/qwen_2.5_vl_7b_fp8_scaled.safetensors" \
"$M/text_encoders/qwen_2.5_vl_7b_fp8_scaled.safetensors"
dl "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/vae/qwen_image_vae.safetensors" \
"$M/vae/qwen_image_vae.safetensors"
echo "[bootstrap] verifying torch + GPU ..."
python -c "import torch; print('torch', torch.__version__, 'cuda', torch.cuda.is_available(), torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'NO GPU')"
echo "[bootstrap] BOOTSTRAP_DONE"

45
a6000-comfy/deploy.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Install/refresh systemd services for Qwen-Image-Edit on the A6000 (CUDA) box.
# Installs 3 services + 1 target; run with sudo.
set -e
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root (use sudo)"
exit 1
fi
A6K="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # a6000-comfy/
REPO="$( cd "$A6K/.." && pwd )" # repo root
TOUR="$REPO/tour-comfy"
TEMPLATES="$A6K/systemd"
SVC_USER="${SUDO_USER:-$(stat -c '%U' "$A6K")}"
SVC_GROUP="$(id -gn "$SVC_USER")"
echo "Installing services: user=$SVC_USER group=$SVC_GROUP"
echo " a6k=$A6K"
echo " tour=$TOUR"
for unit in comfyui-backend comfyui-api comfyui-watcher; do
sed -e "s|__USER__|$SVC_USER|g" \
-e "s|__GROUP__|$SVC_GROUP|g" \
-e "s|__A6K__|$A6K|g" \
-e "s|__TOUR__|$TOUR|g" \
"$TEMPLATES/$unit.service" > "/etc/systemd/system/$unit.service"
echo " wrote /etc/systemd/system/$unit.service"
done
cp "$TEMPLATES/comfyui.target" /etc/systemd/system/comfyui.target
echo " wrote /etc/systemd/system/comfyui.target"
echo "Reloading systemd daemon..."
systemctl daemon-reload
echo "Enabling services + target..."
systemctl enable comfyui-backend.service comfyui-api.service comfyui-watcher.service comfyui.target
echo "Starting system..."
systemctl start comfyui.target
echo "Deployment complete."
echo "Check status with: systemctl status comfyui.target comfyui-backend comfyui-api comfyui-watcher"

17
a6000-comfy/env.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# Shared path resolver for the Qwen-Image-Edit service on the CUDA box (RTX A6000).
# Sourced by bootstrap.sh / run_comfyui.sh / start_api.sh.
#
# Unlike tour-comfy/env.sh (which derives BASE from the script location and dodges
# an NTFS venv), this box installs into a dedicated dir OUTSIDE the git repo so the
# ~31GB model tree + ComfyUI checkout never land in `git status`. Override with
# COMFY_BASE / COMFY_VENV if you want it elsewhere.
ENV_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # repo/a6000-comfy
BASE="${COMFY_BASE:-$HOME/comfyui}" # install root (ext4)
COMFY="$BASE/ComfyUI"
VENV="${COMFY_VENV:-$BASE/venv}"
# The FastAPI service + workflow are backend-agnostic; reuse them from tour-comfy
# (pure HTTP to ComfyUI on :8188 — nothing ROCm-specific in there).
API_DIR="$( cd "$ENV_DIR/../tour-comfy" && pwd )"

16
a6000-comfy/run_comfyui.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
# Launch the ComfyUI backend (headless) for the Qwen-Image-Edit API on the A6000.
# CUDA / Ampere: none of the MI50 OOM workarounds are needed. The 46GB card holds
# the 20B Q8 model + encoder + reference latents resident, so we skip --lowvram and
# --use-split-cross-attention (both only existed to fit 32GB) -> faster.
set -e
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env.sh"
cd "$COMFY"
source "$VENV/bin/activate"
# --highvram keeps weights pinned on-GPU between requests (we have the headroom).
exec python main.py \
--listen 127.0.0.1 \
--port 8188 \
--highvram \
"$@"

16
a6000-comfy/start_api.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
# Launch the FastAPI edit service (talks to the local ComfyUI on :8188).
# Reuses tour-comfy/edit_api.py + workflow verbatim (they're backend-agnostic).
set -e
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/env.sh"
source "$VENV/bin/activate"
cd "$API_DIR"
export COMFY_URL="http://127.0.0.1:8188"
export HOST="0.0.0.0"
export PORT="8500"
# The A6000 is fast and not VRAM-bound on this model, so default to a full ~1MP
# output budget (tour caps at 0.65MP to survive the MI50). Override via MAX_AREA.
export MAX_AREA="${MAX_AREA:-1048576}"
exec python edit_api.py

View File

@@ -0,0 +1,17 @@
[Unit]
Description=Qwen-Image-Edit FastAPI (A6000)
After=comfyui-backend.service
Requires=comfyui-backend.service
[Service]
Type=simple
User=__USER__
Group=__GROUP__
ExecStart=/bin/bash __A6K__/start_api.sh
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=comfyui.target

View File

@@ -0,0 +1,16 @@
[Unit]
Description=ComfyUI Backend (A6000 / CUDA)
After=network.target
[Service]
Type=simple
User=__USER__
Group=__GROUP__
ExecStart=/bin/bash __A6K__/run_comfyui.sh
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=comfyui.target

View File

@@ -0,0 +1,17 @@
[Unit]
Description=Qwen-Image-Edit Folder Watcher (A6000)
After=comfyui-api.service
Requires=comfyui-api.service
[Service]
Type=simple
User=__USER__
Group=__GROUP__
ExecStart=/bin/bash __TOUR__/start_watcher.sh
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=comfyui.target

View File

@@ -0,0 +1,7 @@
[Unit]
Description=Qwen-Image-Edit Complete System (A6000)
Wants=comfyui-backend.service comfyui-api.service comfyui-watcher.service
After=comfyui-watcher.service
[Install]
WantedBy=multi-user.target