# MiniMax H3 换人视频（人物迁移）部署与实测报告

> 日期：2026-09-13 ~ 09-14 ｜ 执行机：DSH 机 192.168.31.76 ｜ 推理机：GPU 机 192.168.31.31（RTX 5060 Ti 16GB）
> 目标：把抖音绿幕人偶参考视频中的人物**全部替换**为用户指定形象，**保留原动作**
> 成本：**本地 0 积分**（仅场景图用即梦 5.0+2K，也是 0 积分）

---

## 一、结论

| 目标 | 结果 |
|---|---|
| **单人换人**（主角替换，动作保留） | ✅ 成功（`migrate-character`，48 帧 / 1344×768） |
| **多人换人**（主角 + 5 配角全员，动作保留，绿幕保持） | ✅ **成功**（`generate --mode rv2v`，141 帧 / 1344×768，9 分 15 秒） |
| 动作是否复刻 | ✅ 保留：抬手、摆动、下蹲、群舞同步都跟随源视频 |
| 水印 | ✅ 参考图带抖音水印无需预处理，提示词声明 `not_referenced` 即可 |

**核心机制**：动作不是靠"单帧姿态参考"，而是**把源视频作为 `<Video 1>` 交给 H3**（RV2V 模式）——模型继承其动作、时序、镜头、构图，只替换人物身份。

---

## 二、部署清单（已在 GPU 机就绪）

| 组件 | 位置/版本 | 备注 |
|---|---|---|
| **MiniMax H3 Video Studio** | `/home/zyw/minimax-h3-video-studio`（社区项目 siyuan-liu31） | Studio UI `:3013`、API `:6020`（**仅监听 127.0.0.1**） |
| Node.js | v22.23.2（用户级 nvm，**没动系统 Node 18**） | Studio 要求 ≥22.13 |
| `h3ctl` | `cli/h3ctl`（v0.5.0，Go 1.22 编译） | `go.mod` 的 `go 1.23` 已改为 1.22（否则 toolchain 下载失败） |
| ComfyUI-KJNodes | `custom_nodes/ComfyUI-KJNodes` | 提供 `PathchSageAttentionKJ`、`MiniMaxH3MemoryEfficientSageAttentionPatch` |
| ComfyUI-H3-Motion-Context | v0.5.1（commit `429e952`） | 提供 `MiniMaxH3MotionContext*` 系列 |
| h3_studio_checkpoint | 软链到 `custom_nodes/` | 提供 `H3StudioLoadLatent/SaveLatent`，解锁 resumable profile |
| 模型 | `minimax_h3_ref2va_pruned_int8_convrot` / `fl2va_pruned_int8_convrot` / `qwen3vl_32b_minimax_h3_nvfp4_awq` / 两个 VAE / `minimax_h3_ref2v_turbo_4step_v0.1_comfyui_bf16` LoRA | 全部为机器上已有文件 |
| 启停脚本 | `bash ~/restart_comfy.sh`、`bash ~/restart_studio.sh` | 两者都**把 pkill 放进脚本内**执行 |

---

## 三、SageAttention A/B 实测（用户要求）

| # | SageAttention | segment-frames | 结果 | 耗时 | 显存峰值 |
|---|---|---|---|---|---|
| 1 | **开**（auto） | 243（默认） | ❌ OOM，失败点落在 `sageattention/quant.py` 的 `per_channel_fp8` | 277.8 s | 12910 MiB |
| 2 | **关** | 243 | ❌ OOM（同样报错） | 259.2 s | 12786 MiB |
| 3 | **关** | 124 | ❌ **GPU 掉总线**（NVRM GSP RPC 失败） | ~3 min | 14380 MiB |
| 4 | **关** | 124（640×360 源） | ✅ 成功（Studio 修复后自动交付） | ~7 min | 14250 MiB |

**结论**：
1. SageAttention 确实增加约 **124 MiB** 额外显存（12910 vs 12786），是 OOM 的爆点之一，但**不是唯一原因**；
2. 关掉 sage 后仍会 OOM / 掉总线 → **真正的瓶颈是 16GB 显存余量太小**；
3. 第 3 次的 GPU 掉总线发生在 **sage 关闭 + nvrtc 零报错**的情况下 → 属**硬件/驱动层**问题。

---

## 四、踩到并解决的 5 个坑

### 1. `nvrtc: error: failed to open libnvrtc-builtins.so.13.0`
- **根因**：torch 编译目标是 **CUDA 13.0**，系统装的是 **CUDA 13.1**；venv 里 `nvidia/cu13/lib/` 下才有 13.0 版 `libnvrtc-builtins.so.13.0`，但该目录不在动态链接器搜索路径里。
- **修复**：启动 ComfyUI 时注入
  `LD_LIBRARY_PATH=$VENV/lib/python3.12/site-packages/nvidia/cu13/lib:$VENV/lib/python3.12/site-packages/nvidia/cuda_nvrtc/lib`
  （已写进 `~/restart_comfy.sh`）

### 2. Studio 把成功的生成误判为 failed
- **报错**：`only permanent ComfyUI outputs may be used`
- **根因**：ComfyUI 的 `record["outputs"]` 里除了成品（`type: "output"`），还会混入上传素材（`type: "input"`）。Studio 的 `find_outputs()` **没按 type 过滤**，取到了素材条目 → 校验 403。
- **修复**：`server/comfy.py` 的 `find_outputs()` 只收 `type == "output"`（原文件备份可按需回滚）。
- **副产品**：即使 Studio 报 failed，**成品通常已在 `ComfyUI/output/h3-studio/videos/`**，可手动捞。

### 3. `--segment-frames` 默认值撑爆 16GB
- 默认 **243 帧（≈10s）**，源片段才 5s → 白算一倍。合法值须满足 `17k+5`（124~362）。
- **建议**：源片段 ≤5s 时用 **124**、`--overlap-frames 5`。

### 4. 输出分辨率与源素材无关
- H3 输出固定 **1344×768**；把源素材降到 640×360 **并不能降显存**（只降了输入侧开销）。

### 5. 模式与参数不匹配
- `--mode r2v` **不接受** `--source-video`（报 `r2v requires --ref inputs and no --source-video`）；
- 要"源视频 + 多角色参考"必须用 **`--mode rv2v`**。

---

## 五、可复现命令

### 单人换人
```bash
cd /home/zyw/minimax-h3-video-studio/cli
./h3ctl video migrate-character \
  --source <源片段.mp4> --character <角色图.jpg> \
  --source-subject "画面中央的红色人偶" \
  --steps 4 --segment-frames 124 --overlap-frames 5 \
  --to <输出.mp4>
```

### 多人换人（主角 + 5 配角）
```bash
./h3ctl generate video \
  --mode rv2v \
  --prompt-file <六段式提示词.txt> \
  --ref char01.jpg --ref char02.jpg --ref char03.jpg \
  --ref char04.jpg --ref char05.jpg --ref char06.jpg \
  --source-video <源片段.mp4> \
  --duration 5.17 --aspect-ratio 16:9 --steps 4 --seed 20260914 \
  --wait --wait-timeout 40m --poll-interval 10s \
  --download <输出.mp4>
```
- `--ref` 最多 12 个文件；角色图 role 用 `identity`，场景用 `scene`；
- **固定 `--seed`**（`-1` 会让背景漂移：绿幕 ↔ 室内空间）。

### 提示词要点（六段式 REF2VA）
1. 每个角色一个 `<Subject N>`，逐个写清脸/发型/服装；
2. `<Video 1>` 声明为 **motion_reference_only**：只取舞蹈、时序、编队、镜头，**人偶本身不得渲染**；
3. 背景**正向写死**（"flat chroma-key green, 全片统一"）；
4. 结尾硬约束：`Exactly N women, each exactly once. No text/watermark/logo. No 3D mannequin, no anime, no extra person, no identity blending.`

---

## 六、产出

| 文件 | 说明 |
|---|---|
| `20260914_H3多人换人/H3多人换人_6角色_rv2v.mp4` | **多人换人成果**（1344×768 / 141 帧 / 5.875s） |
| `20260914_H3人物迁移/H3换人迁移_Studio交付版_48帧.mp4` | 单人迁移（Studio 自动交付版） |
| `20260914_H3人物迁移/H3换人迁移_124帧_1344x768.mp4` | 单人迁移（手动捞出的未 trim 版，绿幕） |

- 下载中心：http://192.168.31.76:8899/10-视频生成流水线/
- 相册：http://192.168.31.76:8900 → 目录 `h3-migrate/`（单人）、`h3-dance/`（多人）

---

## 七、遗留问题与建议

1. **硬件稳定性**：本次期间发生 **1 次整机断电重启**（19:43）+ **1 次 GPU 掉总线（GSP 挂死）**（19:57）。与 sage/nvrtc 均无关，属电源/PCIe/驱动层，建议优先排查 **PSU 与市电**（运维记录已多次建议）。
2. **显存余量**：H3 长上下文在 16GB 上峰值 14.2GB，几乎无余量；要做长片段建议改走**多段短片段 + Motion Context 续接**，而不是单段拉长。
3. **Studio 仅监听 127.0.0.1**：目前只能在 GPU 机本机操作 UI；如需从 DSH 机访问，可改 `H3_STUDIO_HOST/WEB_HOST=0.0.0.0` 或建 SSH 隧道（README 建议后者）。
4. **`go.mod` 与 `comfy.py` 已改动**：升级 Studio 时需重新打这两个补丁（已在本文档记录）。

---

## 八、补充：单人换人必须用官方 identity-migration 规范（2026-09-14 实测）

### 8.1 一次典型失败
用 `migrate-character` 的**内置模板提示词**迁移「室内真人舞蹈 → 黄金盔甲女战士」，结果：
- 原人物**完全没有被替换**（还在画面里跳舞）
- 目标角色被渲染成**她身后的巨型雕像**——用户原话"人物没替换上去，变成了背景"

### 8.2 根因：提示词违反官方规范
项目里有一份**经验证的身份迁移提示词规范**：
`skills/h3-ref2va-prompt-compiler/references/identity-migration.md`
＋中性模板 `references/character-replacement-template.txt`。

| 官方要求 | 我当时的错误写法 |
|---|---|
| `<Subject 1>` = **源实体**（被替换的人）；`<Subject 2>` = 目标身份（来自 `<Picture 1>`） | 把 `<Subject 1>` 给了**目标角色**，源人物连编号都没有 |
| summary 写 `[video editing + character replacement]` | 写成 `[reference generation]` |
| 身份专用关系：`<Subject 1>: identity_not_preserved.` / `<Picture 1>: fully_referenced` / `<Subject 2>: identity_fully_preserved.` | 措辞不对，用的是泛化描述 |
| `detailed_description` 在 **0.00 秒**锚定目标身份 | 没有锚定 |
| 禁止对源实体用 `attribute_transfer` / `weak_reference` / `partially_preserved`（会**削弱**替换效果） | — |
| 三视图需 `reference_interpretation` 块，且**只有观测到 front/side/back** 才能声明 `three-view` | 本次图是 front/back/**面部特写**，不是标准三视图 → 正确做法是用裁出的**正面单视图** |

### 8.3 必须跑官方验证脚本（不过验证不提交）
```bash
cd /home/zyw/minimax-h3-video-studio/skills/h3-ref2va-prompt-compiler
python3 scripts/validate_h3_ref2va_prompt.py --profile identity-migration PROMPT_FILE
# 通过输出：OK: valid H3 Ref2VA prompt (identity-migration)
```
本次验证器直接抓出 `ERROR: three-view reference_interpretation must explain: side`。

### 8.4 参考视频必须低 token 预处理
依据 `docs/h3-reference-video-preprocessing-requirements.md`：**sm120 + SageAttention 长序列会静默产生灰屏/马赛克**（任务"成功"但画面全废）。
参考视频目标规格：**短边 ≤480、长边 ≤864、24fps、H.264、YUV420P、时长 ≤15s**（竖屏 → **480×864**）。
```bash
ffmpeg -y -i in.mp4 \
  -vf "scale=480:864:force_original_aspect_ratio=decrease,pad=480:864:(ow-iw)/2:(oh-ih)/2:color=black" \
  -r 24 -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac out_480x864.mp4
```

### 8.5 成功命令（可复现）
```bash
h3ctl generate video \
  --mode rv2v \
  --prompt-file prompt_official2.txt \
  --ref char_front.jpg \
  --source-video source_5s_480x864.mp4 \
  --duration 5.17 --aspect-ratio 9:16 --steps 4 --seed 20260916 \
  --wait --wait-timeout 40m --download out.mp4
```
结果：**原人物彻底移除、盔甲穿戴在身、无背景雕像、动作与场景保留**（768×1344 / 141 帧 / 6.5 分钟）。

### 8.6 顺手加的"反雕像化"约束（针对本次失败）
```
The armour must always be worn by <Subject 2> on her own body: never render it as a statue,
monument, mannequin, display piece, background prop or room decoration, and never place a second
armoured figure, a giant armoured figure or an oversized figure behind or beside her.
```

### 8.7 教训
**先读项目自带的 skill / references / docs，再动手写提示词**。这次绕了三圈（模板失败 → 自写提示词失败 → 官方规范成功），
而正解一直躺在 `skills/h3-ref2va-prompt-compiler/references/` 里。

### 8.8 追加实测：否定词会把角色图"推向背景"（2026-09-14，用户判断被证实）

盔甲女战士那次失败时，我在提示词里堆了一段否定约束：
```
The armour must always be worn by <Subject 2> on her own body: never render it as a statue,
monument, mannequin, display piece, background prop or room decoration, and never place a second
armoured figure, a giant armoured figure or an oversized figure behind or beside her.
```
结果角色图被渲染成了**她身后的巨型雕像**（"人物没替换上去，变成了背景"）。
用户判断"负面提示词被模型错误理解了"——随后用新素材做了对照实测，**结论支持这个判断**：

| 版本 | 否定词 | 结果 |
|---|---|---|
| 盔甲女战士（单人 rv2v） | 有（statue / prop / decoration 等） | ❌ 原人物没换掉 + 角色被渲染成背景巨型雕像 |
| **红金汉服侍女（单人 rv2v）** | **无**，只用官方正向模板 + `reference_interpretation` | ✅ **一次成功**：原人物彻底移除、角色穿戴在身、动作与舞台保留 |

**结论**：在 H3 的 Ref2VA / identity-migration 提示里，**"不要把 X 做成 Y"式的否定句很可能被当作正向内容**参与生成。
应当：
1. 优先使用官方正向模板 + 明确的 identity retention 关系；
2. 否定只保留官方推荐的那一两句（如 `Do not preserve, blend, or reintroduce the visual identity or appearance of <Subject 1>`）；
3. **不要自行堆叠**"never render it as a statue / prop / decoration"这类猜测性禁令。

### 8.9 三视图的正确用法（本次一次成功的关键）
本次人物图是**标准 front/side/back 三视图**（上次那张是"正面+背面+面部特写"，不满足条件）：
- summary 加 `with a three-view identity reference`
- 在 `retention_analysis` 之后、`detailed_description` 之前插入 `reference_interpretation` 块，
  **逐一说明每个视图提供什么**（正面=整体造型、侧面=发际线/领型/袖型、背面=发髻/背面纹样），
  并声明三图为**同一实体**、禁止复刻拼版布局与重复副本。
- 通过官方验证脚本后即可提交。

**成品**：`20260914_H3单人迁移_汉服侍女/H3单人迁移_汉服侍女_舞台演唱_v1.mp4`
（768×1344 / 141 帧 / 5s，舞台演唱短发女 → 红金汉服侍女，动作与舞美保留）
