Reed's News
← 返回精选

H3-metal:Apple Silicon上的MiniMax-H3原生推理

AI 60 swyx 2026/8/11 5054 字 原文 ↗

Apple Silicon 原生 MiniMax-H3 推理实现

本项目采用"垂直切片迭代"方式开发:先完成确定性主机/模型元数据模块,再依次实现可移植 Metal 块一致性、提示词编码、提示词转音视频、首尾帧条件控制,最后完成有序参考功能。

目前,提示词转音视频、首尾帧条件控制、Ref2VA(参考转音视频)图像/视频/音频参考已实现端到端运行。当前工作重点是针对 M3 Max 和 M5 Max 平台,对 H3 专属 Metal 代码进行性能与内存优化。

示例代码假设 Hugging Face 模型快照存于 ./MiniMax-H3,且 FFmpeg 和 FFprobe 已添加至系统 PATH

make -j8
mkdir -p outputs
./h3 --info -d ./MiniMax-H3

--info 参数用于检查模型结构,并打印选中的 Metal 设备,但不会加载全部权重或生成媒体文件。运行 ./h3 --help 可查看完整命令行参数说明。

不带 -p 参数时,同一二进制文件会启动类 Iris 交互式会话:

./h3 -d ./MiniMax-H3 --width 512 --height 512 --steps 6

输入提示词即可生成带编号的视频。会话会将 BF16 格式的提示词条件、预处理后的 DiT(扩散变换器)及视频解码器常驻内存,因此重复使用同一提示词搭配不同种子时,无需重新加载和编码。常用命令包括 !status(查看状态)、!seed random(随机种子)、!seconds 2(设置时长)、!show(预览画面)、!save output.mp4(保存视频)和 !cache(缓存管理),使用 !help 可查看完整命令列表。

交互式会话中,首尾帧条件设置会持续生效:

h3> !first opening.png
h3> !last ending.png
h3> The camera moves slowly around the subject.

使用 !first clear!last clear 可移除锚点帧。生成的视频会保存至会话启动时显示的目录中。

若要添加通用 Ref2VA 条件图像,可使用 !ref-image PATH 命令。图像会按添加顺序传入模型,被识别为 <Picture 1><Picture 2> 等,文件名对模型无意义。

h3> !ref-image person.png
h3> Make the person shown in Picture 1 wave to the camera.

!refs 命令可查看当前参考图像顺序,!ref-remove N 移除第 N 个参考项,!refs clear 清空所有参考。Ref2VA 参考与 !first/!last 锚点帧不可同时使用。

建议从经过验证的平衡预设开始尝试:该预设生成 22 帧、24 fps 的视频(约 0.92 秒),在支持图形化的终端中,每完成一次去噪迭代就显示视频中间帧的演化状态,并打印各阶段耗时:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
--width 512 --height 512 \
--frames 22 --steps 20 \
--layers 45 --reuse 2 \
--show \
-o outputs/fox-fast.mp4

这并非性能最激进的配置,各参数说明如下:

  • --steps 20:执行默认的 20 次去噪迭代
  • --reuse 2:仅计算 11 次全新去噪器速度值,其余通过外推得到,而非全部 20 次都重新计算
  • --layers 45:运行 50 个变换器块中的 45 个,减少计算量和统一内存占用
  • --show:可选参数,支持 Kitty/Ghostty、iTerm2/WezTerm/Konsole 等终端的图形协议。会加载常驻预览 VAE(变分自编码器),每次欧拉法迭代后显示一帧代表性中间帧,最终展示所有完整帧。默认以 2 倍缩放显示,适配 macOS Retina 屏幕的逻辑尺寸;非高 DPI 显示器可使用 --zoom 1。该参数会增加预览解码时间,并占用约 10 GiB 临时模型内存;不添加则无此影响
  • --profile:可选参数,不改变生成路径,仅用于性能分析

首次运行会产生模型加载和文件系统缓存开销。建议通过多次运行对比性能,且在机器预热后测试不同变体——此工作负载对热节流敏感。

若需快速迭代,可直接指定 4 次去噪迭代:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur." \
--width 512 --height 512 --frames 22 \
--steps 4 --layers 50 --reuse 1 \
--show \
-o outputs/fox-four-step.mp4

--steps N 始终表示精确执行 N 次去噪迭代。4 至 7 次迭代采用的调度策略在低成本测试中表现最优;从 4 次增加到 7 次,画面细节和运动流畅度会逐步提升。在迭代次数较少时,需保持 --reuse 1,确保每一次请求的迭代都运行模型。--show 会在每次迭代后显示一张预览图。

我们评估了多种"重尾"调度策略,因为大部分可见的画面优化都发生在长序列后期,但这类策略保留的早期构图更新过少,会导致纹理失真、运动生硬或色彩断层。最终采用的模式基于发布版线性基础网格,仅保留一个端点。在 512×512、22 帧的狐狸测试中,4 次迭代结果与 29 次迭代参考视频的全视频 SSIM(结构相似性指数)为 0.556;在独立的冲浪者测试中,该数值为 0.547。M5 Max 平台上,4 次去噪耗时约 3.5 秒,而参考的 29 次迭代耗时 26.4 秒。

若需低内存运行,可添加 --ssd-streaming 参数:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 50 --reuse 1 --ssd-streaming \
-o outputs/fox-ssd.mp4

该模式直接使用原始 BF16 检查点,无需转换或量化。仅将两个 DiT 块保留在内存中,GPU 运行当前块时,从 SSD 读取下一个块。在 M5 Max 上,512×512 分辨率下 DiT 跟踪存储从约 36.5 GiB 降至 2.0 GiB,864×480 分辨率下降至 2.1 GiB。热机状态下,50 块前向传播在 512×512 分辨率耗时 1.35 秒(比全内存 BF16 路径慢 84%),864×480 分辨率耗时 2.14 秒(慢 26%)。两种路径的输出字节完全一致。

2.0-2.1 GiB 仅为 DiT 的跟踪张量存储,并非系统总内存占用。提示词编码和两个 VAE 分阶段运行,不会叠加各自的内存峰值;系统、媒体缓冲区和输出分辨率仍需预留空间。--show 参数会使预览 VAE 常驻内存,额外占用约 10 GiB,因此低内存运行时需省略该参数。

SSD 流是一种明确的内存/速度权衡策略,并非默认选项,且不能与 --use-int8-row-fc2 同时使用。交互式会话中可通过 !ssd-streaming on 开启。

评估画质时建议每次仅调整一个控制参数:先恢复所有层,再恢复所有去噪器评估,最后将默认的 20 次迭代调度提升至更慢的 50 次迭代参考水平:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest. Medium tracking shot, natural winter light, realistic fur, soft footsteps and wind." \
--width 512 --height 512 \
--frames 22 --steps 50 \
--layers 50 --reuse 1 \
-o outputs/fox-close.mp4

默认参数为 --steps 20 --layers 50 --reuse 1;此参考路径需显式指定 --steps 50。它会执行 50 次完整的 50 块去噪前向传播,比默认配置耗时多得多,但当快速模式导致主体、结构、运动或构图偏离时,可作为可靠的基准参考。由于随机数和执行引擎不同,无需追求与 MLX 输出的像素级一致,但画面内容和运动逻辑应保持一致。

除非另有说明,以下控制参数相互独立:

控制项 慢速参考配置 默认配置 激进配置 主要影响
去噪迭代次数 --steps 50 --steps 20 --steps 4..7 数值始终代表实际去噪迭代次数
去噪器整体复用 --reuse 1 --reuse 2 --reuse 3 20 次迭代时:分别对应 20、11 或 8 次全新 DiT 评估
激活的 DiT 块数量 --layers 50 --layers 45 --layers 40 块数越少,计算量和常驻变换器权重越小
核心残差复用 --core-reuse 1 --core-reuse 4 --core-reuse 6 每步刷新补丁/头工作,但减少昂贵的核心运算次数
令牌缩减 关闭 可选 --token-reduction 在中间块中合并水平视频令牌;速度更快,但可能改变构图
内部画布 输出尺寸 512×512 输出对应 384x384 320x320 以更小尺寸运行 DiT/VAE,再通过 vImage 放大

在 M5 平台,--use-int8-row-fc2 为每个 FC2 行使用一个激活缩放因子,并采用单全宽 TensorOps 运算。该参数为可选,因为其数值保守性低于分组 int8 量化。对比测试显示,完整去噪前向传播耗时减少约 2.6%。匹配的 4 步狐狸和冲浪者视频在主体、场景和运动上保持一致(全视频 SSIM 分别为 0.919 和 0.828)。交互式会话中可通过 !int8-row-fc2 on 开启。

--reuse--core-reuse 互斥,层裁剪可与两者任意组合使用。

若要在保持输出分辨率的同时加快首次运行速度,可添加令牌缩减:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A surfer riding inside a sharp blue ocean wave, one rider and one white board, realistic spray." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 --token-reduction \
-o outputs/surfer-fast.mp4

在已验证的 512×512 分辨率下,令牌缩减使 45 layers + reuse 2 配置的去噪耗时从 16.69 秒降至 12.60 秒(IT M5 Max 平台)。独立渲染的狐狸和冲浪者视频保持连贯,但构图可能与参考路径差异更大。

若需激进预览,可在内部以 320×320 分辨率渲染,再放大至 512×512 输出:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A red fox walking through snow, realistic, tracking shot." \
--width 512 --height 512 \
--render-width 320 --render-height 320 \
--frames 22 --steps 20 --layers 40 --reuse 3 \
-o outputs/fox-aggressive.mp4

验证显示,该组合可生成清晰可辨的 22 帧狐狸视频,但会丢失细节,且可能改变画面构图。请勿同时使用 --token-reduction--layers 40--reuse 3:测试发现该组合会导致色彩镶边、轮廓失真和肢体重影。

作为整体速度复用的替代方案,以下配置可在每次迭代时刷新时间步相关的补丁和输出头:

./h3 --profile \
-d ./MiniMax-H3 \
-p "A surfer riding a blue ocean wave." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --core-reuse 4 \
-o outputs/surfer-core-reuse.mp4

仅建议将 --core-reuse 6 用于激进预览。数值超过 6 未对外开放,因为验证发现会导致主体保真度下降。

宽度和高度必须为 32 的倍数,且不小于 32,同时像素总数不得超过 768 * 1344。这些是机械限制,不保证所有小尺寸画布都能生成高质量结果。H3-Base 是一款 768p 模型。

画布尺寸 当前使用建议
512x512 最安全的开发尺寸;已通过多个提示词反复验证
768x768 已验证的高质量正方形输出;计算量大幅增加
1344x768768x1344 发布版支持的 768p 级横屏/竖屏上限
1024x768768x1024 有效的 4:3 和 3:4 比例 768p 级画布
384x384 内部渲染,输出 512x512 已验证的快速高质量缩放方案
320x320 内部渲染,输出 512x512 已验证的激进缩放方案
256x256 原生快速预览画布,自动适配低分辨率 RoPE(旋转位置编码)

快速原生 256×256 预览示例:

./h3 -d ./MiniMax-H3 \
-p "A red fox walks through fresh snow in a pine forest." \
--width 256 --height 256 \
--frames 22 --steps 20 \
--layers 50 --reuse 1 \
-o outputs/fox-256.mp4

256×256 分辨率下,H3 仅拥有 8x8 有效空间令牌网格,因此细节和复杂构图的表现受限。H3 会在 256×256 分辨率下自动将空间 RoPE 坐标减半,消除了长序列狐狸渲染中的重复晶格伪影,且在独立人像测试中保持连贯,同时不增加令牌数量或运行时间。可使用 --use-reference-rope 恢复发布版/MLX 坐标以进行一致性检查。此尺寸下请关闭令牌缩减。原生 128×128 分辨率暂不支持:其 4x4 令牌网格即使调整 RoPE 也无法生成可识别的主体。

--render-width--render-height 需同时设置,且与输出分辨率保持相同宽高比,数值不得超过输出尺寸。模型和 VAE 使用内部尺寸运行,终端显示帧和编码视频则保留请求的输出尺寸。

H3 输出帧率为 24 fps,帧数量会自动向上对齐为 5 + 17*n 的形式:

可使用 --seconds N 指定时长,或用 --frames N 直接控制帧数;两者互斥。支持小数时长。时长会按 24 fps 转换为帧数,再向上取整为符合 H3 时间格式的合法值,例如 --seconds 10 会生成 243 帧(10.125 秒)。

帧数 近似视频时长
22 0.917 秒
39 1.625 秒
56 2.333 秒
107 4.458 秒
243 10.125 秒
362 15.083 秒

短剪辑适合开发阶段使用,发布版工作流针对约 4-15 秒的视频设计。例如 --frames 23 会自动向上取整为 39 帧,而非生成任意时间长度的视频。

简短提示词可正常使用,但发布版系统更推荐类似 Context-IR 的详细描述,需包含主体、动作、场景、镜头、灯光/风格及音效要求。示例如下:

场景:黎明时分,白雪覆盖的松树林中有一只红狐。
动作:狐狸稳步从左向右行走,中途看向镜头一次。
镜头:中等高度横向跟拍,50mm 镜头,画面稳定。
风格:毛发逼真,冷蓝色环境光,暖色调日出轮廓光。
音效:雪地中的轻柔脚步声,风吹过松枝的声音,无音乐。

当主体身份和物体数量重要时,请明确说明。--seed N 控制原生随机流,默认值为 42。对比不同选项时,请保持提示词、种子、分辨率、帧数和迭代次数一致。

  • --show:每次去噪迭代后显示一帧代表性画面,视频生成完成后展示所有帧。与 Iris 类似,默认以 2 倍尺寸显示以适配 Retina 终端;--zoom N 可调整缩放比例,但不改变生成视频或终端显示图像的尺寸
  • --frames-dir DIR:将最终回调帧保存为 PPM 文件,--show 的中间预览帧不会保存至此
  • -o '':禁用 MP4 编码;当 FFmpeg 不可用时,可与 --frames-dir 配合使用
  • --profile:报告各阶段实际耗时、Metal 编码/等待时间、峰值活跃张量存储、累计内存分配及调度次数

示例:

./h3 --profile -d ./MiniMax-H3 -p "A hummingbird hovering over red flowers." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 --frames-dir outputs/hummingbird-frames \
-o ''

首尾帧锚点会启用 FL2VA(首尾帧转音视频)路径:

./h3 -d ./MiniMax-H3 -p "The fox keeps walking through the snow." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 45 --reuse 2 \
--first-frame fox.png --last-frame fox-later.png \
-o outputs/fox-anchored.mp4

有序参考会启用独立的 Ref2VA 检查点,需根据媒体类型选择对应参数:

# 单张图像参考
./h3 -d ./MiniMax-H3 -p "Use the animal and setting in the reference." \
--width 512 --height 512 --frames 22 --steps 20 \
--ref-image fox.png -o outputs/fox-reference.mp4
# 续接视频但忽略原音轨
./h3 -d ./MiniMax-H3 -p "Continue the motion in this clip." \
--width 512 --height 512 --frames 22 --steps 20 \
--ref-silent-video fox.mp4 -o outputs/fox-video-reference.mp4
# 保留视频中的嵌入音轨
./h3 -d ./MiniMax-H3 -p "Continue this audiovisual scene." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-video fox-with-audio.mp4 -o outputs/fox-video-audio.mp4
# 显式替换视频音轨
./h3 -d ./MiniMax-H3 -p "Continue the scene with the supplied music." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-video-audio silent-fox.mp4 replacement.wav \
-o outputs/fox-replaced-audio.mp4
# 有序图像参考加独立音频参考
./h3 -d ./MiniMax-H3 -p "Use the animal and music from the references." \
--width 512 --height 512 --frames 56 --steps 20 \
--ref-image fox.png --ref-audio music.wav \
-o outputs/fox-image-audio.mp4

参考参数可重复使用,且命令行顺序会被保留。独立音频参考必须搭配图像或视频参考使用。音频参考时长需为 2-15 秒,最多接受 3 个音频输入,总解码时长上限为 15 秒。

make test
make parity

make test 运行确定性主机测试套件;若在 misc/fixtures/ 下安装了忽略的 MLX 测试环境,会在运行时编译 Metal 源码,并将完整的 H3 测试块与指定 MLX 输出进行对比。运行时编译是有意为之:遵循 Iris 设计,无需依赖 Xcode 的可选离线 Metal 工具链。测试覆盖 F32 诊断路径和生产环境 BF16 存储路径;宽 BF16 矩阵乘积和 SDPA(缩放点积注意力)使用缓存的 MPSGraph 图,并提供直接 Metal 正确性回退方案。make parity 仅运行 Metal/MLX 一致性检查。

媒体输入和 MP4 输出需依赖 PATH 中的 FFmpeg 和 FFprobe(可通过 H3_FFMPEGH3_FFPROBE 指定可执行文件路径)。生成的 RGB24 格式图像和 32 kHz 立体声 F32 PCM 音频通过并发管道传输,不生成中间未压缩媒体文件。

以下内容记录教程预设背后的实现细节,以及用于精确 A/B 诊断的环境变量。

默认采样器采用发布版的偏移音视频调度。--steps 始终表示去噪迭代次数,最后一次迭代后会添加终端零值。去噪器整体复用会评估首次和末次迭代,以及每个指定间隔的迭代,然后针对视频和音频独立调度外推跳过的速度值。当迭代次数极少时,请保持 --reuse 1

针对低成本路径,发布版线性基础网格在对比测试中胜出,测试对象包括实际视频 sigma 线性间隔、二次和三次扭曲、精确 30 点尾部子集、温和幂次扭曲、零阶保持全网格速度、线性速度外推及 RES(残差预测采样)。重尾候选方案常能锐化主体,但会破坏运动效果或留下重复的编织状背景;稀疏 RES 和长间隔外推的失败更为明显。

层裁剪会根据检查点中实际的 AdaLN(自适应层归一化)门控权重排序,同时保留结构重要的首尾块。未使用的权重和调度张量不会保留,因此 --layers 45--layers 40 可同时减少变换器运算时间和统一内存占用。核心复用会保留上一次完整变换器残差,同时刷新补丁投影和时间步感知头;它与整体速度复用互斥。

每个激活的 DiT 块都会将注意力残差门控与后续 MLP(多层感知器)的 AdaLN 融合。BF16 残差仍会精确写入,但同一行会保留在线程组内存中用于归一化,减少一次调度和一次全局重读。在非令牌缩减边界处,MLP 残差门控还会生成下一个块的注意力 AdaLN,并在循环中传递归一化状态。设置 H3_DISABLE_FUSED_GATE_ADALN=1H3_DISABLE_FUSED_CROSS_BLOCK_ADALN=1 可恢复双内核基准实现。

最终音视频 AdaLN 内核直接绑定到残差流中的偏移量,避免两次切片复制,在 512×512 分辨率下节省 18.8 MiB 临时内存(864 级基准分辨率下为 29.4 MiB)。H3_DISABLE_FUSED_FINAL_SLICE=1 可恢复加载时的复制加 AdaLN 基准实现。BF16 最终头会在加载 16×16 投影块时应用 AdaLN,保留独立的舍入和累加顺序,同时移除另一个同等大小的归一化激活。两项优化合计节省 37.5/58.9 MiB 内存。H3_DISABLE_FUSED_FINAL_HEAD=1 可恢复加载时的偏移 AdaLN 加线性基准实现。

--token-reduction 是一种独立的激进 DiT 模式。在第 3 块之后,它会将相邻的水平目标视频令牌配对,但保留文本、音频、条件和参考令牌的原样。完整的全分辨率状态会作为旁路保留。在前 10 次含噪评估中,会在第 40 块前恢复全分辨率;后续细节生成评估则在第 30 块前恢复。每个令牌会恢复为原始值加上其配对令牌学习到的更新,因此配对内的细节不会丢失。

池化内核仅将真实配对基线写入已分配的注意力临时缓冲区的密集尾部;奇数宽度的单令牌无需基线。当空间足够时,完整旁路会使用超大 QKV 尾部,仅在参考密集型布局时启用受保护的专用回退方案。因此,普通纯文本画布在任何令牌网格宽度下都不会增加激活内存占用。池化还会在 BF16 值仍在寄存器中时快照两个源令牌,避免单独的全隐藏复制和冗余源读取。同一入口内核会将每个池化行保留在线程组内存中,并生成第一个缩减块的注意力 AdaLN,消除另一次全局残差读取。在恢复边界处,第一个全分辨率注意力 AdaLN 会融合到扩展过程中:10.5 KiB 的线程组行避免了全局残差重读,同时仍能写入后续残差分支所需的精确旁路。

在热平衡的 512×512×22 分辨率、19 次前向传播的 IT M5 Max A/B 测试中,该优化将去噪时间从 39.13 秒降至 28.06 秒(减少 28.3%)。最终音视频潜变量的相对 L2 误差为 5.56%/15.14%。狐狸视频的首/中/末帧保留了清晰的口鼻、连贯的腿部和锐利的毛发;独立测试的冲浪者视频在浪花中始终保持一人一板的一致性。由于会改变构图,该模式为可选功能,而非参考默认路径。

H3_TOKEN_REDUCTION_BLOCKS 可覆盖后期的 4:30 间隔;H3_TOKEN_REDUCTION_EARLY=STEPS:END 可覆盖早期调度,设置为 0 则禁用早期恢复。H3_DISABLE_TOKEN_REDUCTION=1 提供上下文内的精确基准实现。H3_DISABLE_FUSED_TOKEN_POOL_ADALN=1H3_DISABLE_FUSED_TOKEN_ADALN=1 可分别恢复入口和出口边界的双内核实现用于诊断。

令牌缩减可与已验证的 --layers 45 --reuse 2 设置完美配合:在同一 512 基准测试中,该组合将耗时从 16.69 秒降至 12.60 秒(边际减少 24.5%),且独立渲染的狐狸和冲浪者视频保持连贯。请勿将其与 --layers 40--reuse 3 同时使用;该组合的 6.47 秒测试虽潜变量指标合格,但出现了色彩镶边和肢体重影。

--render-width--render-height 会以较低的同宽高比内部画布运行模型和 VAE,再通过高质量 vImage 将 RGB 帧放大至请求的输出尺寸,之后再进行回调、终端显示和编码。这是一种明确的画质/速度权衡:实测 384 到 512 的提示词渲染,M5 平台 DiT 时间减少 33%,视频 VAE 时间减少 18%,同时仍能保持清晰可辨的真实感结果。两者数值必须为 32 的倍数;精确输出画布为默认值。

对于 512×512 正方形输出,384 是快速高质量平衡点,320 是已验证的激进平衡点。后者生成了连贯的行走狐狸视频,DiT 耗时约 8.02 秒,而原生 512 分辨率耗时约 15.82 秒。原生 256 分辨率使用上述同等成本的空间 RoPE 适配;它仅作为快速构图预览,无法替代 512 或 768 级的最终渲染。

视频 VAE 会根据请求的画布尺寸自动选择 256-320 像素的空间块,在最小化重复重叠运算的同时限制峰值存储。H3_VAE_TILE_PIXELS=256 可恢复原始保守块方案用于参考诊断。

在 M5 级 GPU 上,变换器权重直接从 safetensor 分片映射,而非复制到匿名共享缓冲区。这使 37 GiB 模型文件可被系统回收,且略微提升了总变换器运算时间;M3 平台则使用更快的复制缓冲区路径。H3_ZERO_COPY_WEIGHTS=0 可禁用 M5 平台的该选择用于诊断。

流式 Qwen 文本编码器会预分配一个小型未来层缓冲区环,在 Metal 执行当前层时,由 8 个 I/O 线程填充缓冲区。默认环深度在 M3 及更早硬件上为 2 层,在配备 128 GiB 内存的 M5 平台上为 3 层。H3_QWEN_PREFETCH=0 可恢复单层同步参考路径;数值 1-8 可选择线程数,H3_QWEN_PREFETCH_DEPTH=16 可覆盖环深度。

--ssd-streaming 是 DiT 的一种独立且更激进的内存驻留模式。仅小尺寸的每块归一化权重保持常驻内存。两个完整的 BF16 矩阵槽交替使用,后台读取器按检查点偏移顺序填充下一个槽;当前 Metal 命令缓冲区同时运行。Darwin 非缓存读取避免了在文件系统缓存中保留第二份副本。最后一个块运行时会重新预取第一个激活块,使缓存的交互式 DiT 可随时准备下一次去噪评估。实测内部 SSD 读取速度约为 13-14.6 GiB/s。H3_PROFILE=1 会报告总字节数、读取吞吐量,以及未被 GPU 工作掩盖的读取等待时间占比。

M5 GPU 会自动对序列长度不超过 2048 的 DiT QKV 和注意力输出投影使用原生 BF16 Metal 4/TensorOps。紧凑的莫顿调度将 Q/K/V 直接路由到头部优先的注意力输入,避免三次 MPSGraph 输入转置,且与可移植路径字节完全一致。在 IT/US M5 Max 平台的重复测试中,完整的 512×512 50 块前向传播速度提升约 2%。对于 2049-3072 行(包括 864×480),两次行偏移莫顿调度保留了高效的块几何结构,在平衡测试中完整前向传播速度提升约 2%。更大的序列则仍使用 MPSGraph。H3_NAX=0 可禁用 TensorOps 用于精确 A/B 诊断。该选择在运行时会进行检查,若编译不可用则回退到未修改的可移植库。

H3_NAX=1 强制使用更广泛的原生 BF16 线性路径。它通过了完整的 50 块 MLX 测试,但仍为可选功能:精确形状微基准测试显示其 128 行块更优,但完整 DiT 运行目前 MPSGraph 调度表现更好。这使 NAX 集成可用于后续量化/融合内核,同时避免默认配置出现基准性能倒退。

H3_NAX=mlp 选择更专业的 Metal 4 路径:配对的 FC1 门控/向上 TensorOps 块在线程组内存中应用 SwiGLU,仅输出 14336 宽的激活中间结果,FC2 也使用 TensorOps。H3_DISABLE_NAX_MLP=1 可在同一进程 A/B 测试中保留 MPSGraph MLP。该路径为可选,因为调度依赖于系统 GPU 栈:在 macOS 26.5.2 M5 Max 平台,孤立真实权重 MLP 测试速度提升 1.3-2.0%,但完整 50 块前向传播速度下降约 1-3%;而在配置相同的 macOS 26.5 M5 Max 平台,同一上下文前向传播 A/B 测试速度提升 1.4%。生成的 50 块速度值接近(视频和音频相对 L2 误差分别为 1.9% 和 2.4%),但并非字节完全一致。

窄 DiT 音视频输出头会将其小型发布版 F32 权重一次性转换为 BF16,并直接在 BF16 激活上使用源自 Iris 的 16×16 分块线性运算。在生产环境 320 渲染分辨率下,孤立配对头测试在 M3 Max 上速度提升 2.30 倍,M5 Max 上提升 1.83 倍,相对 L2 误差为 8.64e-4;M5 平台每步评估约节省 0.6 毫秒。完整狐狸和冲浪者序列保持清晰,与 F32 头渲染结果的信噪比为 29.9/38.4 dB。H3_DIT_F32_FINAL=1 可恢复参考头及其额外激活缓冲区。

F32 格式的 96->5376 视频和 32->5376 音频补丁投影使用专用的 16×16 协作块,保留 F32 权重、输入和累加,同时直接将块结果舍入为 BF16。配对生产形状测试在 M3 上速度提升 1.77 倍,M5 上提升 1.62-1.78 倍;生成的完整 RGB 流与标量路径字节完全一致。融合最终转换使 2835 行块本身在 M3 上耗时从 2.499 毫秒降至 1.734 毫秒,M5 上从 1.555 毫秒降至 1.186 毫秒,并在 512/864 级分辨率下减少 38.27/59.66 MiB F32 临时内存。H3_DISABLE_FUSED_PATCH_CAST=1 可恢复分块 F32 输出加独立转换;H3_SCALAR_PATCH=1 选择标量诊断路径。

同一块将输出直接绑定到压缩隐藏流中,移除 BF16 媒体暂存缓冲区及其复制操作,额外节省 19.13/29.83 MiB 内存,并使 2835 行边界在 M3 上耗时从 1.847 毫秒降至 1.730 毫秒,M5 上从 1.282 毫秒降至 1.184 毫秒。连续 T2VA(文本转音视频)使用字节偏移;FL2VA/Ref2VA 使用紧凑目标行映射,使每种模态只需一次大型调度。完整六段 Ref2VA M5 ABBA 测试保持字节完全一致,每对测量前向传播耗时从 5.067 秒降至 5.033 秒。H3_DISABLE_FUSED_PATCH_PACK=1 可恢复暂存缓冲区和复制打包操作。

DiT 核心拆分为两个有序 Metal 命令缓冲区,使第一部分 GPU 执行与第二部分 CPU 编码重叠。热平衡 ABBA 测试显示,M5 平台选择 60% 深度拆分(30/50、27/45 和 24/40),速度提升约 0.5-1.8%;M3 平台仅自动拆分已验证的 30/50 情况,速度提升 1.2%,因为 24/40 拆分在该平台会导致性能倒退。操作顺序和生成字节保持不变。H3_DIT_COMMAND_BLOCKS=0 可恢复单命令缓冲区;数值 1-50 可覆盖拆分比例用于进一步调优。

DiT 激活缓冲区也遵循其实际块内生命周期:QKV 投影内存区先用于注意力头,再用于归一化 MLP 输入;当前注意力输出内存在其分支被消耗后成为 MLP 输出。这在 512 级分辨率下减少 61.25 MiB 内存,864 级分辨率下减少 99.63 MiB,且不改变调度或运算。H3_DISABLE_DIT_ACTIVATION_ALIAS=1 可恢复独立诊断缓冲区。

不可变 DiT 权重和偏置的 MPSGraph 张量数据包装器会与其常驻缓冲区一起保留,避免为每个块和去噪评估重建相同的绑定元数据,且无需复制张量存储;实测 ABBA 测试在 M3 Max 上速度提升 1.6%,M5 Max 上提升 0.4-1.1%。激活包装器保持临时状态,因为保留它们会导致 M5 平台性能倒退。输出保持字节完全一致,H3_DISABLE_GRAPH_DATA_CACHE=1 可恢复所有张量的临时包装器。

在 M3 及更早硬件上,每个 DiT 块中的四个 MPSGraph 段会为其共享的底层 Metal 命令缓冲区复用一个 MPSCommandBuffer 包装器。重复热平衡测试显示,M3 Max 上速度提升 1.0-1.6%;M5 平台测试结果无变化,因此保留全新包装器。H3_REUSE_MPS_COMMAND=01 可覆盖自动选择。结果字节完全一致。

在 M5 平台,服务端欧拉采样器将其补丁压缩的 F32 潜变量和缓存的 BF16 速度值存储在 Metal 缓冲区中。每次选中的去噪器刷新完成后才会编码下一次,避免 MPSGraph 背压,同时移除所有中间潜变量/速度值的回读和重新打包。两次热机八次运行的 A/B 测试显示,速度小幅提升 0.1% 和 0.3%,最终潜变量字节完全一致;该路径还为每个视频潜变量元素节省约 16 字节临时主机状态(768p 分辨率下约 136 MB)。M3 及更早 GPU 默认保留 CPU 采样器。H3_CPU_SAMPLER=1 可在 M5 平台恢复 CPU 采样器;H3_GPU_SAMPLER=1 显式选择 GPU 状态路径;H3_GPU_SAMPLER_WINDOW=0 启用较慢的无限制提前编码诊断模式。

发布版检查点按注意力头交错存储 DiT QKV 行。原生 Metal 在融合 QK 归一化/RoPE 内核中直接使用该布局,避免检查点转置和额外内存占用。此前的身份解读错误导致了诊断输出噪声。

公开生成路径通过流式原生 BigVGAN/AudioVAE 解码联合音频潜变量,并写入同步的 H.264 视频和 32 kHz 立体声 AAC 音频。原生波形与修正后的 MLX 基准实现相对 L2 误差为 6.94e-5

--first-frame--last-frame 及其组合使用发布版视觉 VAE 编码器、Qwen3-VL 视觉塔和三层深度栈多模态呈现、0.999 条件增强,以及原生 DiT 中的固定条件行。第一张图像会拉伸至目标画布;最后一张图像会按宽高比覆盖缩放并居中裁剪,与参考实现一致。--ref-image 选择独立的 Ref2VA 变换器,保留有序 <Picture N> 呈现,并使用发布版仅向下采样的宽高比保留参考画布。--ref-silent-video 额外执行 24 fps 有限解码、视觉 VAE 的因果 ceil(T/4) 压缩、两帧 Qwen 采样,以及带时间戳的 <Video N> 呈现。--ref-video 保留嵌入音轨,--ref-video-audio VIDEO AUDIO 提供显式替换音轨,--ref-audio 添加有序独立音频片段。参考音频解码为 32 kHz 立体声 F32,由原生 AudioVAE 后验均值路径编码,混合为 0.999 干净潜变量加 0.001 种子噪声,固定在音频条件时间步 1.0,并以 32 宽行打包在与视觉参考相同的旋转时间线上。音频输入时长为 2-15 秒,最多接受 3 个,总解码时长上限为 15 秒,且独立音频参考必须搭配图像或视频参考使用。

原生音频编码器与修正后的 MLX 基准实现匹配,在真实两秒立体声测试用例中相对 L2 误差为 3.59e-6。修正确实重要:原始 MLX 重塑会交错左右声道样本,而官方 PyTorch/SGLang 路径会将完整立体声通道折叠到批量维度中。在 128 GB M5 Max 平台,完整的图像+音频和嵌入视频+音频渲染分别耗时 74.58 秒和 76.99 秒,峰值物理内存占用约 40.1 GB,且无交换内存使用。

--profile 分别报告每个 Metal 支持阶段的信息:实际耗时、CPU 端命令编码时间、完整提交到 fence 等待时间、根命令 GPU 时间戳、峰值活跃张量存储、累计内存分配及调度次数。等待时间测量的是完整命令周转时间;仅根 GPU 时间戳可能会遗漏 MPSGraph 内部调度的子缓冲区,并会相应标注。

DiT 快速路径将每个 BF16 fc1 -> SwiGLU -> fc2 块作为一个缓存图评估,避免单独的图边界和持久中间张量。设置 H3_DISABLE_FUSED_MLP=1 可保留参考操作边界用于数值诊断。

在支持的 M5 Metal 4 TensorOps 硬件上,原生 int8 MLP 引擎为默认选项。它动态量化激活,使用每个输出通道的权重缩放因子,并为敏感的 FC2 输入每 1024 个通道分配一个缩放因子。选中的 FC2 内核将缩放部分乘积保存在私有协作片段中,而非反复溢出 32 KiB 线程组块。固定的 50 层、19 次迭代 512×512 渲染测试显示,BF16 MPS 路径耗时 36.30 秒,int8 路径耗时 25.80 秒(M5 Max 平台)。解码后的首、中、末帧保留了相同的主体、构图和运动;边缘和毛发细节可能略有差异。当前诊断实现仅在 A/B 诊断请求时同时保留 BF16 和 int8 MLP 权重。正常 int8 加载会在量化完成后释放每个块的 BF16 FC1/FC2 缓冲区,将峰值张量存储从 BF16 路径的 36.4 GiB 降至 25.9 GiB。运行时权重量化仍会增加启动时间。

最快的 M5 路径还会量化每个 DiT QKV 投影,并将 Q/K/V 块直接以头部优先的注意力布局写入,再传入现有的 Q/K 归一化和 RoPE 内核。在固定的 50 层、19 次迭代 512×512 渲染测试中,去噪时间从 25.80 秒进一步降至 19.32 秒。采样的首、中、末帧仍为连贯清晰的雪地行走狐狸;量化注意力可能改变画面构图和细节。可使用 --use-slower-bf16-qkv 切换到参考 BF16 投影。正常 int8 加载会在量化后释放冗余的 BF16 QKV 权重。

默认 M5 路径中,后续的注意力输出投影也采用 int8 量化。交叉同模型测试显示,512 和 864 分辨率下完整前向传播速度再提升 4.5-5.5%。解码后的狐狸视频保持清晰,与仅 int8-QKV 配置的构图高度匹配;热机状态下去噪耗时 19.18 秒。可使用 --use-slower-bf16-attention-output 保留 BF16 格式的该投影。

在该 int8 路径中,SDPA 现在将结果保留在原生 [head,row,dimension] 顺序中。专用 256 线程内核直接收集并量化每个 H3 行,存入投影的行优先 int8 缓冲区,消除了中间的全宽 BF16 转置,且不改变任何输出字节。热控交叉测试显示,512 和 864 分辨率下完整前向传播速度提升约 0.2-1.2%。可使用 --use-slower-row-major-attention-output 恢复显式 BF16 行优先 SDPA 输出和常规量化器。

M5 路径还将 QKV 和 MLP 激活量化融合到前置的门控 AdaLN 内核中,每 50 层前向传播减少 99 次独立量化器调度,同时保留原输出字节,交叉 512/864 测试速度提升约 0.3-0.6%。可使用 --use-slower-unfused-int8-inputs 恢复独立量化器。

融合门控 AdaLN 路径以 BF16x4 向量加载完整的 5376 宽 H3 行,并写入 int8x4。它会在计算原始每线程 RMS(均方根)序列前本地暂存舍入值,因此归约树和每个输出字节保持不变。交叉测试显示速度再提升约 0.1-0.5%。现有 --use-slower-unfused-int8-inputs 选项保留了可移植标量和独立量化器回退方案。

Q/K RMS 归一化和 RoPE 也在 int8 QKV 投影块内执行。融合尾声与原实现字节完全一致,交叉 M5 测试显示 512 分辨率下完整前向传播速度提升 2.1-3.2%,864 分辨率下提升 1.0-1.8%。可使用 --use-slower-unfused-qkv-rope 恢复独立 Q/K 内核。

该尾声每个工作项处理四个相邻 Q/K 维度,使用 BF16x4 加载和存储。逐元素运算和 BF16 舍入顺序保持不变,冷态交叉测试显示 512 和 864 分辨率下完整前向传播速度提升约 0.4-1.0%。同样,--use-slower-unfused-qkv-rope 选项可恢复标量独立路径。

对于不超过 2048 行的序列,精确 RMS 循环使用 BF16x4 加载,随后执行四次显式有序 FMA(融合乘加)。这保留了每个输出位,512 级分辨率下完整前向传播速度再提升 0.5-0.6%;更大尺寸则保留标量加载,因为两种形式性能相当。可使用 --use-slower-scalar-qkv-rms 强制使用标量加载。

int8 注意力输出投影将其 128 个行和列缩放因子缓存到 1 KiB 线程组内存中,而非为每个协作片段元素重复读取。超过 2048 行时,融合 QKV 内核采用相同思路,再将该存储区复用为逆 RMS 值;较小 QKV 尺寸保留直接加载,因为两种形式性能相当。两种实现均与原版本字节完全一致,在选中场景下完整前向传播速度提升约 0.2-0.7%。可使用 --use-slower-uncached-int8-scales 恢复直接设备缩放因子加载。

对于不超过 2048 行的序列,H3 注意力输出投影还会将其 7168×5376 形状编译到 TensorOps 内核中。结果与原版本字节完全一致,交叉完整 512 前向传播测试显示速度提升约 0.2-0.8%。更大序列保留动态形状内核,因为特化会导致性能倒退。--use-slower-uncached-int8-scales 可恢复通用动态直接缩放因子加载实现。

FC1 也使用 H3 专用的编译时 5376 宽 TensorOps 循环,与通用循环字节完全一致,交叉完整前向传播测试显示速度提升约 0.1-0.4%。可使用 --use-slower-dynamic-fc1-k 恢复运行时绑定循环。

./h3 --profile -d ./MiniMax-H3 \
-p "A red fox walks through fresh snow." \
--width 512 --height 512 --frames 22 --steps 20 \
--layers 50 --reuse 1 -o outputs/fox-int8.mp4

可使用 --use-slower-bf16-mlp 强制使用可移植参考 MPS/BF16 MLP 路径用于数值对比。当所需原生 TensorOps 内核不可用时,旧版 Metal 硬件会自动选择该路径。

对于 FC2 激活量化,不超过 2048 行的序列使用精确的 128 线程归约。每个线程在计算组最大值时保留其八个 BF16 输入值,输出 int8 值时避免第二次设备内存读取;交叉 M5 测试显示 512 分辨率下完整前向传播速度提升约 0.2-0.8%,且不改变任何输出字节。更大序列保留实测的 256 线程内核。--use-slower-grouped-quantizer 可强制在所有尺寸下使用后者用于 A/B 对比。

原生基线针对原始 FL2VA/Ref2VA/ 检查点树设计。模型各阶段分别加载和释放,33B 变换器、Qwen 编码器和解码器无需同时驻留在统一内存中。