File size: 23,401 Bytes
9e65b39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# ComfyUI-RH-MiniMax-H3

[English documentation](README.md)

RunningHub 的 MiniMax-H3 ComfyUI 音视频扩散节点。DiT、Qwen3-VL 文本/多模态
编码器以及视频/音频 VAE 全部在 ComfyUI 进程内运行,不依赖 SGLang 服务,也不
调用 Diffusers Pipeline。

当前任务感知路径已覆盖 T2VA、FL2VA(首/尾帧生成视频与音频)和 Ref2VA(有序
图片/音频/视频参考)。三条路径均已完成本地合同、打包、采样器、媒体预处理、
节点静态检查和单元测试。Ref2VA 已用完整发布权重完成真实 CUDA 端到端验证。
FL2VA 与 T2VA 共用 FL2VA 分区及同一套编码/采样合同;上线前建议再做一次本地
CUDA smoke。

## 安装

```bash
cd ComfyUI/custom_nodes
git clone <repo-url> ComfyUI-RH-MiniMax-H3
pip install -r ComfyUI-RH-MiniMax-H3/requirements.txt
```

装好后需重启 ComfyUI:节点定义只在进程启动时读取一次。

## 节点清单

全部节点注册 ID 带 `RHMiniMaxH3` 前缀,归入 `RunningHub/MiniMax H3` 分类。
**节点 ID** 是工作流里保存的 `class_type` / `type`**显示名**是画布上看到的标题。

**`RunningHub/MiniMax H3/loaders`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3DirectModelLoader` | RunningHub MiniMax H3 Model Loader (Direct) |
| `RHMiniMaxH3DirectTextEncoderLoader` | RunningHub MiniMax H3 Qwen3-VL Loader (Direct) |
| `RHMiniMaxH3DirectVAELoader` | RunningHub MiniMax H3 Dual VAE Loader (Direct) |
| `RHMiniMaxH3FL2VAModelLoader` | RunningHub MiniMax H3 FL2VA Model Loader (Direct) |
| `RHMiniMaxH3FL2VATextEncoderLoader` | RunningHub MiniMax H3 FL2VA Qwen3-VL Loader (Direct) |
| `RHMiniMaxH3FL2VAVAELoader` | RunningHub MiniMax H3 FL2VA Dual VAE Loader (Direct) |
| `RHMiniMaxH3Ref2VAModelLoader` | RunningHub MiniMax H3 Ref2VA Model Loader (Direct) |
| `RHMiniMaxH3Ref2VATextEncoderLoader` | RunningHub MiniMax H3 Ref2VA Qwen3-VL Loader (Direct) |
| `RHMiniMaxH3Ref2VAVAELoader` | RunningHub MiniMax H3 Ref2VA Dual VAE Loader (Direct) |

**`RunningHub/MiniMax H3/conditioning`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3T2VATarget` | RunningHub MiniMax H3 T2VA Target |
| `RHMiniMaxH3T2VATextEncode` | RunningHub MiniMax H3 T2VA Text Encode |
| `RHMiniMaxH3UnsupportedConditioning` | RunningHub MiniMax H3 Legacy Unsupported Conditioning (Migration Error) |

**`RunningHub/MiniMax H3/fl2va`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3FL2VAFirstFrameCondition` | RunningHub MiniMax H3 FL2VA First / First+Last |
| `RHMiniMaxH3FL2VALastFrameCondition` | RunningHub MiniMax H3 FL2VA Last Only |
| `RHMiniMaxH3FL2VATarget` | RunningHub MiniMax H3 FL2VA Target |
| `RHMiniMaxH3FL2VAEncode` | RunningHub MiniMax H3 FL2VA Encode |

**`RunningHub/MiniMax H3/ref2va`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3Ref2VAImageReference` | RunningHub MiniMax H3 Ref2VA Image Reference |
| `RHMiniMaxH3Ref2VAAudioReference` | RunningHub MiniMax H3 Ref2VA Audio Reference |
| `RHMiniMaxH3Ref2VAVideoReference` | RunningHub MiniMax H3 Ref2VA Video Reference |
| `RHMiniMaxH3Ref2VATarget` | RunningHub MiniMax H3 Ref2VA Target |
| `RHMiniMaxH3Ref2VAEncode` | RunningHub MiniMax H3 Ref2VA Encode |

**`RunningHub/MiniMax H3/latent`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3EmptyAVLatent` | RunningHub MiniMax H3 Empty AV Latent |
| `RHMiniMaxH3SeparateAVLatent` | RunningHub MiniMax H3 Separate AV Latent |
| `RHMiniMaxH3CombineAVLatent` | RunningHub MiniMax H3 Combine AV Latent |
| `RHMiniMaxH3EncodeVideoAVLatent` | RunningHub MiniMax H3 Encode Video → AV Latent |

**`RunningHub/MiniMax H3/sampling`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3FrameRate` | RunningHub MiniMax H3 Frame Rate (Experimental) |
| `RHMiniMaxH3DualSigmaSampler` | RunningHub MiniMax H3 Dual Sigma Sampler |

**`RunningHub/MiniMax H3/decode`**

| Node ID | Display name |
|---|---|
| `RHMiniMaxH3DecodeAV` | RunningHub MiniMax H3 Decode Video + Audio |

### 迁移旧工作流

节点 ID 加了 `RH` 前缀,双 VAE loader 的 `vae_path` 也拆成了两个输入,因此更早
保存的工作流会报 `Node type not found`。用迁移工具转换,不必手工重建:

```bash
python3 tools/migrate_workflow.py 旧工作流.json --in-place
```

前端格式与 API 格式都支持。工具会改节点 ID、拆分 VAE 输入、按当前签名补齐缺失的
widget;下拉里已不存在的旧模型名会替换成当前默认值,并逐条打印替换记录供你复核。
`--in-place` 会留一份 `.bak` 备份。

## 环境要求

- ComfyUI 0.27 或更高版本(建议 0.28+)
- 与 ComfyUI 匹配的 PyTorch CUDA、Triton 和 `comfy-kitchen`
- Ref2VA 视频/音频参考需要系统 `PATH` 中存在 `ffmpeg``ffprobe`
  (Encode / Video Reference 在节点加载期软探测;真正跑媒体计划时缺失会 fail-closed)
- 另行下载 MiniMax-H3 权重;本仓库不包含模型权重
- 安装 `requirements.txt` 中的 Python 依赖(`transformers>=4.57.0,<=5.8.1`)

该模型规模很大。INT8 主要降低权重磁盘占用和搬运成本,并不会把 H3 变成小模型。
BF16 DiT 的 layerwise offload 为 **auto**(对齐官方 `auto_dit_layerwise_offload`,
优化基准为单卡 24GB):当可用显存 ≥ 整模权重 + `DIT_INFERENCE_RESERVE` 时自动关闭、
走整模驻留;放不下时非 block 模块常驻 GPU、transformer block 按层预取。开关见
`h3_settings.py``ENABLE_DIT_LAYERWISE_OFFLOAD``False`=强制整模)/
`DIT_LAYERWISE_PREFETCH`。INT8 仍可走 Comfy MixedPrecisionOps 的
partial/streaming offload。两种路径都需要较大的主机内存和高速磁盘。

采样热路径优化默认启用(均可在 `h3_settings.py` 单独关闭以便回滚):
`OPT_SDPA_PRECOMPUTED_BOUNDS`(预计算 attention bounds,消除每层 CUDA→CPU 同步)、
`OPT_PREPARED_STRUCTURE`(RoPE/结构张量 session 缓存)、
`OPT_INPLACE_EULER_UPDATE`(原位更新 target rows,避免每步整序列 clone)、
`OPT_ADALN_SEGMENT_BROADCAST`(adaLN 按连续段广播 in-place,避免每层
`index_select` 物化整序列调制张量)、
`OPT_ADALN_PRECOMPUTE` / `OPT_ADALN_RELEASE_WEIGHTS`(采样前预计算全部
timestep 的 adaLN 并释放约 40% DiT 权重;缓存设备由 `OPT_ADALN_CACHE_DEVICE`
控制:`auto`/`ram`/`vram`)、
`OPT_PREBUILT_TIMESTEPS`(预生成连续 sigma/timestep 张量)、
`OPT_DYNAMIC_ACTIVATION_RESERVE`(按画布/序列估算激活预留并分档
`full`/`layerwise`/`partial`/`reject`;采样输出带 `residency_mode`)。

生命周期与缓存(均可在 `h3_settings.py` 关闭):
- `OPT_RESIDENCY_LEASE` + `RESIDENCY_POLICY``safe`/`balanced`/`resident`):
  推理后 DiT 租约驻留(`gpu-resident` / `layerwise-warm`),TTL 后冷卸载;
- `OPT_ENCODE_CACHE`:文本 / 多模态 Qwen / VAE 条件 rows 共用 LRU(CPU,按字节上限);
- `OPT_VAE_RESIDENCY`:VAE offload 后跳过 `soft_empty_cache`,便于连续任务回载;
- `FORCE_ABSOLUTE_MODEL_ROOTS``True` 时 loader COMBO 一律写绝对路径;默认 `False`,
  按 ComfyUI 目录型模型的约定显示相对搜索路径的短名(如 `MiniMax-H3`),解析时按
  `folder_paths` 搜索路径顺序取首个命中;
- `OPT_WRITE_SIDECAR`:Decode 在 Comfy `output/` 写 JSON(任务/几何/驻留/telemetry + `env`:plugin commit / GPU / torch / Comfy);
- 降档链:16:9 为 `1344x768→1024x576→832x480→640x352``runtime/downscale.py`)。

结构治理(公开节点 class 名不变):
- `nodes.py` 薄 facade → `api/{loaders,targets,conditioning,sampling_nodes,decode,_shared}.py`
- `contracts/``constants` / `target` / `conditioning` / `components` / `fingerprints`(+ `_impl`- `sampling.py``runtime/sampler_core.py`
- `runtime/``packing` / `qwen_encoder` / `media_conditioning` / `model_loader` / `vae_adapter` / `components` / `dit` 均已分包
- DiT 工具:`runtime/attention.py``runtime/prepared_structure.py`

## 基准与可观测性

- `OPT_TELEMETRY`:采样/解码写入阶段耗时、每步 P50/P95、峰值显存;sidecar 带 `telemetry`
- 24GB 主矩阵:`benchmarks/matrix.json` + 采集说明 `benchmarks/BASELINE_24GB.md`
- 汇总:`python3 benchmarks/run_matrix.py --sidecars <Comfy output> --out benchmarks/results`
- latent golden:`python3 benchmarks/compare_golden.py --ref a.pt --cand b.pt`(默认 accel=off)

## 模型目录

权重分两处存放:**官方分片 release** 留在 `models/diffusers`(或
`models/minimax_h3`)下,**单文件转换产物**放进专属根
`ComfyUI/models/MiniMax-H3````text
models/MiniMax-H3/                              # 扁平单文件权重(转换产物)
├── MiniMax-H3-FL2VA-int8_convrot.safetensors
├── MiniMax-H3-Ref2VA-int8_convrot.safetensors
├── qwen3-vl-32b-int8_convrot.safetensors
├── MiniMax-H3-video_vae.safetensors
└── MiniMax-H3-audio_vae.safetensors

models/diffusers/MiniMax-H3/                    # 官方分片 release
├── FL2VA/
│   ├── transformer/                  # 官方 BF16 DiT(分片)
│   ├── text_encoder/                 # 官方 Qwen3-VL(分片 + tokenizer/processor)
│   ├── video_vae/
│   └── audio_vae/
└── Ref2VA/
    └── ...                           # 组件结构相同
```

专属根**只放权重、不带任何 sidecar**:组件类型与分区一律由文件名判定
(`MiniMax-H3-<分区>-<格式>` / `qwen3-vl-32b-*` / `MiniMax-H3-{video,audio}_vae`),
不符合命名规范的文件会被忽略而不是猜类型。`config.json``source/config.json`、
tokenizer、`preprocessor_config.json` 仍然从 `model_root` 指向的分片 release 读取,
因此**两处都要有**:release 提供结构,专属根提供张量。

`model_root` 选官方 release 根。FL2VA 节点只解析 `FL2VA` 分区,Ref2VA 节点只解析
`Ref2VA` 分区。每个任务有三个显式组件加载节点,**每个下拉只列出对应类型的模型**- `... Model Loader (Direct)``transformer_path` 只列 DiT,且按分区过滤;
- `... Qwen3-VL Loader (Direct)``text_encoder_path` 只列文本/多模态编码器;
- `... Dual VAE Loader (Direct)`:拆成 `video_vae_path``audio_vae_path`
  两个下拉,一次性选择并加载 24 通道视频 VAE 和 32 通道音频 VAE。

节点不会在 BF16 和 INT8 之间静默切换。请按模型名选择,例如:

- DiT INT8(单文件):`MiniMax-H3-FL2VA-int8_convrot.safetensors` /
  `MiniMax-H3-Ref2VA-int8_convrot.safetensors`
- DiT BF16(分片):逻辑名 `MiniMax-H3-FL2VA` / `MiniMax-H3-Ref2VA`
- TE INT8(单文件):`qwen3-vl-32b-int8_convrot.safetensors`
- TE BF16(分片):逻辑名 `qwen3-vl-32b`
- VAE 单文件:`MiniMax-H3-video_vae.safetensors` /
  `MiniMax-H3-audio_vae.safetensors`
- VAE 分片/原始包:逻辑名 `MiniMax-H3-video_vae` / `MiniMax-H3-audio_vae`

扁平单文件没有 `quant_meta.json`**分区凭证就是文件名**:把 Ref2VA 的 DiT 选进
FL2VA 节点会直接报错。选中的单文件路径会折进组件 fingerprint,换掉权重会立刻
被下游校验发现。

旧工作流里的目录名(如 `transformer_int8_convrot` / `vae`)以及 release 内的合并
双 VAE 包仍可解析;但旧的单 `vae_path` 输入已被 `video_vae_path` +
`audio_vae_path` 取代,含 VAE Loader 的旧工作流需要重连该节点。

加载 Qwen processor 时会校验官方 `preprocessor_config.json` /
`video_preprocessor_config.json`(短边/长边像素、patch/merge、mean/std)。
通用 Qwen3-VL 或错误硬编码像素阈值会直接报错,避免条件 embedding 静默偏移。

## FL2VA 工作流

支持首帧、尾帧、首帧+尾帧三种合法条件签名。条件图像与语义帧位置会作为整体
传递,并在采样前再次校验。

1. 使用 ComfyUI `LoadImage` 加载图片;
2. 使用 `RunningHub MiniMax H3 FL2VA First / First+Last`(或 `Last Only`)构造关键帧;
3. 分别使用三个 FL2VA Loader 加载 DiT、Qwen3-VL 与 VAE;
4. 创建 `FL2VA Target`,再执行 `FL2VA Encode`5. 将同一个 target 接到 `Empty AV Latent`6. 依次连接 `Dual Sigma Sampler``Decode Video + Audio``CreateVideo``SaveVideo`。

三种签名各一个工作流:
[`fl2va_first_frame.json`](examples/workflows/fl2va_first_frame.json) ·
[`fl2va_last_frame.json`](examples/workflows/fl2va_last_frame.json) ·
[`fl2va_first_last_frame.json`](examples/workflows/fl2va_first_last_frame.json)。
运行前请替换其中的占位输入图片名。

## Ref2VA 工作流

Ref2VA 的参考素材有严格顺序。添加每一个图片、音频、视频或带音轨视频时,应将
上一个节点的 `references` 输出接到下一个参考节点;改变链路顺序会改变多模态提示
和条件行的顺序。

1. 使用标准 `LoadImage``LoadAudio``LoadVideo` 加载素材;
2. 使用对应的 `RunningHub MiniMax H3 Ref2VA ... Reference` 节点按顺序追加;
3. 分别使用三个 Ref2VA Loader 加载 DiT、Qwen3-VL 与 VAE;
4. 将最终 reference 链同时接到 `Ref2VA Target``Ref2VA Encode`5. 依次连接 `Empty AV Latent``Dual Sigma Sampler``Decode Video + Audio``CreateVideo``SaveVideo`。

三种参考形态各一个工作流:
[`ref2va_image.json`](examples/workflows/ref2va_image.json) ·
[`ref2va_image_audio.json`](examples/workflows/ref2va_image_audio.json) ·
[`ref2va_video_audio.json`](examples/workflows/ref2va_video_audio.json)。
Ref2VA 的 Target 建议显式填 width/height;留空时按 aspect_ratio 默认解析到
1344×768,序列和耗时会大幅上升。
运行前请替换图片和音频占位文件名。

`Ref2VA Encode` 新增 `ref_image_size`,决定每张参考图解析到多大:

- `match`(默认):按生成画布的像素面积等比只缩不放;
- `max`:参考管线独立的 2048 短边,identity 保真最好。

参考 token 每个采样步都参与注意力,同画布下 `max` 可能比 `match` 慢数倍。
此选项出现之前保存的工作流现在会按 `match` 运行;要精确复现旧结果请显式选
`max`。切换策略会重新编码,不会复用另一策略的缓存。

Ref2VA 视频参考按官方路径规范为 24 fps,Qwen 展示序列再从该序列按 2 fps 采样。
`video_audio` 类型必须包含实际音轨;参考音频会进入立体声/32 kHz 的音频 VAE
预处理路径。Comfy `AUDIO` 超过双声道且无 layout 时,会在 Reference 节点 / VAE
边界均值下混为 stereo;需要 ffmpeg 布局感知 `-ac 2` 时优先走文件/视频参考。

## Target 与采样语义

- 对外时长限制为 5–15 秒。运行时会把请求帧数向上对齐到 H3 的 `17n+5` 时间
  边界,例如 24 fps 下请求 5.0 秒会解析为 124 帧;
- FL2VA 的 `auto` 尺寸跟随关键帧素材;指定比例时使用官方 `adapt_shape_v1`
  画布规则。Ref2VA 使用六个官方比例桶:`21:9``16:9``4:3``1:1``3:4``9:16``auto` 默认解析为 16:9;
- `Ref2VA Target` 也支持可选的 `width``height`:两者都为 `0` 时保持上述比例桶
  策略;两者同时填写时以手动画布为准。尺寸必须为 32 的倍数、宽高比在 1:4–4:1
  内,且不超过 H3 的像素上限;
- Ref2VA 时长填 `0` 表示从唯一一个真实带音频 reference 推导。没有带音频参考或
  存在多个带音频参考时,必须显式填写 5–15 秒;
- 采样器分别创建视频、音频噪声。视觉条件行在每一步固定为 sigma `0.999`,音频
  参考行固定为 sigma `1.0`。50 个 sigma 点对应 49 次 DiT forward;
- 编码、采样、解码之间会校验 target、条件顺序、任务分区、release 和组件指纹。
  FL2VA/Ref2VA 组件交叉连接会直接报错,不会继续生成未定义结果。

## V2A(视频→音频,可选)

`Dual Sigma Sampler``denoise_video=False`:把 `av_latent.video` 整段冻结为
视觉条件(timestep floor `0.999`),只去噪音频。当前要求 **T2VA 布局**(packed
无既有 visual condition)。

典型接线:

1. `T2VA Target` + `Empty AV Latent`2. `Encode Video → AV Latent`(VAE + 与 target 对齐的 `IMAGE` 帧序列)写入视频;
   或用 `Separate` / `Combine AV Latent` 从已有 AV 壳拼出非空视频;
3. `T2VA Text Encode` + `Dual Sigma Sampler``denoise_video=false`);
4. `Decode Video + Audio`(视频回传输入 latent,音频为新采样结果)。

`Empty AV Latent` 全零视频会直接报错;勿在 FL2VA/Ref2VA 既有 visual cond 布局上开 V2A。

## 帧率条件(实验性,可选)

`RunningHub MiniMax H3 Frame Rate (Experimental)` 对应 PR#15210 的实验能力,**不是**官方
训练契约,也不改 `target.fps=24` 时序格:

- `adaln=True`:把 fps 的 sinusoidal 加到 `TimeEmbedder`(即使填 24 也非 no-op);
  与 adaLN 预计算兼容,会写入 modulation cache 键;
- `temporal_rope=True`:按 `24/fps` 缩放视频行时序 RoPE 低频(可选 hard/linear/
  smoothstep 频率与 sigma 剖面);24fps 时缩放为 1。

接线:`Model Loader``Frame Rate``Dual Sigma Sampler`。换 fps 后若 DiT 已
释放 adaLN 权重,需重新加载模型。

## 单卡采样加速(可选)

开发/部署按**单卡**设计:不做多卡或 Ulysses 门禁。官方 4×H200 数字只作旋钮与
质量参考;单卡收益来自减少 DiT 次数(velocity-cache)或跳过 block 计算
(Cache-DiT)。默认 `accel=off``Dual Sigma Sampler``accel`:

| 值 | 行为 | 单卡建议 |
| --- | --- | --- |
| `off` | 关闭(可作 GT) | 默认 |
| `auto` | 命中 1344×768/124f/50steps/shift12·3 时优先 velocity-cache | 推荐试 |
| `minimax-h3-velocity-cache-v1` | 整步 velocity 复用 + Taylor(无额外依赖) | **首选** |
| `minimax-h3-cache-v1` | Cache-DiT DBCache(需 `pip install cache-dit>=1.3.0`) | 备选 |
| `manual-velocity` / `manual-cache-dit` | 手调 stride 或 RDT/MC/warmup | 调试 |

官方参考:velocity-cache 约 **3.2×**、Cache-DiT 约 **2×**(均为 4×H200 证据)。
近似加速,**不要**当 consistency GT。profile 在
`minimax_h3_nodes/runtime/profiles/`。采样结束会打实际/理论 DiT 次数日志;
`auto` 未命中与 `manual-*` 也会记录当前 workload 并标明非 GT。

在 [`examples/workflows/`](examples/workflows) 任一工作流的采样器上
设置 `accel` 即可;导入前确认模型名与本地 INT8/VAE 选择一致。

与 `accel` 无关的两条融合 kernel 路径(均来自上游 PR#15224):安装的 Comfy 暴露
了对应入口就自动启用,每进程探测一次并打日志;入口缺失(旧版 Comfy、没有
comfy-kitchen、非 CUDA 设备)则原样走现有 PyTorch 路径。

| 开关 | Kernel | 收益 |
| --- | --- | --- |
| `OPT_INT8_FUSED_SWIGLU` | `comfy.ops.linear_input_act` | INT8 MLP:swiglu 折进激活量化 kernel,省掉每层每步一次全尺寸中间张量 |
| `OPT_FUSED_QK_ROPE` | `comfy.quant_ops.ck.rms_rope_split_half_` | 注意力:per-head RMSNorm 与 split-half RoPE 一趟做完,就地写在 qkv 缓冲上 |

两者都在 `minimax_h3_nodes/runtime/h3_settings.py``OPT_FUSED_QK_ROPE_CUDA_ONLY` 让 RoPE kernel 在非 CUDA 设备上一律回退
(comfy-kitchen 没有对应实现)。带梯度时融合 RoPE 也会自动让路——它要就地改写
autograd 视图。

## INT8 转换与 VAE 合并

必须按任务分区分别转换:

```bash
cd custom_nodes/ComfyUI-RH-MiniMax-H3
BASE=/path/to/ComfyUI/models/diffusers/MiniMax-H3

python3 tools/quantize_int8_convrot.py \
  --src "$BASE/FL2VA/transformer" --device cuda --verify
python3 tools/quantize_int8_convrot.py \
  --src "$BASE/Ref2VA/transformer" --device cuda --verify

python3 tools/quantize_text_encoder_int8_convrot.py \
  --src "$BASE/FL2VA/text_encoder" --device cuda --verify
python3 tools/quantize_text_encoder_int8_convrot.py \
  --src "$BASE/Ref2VA/text_encoder" --device cuda --verify

python3 tools/merge_vae.py --src "$BASE/FL2VA"
python3 tools/merge_vae.py --src "$BASE/Ref2VA"
```

VAE 只做合并打包,不做 INT8 量化。即使文件名相同,也不要用一个分区的文件修补
另一个分区;转换前应先校验完整的官方下载权重。

工具输出的是**组件目录**`config.json` + 单文件权重 + `quant_meta.json`)。要用
专属根的扁平布局,把其中的 `.safetensors` 挪到 `models/MiniMax-H3/` 即可——文件名
已经带了模型/类型/量化格式,节点靠它判定类型与分区,配置继续从 `$BASE` 的分片
release 读:

```bash
FLAT=/path/to/ComfyUI/models/MiniMax-H3
mkdir -p "$FLAT"
mv "$BASE/FL2VA/transformer_int8_convrot/MiniMax-H3-FL2VA-int8_convrot.safetensors" "$FLAT/"
mv "$BASE/Ref2VA/transformer_int8_convrot/MiniMax-H3-Ref2VA-int8_convrot.safetensors" "$FLAT/"
mv "$BASE/FL2VA/text_encoder_int8_convrot/qwen3-vl-32b-int8_convrot.safetensors" "$FLAT/"
mv "$BASE/FL2VA/vae/video_vae/MiniMax-H3-video_vae.safetensors" "$FLAT/"
mv "$BASE/FL2VA/vae/audio_vae/MiniMax-H3-audio_vae.safetensors" "$FLAT/"
```

留在 release 里的组件目录(含 `quant_meta.json`)同样可用,两种形态都会出现在
对应类型的下拉里。

## AdaLN 曲线表 DiT(可选,checkpoint 缩小约 40%)

DiT 每层的 adaLN 投影是 `[96768, 2688]`,50 层合计 26 GB——占 BF16 DiT 的 39%、
INT8 的 55%(adaLN 不参与量化)。而它的输入只是 `silu(time_embedder(t))` 这条
一维曲线:把曲线投影到秩 `k` 的共享基后,基被折进每层权重(`[96768, k]`),
time embedder 由 `adaln_t_table [grid, k]` 采样表 + 线性插值取代。这就是上游
PR #15224 引入的 checkpoint 格式;加载器按 `adaln_t_table` 张量自动识别,两种
形态走同一套节点。

```bash
python3 tools/convert_adaln_curve.py \
  --src "$BASE/FL2VA/transformer" --verify           # BF16: 66.3 GiB -> 约 40 GiB
python3 tools/convert_adaln_curve.py \
  --src "$BASE/FL2VA/transformer_int8_convrot" --verify   # INT8: 47.0 GiB -> 约 21 GiB
```

产物写到 `<src>_adaln_curve/`,在 DiT 选择器里作为独立模型名出现。`--verify`
会在随机的非网格 timestep 上比对曲线路径与真实 adaLN 输出,低于
`--cosine-floor`(0.9999)直接失败——此时提高 `--rank` / `--grid`。默认
rank 64 / grid 1024。

与运行时 adaLN 预计算(原版 checkpoint 仍默认走它)的取舍:

- 磁盘更小,无需预计算,不占调制缓存,任意 timestep 都可用。
- adaLN 输入是秩 `k` 近似,而非精确值。
- 实验性 Frame Rate 节点的 `adaln` 模式依赖 time embedder,曲线表 checkpoint 会
  直接报错;`temporal_rope` 模式不受影响。

## 本地验证

```bash
python3 -m compileall -q minimax_h3_nodes tools tests
python3 -m unittest discover -s tests -v
```

这些命令验证本地结构以及 CPU 可执行合同,不能代替使用完整发布权重的真实 CUDA
端到端运行。

## 许可证与上游

插件代码按本仓库 Apache-2.0 许可证发布。模型权重不包含在仓库中,仍受上游模型
许可证及条款约束。实现参考官方
[MiniMax-H3 源码包](https://github.com/MiniMax-AI-Dev/Internal-0727-private-3)。