CondBridge 的 ComfyUI 集成节点——用 1.14B 适配器 + Qwen3.5-4B 学生模型替代 MiniMax-H3 的 33B 文本编码器,让 H3 DiT 视频生成在消费级显卡上本地运行。
适配器把学生模型的文本表示"桥接"到 H3 官方编码器(condition_proj +
token_refiner)的注入空间,输出与教师等价的 [S_T, 5376] 表示,DiT 零改动
直接消费
训练详情与模型下载见 SpXMerlin1D/MiniMaxH3-CondBridge-Qwen3.5-4B。
- 🪶 轻量:33B 教师 → 4B 学生(GGUF 量化可选)+ 1.14B 适配器
- 🔌 零侵入:适配器输出与教师 post-refiner 表示同空间,DiT 前向不改一行
- 🐍 鸭子类型 CLIP:
MiniMaxH3AdapterLoader输出标准CLIP,直接接官方MiniMaxH3ImageToVideo节点 - 🎛️ 显存友好:适配器 encode 后自动卸载;学生支持整卡 /
gpu_mem层间 offload / GGUF 量化驻留三档 - 🧰 自带工具:学生对齐测试、GGUF 检查、契约冒烟测试
官方管线:prompt → 33B 文本编码器 → condition_proj + token_refiner → [S_T, 5376]
→ DiT 采样。
本节点:prompt → Qwen3.5-4B 学生(hidden_states[-1])+ H3 tokenizer ids → 适配器
→ [S_T, 5376](与教师同空间) → DiT 采样。
ComfyUI 的 MiniMaxH3 DiT(comfy/ldm/minimax/model.py)在 preprocess_text_embeds
中条件式跳过投影:
if text_states.shape[-1] != self.hidden_size: # 5376
text_states = token_refiner(condition_proj(text_states))适配器输出已是 5376 维 post-refiner 表示,跳过分支不触发,直接注入。
cd ComfyUI/custom_nodes/
git clone <本仓库地址> ComfyUI-MiniMaxH3-Adapter依赖:transformers>=4.45(学生加载)、safetensors、accelerate(gpu_mem
offload 时)、gguf(inspect_gguf.py 工具)。ComfyUI 自带 torch。
从训练 ckpt 导出(train.py 产物 → 裸 state_dict .safetensors):
python export_adapter.py <adapter_stage2_step2000.pt> --out adapter_stage2.safetensors放到 ComfyUI/models/minimax_h3_adapter/。
Qwen3.5-4B,二选一:
- HF 目录(含
config.json+ safetensors shards):整个文件夹放入ComfyUI/models/text_encoders/ - GGUF 文件(如
Qwen3.5-4B-...Q4_K_M.gguf):放入ComfyUI/models/text_encoders/,且同目录必须有tokenizer.json/tokenizer_config.json/vocab.json/merges.txt(加载器要求)
GGUF 走
gguf_qwen35.py:量化块驻留、前向逐层反量化, 显存占用 ≈ 量化文件大小而非 fp16 展开。布局假设已逐张量验证 (426/426 张量 cos ≥ 0.99 vs bf16 参考)。
tokenizer/ 目录(H3 官方 tokenizer,vocab 151,643)随节点分发,无需额外准备。
标准入口:学生 + 适配器 → 鸭子类型 CLIP。
| 参数 | 类型 | 说明 |
|---|---|---|
student |
下拉 | models/text_encoders/ 下的 HF 文件夹或 .gguf 文件 |
adapter |
下拉 | models/minimax_h3_adapter/ 下的 .safetensors / .pt |
gpu_mem |
字符串 | 留空 = 整卡;24GB 及以下建议 "16GiB"(学生层间 offload) |
输出 CLIP → 接官方 MiniMaxH3ImageToVideo。
CLIP→CLIP 包装:已有学生 CLIP(如 CLIPLoader 加载的 GGUF)的 encode 输出
当 student_hidden,再经适配器。
| 参数 | 类型 | 说明 |
|---|---|---|
clip |
CLIP | 内层学生 CLIP(layer="last" 输出即 post-final-norm,与训练语义一致) |
adapter |
下拉 | 适配器文件 |
透传 clip 并导出 cond embeds 到 models/minimax_h3_adapter/cond_official_ref.npy。
黑屏诊断用:对比官方 CLIP 与本节点的注入表示。
UNETLoader(fl2va) ────────────────┐
├─> MiniMaxH3ImageToVideo -> BasicGuider ...
MiniMaxH3AdapterLoader(student, adapter) -> CLIP
VAELoader(video_vae)
UNETLoader加载 H3 DiT(fl2va)MiniMaxH3AdapterLoader:选学生 + 适配器 →CLIPMiniMaxH3ImageToVideo:官方节点原样使用,clip接上一步VAEDecode→SaveVideo
| 脚本 | 用途 |
|---|---|
export_adapter.py |
训练 ckpt({"model":...} 包装或裸 sd)→ 适配器 .safetensors(bf16,剥 model. 前缀,校验 key) |
check_alignment.py |
换学生前的照妖镜:候选学生(GGUF/微调/HF)vs bf16 原版特征对齐测试。cos>0.99 合格 / 0.95-0.99 有漂移评估后可用 / <0.95 需重提特征重训 |
inspect_gguf.py |
查看 GGUF 张量布局(pip install gguf) |
test_fake_clip.py |
无 ComfyUI 依赖的契约冒烟:形状/维度/tags/5376 透传/offload 显存回落 |
test_gguf_loader.py |
合成迷你 GGUF 回环测试:加载器映射/反量化/置换正确性(数值断言) |
- 适配器 1.14B(bf16 ≈ 2.3GB),
encode后自动卸载回 CPU - 学生
Qwen3.5-4B:整卡约 8GB;gpu_mem="16GiB"层间 offload 后峰值更低; GGUF Q4 量化驻留 ≈ 2.5GB - DiT 采样期间适配器与学生均已 offload,显存让位给 DiT(33B DiT 需 layerwise offload 或 80GB 卡)
Q: 生成了视频但内容与 prompt 无关 / 黑屏?
先确认节点控制台 [adapter] loaded ... (1.144B) 后没有
ignored N unexpected keys 提示——有则说明适配器结构与节点模型定义不匹配,
请提issue更新 adapter/model.py(必须含 gate / qk_norm 结构,与训练一致)。
再用 MiniMaxH3ExportCond 导出对比官方表示。
Q: 学生 GGUF 报错缺 tokenizer?
把 Qwen3.5-4B 的 tokenizer.json / tokenizer_config.json / vocab.json / merges.txt / chat_template.jinja 拷到 GGUF 同目录。
- 适配器训练基于 MiniMax-H3 官方权重做接口蒸馏,仅限研究用途,请遵守 MiniMax 服务条款
- 学生模型:Qwen3.5-4B
- GGUF 加载器参考 city96/ComfyUI-GGUF 的量化驻留方案,针对 qwen35 arch 自研适配