aa
This commit is contained in:
72
a6000-comfy/bootstrap.sh
Executable file
72
a6000-comfy/bootstrap.sh
Executable 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
45
a6000-comfy/deploy.sh
Executable 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
17
a6000-comfy/env.sh
Executable 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
16
a6000-comfy/run_comfyui.sh
Executable 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
16
a6000-comfy/start_api.sh
Executable 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
|
||||
17
a6000-comfy/systemd/comfyui-api.service
Normal file
17
a6000-comfy/systemd/comfyui-api.service
Normal 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
|
||||
16
a6000-comfy/systemd/comfyui-backend.service
Normal file
16
a6000-comfy/systemd/comfyui-backend.service
Normal 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
|
||||
17
a6000-comfy/systemd/comfyui-watcher.service
Normal file
17
a6000-comfy/systemd/comfyui-watcher.service
Normal 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
|
||||
7
a6000-comfy/systemd/comfyui.target
Normal file
7
a6000-comfy/systemd/comfyui.target
Normal 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
|
||||
Reference in New Issue
Block a user