Files
change_hair_3090/DEPLOY.md
T

20 KiB
Raw Blame History

换发型项目部署操作手册

本手册详细描述在全新的 Ubuntu 22.04 + NVIDIA 3090 机器上,从零开始部署并运行换发型、换发色、训练模型三大功能的完整步骤。


目录

  1. 环境前提
  2. 安装系统依赖
  3. Clone 代码
  4. 下载网盘文件
  5. 运行部署脚本
  6. 启动服务
  7. 验证功能
  8. API 接口参考
  9. 停止与重启服务
  10. 常见问题排查
  11. 架构说明

1. 环境前提

项目 要求
操作系统 Ubuntu 22.04 LTS
GPU NVIDIA RTX 3090(或其他 10GB+ 显存的 NVIDIA GPU
NVIDIA 驱动 ≥ 525.x(支持 CUDA 11.8
磁盘空间 ≥ 90GB(代码 + 模型 + 环境)
网络 需要访问 PyPI(创建 py310 环境时下载 pip 包)
Python 不需要预装(通过 conda 管理)

验证 GPU 和驱动:

nvidia-smi
# 应显示 GPU 信息和 CUDA 版本(≥ 11.8

2. 安装系统依赖

2.1 安装基础工具

sudo apt update
sudo apt install -y git curl wget lsof

2.2 安装 Miniconda(如未安装)

# 下载并安装 Miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3

# 初始化 conda
$HOME/miniconda3/bin/conda init bash
source ~/.bashrc

# 验证
conda --version

2.3 配置 conda 镜像(国内可选,加速 py310 创建)

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
conda config --set show_channel_urls yes

3. Clone 代码

cd ~
git clone <仓库地址> change_hair_3090
cd change_hair_3090

Clone 后的目录结构(仅代码,不含模型/环境):

change_hair_3090/
├── hair_service_sd/          # 换发算法服务代码
├── photo_service/            # 训练调度服务代码
├── stable-diffusion-webui/   # SD WebUI 代码(不含 models/
├── kohya_ss_home/            # kohya_ss 训练代码(不含 .local/
├── conda_envs/
│   └── py310.yml             # py310 环境定义文件
├── setup.sh                  # 部署脚本
├── start_all_services.sh     # 启动脚本
├── stop_all_services.sh      # 停止脚本
└── README.md

4. 下载网盘文件

将网盘上的 cloud_packages/ 目录下载到项目根目录。网盘文件已分类打包为 14 个文件,便于上传和下载。

4.1 网盘文件清单(已分类打包)

文件 大小 说明
my_hair.tar.gz 4.2G conda 环境(换发算法服务用)
sdwebui.tar.gz 3.6G conda 环境(SD WebUI 用)
kohya.tar.gz 84M conda 环境(LoRA 训练用,仅含 Python+numpy
sd_base_models.tar.gz 3.6G SD 底模(v1-5-pruned-emaonly.safetensors
lora_0-9.tar.gz 29G LoRA 模型(数字开头,约 228 个)
lora_h.tar.gz 132M LoRA 模型(h 开头)
lora_n.tar.gz 132M LoRA 模型(n 开头)
lora_t.tar.gz 791M LoRA 模型(t 开头)
weights.tar.gz 9.2G 换发算法模型(matting、分割等)
kohya_local.tar.gz 3.4G 训练 pip 包(torch、accelerate、diffusers 等)
kohya_code.tar.gz 365M kohya_ss 训练代码 + CLIP 缓存
data.tar.gz 3.4G 业务数据(参考发型图等)
webui_controlnet.tar.gz 4.1G ControlNet 扩展
webui_repositories.tar.gz 221M SD 依赖仓库(k-diffusion 等)

合计约 62G

4.2 下载后解压

cd ~/change_hair_3090

# 创建 cloud_packages 目录并下载网盘文件到这里
mkdir -p cloud_packages
# ... 将网盘上的 cloud_packages/ 目录下载到这里 ...

# 解压所有包(按顺序执行)
echo "=== 1. 解压 conda 环境 ==="
tar -xzf cloud_packages/my_hair.tar.gz -C conda_envs/
tar -xzf cloud_packages/sdwebui.tar.gz -C conda_envs/
tar -xzf cloud_packages/kohya.tar.gz -C conda_envs/

echo "=== 2. 解压 SD 模型 ==="
tar -xzf cloud_packages/sd_base_models.tar.gz -C stable-diffusion-webui/models/Stable-diffusion/

echo "=== 3. 解压 LoRA 模型 ==="
tar -xzf cloud_packages/lora_0-9.tar.gz -C stable-diffusion-webui/models/Lora/
tar -xzf cloud_packages/lora_h.tar.gz -C stable-diffusion-webui/models/Lora/
tar -xzf cloud_packages/lora_n.tar.gz -C stable-diffusion-webui/models/Lora/
tar -xzf cloud_packages/lora_t.tar.gz -C stable-diffusion-webui/models/Lora/

echo "=== 4. 解压换发算法权重 ==="
tar -xzf cloud_packages/weights.tar.gz -C hair_service_sd/

echo "=== 5. 解压 kohya 训练环境 ==="
tar -xzf cloud_packages/kohya_local.tar.gz -C kohya_ss_home/
tar -xzf cloud_packages/kohya_code.tar.gz -C kohya_ss_home/

echo "=== 6. 解压业务数据 ==="
tar -xzf cloud_packages/data.tar.gz -C .

echo "=== 7. 解压 WebUI 扩展 ==="
tar -xzf cloud_packages/webui_controlnet.tar.gz -C stable-diffusion-webui/extensions/
tar -xzf cloud_packages/webui_repositories.tar.gz -C stable-diffusion-webui/

4.3 解压后验证

cd ~/change_hair_3090

# 检查关键文件是否存在
ls -lh conda_envs/*.tar.gz
ls -d hair_service_sd/weights/
ls -d kohya_ss_home/.local/
ls -lh stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors

期望输出:

-rw------- ... 84M ... conda_envs/kohya.tar.gz
-rw------- ... 4.2G ... conda_envs/my_hair.tar.gz
-rw------- ... 3.6G ... conda_envs/sdwebui.tar.gz
hair_service_sd/weights/
kohya_ss_home/.local/
-rw-rw-r-- ... 4.0G ... v1-5-pruned-emaonly.safetensors

4.3 关于 kohya 训练环境的架构说明

LoRA 训练环境由两部分组成,缺一不可:

conda_envs/kohya.tar.gz (84M)          kohya_ss_home/.local/ (7.6G)
┌─────────────────────────┐            ┌──────────────────────────────────┐
│ Python 3.10 解释器       │            │ torch 2.0.1+cu118                │
│ numpy 1.24.4            │  +PYTHONPATH→ │ accelerate 0.23.0                │
│ tqdm                    │            │ bitsandbytes 0.41.1              │
│ setuptools 69.5.1       │            │ diffusers 0.21.4                 │
│ (conda-pack 打包)        │            │ transformers 4.30.2              │
│                         │            │ xformers 0.0.21                  │
│                         │            │ safetensors, pytorch_lightning   │
│                         │            │ (从 Docker 容器复制的 pip 包)      │
└─────────────────────────┘            └──────────────────────────────────┘

kohya.tar.gz 仅包含 Python 解释器和 numpy(解决版本兼容性),通过 PYTHONPATH 环境变量指向 .local/ 目录来加载 torch 等大包。这样避免重新下载 7.6G 的训练依赖。


5. 运行部署脚本

cd ~/change_hair_3090
chmod +x setup.sh start_all_services.sh stop_all_services.sh
./setup.sh

5.1 setup.sh 执行的 8 个步骤

步骤 说明
1/8 检查前提条件(git、conda、NVIDIA 驱动)
2/8 生成 configure.ini(自动替换 __BASE_DIR__ 为实际路径)
3/8 从 conda-pack 恢复 my_hair、sdwebui、kohya 三个 conda 环境
4/8 py310.yml 创建 py310 环境(需联网下载 pip 包)
5/8 检查模型和数据目录完整性
6/8 检查训练底模 v1-5-pruned-emaonly.safetensors
7/8 创建运行时目录(logs、data/tmp 等)
8/8 验证 kohya 训练环境(测试 torch/accelerate 能否加载)

5.2 成功输出

=== 换发型项目部署脚本 ===
BASE_DIR: /home/xxx/change_hair_3090
CONDA_BASE: /home/xxx/miniconda3

[1/8] 检查前提条件...
  ✓ 前提条件满足
[2/8] 生成 configure.ini...
  ✓ configure.ini 已生成
[3/8] 恢复 conda 环境(my_hair, sdwebui, kohya...
  ✓ my_hair 已恢复
  ✓ sdwebui 已恢复
  ✓ kohya 已恢复
[4/8] 创建 py310 环境(从 yml...
  ✓ py310 已创建
[5/8] 检查模型和数据目录...
  ✓ hair_service_sd/weights
  ✓ stable-diffusion-webui/models/Lora
  ...(全部 ✓)
[6/8] 检查训练底模 v1-5-pruned-emaonly...
  ✓ v1-5-pruned-emaonly.safetensors 已存在
[7/8] 创建运行时目录...
  ✓ 运行时目录已创建
[8/8] 验证 kohya 训练环境...
  测试 torch/accelerate 加载...
  torch=2.0.1+cu118 cuda=True
  accelerate=0.23.0
  ✓ 训练环境验证通过

=== 部署结果 ===
✓ 所有检查通过,部署完成!

5.3 如果 CONDA_BASE 不在默认路径

# 方法1:设置环境变量
export CONDA_BASE=/your/conda/path
./setup.sh

# 方法2:脚本会自动通过 `conda info --base` 检测
# 只要 conda 在 PATH 中即可自动找到

6. 启动服务

./start_all_services.sh

6.1 启动的三个服务

服务 端口 conda 环境 功能
hair_service_sd 8801 my_hair 换发型/换发色核心算法
stable-diffusion-webui 57860 sdwebui SD 图生图推理
photo_service 32678 py310 LoRA 训练调度(训练子进程使用 kohya 环境)

6.2 成功输出

=== 启动换发型服务 ===
[1/3] 启动 hair_service_sd (端口 8801)...
  hair_service_sd 已启动 (PID: xxxx, 端口 8801)
[2/3] 启动 stable-diffusion-webui (端口 57860)...
  stable-diffusion-webui 已启动 (PID: xxxx, 端口 57860)
   WebUI 首次启动需加载模型(约 30-60 秒),请耐心等待
[3/3] 启动 photo_service (端口 32678)...
  photo_service 已启动 (PID: xxxx, 端口 32678)

=== 所有服务已启动 ===
等待 WebUI 就绪(检查端口 57860...
✓ WebUI 已就绪

6.3 查看日志

# 换发型/换发色服务日志
tail -f logs/hair_service.log

# SD WebUI 日志
tail -f logs/webui.log

# 训练服务日志
tail -f logs/photo_service.log

7. 验证功能

7.1 验证服务状态

# 检查三个端口是否在监听
curl -s http://127.0.0.1:8801/ | head -5
curl -s http://127.0.0.1:57860/sdapi/v1/options | head -5
curl -s http://127.0.0.1:32678/ | head -5

7.2 验证换发色功能

# 准备一张人像照片(base64 编码)
IMG_B64=$(base64 -w0 test_photo.jpg)

curl -X POST http://127.0.0.1:8801/hairColor/v2 \
  -H "Content-Type: application/json" \
  -d "{
    \"img\": \"data:image/jpeg;base64,${IMG_B64}\",
    \"userId\": \"test_user\",
    \"rgb\": \"120,60,30\"
  }"

参数说明:

  • img:用户照片,支持 base64data:image/jpeg;base64,...)或 URL
  • userId:用户标识
  • rgb:目标发色 RGB 值(如 120,60,30 表示棕色)

7.3 验证换发型功能

curl -X POST http://127.0.0.1:8801/api/swapHair/v1 \
  -H "Content-Type: application/json" \
  -d "{
    \"hair_id\": \"<发型ID>\",
    \"task_id\": \"test_001\",
    \"is_hr\": \"false\",
    \"user_img_path\": \"data:image/jpeg;base64,${IMG_B64}\"
  }"

参数说明:

  • hair_id:发型 ID(对应 data/ref_hairstyle/ 目录下的发型)
  • task_id:任务唯一标识
  • is_hr:是否高清模式("true""false"
  • user_img_path:用户照片,支持 base64 或 URL

7.4 验证训练功能

训练需要准备训练素材(10+ 张同一发型的照片),组织成指定目录结构:

hair_material_dir/
├── images/
│   └── 1_hairstyle/          # 数字开头的文件夹
│       ├── 001.png            # 训练图片(≥10张)
│       ├── 001.txt            # 标签文件(自动生成)
│       ├── 002.png
│       ├── 002.txt
│       └── ...
└── model/                     # 训练输出目录(需提前创建)

发起训练请求:

curl -X POST http://127.0.0.1:32678/api/hair/train \
  -H "Content-Type: application/json" \
  -d "{
    \"task_id\": \"train_001\",
    \"hair_id\": \"test_hair\",
    \"hair_material_dir\": \"/home/xxx/change_hair_3090/data/tmp/test_material\"
  }"

训练日志查看:

tail -f logs/photo_service.log
# 训练开始后会看到 cmd_train 输出
# 训练完成后会在 hair_material_dir/model/ 下生成 hairstyle_hd_lora.safetensors

训练参数(已在代码中固定):

  • 底模:v1-5-pruned-emaonly.safetensors
  • 训练步数:1500 步
  • 分辨率:2000x2000
  • LoRA dim128alpha64
  • 优化器:AdamW8bit
  • 精度:fp16

8. API 接口参考

8.1 换发色 API

项目
URL POST http://<IP>:8801/hairColor/v2
参数 imgbase64或URL, userId, rgb(如"120,60,30"
返回 JSON,含换色后的图片 URL 或 base64

8.2 换发型 API

项目
URL POST http://<IP>:8801/api/swapHair/v1
参数 hair_id, task_id, is_hr, user_img_pathbase64或URL, output_format(可选)
返回 JSON,含换发后的图片 URL 或 base64

8.3 训练 API

项目
URL POST http://<IP>:32678/api/hair/train
参数 task_id, hair_id, hair_material_dir(训练素材目录绝对路径)
返回 {"state": 0, "msg": "头发lora训练开始", "task_id": "..."}
训练回调 训练完成/失败后 POST 到 http://127.0.0.1:8801/api/hair/trainCallBack

8.4 推理 API

项目
URL POST http://<IP>:32678/api/hair/inference
参数 hair_id, inference_port, hair_material_dir, request_jsonSD WebUI img2img 请求体)

9. 停止与重启服务

9.1 停止所有服务

./stop_all_services.sh

输出:

=== 停止换发型服务 ===
  ✓ 已停止 hair_service_sd (端口 8801, PID xxxx)
  ✓ 已停止 webui (端口 57860, PID xxxx)
  ✓ 已停止 photo_service (端口 32678, PID xxxx)

9.2 重启服务

./stop_all_services.sh
./start_all_services.sh

9.3 手动停止单个服务

kill $(lsof -t -i:8801)     # 停止换发服务
kill $(lsof -t -i:57860)    # 停止 WebUI
kill $(lsof -t -i:32678)    # 停止训练服务

10. 常见问题排查

10.1 setup.sh 报错 "conda 未安装"

# 确认 conda 已安装
which conda
# 如果没有,参考第2.2节安装 Miniconda

10.2 setup.sh 报错 "CONDA_BASE 不正确"

# 查找 conda 安装路径
which conda
# 或
conda info --base

# 设置后重新运行
export CONDA_BASE=$(conda info --base)
./setup.sh

10.3 py310 环境创建失败(网络问题)

py310 环境需要从 PyPI 下载 pip 包(flask、gevent、opencv-python 等)。如果网络不通:

# 使用国内 PyPI 镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 手动创建
conda create -n py310 python=3.10 -y
conda activate py310
pip install flask==3.0.3 gevent==24.2.1 opencv-python==4.10.0.84 numpy==2.0.0 scipy==1.14.0 scikit-image==0.24.0 pillow==10.4.0 requests==2.32.3

10.4 start_all_services.sh 报 "端口已被占用"

# 先停止已有服务
./stop_all_services.sh

# 确认端口已释放
lsof -i :8801
lsof -i :57860
lsof -i :32678

# 重新启动
./start_all_services.sh

10.5 WebUI 启动失败

# 查看详细日志
tail -100 logs/webui.log

# 常见原因:
# 1. 模型文件缺失 → 检查 stable-diffusion-webui/models/Stable-diffusion/
# 2. 显存不足 → 检查 nvidia-smi
# 3. xformers 兼容性 → 尝试去掉 --xformers 参数

10.6 训练失败

# 查看训练日志
tail -100 logs/photo_service.log

# 常见原因:
# 1. 训练素材目录结构不对 → 参考 7.4 节
# 2. 底模缺失 → 检查 v1-5-pruned-emaonly.safetensors
# 3. .local 包损坏 → 重新从网盘下载 kohya_ss_home/.local/
# 4. kohya 环境问题 → 重新运行 setup.sh

10.7 GPU 不可用(CUDA error

# 检查驱动
nvidia-smi

# 检查 CUDA
nvcc --version

# 测试 torch CUDA
CONDA_BASE=$(conda info --base)
PYTHONPATH=$PWD/kohya_ss_home/.local/lib/python3.10/site-packages \
  $CONDA_BASE/envs/kohya/bin/python -c "import torch; print(torch.cuda.is_available())"
# 应输出 True

10.8 内存不足(OOM

3090 有 24GB 显存。如果同时运行三个服务出现 OOM:

# 先停止不需要的服务
./stop_all_services.sh

# 只启动需要的服务(如只换发型)
$CONDA_BASE/envs/my_hair/bin/python hair_service_sd/run_copy_cost_colorb64.py &
$CONDA_BASE/envs/sdwebui/bin/python stable-diffusion-webui/webui.py --api --listen --xformers --port 57860 &

11. 架构说明

11.1 系统架构

                          用户请求
                             │
               ┌─────────────┼─────────────┐
               │             │             │
               ▼             ▼             ▼
        ┌──────────┐  ┌──────────┐  ┌──────────────┐
        │hair_service│  │photo_service│  │stable-diffusion│
        │  _sd      │  │            │  │  -webui        │
        │ (8801)    │  │ (32678)   │  │  (57860)       │
        └────┬─────┘  └─────┬─────┘  └───────┬────────┘
             │              │                 │
             │         训练子进程              │
             │              │                 │
             │     ┌────────┴────────┐        │
             │     │ kohya conda env │        │
             │     │ + .local/ 包    │        │
             │     │ accelerate      │        │
             │     │ train_network   │        │
             │     └─────────────────┘        │
             │                                 │
             ▼                                 ▼
        weights/                        models/Stable-diffusion/
        (换发模型)                       v1-5-pruned-emaonly.safetensors
                                         models/Lora/ (228个LoRA)

11.2 数据流

换发型/换发色

用户图片 → hair_service_sd(8801) → 调用 WebUI(57860) img2img → 返回结果

训练 LoRA

训练素材 → photo_service(32678) → kohya环境+accelerate → train_network.py → 生成 LoRA

训练后推理

用户图片 + LoRA → photo_service(32678) → 复制LoRA到webui/models/Lora/ → WebUI img2img → 返回

11.3 conda 环境说明

环境 用途 包含内容 大小
my_hair 换发算法服务 torch, cv2, flask, 换发依赖 4.2G
sdwebui SD WebUI torch, xformers, webui 依赖 3.6G
py310 训练调度服务 flask, gevent, cv2, numpy 2.0 ~500M
kohya LoRA 训练 Python 3.10, numpy 1.24 84M
.local/ 训练大包(非conda torch 2.0.1, accelerate, diffusers 7.6G

kohya 环境通过 PYTHONPATH 指向 .local/ 目录来复用训练大包,避免重复下载。


附录:完整部署速查

# 1. 安装 conda(如未安装)
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3
source ~/.bashrc

# 2. Clone 代码
cd ~
git clone <仓库地址> change_hair_3090
cd change_hair_3090

# 3. 下载网盘文件(合并到项目根目录)
# ... 手动下载 ...

# 4. 部署
chmod +x setup.sh start_all_services.sh stop_all_services.sh
./setup.sh

# 5. 启动
./start_all_services.sh

# 6. 验证
curl http://127.0.0.1:8801/
curl http://127.0.0.1:57860/sdapi/v1/options
curl http://127.0.0.1:32678/

# 7. 停止
./stop_all_services.sh