Files
hair/scripts/restart_if11_backends.sh
xslandClaude Opus 4.8 0ddfa83743 接口11:发际线生发(接口9遮罩 + change_hair换发型/区域生发 + 按遮罩羽化贴回)+ 分步可视化测试页
- 端点 POST /api/v1/hairline/grow(app.py,纯新增,不影响接口1-5)
- 编排模块 face_analysis/hairline_grow.py:复用接口9 遮罩 → HTTP 调 change_hair(8801) → 按遮罩贴回
- 双生成后端 gen_backend:swaphair(换发型LoRA) / hairgrow(区域生发inpaint)
- swap_mode:ext_mask(接口9遮罩作换发型遮罩) / as_is;融合 feather/alpha_gradient/seamless
- 参数全在测试页可调;可视化按算法文档4步:最终遮罩→生成全帧→严格贴回→接缝融合
- 附启停脚本 scripts/restart_if11_backends.sh、算法文档、测试图

注:change_hair 侧 swapHair 的 ext_mask/denoising_strength 改造在 change_hair 仓库,向后兼容。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 22:06:17 +08:00

91 lines
3.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 接口11(发际线生发)所需的 change_hair 后端服务启停脚本。
#
# webui(57860) + photo_service(32678) + hair_service_sd(8801)
# —— 不需要 ComfyUI。
#
# hair_service_sd 会被【强制重启】以加载接口11 的 ext_mask 改动;
# webui / photo_service 仅在未运行时才拉起(已在跑则不动,避免 webui 重新加载模型)。
#
# 用法:
# bash scripts/restart_if11_backends.sh # 确保三个服务就绪(强制重启 8801)
# bash scripts/restart_if11_backends.sh status # 只看状态
set -u
PROJ="/home/xsl/change_hair/project"
LOGDIR="$PROJ/logs"
PIDD="$LOGDIR/pids"
PY_SD="/home/xsl/miniconda3/envs/sdwebui/bin/python"
PY_PHOTO="/home/xsl/miniconda3/envs/py310/bin/python"
PY_HAIR="/home/xsl/miniconda3/envs/my_hair/bin/python"
mkdir -p "$LOGDIR" "$PIDD"
export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1
export CUDA_VISIBLE_DEVICES=0
export APP_WORKER_ID=1
port_up() { ss -ltn 2>/dev/null | grep -q ":$1 "; }
wait_port() { # $1=port $2=label $3=timeout_s
local p="$1" label="$2" to="${3:-90}" i=0
echo -n " 等待 $label (端口 $p) "
while [ "$i" -lt "$to" ]; do
if port_up "$p"; then echo " ✓ 就绪"; return 0; fi
echo -n "."; sleep 2; i=$((i+2))
done
echo " ✗ 超时(看日志:$LOGDIR/*.log"; return 1
}
status() {
echo "=== 服务状态 $(date '+%H:%M:%S') ==="
for pair in "webui:57860" "photo_service:32678" "hair_service_sd:8801"; do
local name="${pair%%:*}" port="${pair##*:}"
if port_up "$port"; then echo " ✓ $name (端口 $port 就绪)"; else echo " ✗ $name (端口 $port 未监听)"; fi
done
echo " worker 8187: $(curl -s -m3 http://127.0.0.1:8187/health 2>/dev/null || echo '未响应')"
}
if [ "${1:-}" = "status" ]; then status; exit 0; fi
# 1) webui —— 仅未运行时启动(模型加载慢,别乱重启)
if pgrep -f "webui.py.*57860" >/dev/null; then
echo "webui 已在运行,跳过"
else
echo "启动 webui (57860)..."
( cd "$PROJ/onediff/stable-diffusion-webui" && \
HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 \
nohup "$PY_SD" webui.py --api --listen --xformers --port 57860 > "$LOGDIR/webui.log" 2>&1 & \
echo $! > "$PIDD/webui.pid" )
echo " webui PID=$(cat "$PIDD/webui.pid" 2>/dev/null)"
fi
# 2) photo_service —— 仅未运行时启动
if pgrep -f "lora_train_service_1.py" >/dev/null; then
echo "photo_service 已在运行,跳过"
else
echo "启动 photo_service (32678)..."
( cd "$PROJ/photo_service" && \
nohup "$PY_PHOTO" -u lora_train_service_1.py > "$LOGDIR/photo_service.log" 2>&1 & \
echo $! > "$PIDD/photo_service.pid" )
echo " photo_service PID=$(cat "$PIDD/photo_service.pid" 2>/dev/null)"
fi
# 3) hair_service_sd —— 强制重启(加载接口11 的 ext_mask 改动)
echo "强制重启 hair_service_sd (8801)..."
pkill -f "run_copy_cost_colorb64" 2>/dev/null
sleep 2
( cd "$PROJ/hair_service_sd" && \
nohup "$PY_HAIR" run_copy_cost_colorb64.py > "$LOGDIR/hair_service_if11.log" 2>&1 & \
echo $! > "$PIDD/hair_service.pid" )
echo " hair_service_sd PID=$(cat "$PIDD/hair_service.pid" 2>/dev/null)"
echo "--- 等待就绪 ---"
wait_port 57860 webui 180
wait_port 32678 photo_service 60
wait_port 8801 hair_service_sd 120
echo
status
echo
echo "提示:hair_service_sd 端口就绪后,模型可能还需几秒;日志出现 '[HAIR_INIT] All init done' 即完全可用:"
echo " tail -f $LOGDIR/hair_service_if11.log"