208 lines
7.7 KiB
Bash
Executable File
208 lines
7.7 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
|
||
# 自动检测 conda 安装路径(优先用环境变量,其次用 conda info --base)
|
||
if [ -z "$CONDA_BASE" ]; then
|
||
if command -v conda >/dev/null 2>&1; then
|
||
CONDA_BASE="$(conda info --base 2>/dev/null)"
|
||
fi
|
||
fi
|
||
CONDA_BASE="${CONDA_BASE:-$HOME/miniconda3}"
|
||
|
||
# 初始化 conda(脚本中需要 source 才能用 conda activate)
|
||
if [ -f "$CONDA_BASE/etc/profile.d/conda.sh" ]; then
|
||
source "$CONDA_BASE/etc/profile.d/conda.sh"
|
||
else
|
||
echo "WARNING: 未找到 conda.sh,请确认 CONDA_BASE=$CONDA_BASE 正确"
|
||
fi
|
||
|
||
echo "=== 换发型项目部署脚本 ==="
|
||
echo "BASE_DIR: $BASE_DIR"
|
||
echo "CONDA_BASE: $CONDA_BASE"
|
||
echo ""
|
||
|
||
ERRORS=()
|
||
|
||
# 0. 自动解压网盘文件(如果 cloud_packages/ 存在)
|
||
CLOUD_DIR="$BASE_DIR/cloud_packages"
|
||
if [ -d "$CLOUD_DIR" ] && [ "$(ls -A "$CLOUD_DIR")" ]; then
|
||
echo "[0/9] 自动解压网盘文件..."
|
||
|
||
# conda 环境
|
||
for pkg in my_hair.tar.gz sdwebui.tar.gz kohya.tar.gz; do
|
||
if [ -f "$CLOUD_DIR/$pkg" ]; then
|
||
echo " 解压 $pkg..."
|
||
tar -xzf "$CLOUD_DIR/$pkg" -C "$BASE_DIR/conda_envs/"
|
||
echo " ✓ $pkg"
|
||
fi
|
||
done
|
||
|
||
# SD 底模
|
||
if [ -f "$CLOUD_DIR/sd_base_models.tar.gz" ]; then
|
||
echo " 解压 sd_base_models.tar.gz..."
|
||
mkdir -p "$BASE_DIR/stable-diffusion-webui/models/Stable-diffusion"
|
||
tar -xzf "$CLOUD_DIR/sd_base_models.tar.gz" -C "$BASE_DIR/stable-diffusion-webui/models/Stable-diffusion/"
|
||
echo " ✓ sd_base_models.tar.gz"
|
||
fi
|
||
|
||
# LoRA 模型
|
||
mkdir -p "$BASE_DIR/stable-diffusion-webui/models/Lora"
|
||
for pkg in lora_0-9.tar.gz lora_h.tar.gz lora_n.tar.gz lora_t.tar.gz; do
|
||
if [ -f "$CLOUD_DIR/$pkg" ]; then
|
||
echo " 解压 $pkg..."
|
||
tar -xzf "$CLOUD_DIR/$pkg" -C "$BASE_DIR/stable-diffusion-webui/models/Lora/"
|
||
echo " ✓ $pkg"
|
||
fi
|
||
done
|
||
|
||
# 换发算法权重
|
||
if [ -f "$CLOUD_DIR/weights.tar.gz" ]; then
|
||
echo " 解压 weights.tar.gz..."
|
||
tar -xzf "$CLOUD_DIR/weights.tar.gz" -C "$BASE_DIR/hair_service_sd/"
|
||
echo " ✓ weights.tar.gz"
|
||
fi
|
||
|
||
# kohya 训练环境
|
||
if [ -f "$CLOUD_DIR/kohya_local.tar.gz" ]; then
|
||
echo " 解压 kohya_local.tar.gz..."
|
||
tar -xzf "$CLOUD_DIR/kohya_local.tar.gz" -C "$BASE_DIR/kohya_ss_home/"
|
||
echo " ✓ kohya_local.tar.gz"
|
||
fi
|
||
if [ -f "$CLOUD_DIR/kohya_code.tar.gz" ]; then
|
||
echo " 解压 kohya_code.tar.gz..."
|
||
tar -xzf "$CLOUD_DIR/kohya_code.tar.gz" -C "$BASE_DIR/kohya_ss_home/"
|
||
echo " ✓ kohya_code.tar.gz"
|
||
fi
|
||
|
||
# 业务数据
|
||
if [ -f "$CLOUD_DIR/data.tar.gz" ]; then
|
||
echo " 解压 data.tar.gz..."
|
||
tar -xzf "$CLOUD_DIR/data.tar.gz" -C "$BASE_DIR/"
|
||
echo " ✓ data.tar.gz"
|
||
fi
|
||
|
||
# WebUI 扩展
|
||
mkdir -p "$BASE_DIR/stable-diffusion-webui/extensions"
|
||
if [ -f "$CLOUD_DIR/webui_controlnet.tar.gz" ]; then
|
||
echo " 解压 webui_controlnet.tar.gz..."
|
||
tar -xzf "$CLOUD_DIR/webui_controlnet.tar.gz" -C "$BASE_DIR/stable-diffusion-webui/extensions/"
|
||
echo " ✓ webui_controlnet.tar.gz"
|
||
fi
|
||
if [ -f "$CLOUD_DIR/webui_repositories.tar.gz" ]; then
|
||
echo " 解压 webui_repositories.tar.gz..."
|
||
tar -xzf "$CLOUD_DIR/webui_repositories.tar.gz" -C "$BASE_DIR/stable-diffusion-webui/"
|
||
echo " ✓ webui_repositories.tar.gz"
|
||
fi
|
||
|
||
echo " ✓ 网盘文件解压完成"
|
||
else
|
||
echo "[0/9] cloud_packages/ 目录不存在或为空,跳过自动解压"
|
||
fi
|
||
echo ""
|
||
|
||
# 1. 检查前提条件
|
||
echo "[1/9] 检查前提条件..."
|
||
command -v git >/dev/null || { echo " ✗ git 未安装"; ERRORS+=("git"); }
|
||
command -v conda >/dev/null || { echo " ✗ conda 未安装"; ERRORS+=("conda"); }
|
||
nvidia-smi >/dev/null 2>&1 || { echo " ✗ NVIDIA 驱动未安装"; ERRORS+=("nvidia-smi"); }
|
||
if [ ${#ERRORS[@]} -eq 0 ]; then
|
||
echo " ✓ 前提条件满足"
|
||
fi
|
||
|
||
# 2. 生成 configure.ini
|
||
echo "[2/9] 生成 configure.ini..."
|
||
sed "s|__BASE_DIR__|$BASE_DIR|g" "$BASE_DIR/hair_service_sd/config/configure.ini.template" > "$BASE_DIR/hair_service_sd/config/configure.ini"
|
||
echo " ✓ configure.ini 已生成"
|
||
|
||
# 3. 恢复 conda 环境(conda-pack)
|
||
echo "[3/9] 恢复 conda 环境(my_hair, sdwebui, kohya)..."
|
||
for env_name in my_hair sdwebui kohya; do
|
||
if [ -f "$BASE_DIR/conda_envs/${env_name}.tar.gz" ]; then
|
||
echo " 恢复 $env_name ..."
|
||
rm -rf "$CONDA_BASE/envs/$env_name"
|
||
mkdir -p "$CONDA_BASE/envs/$env_name"
|
||
tar -xzf "$BASE_DIR/conda_envs/${env_name}.tar.gz" -C "$CONDA_BASE/envs/$env_name"
|
||
conda activate "$env_name" 2>/dev/null
|
||
conda-unpack 2>/dev/null # 修复打包后的硬编码路径
|
||
conda deactivate 2>/dev/null
|
||
echo " ✓ $env_name 已恢复"
|
||
else
|
||
echo " ✗ conda_envs/${env_name}.tar.gz 不存在,请从网盘下载"
|
||
ERRORS+=("conda_envs/${env_name}.tar.gz")
|
||
fi
|
||
done
|
||
|
||
# 4. 创建 py310 环境(从 yml)
|
||
echo "[4/9] 创建 py310 环境(从 yml)..."
|
||
if [ -f "$BASE_DIR/conda_envs/py310.yml" ]; then
|
||
conda env create -f "$BASE_DIR/conda_envs/py310.yml" -n py310 2>/dev/null && echo " ✓ py310 已创建" || echo " ℹ py310 环境已存在,跳过"
|
||
else
|
||
echo " ✗ conda_envs/py310.yml 不存在"
|
||
ERRORS+=("conda_envs/py310.yml")
|
||
fi
|
||
|
||
# 5. 检查模型/数据目录
|
||
echo "[5/9] 检查模型和数据目录..."
|
||
for dir in hair_service_sd/weights stable-diffusion-webui/models/Lora stable-diffusion-webui/models/Stable-diffusion stable-diffusion-webui/extensions/sd-webui-controlnet stable-diffusion-webui/repositories kohya_ss_home/.local kohya_ss_home/kohya_ss data/ref_hairstyle; do
|
||
if [ -d "$BASE_DIR/$dir" ]; then
|
||
echo " ✓ $dir"
|
||
else
|
||
echo " ✗ $dir 缺失,请从网盘下载"
|
||
ERRORS+=("$dir")
|
||
fi
|
||
done
|
||
|
||
# 6. 检查训练底模
|
||
echo "[6/9] 检查训练底模 v1-5-pruned-emaonly..."
|
||
if [ -f "$BASE_DIR/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors" ]; then
|
||
echo " ✓ v1-5-pruned-emaonly.safetensors 已存在"
|
||
else
|
||
echo " ✗ v1-5-pruned-emaonly.safetensors 缺失,请从网盘下载 models/ 目录"
|
||
ERRORS+=("v1-5-pruned-emaonly.safetensors")
|
||
fi
|
||
|
||
# 7. 创建运行时目录
|
||
echo "[7/9] 创建运行时目录..."
|
||
mkdir -p "$BASE_DIR/logs"
|
||
mkdir -p "$BASE_DIR/data/tmp" "$BASE_DIR/data/res_dir" "$BASE_DIR/data/userImage" "$BASE_DIR/data/user_info"
|
||
mkdir -p "$BASE_DIR/kohya_ss_home/train_material"
|
||
echo " ✓ 运行时目录已创建"
|
||
|
||
# 8. 验证 kohya 训练环境
|
||
echo "[8/9] 验证 kohya 训练环境..."
|
||
KOHYA_PYTHON="$CONDA_BASE/envs/kohya/bin/python"
|
||
KOHYA_LOCAL="$BASE_DIR/kohya_ss_home/.local/lib/python3.10/site-packages"
|
||
if [ -f "$KOHYA_PYTHON" ] && [ -d "$KOHYA_LOCAL" ]; then
|
||
echo " 测试 torch/accelerate 加载..."
|
||
if PYTHONPATH="$KOHYA_LOCAL" "$KOHYA_PYTHON" -c "
|
||
import torch, accelerate, bitsandbytes, diffusers
|
||
print(f' torch={torch.__version__} cuda={torch.cuda.is_available()}')
|
||
print(f' accelerate={accelerate.__version__}')
|
||
print(' ✓ 训练环境验证通过')
|
||
" 2>/dev/null; then
|
||
true
|
||
else
|
||
echo " ✗ 训练环境验证失败,请检查 kohya 环境和 .local 目录"
|
||
ERRORS+=("kohya验证")
|
||
fi
|
||
else
|
||
echo " ✗ kohya Python 或 .local 目录不存在,跳过验证"
|
||
ERRORS+=("kohya环境")
|
||
fi
|
||
|
||
echo ""
|
||
echo "=== 部署结果 ==="
|
||
if [ ${#ERRORS[@]} -eq 0 ]; then
|
||
echo "✓ 所有检查通过,部署完成!"
|
||
else
|
||
echo "⚠ 有 ${#ERRORS[@]} 个问题需要处理:"
|
||
for err in "${ERRORS[@]}"; do
|
||
echo " - $err"
|
||
done
|
||
echo ""
|
||
echo "请从网盘下载缺失的文件后重新运行 ./setup.sh"
|
||
fi
|
||
echo ""
|
||
echo "启动服务: ./start_all_services.sh"
|