182 lines
9.5 KiB
Markdown
182 lines
9.5 KiB
Markdown
# 脸部 LoRA 训练项目(Qwen-Rapid-AIO 匹配版)
|
||
|
||
> 创建:2026-08-03
|
||
> 目标:用老莫的照片训练一个脸部 LoRA,让 AI 出图永久自带他的脸,配合常用 checkpoint `Qwen-Rapid-AIO-NSFW-v23` 使用
|
||
|
||
## 项目背景
|
||
|
||
- 灵感来源:[Z:\wiki\raw\articles\2026-08-02-z-image-turbo-face-lora-训练实操.md](Z-Image-Turbo 路线,已验证技术可信但模型不匹配)
|
||
- 老莫实际模型:`Qwen-Rapid-AIO-NSFW-v23.safetensors`(26.48GB,位于 `D:\AI\sd\novelai-webui-aki-v3-r\models\Stable-diffusion\`)
|
||
- 该 checkpoint 本质:HuggingFace `Phr00t/Qwen-Image-Edit-Rapid-AIO` 融合模型 = **Qwen-Image-Edit-2511 底模(20B MMDiT)** + Lightning 4/8 步蒸馏 LoRA + NSFW LoRAs + VAE + Qwen2.5-VL CLIP(FP8)
|
||
- 结论:LoRA 必须在 **Edit-2511 bf16 官方底模**上训练(不能直接用 FP8 融合模型),训完叠加回 Rapid-AIO 推理
|
||
|
||
## 硬件环境
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| GPU | RTX 3080 Laptop GPU **16GB**(Ampere, sm_86) |
|
||
| 驱动 | 591.74 / CUDA 13.1 |
|
||
| 内存 | **32GB**(无 64G,靠 fp8 量化 + TE 预缓存压内存) |
|
||
| 存储 | D 盘 153GB 空闲 |
|
||
|
||
## 训练方案(定稿)
|
||
|
||
**工具**:kohya musubi-tuner(`D:\AI\sd\musubi-tuner`,v0.3.4)
|
||
**底模**:Qwen-Image-Edit-2511 bf16(从 ModelScope 下载 diffusers 分片,musubi `load_split_weights` 原生支持分片,无需转换)
|
||
|
||
### 核心参数
|
||
```
|
||
--model_version edit-2511
|
||
--network_module networks.lora_qwen_image --network_dim 16
|
||
--learning_rate 5e-5 --optimizer_type adamw8bit
|
||
--fp8_base --fp8_scaled --fp8_vl --gradient_checkpointing --blocks_to_swap 32
|
||
--max_train_epochs 80(≈1600步)
|
||
--timestep_sampling shift --discrete_flow_shift 2.2
|
||
分辨率 1024×1024
|
||
```
|
||
|
||
### 内存策略(32G 关键)
|
||
1. `--fp8_base --fp8_scaled`:DiT 权重 fp8 存储(40GB→20GB)
|
||
2. 预缓存 text encoder 输出(`qwen_image_cache_text_encoder_outputs.py`):训练时不加载 TE(省 7GB)
|
||
3. pagefile 设 64G(SSD)当兜底保险
|
||
4. 训练时关闭浏览器等大内存应用
|
||
|
||
### 实测速度(2026-08-05 冒烟实测)
|
||
| 系统状态 | 速度 | 1600 步预估 |
|
||
|---|---|---|
|
||
| ComfyUI 运行中(空闲占 4.6GB VRAM) | **503-670 s/步**(页面抖动,逐步变慢) | **~12 天,不可行** |
|
||
| 干净系统(初次冒烟) | ~55 s/步 | ~24 小时,隔夜可跑 |
|
||
|
||
**启动条件(必须)**:关闭 ComfyUI + 浏览器等大内存程序 → 双击 `启动训练.bat`(bat 有前置检查:ComfyUI 在跑则拒绝启动、commit <30GB 拒绝启动)。
|
||
**根因**:32GB 物理内存跑 20B fp8 是极限状态,blocks_to_swap 24 的 CPU↔GPU 交换在内存不足时落到 pagefile(SSD),速度跌 10 倍+。训练必须独占物理内存。
|
||
**共存验证**:ComfyUI 空闲时 VRAM 11.8GB 下训练可跑通(不 OOM),但速度不可接受,仅作应急参考。
|
||
|
||
## 文件位置
|
||
|
||
| 用途 | 路径 |
|
||
|---|---|
|
||
| 训练素材(照片) | `素材/` |
|
||
| 打标 caption | `打标/` |
|
||
| 训练配置 | `config/` |
|
||
| LoRA 输出 | `output/` |
|
||
| 参考资料 | `资料/` |
|
||
| musubi-tuner | `D:\AI\sd\musubi-tuner` |
|
||
| 模型文件 | `D:\AI\sd\models\qwen-edit-2511\`(transformer 5 分片 + text_encoder 4 分片 + vae) |
|
||
| VAE(已有) | `D:\AI\sd\ComfyUI\ComfyUI_windows_portable_2\ComfyUI\models\vae\qwen_image_vae.safetensors` |
|
||
|
||
## 流程
|
||
|
||
1. [x] 调研文章 + Qwen 路线验证(2026-08-03)
|
||
2. [x] 排查本地资源(VAE 已有,DiT/TE 需下载)
|
||
3. [x] 立项 + musubi-tuner 就位
|
||
4. [x] 下载模型完成(DiT 38GB + TE 15GB + VAE,ModelScope 8MB/s)
|
||
5. [x] uv 环境装依赖(cu132:torch 2.13 + CUDA 验证通过)
|
||
6. [x] 开发 face_checker 辅助工具(审核 + 智能选图,测试通过)
|
||
7. [ ] 冒烟训练验证(分片加载 + fp8 + swap 内存,3 步小样)
|
||
8. [ ] 素材准备(老莫选照片 → face_checker pick → batch 整理)
|
||
9. [ ] 打标(触发词 + 场景描述,不描述五官)
|
||
10. [ ] 正式训练(1024 + blocks_to_swap 32 + 隔夜)
|
||
11. [ ] checkpoint 对比(每 10 epoch 存档挑最佳)
|
||
12. [ ] 叠加 Rapid-AIO 推理验证
|
||
|
||
## 辅助工具(全部就绪)
|
||
|
||
| 工具 | 位置 | 功能 |
|
||
|---|---|---|
|
||
| **auto 流水线** | `tools/face_checker.py auto` | **丢一堆照片 → 自动分类裁剪打标**(见下) |
|
||
| face_checker | `tools/face_checker.py` | 审核/选图/整理/合影裁切(check/pick/batch/crop) |
|
||
| **打标 GUI** | `tools/caption_gui.py` | Gradio 网页(localhost:7860),**支持目录切换** |
|
||
| **融合工具** | `tools/merge_fixed.py` | **原图 + ComfyUI 修改图 无缝合并**(见下) |
|
||
| 验证脚本 | `tools/validate_lora.py` | 训练后出图对比(备选) |
|
||
|
||
### merge_fixed 融合工具(ComfyUI inpainting 后处理)
|
||
|
||
**问题**:ComfyUI 移除合影人物时,即使指定"非修改区域不得漂移",全图清晰度仍损失。
|
||
**方案**:**按修改幅度连续分级融合** —— 有限修改区保留原图像素,明显修改区用修改图像素,中间平滑过渡。
|
||
|
||
```
|
||
python tools\merge_fixed.py <原图目录> <修改图目录> <输出目录> [--alpha-threshold 15] [--softness 6]
|
||
```
|
||
|
||
**核心规则**(老莫定):
|
||
| 区域 | 修改幅度 | 用谁的像素 |
|
||
|---|---|---|
|
||
| 有限修改(放大才看出,如全图降质/面部) | diff 小 | **原图精确像素**(alpha≈0) |
|
||
| 明显修改(一眼看出,如人物移除) | diff 大 | **修改图像素**(alpha≈1) |
|
||
| 中间 | 平滑过渡 | sigmoid 渐变(无接缝) |
|
||
|
||
- 算法:Lab 色彩空间差异 → 高斯模糊去结构噪声 → **sigmoid 连续 alpha** → 加权混合
|
||
- **面部保护**(默认开,`--no-protect-face` 关):检测修改图残留人脸,强制原图像素兜底
|
||
- **验证**:面部 MAE **0.000**(逐像素零改变)、被移除区干净用修改图、过渡无接缝
|
||
|
||
**参数**:
|
||
| 参数 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `--alpha-threshold` | 15 | 修改幅度分界。残留残影时调低到 8-10(更多区域归修改图) |
|
||
| `--softness` | 6 | 过渡带宽度,越大越平缓 |
|
||
| `--no-protect-face` | - | 关闭面部强制保护 |
|
||
|
||
**注意**:残影分两种——① 人物边缘未清除的痕迹(调低 alpha-threshold);② inpainting 区域内部 AI 生成的残留(ComfyUI 质量问题,融合救不了)。
|
||
|
||
### auto 全自动流水线(v2,核心!)
|
||
|
||
```
|
||
python tools\face_checker.py auto <照片目录> --out <输出目录> [--limit 20]
|
||
```
|
||
|
||
自动完成:
|
||
1. **质量评分(0-100)**:人脸绝对像素(40) + 面部清晰度(35) + 分辨率(25) —— **脸小但锐利 > 脸大但糊**
|
||
2. **清晰度区分**:面部 Laplacian vs 整体 Laplacian(脸糊=淘汰;背景糊但脸清楚=可用)
|
||
3. **构图分类+自动裁剪**(占比 + 脸像素双指标):
|
||
- 脸占比 ≥8% **或** 脸短边 ≥256px → 裁**面部特写**(人脸居中放大 1.8 倍)
|
||
- 脸占比 ≥2% 且脸 ≥150px → 保留**半身**
|
||
- 检测到完整人体 → 裁**全身构图**
|
||
- 多人合影 → 自动裁最大人脸;裁后短边不足 → 降级保留原图
|
||
4. **超量筛选**(--limit 20):每类内部 质量优先 + pHash 多样性贪心,自动挑最优(默认 特写10/半身6/全身4)
|
||
5. **淘汰**:无人脸/脸糊/脸太小无人体/分辨率不足 → 移入 淘汰/ + 原因
|
||
6. **打标草稿**:按类型自动生成 caption txt,GUI 里微调
|
||
|
||
输出:`out/特写/`、`out/半身/`、`out/全身/`、`out/未选中/`、`out/淘汰/`
|
||
|
||
**验证证据**:脸43px极清晰(1260) → 保留;脸大但模糊 → 淘汰。34 张输入 → 自动筛选 12 张最优。
|
||
|
||
### 老莫使用流程(最终版)
|
||
|
||
1. 照片全丢进 `photos_原始/`(不挑,合影也无所谓)
|
||
2. 跑 `auto photos_原始 --out photos_auto` → 自动分类裁剪打标
|
||
3. 打开 http://127.0.0.1:7860 → 顶部输入 `photos_auto` → 加载 → 微调 caption/发型 → 保存
|
||
4. 一键整理训练集 → 喊我开训
|
||
|
||
## 训练自动样本图(已验证)
|
||
|
||
- `config/sample_prompts.txt`:4 个验证场景(证件照/日常/户外全身/半侧脸)
|
||
- 训练脚本已加 `--sample_prompts --sample_every_n_epochs 10`
|
||
- 每 10 epoch 自动出 4 张样本图到 `output/checkpoints/sample/`,隔天看样本图即可判断 LoRA 演化
|
||
- 冒烟验证通过(EXIT 0,样本图正常生成)
|
||
|
||
## 使用流程(最终版)
|
||
|
||
1. 老莫选 15-25 张照片 → 丢进 `photos/`
|
||
2. 浏览器开 `http://127.0.0.1:7860` → 审核/选类型/填发型/改 caption → 保存 → 一键整理
|
||
3. 跑 `config\训练脚本.py`(80 epoch ≈ 1600 步 + 自动样本图,约 25 小时隔夜跑)
|
||
4. 看 `output/checkpoints/sample/` 样本图挑最佳 checkpoint
|
||
5. checkpoint 复制到 WebUI `models\Lora\qwen\`,加载 Rapid-AIO + LoRA 出图验证
|
||
|
||
## 训练验证要点
|
||
|
||
- musubi 分片加载:`--dit` 指向 `...-00001-of-00005.safetensors` 自动合并(源码确认)
|
||
- Edit-2511 无 control image 时**自动降级 T2I 训练**(源码 117-118 行确认)→ 脸部 LoRA 无需编辑图
|
||
- 数据集 toml **不能有 BOM**(toml 库报错)→ 用无 BOM UTF-8 写
|
||
- 模型路径保持 ASCII(`D:\AI\sd\models\...`),数据集目录中文路径 PIL 可读
|
||
|
||
## 伦理与合规
|
||
|
||
- 只训老莫自己的脸,不涉及他人照片
|
||
- 生成内容公开使用按规标注"AI 生成"
|
||
|
||
## 关键结论备忘
|
||
|
||
- musubi 支持分片加载:`--dit` 指向 `diffusion_pytorch_model-00001-of-00005.safetensors` 自动合并全部 5 分片(`load_split_weights` 源码确认)
|
||
- fp8_scaled / fp8_e4m3fn 版本**不能**用于训练(musubi 文档明确)
|
||
- 训练底模用 bf16 官方权重;推理用 Rapid-AIO(FP8)叠加 LoRA
|