1 Commits
Author SHA1 Message Date
xsl 9b7324cd26 chore: 适配本机 xsl 路径(RTX 5090 机器)
将所有绝对路径从 /home/ubuntu 改回 /home/xsl,覆盖启动脚本、
configure.ini 及训练/测试脚本。纯路径替换,无功能性改动。

本分支(xsl5090)用于本机(RTX 5090)运行;master 维持 /home/ubuntu
供远程 ubuntu 机器使用。
2026-07-18 16:26:16 +08:00
31 changed files with 162 additions and 162 deletions
+12 -12
View File
@@ -8,8 +8,8 @@
3. 串行执行,记录每个发型成功/失败 3. 串行执行,记录每个发型成功/失败
用法: 用法:
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
python /home/ubuntu/change_hair/batch_train_hairstyles.py --src /home/ubuntu/change_hair/hair_type_images --gender girl [--only 圆-心形] [--start-from 心形-心形] python /home/xsl/change_hair/batch_train_hairstyles.py --src /home/xsl/change_hair/hair_type_images --gender girl [--only 圆-心形] [--start-from 心形-心形]
注意: 注意:
- 中文 hair_id 直接用文件名(去扩展名)作为 ID - 中文 hair_id 直接用文件名(去扩展名)作为 ID
@@ -24,14 +24,14 @@ import argparse
import subprocess import subprocess
from datetime import datetime from datetime import datetime
SRC_DEFAULT = "/home/ubuntu/change_hair/hair_type_images" SRC_DEFAULT = "/home/xsl/change_hair/hair_type_images"
WORK_DIR = "/home/ubuntu/change_hair/data/batch_train_inputs" WORK_DIR = "/home/xsl/change_hair/data/batch_train_inputs"
LOG_FILE = "/home/ubuntu/change_hair/data/batch_train_log.txt" LOG_FILE = "/home/xsl/change_hair/data/batch_train_log.txt"
TRAIN_SCRIPT = "/home/ubuntu/change_hair/train_hairstyle_full.py" TRAIN_SCRIPT = "/home/xsl/change_hair/train_hairstyle_full.py"
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
LOCK_FILE = "/home/ubuntu/change_hair/data/batch_train.pid" LOCK_FILE = "/home/xsl/change_hair/data/batch_train.pid"
DONE_FILE = "/home/ubuntu/change_hair/data/batch_train_done.txt" # 已完成发型清单(断点续跑) DONE_FILE = "/home/xsl/change_hair/data/batch_train_done.txt" # 已完成发型清单(断点续跑)
LORA_DIR = "/home/ubuntu/change_hair/data/train_material" # LoRA 输出根目录 LORA_DIR = "/home/xsl/change_hair/data/train_material" # LoRA 输出根目录
def acquire_lock(): def acquire_lock():
@@ -125,7 +125,7 @@ def run_one(hair_id, src_img, gender, py, done_set, force=False):
log(f" 调用: {' '.join(cmd[:2])} ... --hair-id {hair_id}") log(f" 调用: {' '.join(cmd[:2])} ... --hair-id {hair_id}")
try: try:
# 子进程输出实时写到日志文件 # 子进程输出实时写到日志文件
proc_log = os.path.join("/home/ubuntu/change_hair/data", f"subprocess_{hair_id}.log") proc_log = os.path.join("/home/xsl/change_hair/data", f"subprocess_{hair_id}.log")
with open(proc_log, "w", encoding="utf-8") as f: with open(proc_log, "w", encoding="utf-8") as f:
r = subprocess.run( r = subprocess.run(
cmd, cwd=HAIR_SERVICE_DIR, cmd, cwd=HAIR_SERVICE_DIR,
@@ -152,7 +152,7 @@ def main():
ap = argparse.ArgumentParser(description="批量训练发型") ap = argparse.ArgumentParser(description="批量训练发型")
ap.add_argument("--src", default=SRC_DEFAULT, help="原图目录") ap.add_argument("--src", default=SRC_DEFAULT, help="原图目录")
ap.add_argument("--gender", default="girl", choices=["boy", "girl"]) ap.add_argument("--gender", default="girl", choices=["boy", "girl"])
ap.add_argument("--py", default="/home/ubuntu/miniconda3/envs/my_hair/bin/python", ap.add_argument("--py", default="/home/xsl/miniconda3/envs/my_hair/bin/python",
help="python 解释器") help="python 解释器")
ap.add_argument("--only", default=None, help="只训练指定 hair_id(调试用)") ap.add_argument("--only", default=None, help="只训练指定 hair_id(调试用)")
ap.add_argument("--start-from", default=None, ap.add_argument("--start-from", default=None,
+33 -33
View File
@@ -2,7 +2,7 @@
> 适用场景:从原服务器打包上传 conda 环境 + SD WebUI 代码,在本机完成换发型推理部署。 > 适用场景:从原服务器打包上传 conda 环境 + SD WebUI 代码,在本机完成换发型推理部署。
> >
> 本机路径:`/home/ubuntu/change_hair`GPURTX 5090 32GCUDA 12.8 > 本机路径:`/home/xsl/change_hair`GPURTX 5090 32GCUDA 12.8
> >
> 原服务器参考:`szlc@192.168.101.63` > 原服务器参考:`szlc@192.168.101.63`
> >
@@ -48,13 +48,13 @@
### 2.1 Conda 环境 × 3 ### 2.1 Conda 环境 × 3
从原服务器 `/home/szlc/miniconda3/envs/` 打包,上传到本机 `/home/ubuntu/miniconda3/envs/` 从原服务器 `/home/szlc/miniconda3/envs/` 打包,上传到本机 `/home/xsl/miniconda3/envs/`
| 环境名 | 原服务器路径 | 本机目标路径 | 用途 | 预估大小 | | 环境名 | 原服务器路径 | 本机目标路径 | 用途 | 预估大小 |
|--------|-------------|-------------|------|---------| |--------|-------------|-------------|------|---------|
| `my_hair` | `/home/szlc/miniconda3/envs/my_hair/` | `/home/ubuntu/miniconda3/envs/my_hair/` | hair_service_sd 主服务(端口 8801 | ~58G | | `my_hair` | `/home/szlc/miniconda3/envs/my_hair/` | `/home/xsl/miniconda3/envs/my_hair/` | hair_service_sd 主服务(端口 8801 | ~58G |
| `sdwebui` | `/home/szlc/miniconda3/envs/sdwebui/` | `/home/ubuntu/miniconda3/envs/sdwebui/` | SD WebUI 推理(端口 57860 | ~812G | | `sdwebui` | `/home/szlc/miniconda3/envs/sdwebui/` | `/home/xsl/miniconda3/envs/sdwebui/` | SD WebUI 推理(端口 57860 | ~812G |
| `py310` | `/home/szlc/miniconda3/envs/py310/` | `/home/ubuntu/miniconda3/envs/py310/` | photo_service LoRA 调度(端口 32678 | ~24G | | `py310` | `/home/szlc/miniconda3/envs/py310/` | `/home/xsl/miniconda3/envs/py310/` | photo_service LoRA 调度(端口 32678 | ~24G |
> ⚠️ **为什么必须上传,不能从公网安装?** 这三个环境包含特定版本的 PyTorch + CUDA 扩展、历史版本的 pip 包、以及编译好的 C++/CUDA 算子,依赖关系复杂。项目中的 `env.yaml` 是旧的 Python 3.7 规格,与实际运行环境(Python 3.10)不一致,无法用于重建。 > ⚠️ **为什么必须上传,不能从公网安装?** 这三个环境包含特定版本的 PyTorch + CUDA 扩展、历史版本的 pip 包、以及编译好的 C++/CUDA 算子,依赖关系复杂。项目中的 `env.yaml` 是旧的 Python 3.7 规格,与实际运行环境(Python 3.10)不一致,无法用于重建。
@@ -72,8 +72,8 @@ tar czf py310.tar.gz py310/
```bash ```bash
# 在本机执行(上传完成后) # 在本机执行(上传完成后)
mkdir -p /home/ubuntu/miniconda3/envs mkdir -p /home/xsl/miniconda3/envs
cd /home/ubuntu/miniconda3/envs cd /home/xsl/miniconda3/envs
tar xzf /path/to/my_hair.tar.gz tar xzf /path/to/my_hair.tar.gz
tar xzf /path/to/sdwebui.tar.gz tar xzf /path/to/sdwebui.tar.gz
tar xzf /path/to/py310.tar.gz tar xzf /path/to/py310.tar.gz
@@ -87,7 +87,7 @@ tar xzf /path/to/py310.tar.gz
| 原服务器路径 | 本机目标路径 | 说明 | 预估大小 | | 原服务器路径 | 本机目标路径 | 说明 | 预估大小 |
|-------------|-------------|------|---------| |-------------|-------------|------|---------|
| `/home/szlc/project/onediff/stable-diffusion-webui/`(排除 `models/` | `/home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/` | webui.py、modules/、extensions/、repositories/ 等 | ~25G | | `/home/szlc/project/onediff/stable-diffusion-webui/`(排除 `models/` | `/home/xsl/change_hair/project/onediff/stable-diffusion-webui/` | webui.py、modules/、extensions/、repositories/ 等 | ~25G |
> ⚠️ 本机当前 `project/onediff/stable-diffusion-webui/` 目录只有 `models/` 子目录(4.6G 模型权重),缺少 `webui.py`、`modules/`、`extensions/` 等所有代码文件。 > ⚠️ 本机当前 `project/onediff/stable-diffusion-webui/` 目录只有 `models/` 子目录(4.6G 模型权重),缺少 `webui.py`、`modules/`、`extensions/` 等所有代码文件。
@@ -131,7 +131,7 @@ tar czf webui_code.tar.gz \
```bash ```bash
# 在本机执行(保留已有 models 目录) # 在本机执行(保留已有 models 目录)
cd /home/ubuntu/change_hair/project/onediff cd /home/xsl/change_hair/project/onediff
tar xzf /path/to/webui_code.tar.gz tar xzf /path/to/webui_code.tar.gz
# 解压后确认 models/ 仍在且未被覆盖 # 解压后确认 models/ 仍在且未被覆盖
ls -lh stable-diffusion-webui/models/Stable-diffusion/ ls -lh stable-diffusion-webui/models/Stable-diffusion/
@@ -147,13 +147,13 @@ ls -lh stable-diffusion-webui/models/Stable-diffusion/
# ===== 必须上传(方案 A,共 4 项,约 18–30G===== # ===== 必须上传(方案 A,共 4 项,约 18–30G=====
# 1. Conda 环境(3 个) # 1. Conda 环境(3 个)
/home/szlc/miniconda3/envs/my_hair/ → /home/ubuntu/miniconda3/envs/my_hair/ /home/szlc/miniconda3/envs/my_hair/ → /home/xsl/miniconda3/envs/my_hair/
/home/szlc/miniconda3/envs/sdwebui/ → /home/ubuntu/miniconda3/envs/sdwebui/ /home/szlc/miniconda3/envs/sdwebui/ → /home/xsl/miniconda3/envs/sdwebui/
/home/szlc/miniconda3/envs/py310/ → /home/ubuntu/miniconda3/envs/py310/ /home/szlc/miniconda3/envs/py310/ → /home/xsl/miniconda3/envs/py310/
# 2. SD WebUI 代码(排除 models/ # 2. SD WebUI 代码(排除 models/
/home/szlc/project/onediff/stable-diffusion-webui/(排除 models/ /home/szlc/project/onediff/stable-diffusion-webui/(排除 models/
→ /home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/ → /home/xsl/change_hair/project/onediff/stable-diffusion-webui/
``` ```
--- ---
@@ -166,16 +166,16 @@ ls -lh stable-diffusion-webui/models/Stable-diffusion/
| 原服务器路径 | 本机目标路径 | 预估大小 | | 原服务器路径 | 本机目标路径 | 预估大小 |
|-------------|-------------|---------| |-------------|-------------|---------|
| `/home/szlc/project/kohya_ss_home/` | `/home/ubuntu/change_hair/project/kohya_ss_home/` | ~13G | | `/home/szlc/project/kohya_ss_home/` | `/home/xsl/change_hair/project/kohya_ss_home/` | ~13G |
| `/home/szlc/miniconda3/envs/kohya/` | `/home/ubuntu/miniconda3/envs/kohya/` | ~5G | | `/home/szlc/miniconda3/envs/kohya/` | `/home/xsl/miniconda3/envs/kohya/` | ~5G |
### 4.2 换发色功能 ### 4.2 换发色功能
| 原服务器路径 | 本机目标路径 | | 原服务器路径 | 本机目标路径 |
|-------------|-------------| |-------------|-------------|
| `/home/szlc/project/data/ref_haircolor/` | `/home/ubuntu/change_hair/project/data/ref_haircolor/` | | `/home/szlc/project/data/ref_haircolor/` | `/home/xsl/change_hair/project/data/ref_haircolor/` |
| `/home/szlc/project/data/ref_color/` | `/home/ubuntu/change_hair/project/data/ref_color/` | | `/home/szlc/project/data/ref_color/` | `/home/xsl/change_hair/project/data/ref_color/` |
| `/home/szlc/project/data/ref_color_imgs/` | `/home/ubuntu/change_hair/project/data/ref_color_imgs/` | | `/home/szlc/project/data/ref_color_imgs/` | `/home/xsl/change_hair/project/data/ref_color_imgs/` |
| `/home/szlc/.../weights/classify_3_2499.pth` | `project/hair_service_sd/weights/classify_3_2499.pth` | | `/home/szlc/.../weights/classify_3_2499.pth` | `project/hair_service_sd/weights/classify_3_2499.pth` |
### 4.3 更多发型 ### 4.3 更多发型
@@ -207,25 +207,25 @@ ls -lh stable-diffusion-webui/models/Stable-diffusion/
# 从原服务器直传到本机(在本机执行) # 从原服务器直传到本机(在本机执行)
rsync -avP --partial \ rsync -avP --partial \
szlc@192.168.101.63:/home/szlc/miniconda3/envs/my_hair/ \ szlc@192.168.101.63:/home/szlc/miniconda3/envs/my_hair/ \
/home/ubuntu/miniconda3/envs/my_hair/ /home/xsl/miniconda3/envs/my_hair/
rsync -avP --partial \ rsync -avP --partial \
szlc@192.168.101.63:/home/szlc/miniconda3/envs/sdwebui/ \ szlc@192.168.101.63:/home/szlc/miniconda3/envs/sdwebui/ \
/home/ubuntu/miniconda3/envs/sdwebui/ /home/xsl/miniconda3/envs/sdwebui/
rsync -avP --partial \ rsync -avP --partial \
szlc@192.168.101.63:/home/szlc/miniconda3/envs/py310/ \ szlc@192.168.101.63:/home/szlc/miniconda3/envs/py310/ \
/home/ubuntu/miniconda3/envs/py310/ /home/xsl/miniconda3/envs/py310/
rsync -avP --partial \ rsync -avP --partial \
--exclude='models/' \ --exclude='models/' \
szlc@192.168.101.63:/home/szlc/project/onediff/stable-diffusion-webui/ \ szlc@192.168.101.63:/home/szlc/project/onediff/stable-diffusion-webui/ \
/home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/ /home/xsl/change_hair/project/onediff/stable-diffusion-webui/
``` ```
### 方式 2:先 tar 再上传到 `/home/ubuntu/data` ### 方式 2:先 tar 再上传到 `/home/xsl/data`
若通过网盘中转,先 tar 再上传到 `/home/ubuntu/data/`,上传完成后告知我解压。 若通过网盘中转,先 tar 再上传到 `/home/xsl/data/`,上传完成后告知我解压。
--- ---
@@ -235,15 +235,15 @@ rsync -avP --partial \
```bash ```bash
# 1. Conda 环境 # 1. Conda 环境
ls /home/ubuntu/miniconda3/envs/my_hair/bin/python ls /home/xsl/miniconda3/envs/my_hair/bin/python
ls /home/ubuntu/miniconda3/envs/sdwebui/bin/python ls /home/xsl/miniconda3/envs/sdwebui/bin/python
ls /home/ubuntu/miniconda3/envs/py310/bin/python ls /home/xsl/miniconda3/envs/py310/bin/python
# 2. WebUI 代码 # 2. WebUI 代码
ls /home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/webui.py ls /home/xsl/change_hair/project/onediff/stable-diffusion-webui/webui.py
# 3. 模型未被覆盖 # 3. 模型未被覆盖
ls -lh /home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors ls -lh /home/xsl/change_hair/project/onediff/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors
``` ```
期望结果:4 项均存在,SD 底模约 4.0G。 期望结果:4 项均存在,SD 底模约 4.0G。
@@ -254,7 +254,7 @@ ls -lh /home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/models/St
你上传完毕并告知后,我会依次执行: 你上传完毕并告知后,我会依次执行:
1. **路径适配**:运行 `adapt_paths.sh`,将所有硬编码路径从 `/home/xsl/change_hair` 改为 `/home/ubuntu/change_hair``/home/xsl/miniconda3` 改为 `/home/ubuntu/miniconda3` 1. **路径适配**:运行 `adapt_paths.sh`,将所有硬编码路径从 `/home/xsl/change_hair` 改为 `/home/xsl/change_hair``/home/xsl/miniconda3` 改为 `/home/xsl/miniconda3`
2. **Conda 路径修复**:运行 `fix_conda_paths.py`,修复 3 个环境中二进制文件的 shebang 和内部路径前缀 2. **Conda 路径修复**:运行 `fix_conda_paths.py`,修复 3 个环境中二进制文件的 shebang 和内部路径前缀
3. **安装 Miniconda 基础环境**(如尚未安装):从 `repo.anaconda.com` 下载安装 3. **安装 Miniconda 基础环境**(如尚未安装):从 `repo.anaconda.com` 下载安装
4. **启动服务**`bash start_all.sh start`(依赖顺序:webui → photo_service → hair_service_sd 4. **启动服务**`bash start_all.sh start`(依赖顺序:webui → photo_service → hair_service_sd
@@ -283,11 +283,11 @@ POST http://127.0.0.1:8801/api/swapHair/v1
**Q:能否只上传 miniconda3 整包,不传单个 env** **Q:能否只上传 miniconda3 整包,不传单个 env**
可以。上传 `/home/szlc/miniconda3/` 整包到 `/home/ubuntu/miniconda3/` 也行,体积更大(约 20–30G)但更省事。 可以。上传 `/home/szlc/miniconda3/` 整包到 `/home/xsl/miniconda3/` 也行,体积更大(约 20–30G)但更省事。
**Qwebui 上传时不小心覆盖了 models 怎么办?** **Qwebui 上传时不小心覆盖了 models 怎么办?**
重新从 `/home/ubuntu/data/sdwebui/models/` 或原服务器补传 models 目录即可。 重新从 `/home/xsl/data/sdwebui/models/` 或原服务器补传 models 目录即可。
**Q:本机没有 miniconda 基础安装,只传 envs 够吗?** **Q:本机没有 miniconda 基础安装,只传 envs 够吗?**
@@ -299,4 +299,4 @@ webui 启动参数可能需要去掉 `--xformers`,改用 `--opt-sdp-no-mem-att
**Q:本机磁盘空间是否足够?** **Q:本机磁盘空间是否足够?**
当前 `/home` 剩余约 30G。3 个 conda 环境约 20–25G,解压后可能吃紧。建议解压一个删一个 tar 包,或考虑清理 `/home/ubuntu/data/`(已有 16G 冗余数据,解压完成后可删除)。 当前 `/home` 剩余约 30G。3 个 conda 环境约 20–25G,解压后可能吃紧。建议解压一个删一个 tar 包,或考虑清理 `/home/xsl/data/`(已有 16G 冗余数据,解压完成后可删除)。
+2 -2
View File
@@ -9,7 +9,7 @@ OLD_PREFIXES = [
b"/home/szlc/miniconda3", b"/home/szlc/miniconda3",
b"/usr/local/miniconda3", b"/usr/local/miniconda3",
] ]
NEW_PREFIX = b"/home/ubuntu/miniconda3" NEW_PREFIX = b"/home/xsl/miniconda3"
def is_probably_binary(filepath): def is_probably_binary(filepath):
"""通过文件扩展名和内容判断是否为二进制文件""" """通过文件扩展名和内容判断是否为二进制文件"""
@@ -61,7 +61,7 @@ def fix_env(env_dir):
if __name__ == "__main__": if __name__ == "__main__":
for env in sys.argv[1:]: for env in sys.argv[1:]:
env_path = f"/home/ubuntu/miniconda3/envs/{env}" env_path = f"/home/xsl/miniconda3/envs/{env}"
if os.path.isdir(env_path): if os.path.isdir(env_path):
print(f"[{env}] 修复中...") print(f"[{env}] 修复中...")
fix_env(env_path) fix_env(env_path)
+3 -3
View File
@@ -8,7 +8,7 @@ import sys
import cv2 import cv2
import numpy as np import numpy as np
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.environ.setdefault("HF_HUB_OFFLINE", "1") os.environ.setdefault("HF_HUB_OFFLINE", "1")
@@ -87,7 +87,7 @@ def gen_hairline_mask(img_path, mask_path):
if __name__ == "__main__": if __name__ == "__main__":
img_path = sys.argv[1] if len(sys.argv) > 1 else \ img_path = sys.argv[1] if len(sys.argv) > 1 else \
"/home/ubuntu/change_hair/project/data/userImage/8488902485_20250630055547.jpg" "/home/xsl/change_hair/project/data/userImage/8488902485_20250630055547.jpg"
mask_path = sys.argv[2] if len(sys.argv) > 2 else \ mask_path = sys.argv[2] if len(sys.argv) > 2 else \
"/home/ubuntu/change_hair/project/logs/hairgrow_test_mask.png" "/home/xsl/change_hair/project/logs/hairgrow_test_mask.png"
gen_hairline_mask(img_path, mask_path) gen_hairline_mask(img_path, mask_path)
+6 -6
View File
@@ -14,15 +14,15 @@ import time
import base64 import base64
import requests import requests
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
BOY_IMG = "/home/ubuntu/change_hair/images/boy.png" BOY_IMG = "/home/xsl/change_hair/images/boy.png"
GIRL_IMG = "/home/ubuntu/change_hair/images/girl.png" GIRL_IMG = "/home/xsl/change_hair/images/girl.png"
HAIRSTYLE_DIR = "/home/ubuntu/change_hair/project/data/ref_hairstyle" HAIRSTYLE_DIR = "/home/xsl/change_hair/project/data/ref_hairstyle"
TRAIN_DIR = "/home/ubuntu/change_hair/data/train_material" TRAIN_DIR = "/home/xsl/change_hair/data/train_material"
PREVIEW_DIR = "/home/ubuntu/change_hair/hair_grow_service/static/previews" # 预览图存储目录 PREVIEW_DIR = "/home/xsl/change_hair/hair_grow_service/static/previews" # 预览图存储目录
SWAP_API = "http://127.0.0.1:8801/api/swapHair/v1" SWAP_API = "http://127.0.0.1:8801/api/swapHair/v1"
+2 -2
View File
@@ -8,7 +8,7 @@
hair_template_material/<hair_id>/first##<name>.pkl 1k关键点 hair_template_material/<hair_id>/first##<name>.pkl 1k关键点
用法: 用法:
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
python gen_template_material.py --hair-id new_test_001 --img /path/to/template.jpg python gen_template_material.py --hair-id new_test_001 --img /path/to/template.jpg
""" """
import os import os
@@ -19,7 +19,7 @@ import pickle
import argparse import argparse
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.environ.setdefault("HF_HUB_OFFLINE", "1") os.environ.setdefault("HF_HUB_OFFLINE", "1")
+4 -4
View File
@@ -6,12 +6,12 @@
需要在 hair_service_sd 目录下运行(依赖其模块导入)。 需要在 hair_service_sd 目录下运行(依赖其模块导入)。
用法: 用法:
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
/home/ubuntu/miniconda3/envs/my_hair/bin/python /home/ubuntu/change_hair/hair_grow_cli.py \ /home/xsl/miniconda3/envs/my_hair/bin/python /home/xsl/change_hair/hair_grow_cli.py \
--img test.jpg --mask mask.png --strength 0.5 -o result.jpg --img test.jpg --mask mask.png --strength 0.5 -o result.jpg
# 批量跑三档强度对比 # 批量跑三档强度对比
/home/ubuntu/miniconda3/envs/my_hair/bin/python /home/ubuntu/change_hair/hair_grow_cli.py \ /home/xsl/miniconda3/envs/my_hair/bin/python /home/xsl/change_hair/hair_grow_cli.py \
--img test.jpg --mask mask.png --compare --img test.jpg --mask mask.png --compare
""" """
import os import os
@@ -20,7 +20,7 @@ import cv2
import argparse import argparse
# 把 hair_service_sd 加入路径,使其模块可被导入 # 把 hair_service_sd 加入路径,使其模块可被导入
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
# 设置离线模式(本机无法访问 huggingface.co # 设置离线模式(本机无法访问 huggingface.co
+2 -2
View File
@@ -7,12 +7,12 @@
### 1. 确认 webui 已启动(生发依赖 SD inpainting ### 1. 确认 webui 已启动(生发依赖 SD inpainting
```bash ```bash
ss -tlnp | grep 57860 # 确认 webui 在跑 ss -tlnp | grep 57860 # 确认 webui 在跑
bash /home/ubuntu/change_hair/start_all.sh status # 看 webui 是否就绪 bash /home/xsl/change_hair/start_all.sh status # 看 webui 是否就绪
``` ```
### 2. 启动生发服务(端口 8899) ### 2. 启动生发服务(端口 8899)
```bash ```bash
nohup /home/ubuntu/change_hair/start_hairgrow.sh > /home/ubuntu/change_hair/project/logs/hair_grow_service.log 2>&1 & nohup /home/xsl/change_hair/start_hairgrow.sh > /home/xsl/change_hair/project/logs/hair_grow_service.log 2>&1 &
``` ```
### 3. 打开测试页面 ### 3. 打开测试页面
+2 -2
View File
@@ -14,7 +14,7 @@ import base64
import traceback import traceback
# 把 hair_service_sd 加入 path,使其模块可被导入 # 把 hair_service_sd 加入 path,使其模块可被导入
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
# 切换到 hair_service_sd 目录,使 common.logger 能读到 config/configure.ini(相对路径) # 切换到 hair_service_sd 目录,使 common.logger 能读到 config/configure.ini(相对路径)
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
@@ -414,7 +414,7 @@ def train_src_img(hair_id):
"""返回发型的训练原图(hair_type_images/<hair_id>.jpg/.png)。 """返回发型的训练原图(hair_type_images/<hair_id>.jpg/.png)。
用于测试页展示发型真实样子,而非套在标准脸上的效果图。 用于测试页展示发型真实样子,而非套在标准脸上的效果图。
""" """
src_dir = "/home/ubuntu/change_hair/hair_type_images" src_dir = "/home/xsl/change_hair/hair_type_images"
for ext in (".jpg", ".jpeg", ".png"): for ext in (".jpg", ".jpeg", ".png"):
path = os.path.join(src_dir, hair_id + ext) path = os.path.join(src_dir, hair_id + ext)
if os.path.exists(path): if os.path.exists(path):
+4 -4
View File
@@ -6,9 +6,9 @@
原始图 → 人脸检测+1k关键点 → Generator_Matte头发抠图 → 白底合成 + 居中裁剪 → 打标签 原始图 → 人脸检测+1k关键点 → Generator_Matte头发抠图 → 白底合成 + 居中裁剪 → 打标签
用法: 用法:
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
/home/ubuntu/miniconda3/envs/my_hair/bin/python /home/ubuntu/change_hair/prepare_train_data.py \ /home/xsl/miniconda3/envs/my_hair/bin/python /home/xsl/change_hair/prepare_train_data.py \
--input /home/ubuntu/change_hair/train_images \ --input /home/xsl/change_hair/train_images \
--hair-id new_hairstyle_001 \ --hair-id new_hairstyle_001 \
--gender boy --gender boy
""" """
@@ -22,7 +22,7 @@ import argparse
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
# 必须在 hair_service_sd 目录运行(依赖其模块) # 必须在 hair_service_sd 目录运行(依赖其模块)
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.environ.setdefault("HF_HUB_OFFLINE", "1") os.environ.setdefault("HF_HUB_OFFLINE", "1")
+15 -15
View File
@@ -1,21 +1,21 @@
[default] [default]
modelDir = weights modelDir = weights
hairstyleDir = /home/ubuntu/change_hair/project/data/ref_hairstyle hairstyleDir = /home/xsl/change_hair/project/data/ref_hairstyle
haircolorDir= /home/ubuntu/change_hair/project/data/ref_haircolor haircolorDir= /home/xsl/change_hair/project/data/ref_haircolor
userDir=/home/ubuntu/change_hair/project/data/userImage userDir=/home/xsl/change_hair/project/data/userImage
tmp_dir=/home/ubuntu/change_hair/project/data/tmp tmp_dir=/home/xsl/change_hair/project/data/tmp
res_dir=/home/ubuntu/change_hair/project/data/res_dir res_dir=/home/xsl/change_hair/project/data/res_dir
userInfo_dir=/home/ubuntu/change_hair/project/data/user_info userInfo_dir=/home/xsl/change_hair/project/data/user_info
baseColor_ID=HDR10_443322 baseColor_ID=HDR10_443322
Port = 11023 Port = 11023
refer_dir = /home/ubuntu/change_hair/project/data/ref_online refer_dir = /home/xsl/change_hair/project/data/ref_online
ref_user_dir = /home/ubuntu/change_hair/project/data/ref_user_imgs ref_user_dir = /home/xsl/change_hair/project/data/ref_user_imgs
train_dir = /home/ubuntu/change_hair/data/train_material train_dir = /home/xsl/change_hair/data/train_material
refImgDir=/home/ubuntu/change_hair/project/data/refImage refImgDir=/home/xsl/change_hair/project/data/refImage
hair_template_material_dir=/home/ubuntu/change_hair/project/data/hair_template_material hair_template_material_dir=/home/xsl/change_hair/project/data/hair_template_material
ref_color=/home/ubuntu/change_hair/project/data/ref_color ref_color=/home/xsl/change_hair/project/data/ref_color
ref_color_img=/home/ubuntu/change_hair/project/data/ref_color_imgs ref_color_img=/home/xsl/change_hair/project/data/ref_color_imgs
upload_train_dir=/home/ubuntu/change_hair/project/data/upload_train_imgs upload_train_dir=/home/xsl/change_hair/project/data/upload_train_imgs
;version=local ;version=local
version=online version=online
@@ -23,7 +23,7 @@ version=online
strength=1 strength=1
[logger] [logger]
logpath = /home/ubuntu/change_hair/project/logs logpath = /home/xsl/change_hair/project/logs
level=INFO level=INFO
[timelogger] [timelogger]
+1 -1
View File
@@ -1,4 +1,4 @@
#!/home/ubuntu/miniconda3/envs/yd/bin/python #!/home/xsl/miniconda3/envs/yd/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
# 监听本机的端口 # 监听本机的端口
+1 -1
View File
@@ -25,7 +25,7 @@ import cv2
import numpy as np import numpy as np
# MediaPipe 模型路径 # MediaPipe 模型路径
MP_MODEL = "/home/ubuntu/change_hair/project/hair_service_sd/weights/mediapipe/face_landmarker.task" MP_MODEL = "/home/xsl/change_hair/project/hair_service_sd/weights/mediapipe/face_landmarker.task"
_mp_detector = None _mp_detector = None
+7 -7
View File
@@ -4,7 +4,7 @@
export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1
# 创建Lora目录软连接 # 创建Lora目录软连接
TARGET_LORA="/home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/models/Lora" TARGET_LORA="/home/xsl/change_hair/project/onediff/stable-diffusion-webui/models/Lora"
if [ -e "$TARGET_LORA" ]; then if [ -e "$TARGET_LORA" ]; then
echo "删除已存在的Lora连接或目录: $TARGET_LORA" echo "删除已存在的Lora连接或目录: $TARGET_LORA"
rm -rf "$TARGET_LORA" rm -rf "$TARGET_LORA"
@@ -13,16 +13,16 @@ ln -s /gz-fs/Lora "$TARGET_LORA"
echo "创建软连接成功: /gz-fs/Lora -> $TARGET_LORA" echo "创建软连接成功: /gz-fs/Lora -> $TARGET_LORA"
# 1. 换发算法服务 # 1. 换发算法服务
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
nohup /home/ubuntu/miniconda3/envs/condiff-train-hair/bin/python run_copy_cost_colorb64.py > hair_service.log 2>&1 & nohup /home/xsl/miniconda3/envs/condiff-train-hair/bin/python run_copy_cost_colorb64.py > hair_service.log 2>&1 &
# 2. webUI服务推理 + onediff # 2. webUI服务推理 + onediff
cd /home/ubuntu/change_hair/project/onediff/stable-diffusion-webui cd /home/xsl/change_hair/project/onediff/stable-diffusion-webui
nohup /home/ubuntu/miniconda3/envs/onediff/bin/python webui.py --api --listen --xformers --port 57860 > webui.log 2>&1 & nohup /home/xsl/miniconda3/envs/onediff/bin/python webui.py --api --listen --xformers --port 57860 > webui.log 2>&1 &
nohup ./webui.sh --api --listen --disable-safe-unpickle --port 9038 > webui_sh.log 2>&1 & nohup ./webui.sh --api --listen --disable-safe-unpickle --port 9038 > webui_sh.log 2>&1 &
# 3. photo_service # 3. photo_service
cd /home/ubuntu/change_hair/project/photo_service cd /home/xsl/change_hair/project/photo_service
nohup /home/ubuntu/miniconda3/envs/py310/bin/python lora_train_service_1.py > photo_service.log 2>&1 & nohup /home/xsl/miniconda3/envs/py310/bin/python lora_train_service_1.py > photo_service.log 2>&1 &
echo "所有服务已在后台启动" echo "所有服务已在后台启动"
@@ -37,8 +37,8 @@ if version == "local":
callback_url = 'http://service.aicloud.fit:7395/api/hair/trainCallBack' callback_url = 'http://service.aicloud.fit:7395/api/hair/trainCallBack'
else: else:
current_url = 'http://0.0.0.0:7393/' current_url = 'http://0.0.0.0:7393/'
kohya_ss_home_dir = '/home/ubuntu/change_hair/project/kohya_ss_home' kohya_ss_home_dir = '/home/xsl/change_hair/project/kohya_ss_home'
webui_lora_dir = '/home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/models/Lora' webui_lora_dir = '/home/xsl/change_hair/project/onediff/stable-diffusion-webui/models/Lora'
inference_use_onediff = False inference_use_onediff = False
callback_url = 'http://0.0.0.0:8801/api/hair/trainCallBack' callback_url = 'http://0.0.0.0:8801/api/hair/trainCallBack'
base_webui_port = '57860' base_webui_port = '57860'
@@ -307,13 +307,13 @@ def train_thread(sq, gpu_id):
# 3. GPU 固定 device=0(单卡) # 3. GPU 固定 device=0(单卡)
# 4. 去掉 tokenizer_cache_dir(改用 HF 本地缓存 + 离线模式) # 4. 去掉 tokenizer_cache_dir(改用 HF 本地缓存 + 离线模式)
# 5. 设置 HF_HUB_OFFLINE 避免联网检查 # 5. 设置 HF_HUB_OFFLINE 避免联网检查
kohya_python = '/home/ubuntu/miniconda3/envs/kohya/bin/python' kohya_python = '/home/xsl/miniconda3/envs/kohya/bin/python'
kohya_workdir = os.path.join(kohya_ss_home_dir, 'kohya_ss') kohya_workdir = os.path.join(kohya_ss_home_dir, 'kohya_ss')
base_model = '/home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors' base_model = '/home/xsl/change_hair/project/onediff/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors'
cmd_train = ( cmd_train = (
f'cd {kohya_workdir} && ' f'cd {kohya_workdir} && '
f'HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 CUDA_VISIBLE_DEVICES={device_id} ' f'HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 CUDA_VISIBLE_DEVICES={device_id} '
f'/home/ubuntu/miniconda3/envs/kohya/bin/accelerate launch --num_cpu_threads_per_process=2 "./train_network.py" --enable_bucket ' f'/home/xsl/miniconda3/envs/kohya/bin/accelerate launch --num_cpu_threads_per_process=2 "./train_network.py" --enable_bucket '
f'--min_bucket_reso=256 --max_bucket_reso=2048 --pretrained_model_name_or_path="{base_model}" ' f'--min_bucket_reso=256 --max_bucket_reso=2048 --pretrained_model_name_or_path="{base_model}" '
f'--train_data_dir={images_dir} --resolution="2000,2000" ' f'--train_data_dir={images_dir} --resolution="2000,2000" '
f'--output_dir={model_dir} ' f'--output_dir={model_dir} '
+2 -2
View File
@@ -1,10 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# 断点续传大文件到云服务器 /home/ubuntu/data # 断点续传大文件到云服务器 /home/xsl/data
# 用法: bash scripts/sync_data_to_server.sh [all|weights|sd|hairstyles] # 用法: bash scripts/sync_data_to_server.sh [all|weights|sd|hairstyles]
set -euo pipefail set -euo pipefail
REMOTE="ubuntu@117.50.213.111" REMOTE="ubuntu@117.50.213.111"
REMOTE_BASE="/home/ubuntu/data" REMOTE_BASE="/home/xsl/data"
LOCAL_BASE="/home/xsl/change_hair" LOCAL_BASE="/home/xsl/change_hair"
LOG_DIR="${LOCAL_BASE}/project/logs" LOG_DIR="${LOCAL_BASE}/project/logs"
mkdir -p "$LOG_DIR" mkdir -p "$LOG_DIR"
+4 -4
View File
@@ -10,16 +10,16 @@
# bash start_all.sh status # 查看状态 # bash start_all.sh status # 查看状态
# ===================================================================== # =====================================================================
set -u set -u
BASE="/home/ubuntu/change_hair" BASE="/home/xsl/change_hair"
PROJ="$BASE/project" PROJ="$BASE/project"
LOGDIR="$PROJ/logs" LOGDIR="$PROJ/logs"
PIDD="$LOGDIR/pids" PIDD="$LOGDIR/pids"
mkdir -p "$LOGDIR" "$PIDD" mkdir -p "$LOGDIR" "$PIDD"
# conda 环境的 python 路径 # conda 环境的 python 路径
PY_HAIR="/home/ubuntu/miniconda3/envs/my_hair/bin/python" PY_HAIR="/home/xsl/miniconda3/envs/my_hair/bin/python"
PY_SD="/home/ubuntu/miniconda3/envs/sdwebui/bin/python" PY_SD="/home/xsl/miniconda3/envs/sdwebui/bin/python"
PY_PHOTO="/home/ubuntu/miniconda3/envs/py310/bin/python" PY_PHOTO="/home/xsl/miniconda3/envs/py310/bin/python"
# 公共环境变量 # 公共环境变量
export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 # 旧版 cryptography 兼容 export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 # 旧版 cryptography 兼容
+2 -2
View File
@@ -2,5 +2,5 @@
export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1
export CUDA_VISIBLE_DEVICES=0 export CUDA_VISIBLE_DEVICES=0
export APP_WORKER_ID=1 export APP_WORKER_ID=1
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
exec /home/ubuntu/miniconda3/envs/my_hair/bin/python run_copy_cost_colorb64.py exec /home/xsl/miniconda3/envs/my_hair/bin/python run_copy_cost_colorb64.py
+2 -2
View File
@@ -5,5 +5,5 @@ export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1
export CUDA_VISIBLE_DEVICES=0 export CUDA_VISIBLE_DEVICES=0
export HF_HUB_OFFLINE=1 export HF_HUB_OFFLINE=1
export TRANSFORMERS_OFFLINE=1 export TRANSFORMERS_OFFLINE=1
cd /home/ubuntu/change_hair/hair_grow_service cd /home/xsl/change_hair/hair_grow_service
exec /home/ubuntu/miniconda3/envs/my_hair/bin/python app.py exec /home/xsl/miniconda3/envs/my_hair/bin/python app.py
+2 -2
View File
@@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# 独立启动 photo_service,确保脱离会话 # 独立启动 photo_service,确保脱离会话
export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1
cd /home/ubuntu/change_hair/project/photo_service cd /home/xsl/change_hair/project/photo_service
exec /home/ubuntu/miniconda3/envs/py310/bin/python -u lora_train_service_1.py exec /home/xsl/miniconda3/envs/py310/bin/python -u lora_train_service_1.py
+10 -10
View File
@@ -4,7 +4,7 @@
# 已传数据自动续传(--partial) # 已传数据自动续传(--partial)
set -u set -u
LOGDIR="/home/ubuntu/change_hair/project/logs" LOGDIR="/home/xsl/change_hair/project/logs"
DONE_MARKER="$LOGDIR/sync_all.done" DONE_MARKER="$LOGDIR/sync_all.done"
mkdir -p "$LOGDIR" mkdir -p "$LOGDIR"
@@ -14,15 +14,15 @@ mkdir -p "$LOGDIR"
# 任务定义:名称|源|目标 # 任务定义:名称|源|目标
# 优先级排序:换发色关键链路优先 → 换发型 → 训练相关 → 大数据最后 # 优先级排序:换发色关键链路优先 → 换发型 → 训练相关 → 大数据最后
TASKS=( TASKS=(
"photo_service|szlc@192.168.101.63:/home/szlc/project/photo_service/|/home/ubuntu/change_hair/project/photo_service/" "photo_service|szlc@192.168.101.63:/home/szlc/project/photo_service/|/home/xsl/change_hair/project/photo_service/"
"project_data|szlc@192.168.101.63:/home/szlc/project/data/|/home/ubuntu/change_hair/project/data/" "project_data|szlc@192.168.101.63:/home/szlc/project/data/|/home/xsl/change_hair/project/data/"
"hair_service_sd|szlc@192.168.101.63:/home/szlc/project/hair_service_sd/|/home/ubuntu/change_hair/project/hair_service_sd/" "hair_service_sd|szlc@192.168.101.63:/home/szlc/project/hair_service_sd/|/home/xsl/change_hair/project/hair_service_sd/"
"conda_py310|szlc@192.168.101.63:/home/szlc/miniconda3/envs/py310/|/home/ubuntu/miniconda3/envs/py310/" "conda_py310|szlc@192.168.101.63:/home/szlc/miniconda3/envs/py310/|/home/xsl/miniconda3/envs/py310/"
"conda_my_hair|szlc@192.168.101.63:/home/szlc/miniconda3/envs/my_hair/|/home/ubuntu/miniconda3/envs/my_hair/" "conda_my_hair|szlc@192.168.101.63:/home/szlc/miniconda3/envs/my_hair/|/home/xsl/miniconda3/envs/my_hair/"
"conda_sdwebui|szlc@192.168.101.63:/home/szlc/miniconda3/envs/sdwebui/|/home/ubuntu/miniconda3/envs/sdwebui/" "conda_sdwebui|szlc@192.168.101.63:/home/szlc/miniconda3/envs/sdwebui/|/home/xsl/miniconda3/envs/sdwebui/"
"kohya_ss_home|szlc@192.168.101.63:/home/szlc/project/kohya_ss_home/|/home/ubuntu/change_hair/project/kohya_ss_home/" "kohya_ss_home|szlc@192.168.101.63:/home/szlc/project/kohya_ss_home/|/home/xsl/change_hair/project/kohya_ss_home/"
"onediff|szlc@192.168.101.63:/home/szlc/project/onediff/|/home/ubuntu/change_hair/project/onediff/" "onediff|szlc@192.168.101.63:/home/szlc/project/onediff/|/home/xsl/change_hair/project/onediff/"
"train_material|szlc@192.168.101.63:/data/train_material/|/home/ubuntu/change_hair/data/train_material/" "train_material|szlc@192.168.101.63:/data/train_material/|/home/xsl/change_hair/data/train_material/"
) )
echo "========================================" | tee -a "$LOGDIR/sync_main.log" echo "========================================" | tee -a "$LOGDIR/sync_main.log"
+2 -2
View File
@@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
# 重新同步 conda 环境(上次被 sed 损坏,这次纯净拷贝) # 重新同步 conda 环境(上次被 sed 损坏,这次纯净拷贝)
set -u set -u
CONDA_ENVS="/home/ubuntu/miniconda3/envs" CONDA_ENVS="/home/xsl/miniconda3/envs"
LOGDIR="/home/ubuntu/change_hair/project/logs" LOGDIR="/home/xsl/change_hair/project/logs"
mkdir -p "$CONDA_ENVS" "$LOGDIR" mkdir -p "$CONDA_ENVS" "$LOGDIR"
echo "conda 环境重传开始: $(date '+%H:%M:%S')" | tee -a "$LOGDIR/sync_conda.log" echo "conda 环境重传开始: $(date '+%H:%M:%S')" | tee -a "$LOGDIR/sync_conda.log"
+3 -3
View File
@@ -2,8 +2,8 @@
"""端到端测试:生发走换发型工作流""" """端到端测试:生发走换发型工作流"""
import base64, requests, time, sys import base64, requests, time, sys
img_path = "/home/ubuntu/change_hair/project/data/userImage/8488902485_20250630055547.jpg" img_path = "/home/xsl/change_hair/project/data/userImage/8488902485_20250630055547.jpg"
mask_path = "/home/ubuntu/change_hair/project/logs/hairgrow_test_mask.png" mask_path = "/home/xsl/change_hair/project/logs/hairgrow_test_mask.png"
with open(img_path, "rb") as f: with open(img_path, "rb") as f:
img_b64 = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode() img_b64 = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode()
@@ -24,7 +24,7 @@ try:
d = r.json() d = r.json()
print(f"HTTP {r.status_code} | state={d.get('state')} | msg={d.get('msg','')} | 耗时={time.time()-t0:.1f}s") print(f"HTTP {r.status_code} | state={d.get('state')} | msg={d.get('msg','')} | 耗时={time.time()-t0:.1f}s")
if d.get("state") == 0: if d.get("state") == 0:
out = "/home/ubuntu/change_hair/project/logs/test_grow_swap_result.jpg" out = "/home/xsl/change_hair/project/logs/test_grow_swap_result.jpg"
with open(out, "wb") as f: with open(out, "wb") as f:
f.write(base64.b64decode(d["result"])) f.write(base64.b64decode(d["result"]))
print(f"✅ 生发成功! 结果图: {out}") print(f"✅ 生发成功! 结果图: {out}")
+2 -2
View File
@@ -2,7 +2,7 @@
"""换发色接口测试""" """换发色接口测试"""
import base64, json, requests, sys import base64, json, requests, sys
img_path = "/home/ubuntu/change_hair/project/data/userImage/8488902485_20250630055547.jpg" img_path = "/home/xsl/change_hair/project/data/userImage/8488902485_20250630055547.jpg"
with open(img_path, "rb") as f: with open(img_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode() img_b64 = base64.b64encode(f.read()).decode()
@@ -21,7 +21,7 @@ try:
result = d.get("result", "") result = d.get("result", "")
if d.get("state") == 0 and result: if d.get("state") == 0 and result:
# 保存结果图 # 保存结果图
out = "/home/ubuntu/change_hair/project/logs/test_haircolor_result.jpg" out = "/home/xsl/change_hair/project/logs/test_haircolor_result.jpg"
with open(out, "wb") as f: with open(out, "wb") as f:
f.write(base64.b64decode(result)) f.write(base64.b64decode(result))
print(f"✅ 换发色成功! 结果图已保存: {out} ({len(result)} bytes base64)") print(f"✅ 换发色成功! 结果图已保存: {out} ({len(result)} bytes base64)")
+3 -3
View File
@@ -2,8 +2,8 @@
"""测试 /api/hairGrow/v1 接口""" """测试 /api/hairGrow/v1 接口"""
import base64, requests, sys import base64, requests, sys
img_path = "/home/ubuntu/change_hair/project/data/userImage/8488902485_20250630055547.jpg" img_path = "/home/xsl/change_hair/project/data/userImage/8488902485_20250630055547.jpg"
mask_path = "/home/ubuntu/change_hair/project/logs/hairgrow_test_mask.png" mask_path = "/home/xsl/change_hair/project/logs/hairgrow_test_mask.png"
with open(img_path, "rb") as f: with open(img_path, "rb") as f:
img_b64 = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode() img_b64 = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode()
@@ -26,7 +26,7 @@ try:
print(f"HTTP {r.status_code} | msg={d.get('msg')} | state={d.get('state')} | 耗时={time.time()-t0:.1f}s") print(f"HTTP {r.status_code} | msg={d.get('msg')} | state={d.get('state')} | 耗时={time.time()-t0:.1f}s")
result = d.get("result", "") result = d.get("result", "")
if d.get("state") == 0 and result: if d.get("state") == 0 and result:
out = "/home/ubuntu/change_hair/project/logs/test_hairgrow_api_result.jpg" out = "/home/xsl/change_hair/project/logs/test_hairgrow_api_result.jpg"
with open(out, "wb") as f: with open(out, "wb") as f:
f.write(base64.b64decode(result)) f.write(base64.b64decode(result))
print(f"✅ 生发成功! 结果图: {out}") print(f"✅ 生发成功! 结果图: {out}")
+2 -2
View File
@@ -2,7 +2,7 @@
"""换发型接口测试""" """换发型接口测试"""
import base64, json, requests, sys, time import base64, json, requests, sys, time
img_path = "/home/ubuntu/change_hair/project/data/userImage/8488902485_20250630055547.jpg" img_path = "/home/xsl/change_hair/project/data/userImage/8488902485_20250630055547.jpg"
with open(img_path, "rb") as f: with open(img_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode() img_b64 = base64.b64encode(f.read()).decode()
@@ -22,7 +22,7 @@ try:
print(f"HTTP {r.status_code} | msg={d.get('msg')} | state={d.get('state')} | 耗时={time.time()-t0:.1f}s") print(f"HTTP {r.status_code} | msg={d.get('msg')} | state={d.get('state')} | 耗时={time.time()-t0:.1f}s")
data = d.get("data", "") data = d.get("data", "")
if d.get("state") == 0 and data: if d.get("state") == 0 and data:
out = "/home/ubuntu/change_hair/project/logs/test_swaphair_result.jpg" out = "/home/xsl/change_hair/project/logs/test_swaphair_result.jpg"
with open(out, "wb") as f: with open(out, "wb") as f:
f.write(base64.b64decode(data)) f.write(base64.b64decode(data))
print(f"✅ 换发型成功! 结果图已保存: {out} ({len(data)} bytes base64)") print(f"✅ 换发型成功! 结果图已保存: {out} ({len(data)} bytes base64)")
+1 -1
View File
@@ -4,7 +4,7 @@ import requests, json
# 用一个已有完整训练素材的发型 # 用一个已有完整训练素材的发型
HAIR_ID = "1905785164224868354" HAIR_ID = "1905785164224868354"
MATERIAL_DIR = f"/home/ubuntu/change_hair/data/train_material/{HAIR_ID}" MATERIAL_DIR = f"/home/xsl/change_hair/data/train_material/{HAIR_ID}"
payload = { payload = {
"task_id": f"test_train_{HAIR_ID}", "task_id": f"test_train_{HAIR_ID}",
+7 -7
View File
@@ -15,7 +15,7 @@ import time
import json import json
import shutil import shutil
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.environ.setdefault("HF_HUB_OFFLINE", "1") os.environ.setdefault("HF_HUB_OFFLINE", "1")
@@ -26,15 +26,15 @@ import requests as req
# (hair_id, gender, template_img) # (hair_id, gender, template_img)
HAIRSTYLES = [ HAIRSTYLES = [
("chang_tuoyuan", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_tuoyuan/chang_tuoyuan.jpg"), ("chang_tuoyuan", "girl", "/home/xsl/change_hair/hair_type_images/chang_tuoyuan/chang_tuoyuan.jpg"),
("chang_bolang", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_bolang/chang_bolang.jpg"), ("chang_bolang", "girl", "/home/xsl/change_hair/hair_type_images/chang_bolang/chang_bolang.jpg"),
("chang_zhixian", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_zhixian/chang_zhixian.jpg"), ("chang_zhixian", "girl", "/home/xsl/change_hair/hair_type_images/chang_zhixian/chang_zhixian.jpg"),
("chang_huaban", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_huaban/chang_huaban.jpg"), ("chang_huaban", "girl", "/home/xsl/change_hair/hair_type_images/chang_huaban/chang_huaban.jpg"),
("chang_xinxing", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_xinxing/chang_xinxing.jpg"), ("chang_xinxing", "girl", "/home/xsl/change_hair/hair_type_images/chang_xinxing/chang_xinxing.jpg"),
] ]
HAIR_CALLBACK = "http://127.0.0.1:8801/api/hair/trainCallBack" HAIR_CALLBACK = "http://127.0.0.1:8801/api/hair/trainCallBack"
UPLOAD_TRAIN_DIR = "/home/ubuntu/change_hair/project/data/upload_train_imgs" UPLOAD_TRAIN_DIR = "/home/xsl/change_hair/project/data/upload_train_imgs"
# 导入 step4/step5 函数(会触发模型加载) # 导入 step4/step5 函数(会触发模型加载)
from train_hairstyle_full import step4_template_material, step5_preview from train_hairstyle_full import step4_template_material, step5_preview
+6 -6
View File
@@ -6,8 +6,8 @@
串接 prepare_train_data / gen_template_material / photo_service训练 / 回调 / 预览图 串接 prepare_train_data / gen_template_material / photo_service训练 / 回调 / 预览图
用法: 用法:
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
python /home/ubuntu/change_hair/train_hairstyle_full.py --hair-id huaban1 --input /home/ubuntu/change_hair/huaban1 --gender girl --template-img /home/ubuntu/change_hair/huaban1/huaban1.jpg python /home/xsl/change_hair/train_hairstyle_full.py --hair-id huaban1 --input /home/xsl/change_hair/huaban1 --gender girl --template-img /home/xsl/change_hair/huaban1/huaban1.jpg
""" """
import os import os
import sys import sys
@@ -21,7 +21,7 @@ import argparse
import requests as req import requests as req
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.environ.setdefault("HF_HUB_OFFLINE", "1") os.environ.setdefault("HF_HUB_OFFLINE", "1")
@@ -48,9 +48,9 @@ RESOLUTIONS = [512, 768, 1024, 1280, 1536]
PHOTO_TRAIN = "http://127.0.0.1:32678/api/hair/train" PHOTO_TRAIN = "http://127.0.0.1:32678/api/hair/train"
HAIR_CALLBACK = "http://127.0.0.1:8801/api/hair/trainCallBack" HAIR_CALLBACK = "http://127.0.0.1:8801/api/hair/trainCallBack"
SWAP_API = "http://127.0.0.1:8801/api/swapHair/v1" SWAP_API = "http://127.0.0.1:8801/api/swapHair/v1"
GIRL_IMG = "/home/ubuntu/change_hair/images/girl.png" GIRL_IMG = "/home/xsl/change_hair/images/girl.png"
BOY_IMG = "/home/ubuntu/change_hair/images/boy.png" BOY_IMG = "/home/xsl/change_hair/images/boy.png"
PREVIEW_DIR = "/home/ubuntu/change_hair/hair_grow_service/static/previews" PREVIEW_DIR = "/home/xsl/change_hair/hair_grow_service/static/previews"
_detector = _aligner = _matte = None _detector = _aligner = _matte = None
def get_models(): def get_models():
+9 -9
View File
@@ -8,8 +8,8 @@
阶段C: 启动服务后串行 step3(回调生成ref材质) + step4(模板) + step5(预览) 阶段C: 启动服务后串行 step3(回调生成ref材质) + step4(模板) + step5(预览)
用法: 用法:
cd /home/ubuntu/change_hair/project/hair_service_sd cd /home/xsl/change_hair/project/hair_service_sd
python /home/ubuntu/change_hair/train_hairstyles_parallel.py python /home/xsl/change_hair/train_hairstyles_parallel.py
""" """
import os import os
import sys import sys
@@ -18,7 +18,7 @@ import json
import subprocess import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
HAIR_SERVICE_DIR = "/home/ubuntu/change_hair/project/hair_service_sd" HAIR_SERVICE_DIR = "/home/xsl/change_hair/project/hair_service_sd"
os.chdir(HAIR_SERVICE_DIR) os.chdir(HAIR_SERVICE_DIR)
sys.path.insert(0, HAIR_SERVICE_DIR) sys.path.insert(0, HAIR_SERVICE_DIR)
os.environ.setdefault("HF_HUB_OFFLINE", "1") os.environ.setdefault("HF_HUB_OFFLINE", "1")
@@ -29,11 +29,11 @@ os.environ.setdefault("CUDA_VISIBLE_DEVICES", "0")
# ====== 配置:本次要训练的发型 ====== # ====== 配置:本次要训练的发型 ======
# (hair_id, input_dir, gender, template_img) # (hair_id, input_dir, gender, template_img)
HAIRSTYLES = [ HAIRSTYLES = [
("chang_tuoyuan", "/home/ubuntu/change_hair/hair_type_images/chang_tuoyuan", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_tuoyuan/chang_tuoyuan.jpg"), ("chang_tuoyuan", "/home/xsl/change_hair/hair_type_images/chang_tuoyuan", "girl", "/home/xsl/change_hair/hair_type_images/chang_tuoyuan/chang_tuoyuan.jpg"),
("chang_bolang", "/home/ubuntu/change_hair/hair_type_images/chang_bolang", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_bolang/chang_bolang.jpg"), ("chang_bolang", "/home/xsl/change_hair/hair_type_images/chang_bolang", "girl", "/home/xsl/change_hair/hair_type_images/chang_bolang/chang_bolang.jpg"),
("chang_zhixian", "/home/ubuntu/change_hair/hair_type_images/chang_zhixian", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_zhixian/chang_zhixian.jpg"), ("chang_zhixian", "/home/xsl/change_hair/hair_type_images/chang_zhixian", "girl", "/home/xsl/change_hair/hair_type_images/chang_zhixian/chang_zhixian.jpg"),
("chang_huaban", "/home/ubuntu/change_hair/hair_type_images/chang_huaban", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_huaban/chang_huaban.jpg"), ("chang_huaban", "/home/xsl/change_hair/hair_type_images/chang_huaban", "girl", "/home/xsl/change_hair/hair_type_images/chang_huaban/chang_huaban.jpg"),
("chang_xinxing", "/home/ubuntu/change_hair/hair_type_images/chang_xinxing", "girl", "/home/ubuntu/change_hair/hair_type_images/chang_xinxing/chang_xinxing.jpg"), ("chang_xinxing", "/home/xsl/change_hair/hair_type_images/chang_xinxing", "girl", "/home/xsl/change_hair/hair_type_images/chang_xinxing/chang_xinxing.jpg"),
] ]
PARALLEL = 2 # LoRA 训练并发数 PARALLEL = 2 # LoRA 训练并发数
@@ -137,7 +137,7 @@ def main():
log(f"阶段B完成: LoRA 训练完成 {len(completed)}/{len(step1_ok)}") log(f"阶段B完成: LoRA 训练完成 {len(completed)}/{len(step1_ok)}")
# 写一个完成清单文件,供阶段C脚本读取 # 写一个完成清单文件,供阶段C脚本读取
done_file = "/home/ubuntu/change_hair/project/logs/train_batch_done.json" done_file = "/home/xsl/change_hair/project/logs/train_batch_done.json"
with open(done_file, "w") as f: with open(done_file, "w") as f:
json.dump({"completed": sorted(completed), "all": ids}, f) json.dump({"completed": sorted(completed), "all": ids}, f)
log(f"已写入完成清单: {done_file}") log(f"已写入完成清单: {done_file}")
+6 -6
View File
@@ -6,7 +6,7 @@
通过 ThreadPoolExecutor 控制并发数。 通过 ThreadPoolExecutor 控制并发数。
用法: 用法:
python /home/ubuntu/change_hair/train_lora_parallel.py python /home/xsl/change_hair/train_lora_parallel.py
前提:step1 训练数据已准备好(data/train_material/<hid>/images/1_hairstyle/*.png 前提:step1 训练数据已准备好(data/train_material/<hid>/images/1_hairstyle/*.png
""" """
@@ -16,11 +16,11 @@ import time
import subprocess import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
TRAIN_DIR = "/home/ubuntu/change_hair/data/train_material" TRAIN_DIR = "/home/xsl/change_hair/data/train_material"
KOHYA_WORKDIR = "/home/ubuntu/change_hair/project/kohya_ss_home/kohya_ss" KOHYA_WORKDIR = "/home/xsl/change_hair/project/kohya_ss_home/kohya_ss"
BASE_MODEL = "/home/ubuntu/change_hair/project/onediff/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors" BASE_MODEL = "/home/xsl/change_hair/project/onediff/stable-diffusion-webui/models/Stable-diffusion/v1-5-pruned-emaonly.safetensors"
KOHYA_ACCEL = "/home/ubuntu/miniconda3/envs/kohya/bin/accelerate" KOHYA_ACCEL = "/home/xsl/miniconda3/envs/kohya/bin/accelerate"
LOG_DIR = "/home/ubuntu/change_hair/project/logs" LOG_DIR = "/home/xsl/change_hair/project/logs"
# 本次要训练的发型 # 本次要训练的发型
HAIRSTYLES = ["chang_tuoyuan", "chang_zhixian", "chang_huaban", "chang_xinxing"] HAIRSTYLES = ["chang_tuoyuan", "chang_zhixian", "chang_huaban", "chang_xinxing"]