为什么要同时提供 FP8 与 INT8 ConvRot?minimax-h3-nvfp4-convrot 速度 A/B 对比变体的设计思路
minimax-h3-nvfp4-convrot是面向 33B 视频+音频生成模型 MiniMax H3 的 ComfyUI 单文件量化检查点仓库。仓库里同时提供了pruned_nvfp4_fp8和pruned_nvfp4_convrot_int8两个变体——它们体积都是 20 GB、质量档位相同,唯一区别是attn.qkv_proj层的存储格式:一个用 FP8,一个用 INT8 ConvRot。这正是全仓库最标准的一对"控制变量法"速度 A/B 对比文件。本文带你拆透它背后的设计思路。
1. 先看家族全貌:从 34 GB 到 20 GB
仓库中的检查点文件名遵循minimax_h3_<fl2va|ref2va>_<variant>.safetensors的规律:
fl2va— 首/尾帧模式:零张图输入即纯文生视频,给 1~2 张图则变成帧条件视频ref2va— 全参考模式:最多支持 9 张图 / 3 段视频 / 3 段音频
其中 "pruned"(剪枝)家族的关键在于 AdaLN 剪枝:官方团队发现 H3 的 AdaLN 调制网络占了总参数的 39%(33.1B 中的 13.1B),但它实际上只依赖扩散时间步、不依赖内容,于是可以坍缩成一张小查找表且输出质量无损失——模型体积因此从 34 GB 直接砍到 20 GB。
| 变体 | 体积 | 适用 GPU | 定位 |
|---|---|---|---|
pruned_nvfp4_convrot_int8 | 20 GB | Blackwell | ✅ 官方推荐变体 |
pruned_nvfp4_fp8 | 20 GB | Blackwell | ⚡ 速度 A/B 对比基准变体 |
pruned_nvfp4 | 20 GB | Blackwell | 基准版,同体积下稍慢 |
nvfp4 | 34 GB | Blackwell | 未剪枝基础版 |
pruned_int4_convrot_simple等 | 17~25 GB | 任意 GPU | ⚠️ 实验性,质量未评估 |
完整清单见仓库 README.md。
2. 共同底座:NVFP4 / FP8 / BF16 三层量化
所有变体共享同一套分层量化配置(完整文件见 minimax_h3_layer_config.json):
| 层 | 格式 |
|---|---|
blocks.{2..46}.mlp.fc1/mlp.fc2(90 层) | NVFP4 |
attn.qkv_proj、adaln_proj.linear(90 层) | FP8,tensor-wise scale |
前 2 + 后 3 个 block、attn.out_proj、condition_proj、time_embedder等(86 层) | 保留 BF16 不量化 |
思路很朴素:能压的地方用最狠的 4 bit,敏感的地方一分不留。原检查点中存储为 F32 的层被视为"精度敏感"的信号,一律原样保留。
3. A/B 对比的关键:两个文件只差attn.qkv_proj
🎯 这对 A/B 变体的差异被压缩到了最小——只有 blocks 2~46 中 45 层attn.qkv_proj的量化格式不同:
| 维度 | pruned_nvfp4_fp8 | pruned_nvfp4_convrot_int8 |
|---|---|---|
attn.qkv_proj格式 | FP8,tensor-scale(F8_E4M3) | INT8,row-scale + ConvRot 元数据(I8) |
| 文件体积 | 20 GB | 20 GB |
| Tensor 数量 | 892 | 892 |
| 存在目的 | 速度对比基准 | 推荐的高速版本 |
其余部分——MLP 的 NVFP4、敏感层的 BF16、AdaLN 剪枝——两者完全一致。这是教科书式的控制变量设计:测出来的速度差,只能来自attn.qkv_proj这一个变量。ref2va也有同样的一对文件可供对比。
4. INT8 ConvRot 是什么:用"旋转"解决离群值难题
扩散 Transformer 的权重里存在离群值(outlier),INT8 数值范围窄,直接量化容易被峰值截断。ConvRot 的做法是量化前先对权重做分组 Hadamard 旋转(组大小 256):旋转把"尖峰"能量摊平到整组,INT8 的范围就装得下了——精度上追平 FP8,而 INT8 的 tensor-core 吞吐通常又高于 FP8。一句话:同档位精度,更高的算力。
对应量化时使用--int8 --scaling-mode row --dynamic-convrot --convrot-group-size 256等参数,--dynamic-convrot会自动为每层挑选兼容的最大 4 的幂组大小(45 层qkv_proj的 in_features 均为 5376,可被 256 整除)。
5. 一个容易被忽略的细节:从 BF16 重新量化,而不是层层压缩
INT8 ConvRot 的权重不是从它所替代的 FP8 张量转换而来,而是直接从原始 BF16 权重重新量化。原因很简单:FP8 本身已带量化误差,在其之上再量化一次会让误差叠加。
整个流程采用"提取 → 量化 → 拼接"三步走:
- 从 BF16 原文件中提取 45 个
qkv_proj.weight(该层无 bias) - 对这个小文件单独执行 INT8 ConvRot 量化
- 把
{weight, weight_scale, comfy_quant}张量拼回 pruned NVFP4 文件
FP8 变体同理:同样从 BF16 全新量化后,替换掉 ConvRot 版的attn.qkv_proj。所以两个文件的 Tensor 数量都是 892——结构分毫未动,变的只是那 45 层的格式与元数据。
6. 为什么同体积还要提供两个文件?
💡 有人会问:如果 INT8 ConvRot 更快,为什么还保留 FP8 版?
- FP8 是"已知量":它是量化工具
ctq(convert-to-quant)的默认输出路径,实现最简单;而 INT8 ConvRot 多了旋转元数据,推理路径更长。一旦实测速度回退,FP8 版能帮你快速判断是格式问题还是实现问题。 - 给用户一个可自控的对比锚点:两文件体积、质量档位完全一致、只差一个变量,用户可以在自己的硬件上直接实测生成耗时,亲自验证"INT8 吞吐是否真的高于 FP8"。
- 官方立场很明确:README 中
pruned_nvfp4_fp8的定位是 "benchmark variant"(基准对比变体),不是质量主张——它不削弱convrot_int8作为推荐版本的地位。
这个设计还顺带推动了上游工具的完善:为了方便在层配置中声明 ConvRot 参数,ctq的--layer-configJSON 被扩展,新增了convrot/dynamic_convrot/convrot_group_size字段。
7. 怎么选:一张快速决策表
| 你的情况 | 推荐文件 |
|---|---|
| Blackwell 显卡(RTX 50 系 / B100/B200),追求速度 | pruned_nvfp4_convrot_int8(fl2va / ref2va 均有) |
| 想亲自验证两种格式的速度差 | 依次跑 A/B 两文件,对比生成耗时 |
| 非 Blackwell 显卡,想要更小体积 | ⚠️pruned_int4_convrot_simple(17 GB,实验性) |
| 不用 ComfyUI、想要更稳的结构 | 未剪枝的nvfp4(34 GB) |
两点提醒:
- NVFP4 只支持 Blackwell(SM ≥ 10.0/12.0),老卡无回退方案——包括两个
convrot_int8文件,它们的其余部分仍是 NVFP4,只有qkv_proj是 INT8。 - 仓库没有测量过质量指标。NVFP4 系列被推荐,是因为格式保守成熟且确认可用,而不是因为跑赢了任何 benchmark;INT4 系列仅确认可加载并端到端生成。
写在最后
minimax-h3-nvfp4-convrot 的设计可以概括为一句话:用 NVFP4 压主体、用 BF16 保敏感、用 AdaLN 剪枝省下 14 GB,最后用一对"FP8 vs INT8 ConvRot"的同体积孪生文件,把速度选择从猜测变成一道你自己就能动手测的 A/B 题。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考