yue2-studio / scripts /space-start.sh
RalphThings's picture
Upload folder using huggingface_hub
88a2108 verified
Raw History Blame Contribute Delete
3.98 kB
#!/usr/bin/env bash
# Boots the Space: ComfyUI in the background, the studio in front.
#
# The UI comes up first on purpose. A Space counts as started once its port
# answers, and ComfyUI needs minutes to resolve weights and load a 4 GB model.
# The UI already polls for its backend and turns the header green by itself.
set -uo pipefail
COMFY=$HOME/ComfyUI
ENGINE_LOG=${ENGINE_LOG:-/tmp/comfyui.log}
CHECKPOINT=${YUE2_CHECKPOINT:-yue2_3b_int8_convrot.safetensors}
# The bf16 weights are what the Real-Audio adapter was built against, and what
# anyone with headroom should be picking anyway. Both are offered; the UI picks.
CHECKPOINT_ALT=${YUE2_CHECKPOINT_ALT:-yue2_3b_bf16.safetensors}
ENCODER=${SHEETSAGE_ENCODER:-sheetsage2_bf16.safetensors}
REAL_AUDIO_LORA=${YUE2_REAL_AUDIO_LORA:-nar_lora_joint_v9_comfyui.safetensors}
REAL_AUDIO_REPO=${YUE2_REAL_AUDIO_REPO:-Mothersuperior/yue2-mothersuperior-realaudio-tokenizer-v4}
INST_LORA=${YUE2_INSTRUMENTAL_LORA:-ar_lora_inst_v3abc_comfyui.safetensors}
INST_REPO=${YUE2_INSTRUMENTAL_REPO:-Mothersuperior/YuE2-instrumental-cot-full-loras}
export ENGINE_LOG
# The hf CLI writes hints and warnings to stdout, so capturing its output in a
# command substitution yields banner text rather than a path. Ask the library
# directly instead, which prints the cached path and nothing else.
resolve() {
python - "$1" "$2" <<'PY'
import sys
from huggingface_hub import hf_hub_download
print(hf_hub_download(repo_id=sys.argv[1], filename=sys.argv[2]))
PY
}
link_weight() {
local repo=$1 path=$2 dest=$3
local name src
name=$(basename "$path")
mkdir -p "$dest"
if [ -e "$dest/$name" ]; then
echo "[yue2] $name already present"
return 0
fi
echo "[yue2] resolving $name"
if ! src=$(resolve "$repo" "$path" 2>>"$ENGINE_LOG"); then
echo "[yue2] ERROR could not resolve $name, see $ENGINE_LOG"
return 1
fi
if [ ! -s "$src" ]; then
echo "[yue2] ERROR resolved $name to an empty path: $src"
return 1
fi
ln -sfn "$src" "$dest/$name"
echo "[yue2] linked $name"
}
# Which image is actually running. Without this the only way to tell a stale
# container from a fresh one is to read a traceback's interpreter paths.
stamp() {
{
echo "[yue2] build ${BUILD_STAMP:-unstamped}"
echo "[yue2] python $(python -c 'import sys; print(sys.version.split()[0])' 2>&1)"
echo "[yue2] torch $(python -c 'import torch; print(torch.__version__)' 2>&1 | tail -1)"
} | tee -a "$ENGINE_LOG"
}
start_comfy() {
: > "$ENGINE_LOG"
stamp
link_weight Comfy-Org/YuE2 "checkpoints/$CHECKPOINT" "$COMFY/models/checkpoints" \
|| echo "[yue2] the checkpoint is missing, generation will fail" | tee -a "$ENGINE_LOG"
link_weight Comfy-Org/YuE2 "checkpoints/$CHECKPOINT_ALT" "$COMFY/models/checkpoints" \
|| echo "[yue2] the bf16 checkpoint is missing, only the int8 one is selectable" | tee -a "$ENGINE_LOG"
link_weight Comfy-Org/YuE2 "audio_encoders/$ENCODER" "$COMFY/models/audio_encoders" \
|| echo "[yue2] the transcriber is missing, covers will fail" | tee -a "$ENGINE_LOG"
# Optional. Its absence greys the toggle out rather than breaking a render.
link_weight "$REAL_AUDIO_REPO" "$REAL_AUDIO_LORA" "$COMFY/models/loras" \
|| echo "[yue2] the real-audio adapter is missing, that toggle stays off" | tee -a "$ENGINE_LOG"
link_weight "$INST_REPO" "$INST_LORA" "$COMFY/models/loras" \
|| echo "[yue2] the instrumental adapter is missing, that toggle stays off" | tee -a "$ENGINE_LOG"
cd "$COMFY"
echo "[yue2] starting ComfyUI on 8188"
# Tee so the Space log shows it live and the app can read the tail back.
python main.py --listen 127.0.0.1 --port 8188 ${COMFY_EXTRA_ARGS:-} 2>&1 | tee -a "$ENGINE_LOG"
echo "[yue2] ComfyUI exited. The studio stays up so the failure is visible." | tee -a "$ENGINE_LOG"
}
start_comfy &
cd "$HOME/app/.next/standalone"
echo "[yue2] starting the studio on ${PORT:-7860}"
export PORT="${PORT:-7860}" HOSTNAME=0.0.0.0
exec node server.js