# KAP MiniMax H3 完整汇总

> 本文档汇总 kais-aigc-platform (KAP) 中所有 MiniMax H3 相关的工作流、API 端点、配置常量与节点拓扑。
> 代码主路径：`src/routes/production/minimax-h3/`；后端服务端口 **10588**；ComfyUI 容器 **comfyui-primary** 端口 **8188**。
> 生成日期：2026-08-14。

---

## 1. API 端点一览表

KAP 中 H3 通过 **两条完全独立的链路** 暴露，务必区分（双重路径陷阱）：

### 1.1 主链路（TypeScript 直连 ComfyUI-Primary :8188）

注册位置：`src/router.ts:46-51`（import）+ `:207-212`（`app.use`）。共 **6 个 REST 端点**（5 POST + 1 GET）：

| 端点 | 方法 | 说明 | 源文件 |
|---|---|---|---|
| `/api/production/minimax-h3/t2va` | POST | 纯文本 → 视频+音频（multipart 或 JSON） | `t2va.ts` |
| `/api/production/minimax-h3/i2va` | POST | 首帧/尾帧 → 视频+音频（multipart） | `i2va.ts` |
| `/api/production/minimax-h3/ref2va` | POST | 参考图/视频/音频 → 视频+音频（multipart） | `ref2va.ts` |
| `/api/production/minimax-h3/generate` | POST | **统一管线入口**：H3 生成 + Foley 环境音 + (可选)TTS 合并 | `generate.ts` |
| `/api/production/minimax-h3/replace-audio` | POST | 已有 H3 视频 → LTX Foley 环境音替换 + BGM 检测重试 | `replace-audio.ts` |
| `/api/production/minimax-h3/status/:promptId` | GET | 单次轮询 ComfyUI `/history/{promptId}` | `status.ts` |

> ⚠️ **双重路径陷阱**：除上述主链路外，还存在第二通道——
> `/api/proxy/goldTeam`（`router.ts:233`，`route68`）会把请求原样转发到 `http://gold-team:8002`（`src/routes/proxy/goldTeam.ts`，`GOLD_TEAM_URL`）。
> gold-team 引擎内的 `docker/gold-team/src/v6/engines/workflows/minimax_h3.py` 用 **另一套拓扑 + 另一个模型（pruned int8）+ 另一个 ComfyUI 后端** 构建 H3，且**只出视频、不出音频**。
> 即同一个“H3 生成”有两个入口，模型/拓扑/产物都不同，调用时必须明确走哪条。详见 §3.5。

### 1.2 供应商云 API（非本地推理）

`data/vendor/minimax.ts` 是 MiniMax 官方云接口（海螺 AI）的适配模板（v2.1），走 `https://api.minimaxi.com`，与本仓库的本地 ComfyUI 推理**完全不同**。包含文本模型（M2/M2.1/M2.5/M2.7）、图像（image-01）、视频（海螺 2.3 / 2.3-Fast / 02，支持 text / singleImage / startEndRequired）。它通过 `videoRequest()` 提交 `/v1/video_generation` 并轮询 `/v1/query/video_generation`，与本汇总的本地 H3 引擎无关，仅作对比记录。

---

## 2. 生成模式（T2VA / I2VA / FL2VA / L2VA / Ref2VA / Hybrid）

H3 是单一 AV（音视频联合）模型，模式由 **连接的可选输入** 自动判定。在 T8 链路中由 `MiniMaxH3AudioConditioningT8` 的 `task_type="auto"` 决定；原生链路由不同的 conditioning 节点 + 槽位决定。

| 模式 | 触发条件 | 端点 | conditioning 节点 | 说明 |
|---|---|---|---|---|
| **T2VA** | 纯 prompt，无任何帧/参考 | `/t2va` | `MiniMaxH3AudioConditioningT8`（无帧输入）/ 原生 `MiniMaxH3ImageToVideo` | 文本 → 视频+音频 |
| **I2VA** | 仅 firstFrame | `/i2va` | 同上 + `first_frame=[14,0]` | 首帧 → 后续动作 |
| **L2VA** | 仅 lastFrame | `/i2va` | 同上 + `last_frame=[15,0]` | 推导前因，落在尾帧 |
| **FL2VA** | firstFrame + lastFrame 同时 | `/i2va` | 同上 + 两帧 | 首尾帧间插值 |
| **Ref2VA** | refImages / refAudios / refVideos（无首尾帧） | `/ref2va` | T8 接 `ref_images[]` 数组 / 原生 `MiniMaxH3ReferenceToVideo` 槽位 `ref_images.ref_image_N` | 角色身份/风格/声音锁定 |
| **Hybrid** | refImages + firstFrame/lastFrame | `/ref2va` | T8 同时接 `ref_images[]` 与 `first_frame`/`last_frame`；节点 90/91 | 参考图与关键帧共存 |

**自动判定逻辑（T8）**：`task_type="auto"` 按实际连接的可选输入判 t2va / i2va / fl2va / l2va / ref2va / hybrid，调用方无需手填。
**`/i2va` 的判别**：handler 里 `firstFrame && lastFrame → fl2va`；`firstFrame → i2va`；`lastFrame → l2va`；都没有 → 400（引导改用 `/t2va`）。
**`/ref2va` 的判别**：`firstFrameFile || lastFrameFile` 存在则 `mode="hybrid"`，否则 `mode="ref2va"`。

---

## 3. 五条工作流链路

H3 在代码中共有 **5 条节点拓扑链路**，由 `profile` / `native` / `turbo` 入参选择：

### 3.1 T8 Dual-Clock 链路（默认）

- **何时用**：所有 T8 profile（preview / production / turbo 的底层；`native=false` 且非 lightx2v）。
- **核心三节点**（`comfyui-minimax-h3-audio-T8` 插件）：
  - `MiniMaxH3AudioConditioningT8` — 统一条件（替代原生 ImageToVideo/ReferenceToVideo），一个节点覆盖全部 6 模式。
  - `MiniMaxH3DualClockSamplerT8` — Dual-Clock Euler 采样器配置，内置 `shift_video=12 / shift_audio=3` + flow sigma 网格 + 双时钟 Euler；**修复原生 KSampler 低步数音频白噪声 bug**。输出 `(MODEL, SAMPLER, SIGMAS)` 三元组（**不是 LATENT**）。
  - `MiniMaxH3AVDecodeT8` — 联合 AV latent 解码，一次出 IMAGE + AUDIO。
- **模型**：`minimax_h3_fl2va_int8_convrot.safetensors`（非剪枝 ~34GB，统一覆盖所有 task_type，且能完整应用 Turbo LoRA）。
- **采样契约**（关键）：DualClock 输出三件套，必须配 `RandomNoise + BasicGuider + SamplerCustomAdvanced` 才产出 LATENT（详见 §8.1）。
- **TESpeed**：T8 链路**不插入** TESpeed 节点；它是全局 patch（`patch_model.py` 注入钩子），T8 调同一底层 model 故钩子仍生效（50 步 20m40s→12m01s，-42%）。

### 3.2 Native KSampler + SigmaShift 链路（pre-T8 拓扑）

- **何时用**：`profile="native"` / `"native-sage"` 或显式 `native=true`。从 commit `c2ad955a~1` 恢复。
- **采样**：`MiniMaxH3SigmaShift`(shift_video/shift_audio) → `[TESpeed(35) 可选]` → `KSampler`。
- **t2va/i2va/fl2va**：euler + normal 调度 + **50 步**；**ref2va**：res_multistep + normal + **20 步**。
- **模型**：t2va/i2va 用 `fl2vaModel`；ref2va 用 `ref2vaModel`（当前两者别名同指向非剪枝 fl2va；注释保留历史 pruned 区分）。
- **TESpeed 节点(35)**：`native` 插入（可能有质量损失）；`native-sage` 不插入（依赖全局 `--use-sage-attention`，SageAttention 自动生效，无质量损失）。两者唯一区别即 `tespeed`。
- **音频**：用 `VAEDecodeAudio`(41/43) 独立解码音频 → `CreateVideo` 合并。

### 3.3 LightX2V Turbo LoRA v1.0 链路（4步 / 8步）

- **何时用**：`profile="lightx2v-4"` / `"lightx2v-8"` / `"lineart-anime"`。独立于 T8 与 T8-Turbo。
- **模型链**：`UNETLoader(12) → SigmaShift(14_shift) → LoraLoaderModelOnly(15) → 采样链路`。
- **关键区别**（vs native/T8/Turbo）：
  1. **必须用 SigmaShift**（v0.1 预览版不带 SigmaShift 导致极暗画面——真因是缺 shift，不是 shift 过大）。
  2. shift_video 按 variant：4步版=**6**（768p 训练），8步版=**12**（544p mixed）；shift_audio 恒 3.0。
  3. 不用 T8 节点，不用 T8 Turbo LoRA（用独立 LightX2V LoRA，完整 bf16 权重 → 合并型 `LoraLoaderModelOnly`，非 bypass）。
  4. 采样：`KSamplerSelect(30) + BasicScheduler(31,simple) + RandomNoise(32) + BasicGuider(33) + SamplerCustomAdvanced(34)`。
- **lineart-anime**：基于 Ref2VA 训练的线稿上色 LoRA，强制 `mode=ref2va` + `refVideo`（线稿视频），走 lightx2v-8 variant；额外构建 `LoadVideo(60) → GetVideoComponents(61)` 拆出 IMAGE/AUDIO 注入 `ref_videos`/`ref_video_audios` 槽位。
- **渲染耗时**：lightx2v-4 ~72s；lightx2v-8 ~120s（画质更高）。均跳过 Foley，直出 H3 原生音频。

### 3.4 T8 Turbo LoRA 加速（T8 + LoRA 叠加）

- **何时用**：`turbo=true` 或 `profile="turbo"`。在 T8 链路的 `UNETLoader(12)` 与 `DualClockSamplerT8(30)` 间插入 `LoraLoaderBypassModelOnly`(节点 `14_lora`)。
- **步数**：motion-adaptive——low/medium=**4**，high=**8**（高动态 4 步画面崩坏，8 步显著改善）。实测 4 步 ~3.1x 加速（~140s）。
- **加载门控**：仅 `turbo && steps ≤ 15` 时加载 LoRA（高步数 LoRA 无益反引入伪影）；`i2va`/`ref2va`/`generate` 都遵守此 `steps <= 15` 守卫。
- **⚠️** INT8/量化模型必须用 `*Bypass*` loader 而非合并型；Turbo 需非剪枝 fl2va（pruned 无法完整应用 Turbo LoRA）；默认 EMA 版（画质略好，作者推荐）；`strength_model=1.0`。

### 3.5 Gold-team Python 构建器（:8002 路径）

- **何时用**：经 `/api/proxy/goldTeam` → `http://gold-team:8002` 调用 `docker/gold-team/src/v6/engines/workflows/minimax_h3.py`。
- **拓扑**（原生 KSampler + SigmaShift + TESpeed，节点编号与 TS 不同）：`10 UNETLoader → 14 SigmaShift → [35 TESpeed] → 30 KSampler`；`11 CLIPLoader`、`12 VAELoader`；`20 MiniMaxH3ImageToVideo`（正面）、`21 CLIPTextEncode("")`（负面占位）；`40 VAEDecode → 45 CreateVideo → 50 SaveVideo`。
- **模型**：`minimax_h3_fl2va_pruned_int8_convrot.safetensors`（~20GB **pruned**）+ NVFP4 文本编码器。
- **⚠️ 与主链路核心区别**：① 用 **pruned** 模型；② ComfyUI 后端是 gold-team 容器（GPU1）而非 comfyui-primary；③ **CreateVideo(45) 只接 images+fps，无 audio 输入**——即此路径只产出**无声视频**，无 H3 原生音频；④ 默认 15 步 fast preview（36 HQ / 50 official）。
- 文件注释自称“int8(UNet)+NVFP4(TE) 量化，单 3090 可跑 Flow Matching AV 模型”。

---

## 4. Profile 预设体系（`H3_PROFILES`，`config.ts:323`）

`generate` 通过 `profile` 入参选择档位；`t2va/i2va/ref2va` 也读 profile 影响 `native`/`turbo`/`tespeed`/步数。共 **8 个 profile**：

| Profile | steps | skipFoley | turbo | native | tespeed | 引擎链路 | 备注 |
|---|---|---|---|---|---|---|---|
| `preview` | 15 | ✅ | ✗ | ✗ | ✗ | T8 | 快速预览，直出 H3 原生音频，~6min |
| `turbo` | 4（motion 自适应） | ✅ | ✅ | ✗ | ✗ | T8 + Turbo LoRA | ~3min，low/med=4 high=8 |
| `production` | 50 | ✗ | ✗ | ✗ | ✗ | T8 lossless | 完整 Foley（LTX+BGM检测+TTS），~20min |
| `native` | null（按模式） | ✗ | ✗ | ✅ | ✅ | Native KSampler+SigmaShift+TESpeed节点 | t2v/i2va=50 / ref2va=20；可能有质量损失 |
| `native-sage` | null（按模式） | ✅ | ✗ | ✅ | ✗ | Native，无 TESpeed 节点 | SageAttention 全局，无质量损失；与 native 唯一区别=tespeed |
| `lightx2v-4` | 5 | ✅ | ✗ | ✗ | ✗ | LightX2V v1.0（768p, shift=6） | ~72s |
| `lightx2v-8` | 9 | ✅ | ✗ | ✗ | ✗ | LightX2V v1.0（544p, shift=12） | ~120s，画质更高 |
| `lineart-anime` | null（→lightx2v-8=9） | ✅ | ✗ | ✗ | ✗ | LightX2V + ref_video | 线稿上色，强制 ref2va + refVideo |

> `steps=null` 表示沿用按模式/variant 默认（native: t2v/i2va=50、ref2va=20；lightx2v: variant 自带步数）。
> generate 默认 `profile="production"`；其余端点不传 profile 走 T8 默认。

---

## 5. 配置常量（`config.ts`）

### 5.1 `H3_CONFIG`（运行时连接，env 可覆盖）
| 字段 | 值 | 说明 |
|---|---|---|
| `comfyuiUrl` | `http://localhost:8188`（env `COMFYUI_URL`） | ComfyUI-Primary |
| `containerName` | `comfyui-primary` | docker cp 目标 |
| `outputDir` | `/mnt/agents/output`（env `OUTPUT_DIR`） | 最终产物 |
| `comfyuiInputDir` | `/root/ComfyUI/input` | 容器内输入 |
| `comfyuiOutputDir` | `/root/ComfyUI/output` | 容器内输出 |
| `pollIntervalMs` | 2000 | status 轮询间隔 |
| `pollTimeoutMs` | 900000（15min） | 单次任务上限 |

### 5.2 `H3_CONSTANTS`（⚠️ 固化常量，官方源码硬编码，严禁变更）
| 常量 | 值 | 含义 |
|---|---|---|
| `CANVAS_MULTIPLE` | 32 | 宽高必须 32 倍数 |
| `BASE_SHORT_EDGE` | 768 | 短边基准 |
| `MAX_PIXELS` | 768×1344 = 1,032,192 | 最大面积 |
| `FPS` | 24 | 帧率固定 |
| `AUDIO_SAMPLE_RATE` | 32000 | 32kHz 立体声 |
| `AUDIO_LATENT_FPS` | 40 | 音频 latent 帧率 |
| `REF_IMAGE_SHORT_EDGE` | 2048 | ref_image_size="max" 时参考图短边 |
| `FRAME_GRID` / `FRAME_OFFSET` | 17 / 5 | 帧数须 `n%17==5` |
| `MIN_FRAMES` / `MAX_FRAMES` | 5 / 362 | ~0.2s / ~15s |
| `MIN_DURATION` / `MAX_DURATION` | 4 / 15 | 秒 |
| `MAX_REF_IMAGES/VIDEOS/AUDIOS` | 9 / 3 / 3 | 单类上限 |
| `MAX_REF_FILES_TOTAL` | 12 | 参考文件总数 |
| `CFG` | 1.0 | CFG-distilled，必须 1.0 |

### 5.3 `H3_DEFAULTS`（默认，可被 API 入参覆盖）
- **模型**：`fl2vaModel = ref2vaModel = minimax_h3_fl2va_int8_convrot.safetensors`（统一非剪枝）；`clipName = qwen3vl_32b_minimax_h3_nvfp4_awq.safetensors`；`videoVaeName = minimax_h3_video_vae_fp16.safetensors`；`audioVaeName = minimax_h3_audio_vae_fp32.safetensors`。
- **采样（T8 面）**：`t2vSteps=15`、`r2vSteps=15`、`shiftVideo=12.0`（⚠️不建议改）、`shiftAudio=3.0`（⚠️不建议改）；`t2vSamplerName="euler"` / `t2vScheduler="simple"`（T8 下不被引用，向后兼容别名）。
- **输出**：`fps=24`、`codec="vp9"`、`crf=20.0`、`denoise=1.0`。
- **分辨率/帧**：`defaultWidth=1344`、`defaultHeight=768`、`defaultLength=124`（~5s）。
- 向后兼容别名：`modelName/steps/samplerName/scheduler/cfg`。

> `H3_NATIVE`（原生链路）：t2v `euler/normal/50`；r2v `res_multistep/normal/20`。

### 5.4 分辨率预设表 `H3_RESOLUTION_TABLE`
| 比例 | 尺寸 | 标签 |
|---|---|---|
| 16:9 | 1344×768 | Widescreen（默认） |
| 9:16 | 768×1344 | Portrait（竖屏短剧） |
| 1:1 | 768×768 | Square |
| 4:3 | 1024×768 | Standard |
| 3:4 | 768×1024 | Portrait 4:3 |
| 21:9 | 1344×576 | Ultrawide |

### 5.5 时长→帧数预设表 `H3_DURATION_TABLE`
| 时长 | 帧数 | | 时长 | 帧数 |
|---|---|---|---|---|
| 4s | 101 | | 10s | 229 |
| 5s | 124（默认） | | 12s | 292 |
| 6s | 141 | | 15s | 362 |
| 8s | 175 | | | |

**对齐函数**：`alignH3FrameCount(n)` → 递增直到 `n%17==5`。`adaptH3Canvas(w,h)` → 短边归一到 768 → 面积裁到 MAX_PIXELS → 对齐 32 倍数（i2va `aspectRatio="auto"` 跟随首帧比例用）。

---

## 6. `generate.ts` 统一管线详解

`POST /api/production/minimax-h3/generate` 是 KMC 管线主入口，把 **H3 生成 + replace-audio Foley + (可选)TTS 混音** 串成一次同步调用。代码复用策略：H3 工作流在本文件**内联构建**（不 import 三个路由文件，仅 import config 常量），节点拓扑与三者一致；Foley/合并/BGM 检测/轮询等辅助函数复用自 `replace-audio`。

```
入参: mode(t2va|i2va|ref2va) + profile + prompt + [image/refImages/refVideo/ttsAudio] + 分辨率/帧/seed
  │
  ├─ 解析 profile → 决定 native / turbo / tespeed / skipFoley / 步数
  ├─ copyToContainer: 上传首帧/参考图/线稿视频到容器
  │
=== Step 1: H3 视频生成 ===
  │  effectiveNative ? buildH3WorkflowNative
  │  lightx2vVariant ? buildH3WorkflowLightX2V
  │  else            → buildH3WorkflowT8
  │  POST /prompt → promptId
  │  pollComfyuiCompletion(≤45min, 2700000ms)   ← 362帧 ref2va 实测 33min
  │  downloadVideoFromOutputs → localH3VideoPath (mp4 内嵌音频)
  │
  ├─ if profile.skipFoley:  copy → outputDir/{prefix}_h3.mp4 → 直接返回（预览档）
  │
=== Step 2: Foley 环境音 (LTX + NAG + BGM 检测重试) ===
  │  ensureResolutionAndStripAudio(H3视频 → 1280×704, -an 去音频)
  │  probeFrameCount → alignLtxFrames(8n+1, 最小97)
  │  buildLtxAmbientWorkflow → POST /prompt → poll(≤10min)
  │  downloadAudioFromOutputs → ambient.flac
  │  detectBgm → while(hasBgm && retries<2): seed+=1000 重生成，仅当 suspectSegments 改善才采用
  │
=== Step 3: 最终合并 (保留 H3 原始分辨率) ===
  │  mergeAudioAndVideo(H3视频, TTS?, ambient) → outputDir/{prefix}_final.mp4
  │    有TTS: loudnorm amix(TTS I=-16 ×1 + ambient I=-24 ×0.5)
  │    无TTS: loudnorm ambient I=-20
  │    -map 0:v:0 (视频流copy) + 新音轨 aac
  │
  └─ 返回 { videoUrl, videoPath, pipeline:{h3,foley}, bgmDetection }
```

**超时预算**：H3 ≤15min、Foley ≤10min、BGM 重试每次 ≤10min 最多 2 次，总计 ≤45min。**临时文件**：`/tmp/comfyui-h3-generate`，`safeUnlink` 幂等清理。

---

## 7. `replace-audio` BGM 替换机制（`replace-audio.ts`）

`POST /api/production/minimax-h3/replace-audio` 接收已生成的 H3 视频，用 **LTX-2.3 dev int8 + Foley LoRA** 生成无 BGM 环境音轨。

**两种模式**：
- `autoMerge=false`（默认，异步）：返回 `promptId`，客户端轮询 `GET /status/:promptId`。
- `autoMerge=true`（同步）：服务端等待 LTX 完成 → BGM 检测重试 → 合并 TTS+环境音+视频 → 返回最终 mp4。

### 7.1 N1 工作流（非蒸馏 dev int8 + Foley LoRA + SolidMask + ModelSamplingLTXV）
- **模型**：`ltx-2.3-22b-dev_transformer_only_int8_convrot.safetensors`（非蒸馏，LRA 2.6~10.4，听感自然，代价 ~3x 渲染）。
- **Foley LoRA**：`ltx-2.3-foley-400-steps.safetensors`（`LTX2LoraLoaderAdvanced`，video=0 / audio=1 / video_to_audio=1，strength=1.0）。
- **冻结视频 latent**：`VHS_LoadVideoFFmpeg → VHS_VAEEncodeBatched → SolidMask(value=0, 40×22) → SetLatentNoiseMask` → 完全冻结视频，采样只生成音频。
- **音频 from scratch**：`LTXVEmptyLatentAudio` → `LTXVConcatAVLatent`（合 AV）。
- **采样**：`CFGGuider(cfg=2.05)` + `LTXVScheduler(30步, max_shift=2.05, base_shift=0.95, stretch, terminal=0.1)` + `KSamplerSelect(euler_ancestral_cfg_pp)` + `ModelSamplingLTXV`。
- **解码**：`LTXVSeparateAVLatent → LTXVAudioVAEDecode → SaveAudio`。
- **分辨率**：固定 1280×704；帧规则 `8n+1`，最小 97 帧（短视频音频 VAE 信号过弱：39帧=-85dB，124帧=-43dB）。

### 7.2 BGM 残留检测 + 换 seed 重试（`detectBgm`）
- 原理：ffmpeg → WAV → python3 + numpy/scipy FFT 频谱分析。BGM 特征 = 持续高 `tonal_ratio(>0.15)` 且中频占比 `mid_pct(>0.4)`。
- 判定：1s 一段；`suspect ≥ n_segs×0.5 → HIGH`，`>0 → MEDIUM`，`0 → LOW`。
- 重试：`bgmMaxRetries=2`，每次 `seed = baseSeed + retries×1000`，**仅当 `suspectSegments` 改善才采用**新音频，否则放弃。

### 7.3 混音（`mergeAudioAndVideo`，EBU R128 loudnorm）
- 有 TTS：TTS `loudnorm I=-16:TP=-1.5` + ambient `loudnorm I=-24 + volume=0.5` → `amix(weights=1 1, normalize=0)` → 合并视频。
- 无 TTS：ambient `loudnorm I=-20:TP=-2:LRA=11,apad` → 合并视频。
- 视频流 `-map 0:v:0 -c:v copy`（保留 H3 原始分辨率），音轨 `-c:a aac -b:a 192k`。

---

## 8. ComfyUI 工作流 JSON 结构（节点拓扑）

### 8.1 T8 链路拓扑（t2va / i2va / ref2va / generate 共享）

```
10 CLIPLoader(qwen3vl, type=minimax) ─┐
11 VAELoader(video vae)               ┤
12 UNETLoader(fl2va_int8_convrot) ─────┼─► [14_lora LoraLoaderBypassModelOnly] (turbo&steps≤15 可选)
13 VAELoader(audio vae)                │
                                       ▼
20 MiniMaxH3AudioConditioningT8 ◄── clip[10] vae[11] audiovae[13] prompt w/h/length
   │  (i2va:+first_frame[14]  ref2va:+ref_images[14,141..]  hybrid:+90/91)
   ├─[0]=CONDITIONING ─► 32 BasicGuider.conditioning
   └─[1]=LATENT ───────┬─► 30 DualClock.av_latent
                        └─► 33 SamplerCustomAdvanced.latent_image
30 MiniMaxH3DualClockSamplerT8 ◄── model(useLora?[14_lora]:12) av_latent[20,1] steps shift_v/a
   ├─[0]=MODEL ─► 32 BasicGuider.model
   ├─[1]=SAMPLER ─► 33 .sampler
   └─[2]=SIGMAS ─► 33 .sigmas
31 RandomNoise(noise_seed=API seed) ─► 33 .noise
32 BasicGuider ◄── model[30,0] conditioning[20,0] ─[0]─► 33 .guider
33 SamplerCustomAdvanced ◄── noise[31] guider[32] sampler[30,1] sigmas[30,2] latent[20,1]
   └─[0]=LATENT ─► 40 AVDecodeT8.av_latent
40 MiniMaxH3AVDecodeT8 ◄── av_latent[33,0] video_vae[11] audio_vae[13]
   ├─[0]=IMAGE ─► 42 CreateVideo.images
   └─[1]=AUDIO ─► 42 CreateVideo.audio
42 CreateVideo(images, fps=24, audio) ─► 50 SaveVideo(mp4 内嵌音频)
```

> i2va/ref2va 的 LoadImage：首帧=`14`、尾帧=`15`（i2va）；ref2va 参考图=`14/141/142...`，参考音频=`15/151...`，参考视频帧=`170/171...`，视频配对音轨=`180/181...`，hybrid 首尾帧=`90/91`。
> ref2va 可选 `51 SaveAudio`（分离音频，取 AVDecodeT8[1]）。

### 8.2 Native 链路拓扑（KSampler + SigmaShift）

```
10 CLIPLoader / 11 VAELoader(video) / 12 UNETLoader / 13 VAELoader(audio)
14/141.. LoadImage (i2va首帧 / ref2va参考图)
16 MiniMaxH3ImageToVideo (负面占位, cfg=1.0 不生效)
20 正面条件: t2va/i2va → MiniMaxH3ImageToVideo(+first_frame)
            ref2va → MiniMaxH3ReferenceToVideo(ref_images.ref_image_N 槽位)
21 MiniMaxH3SigmaShift(model[12], shift_video=12, shift_audio=3)
[35 TESpeedMiniMaxH3] (仅 native profile, native-sage 跳过)
30 KSampler(model=35?:21, positive[20,0], negative[16,0], latent_image[20,1], seed, steps, cfg=1.0, sampler, scheduler, denoise)
40 VAEDecode(samples[30,0], vae[11]) ─► IMAGE
41/43 VAEDecodeAudio(samples[30,0], vae[13]) ─► AUDIO
42/44 CreateVideo(images, fps, audio) ─► 50 SaveVideo
```

> 原生 t2va/i2va：euler/normal/50；ref2va：res_multistep/normal/20。

### 8.3 LightX2V 链路拓扑

```
10 CLIPLoader / 11 VAELoader(video) / 12 UNETLoader / 13 VAELoader(audio)
14_shift MiniMaxH3SigmaShift(model[12], shift_video=4步版6/8步版12, shift_audio=3)
15 LoraLoaderModelOnly(model[14_shift,0], lora=LightX2V variant, strength=4步1.0/8步16.0)
[16 MiniMaxH3ImageToVideo 负面占位 — 不可达50, 不执行]
20 正面条件: t2va/i2va → MiniMaxH3ImageToVideo ; ref2va → MiniMaxH3ReferenceToVideo
   (lineart-anime: 60 LoadVideo → 61 GetVideoComponents → [0]IMAGE/[1]AUDIO 注入 ref_videos/ref_video_audios)
30 KSamplerSelect(sampler=euler)
31 BasicScheduler(model[15,0], simple, steps, denoise) ─► sigmas
32 RandomNoise(noise_seed)
33 BasicGuider(model[15,0], conditioning[20,0])
34 SamplerCustomAdvanced(noise[32], guider[33], sampler[30,0], sigmas[31,0], latent_image[20,1])
40 VAEDecode[34,0] + 41 VAEDecodeAudio[34,0] → 42 CreateVideo → 50 SaveVideo
```

### 8.4 二采重绘放大拓扑（`workflows/h3-redraw-upscale/`，静态 JSON + `build_workflow.py`）

围绕 `MiniMaxH3LatentUpscaleCombined`(Tr1dae) 的双采样 pass：pass1 低分全去噪 → latent 空间放大+重加噪 → pass2 高分重绘。stock `LatentUpscaleBy`/`AddNoise` 会破坏 H3 packed `NestedTensor` AV latent，Tr1dae 节点是唯一正确的两采样器间放大方式。

```
UNETLoader ─┐
CLIPLoader ─┤
VAELoader(vid/aud) ─► TESpeedMiniMaxH3 ─► (patched MODEL, 全链路用)
                                    │
              MiniMaxH3ReferenceToVideo ─► CONDITIONING, LATENT(low-res)
RandomNoise ► SamplerCustomAdvanced ◄─ BasicGuider(conditioning)        [PASS 1: 低分, denoise=1.0, steps=20]
              KSamplerSelect  BasicScheduler(beta, 20, denoise=1.0)
                    │ denoised_output (取 denoised_output, 非 output!)
                    ▼
         ★ MiniMaxH3LatentUpscaleCombined ★  scale_by=1.5, audio_denoise=0.35
                    │   (放大 video latent + 缩放 minimax_refs 到新画布; sigmas[0] 处重加噪)
                    │   positive=ref2va conditioning → 放大后 CONDITIONING
                    ▼ 放大后 LATENT
DisableNoise ► SamplerCustomAdvanced ◄─ BasicGuider(放大后 conditioning) [PASS 2: 高分重绘]
              KSamplerSelect  BasicScheduler(beta, 10, denoise=0.35) ◄─ 也喂 Combined.sigmas
                    ▼
              VAEDecode + VAEDecodeAudio → CreateVideo → 最终高分 MP4 (含音频)
```

**关键参数**（smoke 默认，864×480 → scale_by 1.5 → 1312×736，73帧/3.04s，~23.7GB VRAM，202s）：
| 参数 | 默认 | 说明 |
|---|---|---|
| pass-1 res | 864×480 (0.4MP) | 便宜的首遍 |
| `scale_by` | 1.5 | 1.5×→~0.9MP；2.0×→~1.6MP（24GB 吃紧） |
| `audio_denoise` | 0.35 | pass2 改写音频强度；0=锁 pass1 音频 |
| pass-2 `denoise` | 0.35 | 视频重绘强度，须与 audio_denoise 一致；同时喂 Combined.sigmas 与 pass2 采样器 |
| steps | 20 / 10 | pass1 / pass2 |
| length | 73 | 须满足 H3 帧数约束 |

**Tr1dae 规则**：① pass1 取 `denoised_output`；② pass2 Guider 用 Combined 返回的 conditioning；③ pass2 用 `DisableNoise`（Combined 已重加噪）；④ 两 pass 间**不要** Empty Cache/强制卸载；⑤ pass2 sigma 同时喂 `Combined.sigmas` 与 pass2 采样器，保持一致。
**模型**：`minimax_h3_ref2va_pruned_int8_convrot.safetensors`（pruned）。
**工具节点**（comfyui-primary 已注册 5 个）：`MiniMaxH3LatentUpscaleCombined`、`UniBlockSwap`/`UniBlockSwapTE`/`UniBlockSwapCacheControl`、`ReservedVRAMSetter`、`PT_H3ConcatAVLatent`、`SolAttnPatch`/`SolAttnBlockProbe`。

---

## 9. 关键参数详解

### 9.1 steps 优先级
**generate.ts**：`显式 steps > motion-based(turbo 时) > profile.steps`；native profile `steps=null` → 按模式默认（t2v/i2va=50，ref2va=20）；lightx2v/lineart-anime `steps=null` → variant 自带步数。
**t2va/i2va/ref2va handlers**：`turbo ? (显式 || getTurboSteps(motion)) : (显式 || (native ? NATIVE.{t2v|r2v}Steps : DEFAULTS.{t2v|r2v}Steps))`。

### 9.2 motion 分级（`getTurboSteps`，仅 turbo 生效）
| motion | steps | 场景 |
|---|---|---|
| low | 4 | 站立/对白/慢速 |
| medium（默认） | 4 | 拥抱/行走/轻微动作 |
| high | 8 | 追逐/赛车/打斗/快速运动 |

### 9.3 seed
- H3：默认随机（`Math.floor(rand*2147483647)`）；显式传入接 T8 `RandomNoise.noise_seed`，保留可复现性。
- Foley：默认 `42`；BGM 重试时 `seed += retries×1000`。

### 9.4 Turbo LoRA 加载条件
`turbo && steps ≤ 15` 才插入 `LoraLoaderBypassModelOnly`（节点 `14_lora`，EMA 版，strength=1.0）。i2va/ref2va/generate 三处均有此守卫。native 链路强制 `turbo=false`。

### 9.5 shift
`shiftVideo=12.0` / `shiftAudio=3.0`（H3_DEFAULTS）。⚠️ 官方硬推荐，不建议变更（低于 12 会帧间像素微漂移）。LightX2V-4 例外用 6.0（768p 训练优化）。

### 9.6 T8 conditioning 默认（`H3_T8`）
`taskType="auto"`、`audioMode="native"`（从零生成目标音频，不接 drive_audio）、`audioDenoiseStrength=0.35`、`addSourceAsReference=false`、`promptPrimaryAudioOrdinal=0`、`strictPromptTags=true`、`referenceVideoPolicy="official_2_to_15s"`。

### 9.7 提示词标签约定（ref2va）
- 参考媒体连接（决定哪些参考参与条件）与文本标签（锚定位置，可选增强）是两条独立路径。
- 标签：`<Picture 1>`(或 `<Image 1>`)、`<Video 1>`、`<Audio 1>`；顺序必须 images→videos→audios，多参考递增。
- T8 `strict_prompt_tags` 严格校验标签编号与连接的参考数量一致。

---

## 10. 已知陷阱和注意事项（⚠️ 汇总）

1. **双重 H3 路径**：主链路 `/api/production/minimax-h3/*`（ComfyUI-Primary :8188，T8，出音视频）vs gold-team `/api/proxy/goldTeam`→:8002（python，pruned 模型，**只出无声视频**）。两条模型/拓扑/产物都不同。
2. **cfg 必须 1.0**：H3 是 CFG-distilled，负面提示词实际不生效（native KSampler 仅需 negative conditioning 占位）。T8 链路无负面条件。
3. **帧数 `n%17==5` 网格**：所有入参帧数自动 snap；`alignH3FrameCount` 向上取整。
4. **分辨率 32 倍数 + 面积 ≤ 1,032,192**：违反报 400。
5. **shiftVideo 不要降**：低于 12.0 导致帧间像素微漂移（水流波动）。
6. **R2V 必须用 `res_multistep`**（原生链路），不是 euler。
7. **Turbo 需非剪枝 fl2va 模型**：pruned 无法完整应用 Turbo LoRA；INT8 模型必须用 `LoraLoader*Bypass*` loader。
8. **Turbo 高步数不加 LoRA**：`steps>15` 跳过 LoRA（无益反伪影）。
9. **LightX2V v1.0 必须 SigmaShift**：v0.1 旧版不带 SigmaShift → 极暗画面（真因是缺 shift）。4步版 shift_video=**6**（非12）。
10. **LightX2V-8 LoRA strength=16.0**：alpha=8/rank=128=0.0625，需补偿到 1.0：`128/8=16`。
11. **TESpeed 是全局 patch**：T8/LightX2V 链路不插节点（仅 `enabled=true` 标记 patch 就位）；仅 native profile 插节点(35)。前置条件：`ComfyUI-TE-Speed-MiniMaxH3-OSS` 已装 + `patch_model.py` 已执行；未满足时静默回退 stock speed，不报错。
12. **native vs native-sage 唯一区别**：`tespeed` 节点(35)。native-sage 依赖全局 `--use-sage-attention`（无质量损失）。
13. **H3 BGM ban 策略（特殊）**：cfg=1.0 → 负面词无效。正面须用 diegetic 锚定语：`strictly diegetic in-world sound, unscored scene, no scored music`；**绝不能**在正面出现 "no music"（会把全部音频压到 -57dB）。
14. **Foley 短视频音频极弱**：39帧=-85dB、124帧=-43dB，故 `alignLtxFrames` 最小 97 帧（~4s）。
15. **Foley BGM 重试策略**：仅当 `suspectSegments` 改善才采用新音频；无改善则放弃（避免越改越差）。
16. **首帧拉伸、尾帧 center-crop**（源码行为）；i2va `aspectRatio="auto"` 跟随首帧比例经 `adaptH3Canvas` 适配。
17. **status 是单次查询**（非阻塞长轮询），客户端按 `pollUrl` 反复调用；`queued`/`executing`/`success`/`error` 四态。
18. **重绘放大输出目录陷阱**：`fix-kornia.sh` 覆盖 `CLI_ARGS` 会丢 `--output-directory /mnt/agents/output/gpu1` 与 `--lowvram` → 渲染存到容器默认 `/root/ComfyUI/output/`（writable layer，recreate 即失），且无 `--lowvram` 贴近 24GB 上限。
19. **`copyToContainer`** 先 `docker cp`，失败回退 `docker exec -i cat`；上传后立即 `safeUnlink` 本地 multer 暂存。
20. **`router.ts` 手动维护**（非自动生成，见 KAP 后端约定）：新增 H3 路由须手动追加 import + `app.use`，且 prod 需 `yarn build:server` 重建 `data/serve/app.js`。

---

### 附：文件清单
| 文件 | 行数 | 角色 |
|---|---|---|
| `src/routes/production/minimax-h3/config.ts` | 481 | 配置常量（H3_CONFIG/CONSTANTS/DEFAULTS/T8/TURBO/TESPEED/LIGHTX2V/NATIVE/PROFILES + 分辨率/时长表） |
| `src/routes/production/minimax-h3/t2va.ts` | 474 | 纯文本→视频（T8 + Native builder） |
| `src/routes/production/minimax-h3/i2va.ts` | 540 | 首尾帧→视频（I2VA/L2VA/FL2VA 自动判定） |
| `src/routes/production/minimax-h3/ref2va.ts` | 691 | 参考图/视频/音频→视频（Ref2VA/Hybrid） |
| `src/routes/production/minimax-h3/generate.ts` | 1061 | 统一管线（H3 + Foley + TTS 三步，内联 T8/Native/LightX2V builder） |
| `src/routes/production/minimax-h3/replace-audio.ts` | 1055 | LTX Foley 环境音 + BGM 检测重试 + 混音（导出辅助函数供 generate 复用） |
| `src/routes/production/minimax-h3/status.ts` | 64 | 任务状态轮询 |
| `src/router.ts` | 325 | 路由注册（H3 在 46-51 / 207-212；goldTeam 72/233） |
| `docker/gold-team/.../minimax_h3.py` | 276 | gold-team :8002 路径 H3 工作流构建（native KSampler, pruned, 无音频） |
| `workflows/h3-redraw-upscale/` | — | 二采重绘放大（build_workflow.py + api/ui JSON + case08 + README） |
| `docs/minimax-h3-api-guide.md` | 253 | 用户面 API 手册 |
| `data/vendor/minimax.ts` | 399 | MiniMax 云供应商模板（与本地推理无关） |
