MiniMax-H3 自托管 vs fal H3 Max

速度、成本、画质的并排对照。每个数字都标了来源等级——这个项目最贵的几次错误都是把建模常数当成实测值读,所以哪些是量出来的、哪些是算出来的,写在数字旁边。

measured 我们跑出来的   vendor 厂商自己的仪表返回的   published 他人发表并引用   derived 在实测输入上做的算术   estimate 判断,已标注
fal H3 Max 实测推理
2.89s
vendor 他们的仪表,n=8,5 秒 768p
我们 8×B200 · 同分辨率同步数
2.87s
measured sglang 0.5.18,4 次去噪
速度比
1.01×
derived 基本打平
每片成本比
10.1×
derived $0.0399 对 $0.4033
结论:同配置下速度打平,成本便宜一个数量级。 8×B200 上 1344×768、4 次去噪,服务端 2.87 秒,对 fal 自报的 2.89 秒。降到 896×512 是 1.43 秒,比 fal 快 2.02 倍——但那是更低的分辨率,不是同一件产品。
一个被证伪的宣传数字。 fal 的模型页写 timings.inference2.5 秒。我们用自己的 prompt 调他们的 API,他们自己的仪表返回的是 2.823–3.05 秒,均值 2.89 秒(n=8),比宣传慢 16%。
以及一个我们自己错了三次的数字。 早前版本反复写「文本编码缓存污染了测量,直播每片要多付 4.64 秒」。用四个完全不同的场景 prompt 重测后:第一个请求 6.07 秒,之后每个不同 prompt 都只要 0.065 秒。那 6 秒是编码路径的首次 JIT,每个容器付一次,不是每个 prompt 付一次。所以我们的数字本来就和 fal 可比,不该打折——这个更正的方向对我们有利,而它之所以被发现,是因为把「加后缀」换成了真正不同的文本。

1 · 这些数字分别在什么配置上测的

这一节存在,是因为这份报告是在三次换框架之后长出来的:先把所有东西在 1 卡上测完,然后发现1 卡会系统性地错估每一个杠杆而改到 8 卡,再然后发现 sglang 0.5.18 把启动和单片都砍了一半。三种配置的数字曾经混在一页上、无法分辨来源。下表把每个结论钉回它的配置。

测的是什么GPUsglang画布有片段结果
对 fal 的速度对照8× B2000.5.181344×7682.87 s,对 fal 2.89 s
低分辨率速度8× B2000.5.18 + 补丁896×5121.43 s,比 fal 快 2.02×
步数 4 vs 88× B2000.5.18两种画布768p 2.87 / 4.36 s
版本 0.5.17 vs 0.5.188× B200 与 1× B200两者1344×768部分8 卡 1.66×,1 卡无效
冷启动8× B200两者不适用508.5 → 242.5 s
分阶段拆解1× B200 与 8× B200两者1344×768不适用解码在 8 卡 0.5.18 上分片了
GPU 数对画面的影响1× 与 8× B2000.5.171344×768编码大小差 0.07–2.1%
LoRA:现役 vs lightx2v1× B2000.5.171344×768仅画质轴,速度无关
flow_shift 三档1× B2000.5.171344×768仅画质轴
ref2va 人物参考1× B2000.5.171344×768355.7 → 25.7 s/片
首帧条件(fl2va)1× B2000.5.171344×7681.147×,n=1
时长 4s vs 15s1× B2000.5.171344×768duration^1.59
fal 对照臂fal 自有硬件不适用768p2.890 s,n=8
怎么读这张表。 绿底行是「8 卡 + 0.5.18」——也就是头条数字所在的配置。其余行要么是画质轴(在 1 卡上判断画质是合理的,因为 1 卡和 8 卡的画面只差 0.07–2.1%),要么是已经被更好的测量取代的历史数据。凡是标着 1× B200 的速度结论,都不要外推到 8 卡——第 5 节说明为什么。

2 · 画面对照

同一个 prompt、同一个种子、同一张首帧。每一行是一个场景,每一列是一条臂。ref2va 的对手不是 H3 Max —— 查 fal 自己的模型库 API 确认:minimax/h3/reference-to-video 存在,但 H3 Max 只有 text-to-video 和 image-to-video 两个端点。所以那一格要和 fal 的基座 H3 比,而那反而是这份报告里唯一一个双方模型完全相同的比较 —— 差的纯粹是工程。

输入素材

ambience
a still frame where the SOUND carries the clip — H3's joint audio is the point
camera
a sustained camera move — temporal coherence
host
a recurring virtual presenter — identity consistency is what a hosted channel lives on
motion
fast multi-subject motion — reportedly the first thing few-step distillation smears
refsubject
ref2va 的身份参考
refsubject2
ref2va 的身份参考

2.1 头对头:配置对齐的对照

只有这张表里的臂是可比的 —— 同 prompt、同种子、同输出规格(ffprobe 核实:两边都是 1344×768 / 24fps / 124 帧 / AAC 立体声 32kHz)。我们这边是 8×B200 · sglang 0.5.18,也就是速度表里那个 2.87 秒的配置。

场景 fal-t2vfal H3 Max 文生视频 —— 他们的后训练模型、他们的硬件、1344×768 win768-evals4★ 头条配置 · 文生视频:8×B200 · sglang 0.5.18 · 1344×768 · 4 次去噪 · 服务端 2.87s fal-i2vfal H3 Max 图生视频 —— 与我们 fl2va 各臂同一张首帧 win768-fl2va-evals4★ 头条配置 · 图生视频:同上,加首帧条件 —— 对齐 fal 的 i2v win512-evals4★ 低分辨率:8×B200 · 0.5.18 + 短边补丁 · 896×512 · 4 次去噪 · 服务端 1.43s
ambiencea still frame where the SOUND carries the clip — H3's joint audio is the point
cameraa sustained camera move — temporal coherence
hosta recurring virtual presenter — identity consistency is what a hosted channel lives on
motionfast multi-subject motion — reportedly the first thing few-step distillation smears

2.2 人物参考 —— 同一套开源权重,两种采样档

两边都是 MiniMax 的开源基座权重(H3 Max 没有 reference-to-video 端点,查 fal 模型库 API 确认)。输出规格相同(1344×768 / 124 帧)。但采样档几乎肯定不同:我们跑 4 次去噪加 turbo LoRA,服务端 4.93 秒;fal 墙钟 140–194 秒,且其基座端点不返回 timings,所以只有墙钟可比。这不是纯工程对照,而是同一套权重下「4.93 秒」对「约 3 分钟」买到了什么

场景 fal-base-r2vfal 的<b>基座</b> H3 参考生视频(H3 Max 没有这个端点)。同样输出 1344×768/124帧,但墙钟 140–194 秒 —— 大概率跑的是官方完整采样档,不是我们的 4 次去噪 win768-ref2va我们的人物参考:8×B200 · 0.5.18 · ref2v turbo LoRA · 4 次去噪 · 服务端 4.93s ref2va人物参考 —— 同一角色进不同场景。对手是 fal 的<b>基座</b> H3 r2v,不是 H3 Max(Max 没有这个端点)
ambiencea still frame where the SOUND carries the clip — H3's joint audio is the point 25.65s 端到端
cameraa sustained camera move — temporal coherence 25.66s 端到端
hosta recurring virtual presenter — identity consistency is what a hosted channel lives on 25.79s 端到端
motionfast multi-subject motion — reportedly the first thing few-step distillation smears 25.64s 端到端

2.2 画质轴 —— 全部在 1×B200 · sglang 0.5.17 上渲染

这些臂只改一个变量,用来判断画质。不要拿它们的耗时和上表比 —— 配置不同。在 1 卡上判断画质是合理的:同请求在 1 卡和 8 卡之间画面只差 0.07–2.1%(浮点归约顺序)。

场景 basewhat we ship: larryvrh v4_step600_ema, 8 denoiser evaluations, default flow shifts evals4same, 4 evaluations — the speed knob shift12-34 evaluations with SGLang's benchmark shifts (video 12.0 / audio 3.0) shift6-34 evaluations with LightX2V's 4-step shifts (video 6.0 / audio 3.0) lightx2v-t2vaa different distillation: 208 modules, no AdaLN coverage, 4 evaluations fl2vafirst frame conditioned; the counterpart to fal's image-to-video fl2va-evals4first frame conditioned at 4 evaluations lightx2v-fl2vasame distillation, first frame conditioned ref2va人物参考 —— 同一角色进不同场景。对手是 fal 的<b>基座</b> H3 r2v,不是 H3 Max(Max 没有这个端点)
ambiencea still frame where the SOUND carries the clip — H3's joint audio is the point 8.09s 端到端 6.63s 端到端 15.59s 端到端 15.60s 端到端 17.82s 端到端 29.18s 端到端 17.10s 端到端 18.33s 端到端 25.65s 端到端
cameraa sustained camera move — temporal coherence 7.58s 端到端 5.62s 端到端 15.59s 端到端 15.60s 端到端 17.30s 端到端 29.19s 端到端 17.10s 端到端 18.33s 端到端 25.66s 端到端
hosta recurring virtual presenter — identity consistency is what a hosted channel lives on 68.28s 端到端 26.51s 端到端 15.58s 端到端 15.60s 端到端 45.22s 端到端 29.20s 端到端 17.10s 端到端 18.93s 端到端 25.79s 端到端
motionfast multi-subject motion — reportedly the first thing few-step distillation smears 7.60s 端到端 5.61s 端到端 15.59s 端到端 15.60s 端到端 17.31s 端到端 29.16s 端到端 17.10s 端到端 18.34s 端到端 25.64s 端到端

2.3 GPU 数是否改变画面 —— 同请求同种子,只改卡数

左边 1 卡、右边 8 卡,两者都是 sglang 0.5.17。用来检验「画面不随 GPU 数改变」这句断言。

场景 basewhat we ship: larryvrh v4_step600_ema, 8 denoiser evaluations, default flow shifts 8gpu-base与 base 完全相同的请求,只是渲染在 8×B200 上(sglang 0.5.17) evals4same, 4 evaluations — the speed knob 8gpu-evals4与 evals4 完全相同的请求,8×B200,sglang 0.5.17
ambiencea still frame where the SOUND carries the clip — H3's joint audio is the point 8.09s 端到端 6.63s 端到端
cameraa sustained camera move — temporal coherence 7.58s 端到端 5.62s 端到端
hosta recurring virtual presenter — identity consistency is what a hosted channel lives on 68.28s 端到端 26.51s 端到端
motionfast multi-subject motion — reportedly the first thing few-step distillation smears 7.60s 端到端 5.61s 端到端

2.1 逐片对照:我们 vs fal

同场景同 prompt 同种子。fal 的列是他们自己的仪表返回的 timings.inference;我们的列是围绕同一个请求的秒表。两者口径不同,所以分开列而不是硬凑成一个比值——fal 的端到端还要加上排队和传输,我们的还要减去 HTTP 轮询。

场景模式去噪次数耗时口径
ambiencebaset2va88.09smeasured 我们 1×B200 端到端
ambienceevals4t2va46.63smeasured 我们 1×B200 端到端
ambiencefl2vafl2va829.18smeasured 我们 1×B200 端到端
ambiencefl2va-evals4fl2va417.10smeasured 我们 1×B200 端到端
ambienceshift12-3t2va415.59smeasured 我们 1×B200 端到端
ambienceshift6-3t2va415.60smeasured 我们 1×B200 端到端
ambiencelightx2v-t2vat2va417.82smeasured 我们 1×B200 端到端
ambiencelightx2v-fl2vafl2va418.33smeasured 我们 1×B200 端到端
ambienceref2varef2va425.65smeasured 我们 1×B200 端到端
camerabaset2va87.58smeasured 我们 1×B200 端到端
cameraevals4t2va45.62smeasured 我们 1×B200 端到端
camerafl2vafl2va829.19smeasured 我们 1×B200 端到端
camerafl2va-evals4fl2va417.10smeasured 我们 1×B200 端到端
camerashift12-3t2va415.59smeasured 我们 1×B200 端到端
camerashift6-3t2va415.60smeasured 我们 1×B200 端到端
cameralightx2v-t2vat2va417.30smeasured 我们 1×B200 端到端
cameralightx2v-fl2vafl2va418.33smeasured 我们 1×B200 端到端
cameraref2varef2va425.66smeasured 我们 1×B200 端到端
hostbaset2va868.28smeasured 我们 1×B200 端到端
hostevals4t2va426.51smeasured 我们 1×B200 端到端
hostfl2vafl2va829.20smeasured 我们 1×B200 端到端
hostfl2va-evals4fl2va417.10smeasured 我们 1×B200 端到端
hostshift12-3t2va415.58smeasured 我们 1×B200 端到端
hostshift6-3t2va415.60smeasured 我们 1×B200 端到端
hostlightx2v-t2vat2va445.22smeasured 我们 1×B200 端到端
hostlightx2v-fl2vafl2va418.93smeasured 我们 1×B200 端到端
hostref2varef2va425.79smeasured 我们 1×B200 端到端
motionbaset2va87.60smeasured 我们 1×B200 端到端
motionevals4t2va45.61smeasured 我们 1×B200 端到端
motionfl2vafl2va829.16smeasured 我们 1×B200 端到端
motionfl2va-evals4fl2va417.10smeasured 我们 1×B200 端到端
motionshift12-3t2va415.59smeasured 我们 1×B200 端到端
motionshift6-3t2va415.60smeasured 我们 1×B200 端到端
motionlightx2v-t2vat2va417.31smeasured 我们 1×B200 端到端
motionlightx2v-fl2vafl2va418.34smeasured 我们 1×B200 端到端
motionref2varef2va425.64smeasured 我们 1×B200 端到端
为什么我们的逐片数字比 8 卡那个 4.77 秒大。 这张表的片段是在 1×B200 上渲染的,因为它回答的是「长什么样」,而画面不随 GPU 数改变——Ulysses 分的是同一份算术。速度结论来自 8 卡那次测量,渲染网格在单卡上做便宜六分之一。
这些逐片耗时低估了真实直播,不要直接拿去算成本。 六条臂复用同样四个场景 prompt,所以除了每个场景第一次出现之外,MiniMaxH3TextEncodingStage 全是缓存命中——实测新 prompt 要 4.64s,缓存命中只要 0.05s。表里多数格子是 15.6s 左右,而同配置新 prompt 的实测是 19.94s。直播每个片段的 prompt 都不同,所以成本要按后者算。这一条是我们自己第一版基准里的缺陷,发现后才补上的。

3 · 速度

3.1 sglang 0.5.18:全部收益都是多卡的

把 pin 从 0.5.17 抬到 0.5.18,8 卡上快了 1.66 倍、冷启动快了 2.1 倍。但 1 卡上没有任何收益——而那个「没有收益」正是解释机制的对照组。

阶段0.5.170.5.18读法
VAE 解码 · 1 卡3.46s3.09s基本没变 — 1 卡没有东西可分
VAE 解码 · 8 卡~3.5s(推断)0.275s解码开始分片了 — 这就是全部收益的来源
整片服务端 · 1 卡15.08s15.88s略慢,在噪声内
整片服务端 · 8 卡(768p,4 次)4.77s2.87s1.66×
8 卡冷启动508.5s242.5s2.1×
为什么这个 1 卡对照重要。 没有它,「0.5.18 更快」只是一个观察。有了它,机制就可判定:1 卡解码没变、8 卡解码从约 3.5 秒降到 0.275 秒,而去噪在两个版本上都没动(1.23 → 1.19)。0.5.18 让 VAE 解码用上了多卡——这恰好修复了我们在 0.5.17 上实测到的「解码完全不随 Ulysses 分片」。代码层面我们没有找到对应提交(0.5.17→0.5.18 的 250 个提交里没有 VAE 文件改动),所以这是测量强烈支持的机制,不是已确认的代码变更
一条未控制的变量。 0.5.18 的镜像没有挂 kernel-cache Volume(装 0.5.18 那层会往该路径写字节码,导致挂载被拒)。缺少 kernel 缓存只会让它更慢,所以上面的收益是下界;但它仍然是个没控制住的差异,写在这里而不是抹掉。

3.2 同一个请求,1 卡 vs 8 卡

这一节存在,是因为报告早期版本里有一句未经验证的断言:「画面不随 GPU 数改变,Ulysses 分的是同一份算术」。它被用来正当化「速度数字取自 8 卡、画面取自 1 卡」。Ulysses 的 all-to-all 改变了 attention 内部的浮点归约顺序,所以逐位相同本来就不该期待。下面是同请求、同种子、只改 GPU 数的实测。

片段1 卡字节8 卡字节
base.host469,505463,265-1.33%
base.motion1,190,2871,178,260-1.01%
base.ambience459,804452,238-1.65%
base.camera1,202,1601,220,459+1.52%
evals4.host411,760410,449-0.32%
evals4.motion1,107,8031,095,019-1.15%
evals4.ambience356,517349,028-2.10%
evals4.camera1,123,7591,124,511+0.07%
所以那句断言严格说是假的。 输出不是逐位相同,差异 0.07%–2.1%、有正有负——这是舍入的特征,不是「生成了不同的东西」的特征。但文件大小不是感知指标,所以两份渲染都放在上面的网格里(base8gpu-base),由人眼判断,而不是由我替你断言。

速度:并行效率

1 卡8 卡加速并行效率
evals4(4 次去噪)15.59s5.83s2.67×33%
base(8 次去噪)26.64s7.76s3.43×43%
并行效率只有 33–43%,而不是社区常引的 65%。原因就是下一节:去噪被 Ulysses 切得很好,但文本编码和 VAE 解码完全不分片,而在少步配置下它们才是大头。步数越少,加卡越不划算——4 次去噪时效率 33%,8 次时 43%。

3.5 多镜头故事:一次生成里的四个镜头、两个角色

H3 的镜头语法是 MiniMax 官方文档的,不是社区约定。base guide 4.2:“Do not add a timestamp to the first shot. Use sequential shot numbers for later shots, and begin each one with a strictly increasing cut time that falls within the video duration”,ref guide 5.1 把格式钉成 [Shot N] At MM:SS.mmm,。下面这个 prompt 用了四个镜头,切点 00:04.000 / 00:08.000 / 00:11.500,两个角色各自绑定自己的参考图,同一个 prompt 跑三个时长。ffprobe 核实全部是 1344×768 / 24fps / AAC 立体声 32kHz。

时长片段服务端计算/视频秒$/视频秒
10s12.24s1.224$0.0170
15s18.02s1.201$0.0167
5s7.26s1.452$0.0202
该看什么,按最可能失败的顺序。 (1) 三处切镜有没有真的发生,还是镜头只是在飘;(2) 切过之后两个角色还是不是原来那两个;(3) 两人的特征有没有互相污染;(4) 音频跟不跟着切 —— 这条仍未验证。「片内切镜共享一条连续音轨」的社区说法没有通过对抗核查,所以听的时候要特别留意。
时长的方向按任务分叉,而且和我们先前写的相反。 在 1 卡 · 0.5.17 上量到的是 duration^1.59,即长片段每秒更贵。在 8 卡 · 0.5.18 上:t2va 是 duration^1.207(长片段每秒贵 26%),而 ref2va 是 duration^0.828(长片段每秒便宜 17%)。原因:attention 对序列长度是二次的,而 Ulysses 切的正是序列维,二次项被摊掉;ref2va 还额外有编码参考图的固定成本,片段越长摊得越薄。所以有固定角色的频道应该用 15 秒多镜头长片段 —— 切镜在片段内免费,没有接缝,而且每秒更便宜。

3.3 时间花在哪

SGLang 默认只打印九个 pipeline 阶段里的两个,所以最初的 8 卡测量留下 3.5 秒「测到了但没归属」。把日志级别打开之后:

文本编码 4.64s
去噪 7.10s
VAE 解码 3.46s
阶段1× B2008× B200被 Ulysses 分片?来源
文本编码(新 prompt)4.64s部分折叠部分measured
文本编码(prompt 重复)0.05s缓存命中,不代表直播measured
去噪7.10s1.23s是,很好measured
VAE 解码3.46s≈3.5s完全不能measured
瓶颈换人了。 去噪在 8 卡上是 1.23 秒,只占 26%。剩下的是文本编码加 VAE 解码,两者都不随 Ulysses 分片。再加卡、再减步数都动不了它们。

3.4 汇总

配置5 秒 768p 耗时实时倍数来源
我们 1× B200,4 次去噪,新 prompt19.94s0.25×measured
我们 8× B200 Ulysses8,4 次去噪4.77s1.06×measured
我们 8× B200,8 次去噪6.19s0.81×measured
fal H3 Max(他们的仪表)2.89s1.74×vendor
fal 宣传值2.50s2.02×published

4 · 成本

配置GPU-秒/片$/片比 fal 便宜
我们 1× B200(新 prompt)19.9$0.034611.6×
我们 8× B20038.2$0.06626.1×
fal H3 Max$0.40321.0×

全成本口径

上表只算 GPU 那一行。这几项核对过 Modal 的定价页,并用我们自己的账单账本交叉验证:

影响说明来源
CPU + 内存+1.81%GPU 之外单独计费。实测取自本月我们自己 B200 运行的账单行,区间 0.65%–3.19%。单片 $0.0346 → $0.0353,对 fal 的优势 11.65× → 11.44×measured
非抢占式执行 ×3不存在这一行是我们写错的,已实测更正。Modal 的 nonpreemptible=True 对 GPU 函数直接拒绝:Non-preemptible is not supported for GPU workloads。三路对照(仅 deploy,0 GPU-秒)确认:带 GPU 被拒、纯 CPU 接受并警告 3× 计费、纯 GPU 无该参数接受。所以 3× 只适用于 CPU 和内存,GPU 直播花再多钱也买不到不被抢占——只能靠架构冗余measured
指定区域×1.5–1.75与上一项不叠加时的另一档published
Volume 存储$0.09/GiB/月1 TiB 免费额度以上。本工作区本月实付 $200.72published
8 卡冷启动$7.03/次8 × 506.2 秒 × 费率,约等于 17 个 fal 片段的钱derived
八卡是更贵的那条臂,不是更便宜的。 因为按每张卡计费,8×B200 跑一个片段是 $0.0844,只比 fal 便宜 4.78×,而单卡是 11.4×。它用 2.4 倍的钱买 3.3 倍的延迟——这是个取舍,不是免费加速。要持续直播就用单卡横向扩;要「观众发一句话、几秒后上屏」才值得上八卡。
最要紧的一条,和钱无关。 $0.08 买的是 fal 后训练过的 H3 Max——他们加了自有数据并做了 RL。我们服务的是基座 MiniMax-H3。推理优化补不上训练差距,所以这张成本表比的是「他们的模型 + 他们的工程」对「同一个开源底座 + 我们的工程」,不是同一件商品的两个报价。上面的画面对照就是让你自己判断这个差距有多大。

5 · ref2video 持续直播:能不能实时,要几张卡

直播的门槛不是延迟,是 RTF(real time factor)= 片长 ÷ 生成耗时。RTF 必须 > 1.0,否则缓冲会被慢慢耗干,一小时后就断流。本节的每个数字都是 ref2va + 两张人物参考图 + 15 秒片段,也就是要上线的那个形态。

5.1 起点:全部卡数都不实时

卡数512 / 15sRTF512 / 5sRTF768 / 15sRTF
226.4s0.5713.6s0.3763.9s0.235
418.1s0.8310.3s0.48536.3s0.413
89.26s1.6218.51s0.81
768p 的 ref2video,连 8 卡都不实时(0.81×)。 而且 RTF 随片长上升(0.37 → 0.52 → 0.57),因为 ref2va 有一笔与时长无关的固定开销——所以 ref2video 直播要用长片段(15 秒),不是短片段。这跟 t2va 正好相反。

5.2 拆解:ref2video 为什么比 t2v 慢 3.1 倍

同一台 4 卡机器、同一次测量、768p / 5 秒:

阶段t2varef2video倍数
文本编码0.064s2.027s31.6×
视觉编码0.000s0.745s新增
denoise2.293s6.047s2.64×
VAE decode0.815s0.887s1.09×
wall4.71s14.60s3.10×

5.3 消融:唯一有用的是参考图「张数」,不是尺寸,也不是 prompt 长度

4 卡 · 512 · 15 秒,每档 3 次,每个 arm 只改一个变量:

arm改动wallRTFvs baseline
baseline2 张原图 + 439 词16.11s0.93 ✗
one_ref只用 1 张参考图11.58s1.295 ✓−28%
small_refs2 张缩到短边 44815.97s0.939 ✗−0.9%
short_txtprompt 缩到 ~80 词16.00s0.937 ✗−0.7%
缩图完全无效,而这条否定结果才是线索。 源码给出的原因是 MINIMAX_H3_REFERENCE_IMAGE_SHORT_EDGE = 2048:每张参考图都被强制上采样到 2048 短边,与目标画布无关、与原图大小无关。1024×576 和 796×448 都解析到同一张 3648×2048 画布,所以两个 arm 在跑同一件事。

5.4 突破:把那个 2048 常量改掉

每张参考图进 DiT 两次——7,296 个 VAE latent row,加上 7,296 个 <|image_pad|> vision token 拼进 prompt,共 14,592 token。对照目标序列(896×512 / 15 秒 = 47,936 video row + 1,200 audio row),一张参考图就占序列的 22.7%。而我们喂的是 576 高的图,被上采样出来的像素原图里根本不存在

阶段(4 卡 · 512 · 15s · 双角色)参考图短边 2048参考图短边 576变化
文本编码1.692s0.106s−94%
视觉编码0.724s0.057s−92%
denoise8.129s3.841s−53%
VAE decode1.452s1.406s
wall15.98s7.59s−53%
RTF0.939 ✗1.98 ✓2.1×
双角色在 4 卡上从「不实时」变成「2 倍实时余量」,每张参考图的 token 从 14,592 降到 1,152(12.7 倍)。那省下的 6.54 秒(占原来的 41%),原本纯粹是在给上采样出来的假像素做 attention。

5.5 优化阶梯:每个配置的完整参数、时间与成本

全部为 ref2video · 两个人物参考图 · 15 秒片段 · 896×512 画布 · 同一 DRAMA prompt。「工作成本」是产出一小时视频消耗的 GPU 秒折算;「常驻成本」是容器不间断运行一小时的账单——RTF 超过 1 的部分是空转,照样计费。

卡数参考图短边去噪步数AdaLN其他wallRTFGPU-s/视频秒工作成本 $/hr常驻 $/hr备注
22048426.40s0.57 ✗3.52$22.0$12.5stock
25764on16.20s0.93 ✗2.16$13.5$12.5
25763on11.95s1.26 ✓1.59$10.0$12.5
25763onon11.28s1.33 ✓1.50$9.4$12.5cache-dit 的 5.5% 未达显著
42048415.98s0.94 ✗4.26$26.6$25.0stock
420484on15.40s0.97 ✗4.11$25.7$25.0
457647.59s1.98 ✓2.02$12.6$25.0
8204849.26s1.62 ✓4.94$30.9$50.0stock
25764fp814.10s1.06 ✓1.88$11.7$12.5fp8 量化,画质无可见损失
45764fp87.38s2.03 ✓1.97$12.3$25.0fp8,余量 103%
绿底行是每视频秒最便宜且仍然实时的配置。 注意最便宜的不是最快的——4 卡 7.59 秒是延迟最低的,但它把 RTF 拉到 1.98,意味着容器有一半时间在空转并计费。直播只需要 RTF > 1,超出的部分是买了用不上的延迟。
两条尚未证实的,不要当结论用。 (1) Cache-DiT 的 5.5% 是跨容器比较,而同配置的容器间波动实测约 11%,所以它落在噪声里。(2) 3 步去噪超出了 turbo LoRA 的蒸馏区间(4–8 步),画质必须看片子判断,速度数字不能替代。

5.6 几张卡:2 卡在 4 步下差最后 7%

配置(双角色 · 512 · 15s · 全优化)wallRTFGPU-s / 视频秒
2 卡 · 优化前26.4s0.57 ✗3.51
2 卡 · 全优化16.2s0.93 ✗2.16
4 卡 · 全优化7.59s1.98 ✓2.02
8 卡 · 优化前9.26s1.62 ✓4.94
建议:4 卡 · 512 · 15 秒段 · --minimax-h3-adaln-online · 参考图短边 576。 RTF 1.98,双角色,2.02 GPU-s/视频秒——比最初的 8 卡方案便宜 2.4 倍,而且余量足够一个容器跑两条流。2 卡差 7%,而 2×2 卡并不比 1×4 卡便宜,所以没有理由选它。

5.6 画质 2×2:参考图分辨率 × 去噪步数

同一 2 卡容器、同一 seed(20260830)、同一 prompt、同一画布,只有两个变量在动。左列是 sglang 原生的 2048 参考图,右列是 patch 后的 576;上排 4 步去噪,下排 3 步。右下角就是最便宜的那个配置——它比左上角快 2.5 倍、便宜一半,代价就在这四格的对比里。

参考图 2048(原生)参考图 576(patch)
4 步去噪
baseline.refedge2048.512.15s.g2.e4.adaln.mp4
baseline.refedge576.512.15s.g4.e4.fp8.mp4
3 步去噪 · 超出蒸馏区间
baseline.refedge2048.512.15s.g2.e3.adaln.mp4
baseline.refedge576.512.15s.g2.e3.adaln.mp4 ★ 候选配置
抽帧看过之后的判断。 身份在四格里全部保留——男角色的圆框眼镜、黑色卷发、芥末黄针织衫,女角色的赤褐色中长发、墨绿夹克、白 T。所以把参考图从 2048 降到 576 不会让人物崩,那条 2.1 倍的成本优化在身份上是安全的。(疤和雀斑在这个尺寸下看不出来,未验证。)
但风格轴上的排序,基准本身是矛盾的。 DRAMA 的 prompt 写的是 Live-action, cinematic, handheld documentary style,而参考图本身是扁平 2D 卡通插画——生成它的 prompt 里写了 photorealistic,拿回来的却是卡通。四条片子都只是落在这条冲突线上的不同位置,更卡通的 3 步反而更接近参考图。所以「越写实越好」是错的判据。要真正的写实输出,得先换写实的参考图——那是比这里任何一个轴都大的杠杆。

5.7 其余片段

这些是早期的运行,文件名不带参数轴。 当时所有 576 的渲染共用同一个文件名并互相覆盖,所以它们无法归属到具体配置——保留是为了完整,判断请看上面那个 2×2。
双角色 · 参考图短边 2048(原生管线)
baseline.refedge2048.512.15s.mp4
双角色 · 参考图短边 576(patch 后)
baseline.refedge576.512.15s.mp4
单角色 · 参考图短边 576(patch 后)
one_ref.refedge576.512.15s.mp4

6 · 已经排除的路,和我们自己错了什么

负面结果和正面结果一样值钱,而且更容易被重复踩。

结论依据来源
并发买不到任何东西,开 batching 反而更糟sglang 串行服务 H3:K=1,2,4,8 的吞吐是 0.324 / 0.337 / 0.346 / 0.348 clips/s,持平。把 --batching-max-size 提到 4 之后吞吐掉 41%、K=1 延迟涨 87%、启动涨 64%——dynamic admission 每个请求加约 2.2 s,而且完全不与 mp4 muxing 重叠。measured
B200 没有编码引擎,NVENC 这条路物理上不存在ffmpeg 列出 h264_nvenc 且 libnvidia-encode.so.1 在,但真实编码失败:OpenEncodeSessionEx failed: unsupported device。和 A100 一样。measured
mp4 的尾巴不是编码器的问题,调 x264 preset 无效ultrafast+zerolatency 让尾巴慢 70%(zerolatency 是延迟调优,砍掉帧级并行),单独 ultrafast 也没有改善。瓶颈是 Python 逐帧喂管道,不是压缩。measured
torch.compile 直接超过 15 分钟启动超时TORCHINDUCTOR_CACHE_DIR 指向容器文件系统,每个冷容器从零编译 33B DiT。只有把这个缓存持久化到 Volume 之后才可能可用。measured
H3 → LTX-2.5 级联在 sglang 里做不出来请求 schema 里没有 v2v / strength 参数,ModelTaskType 连 V2V 都没有;video_path 对 LTX 是死字段;LTX2RefinementStage 存在但从请求无法触达。而且我们下载的 Lightricks/LTX-2.5 是裸 safetensors,sglang 只认 -Diffusers 布局。measured
缩小参考图文件没用,因为 H3 会把它强制放大MINIMAX_H3_REFERENCE_IMAGE_SHORT_EDGE = 2048,上采样、无面积上限。1024×576 和 796×448 解析到同一张 3648×2048 画布,所以两个 arm 在跑同一件事。真正的杠杆是改那个常量,不是改输入文件。measured
AdaLN 缓存和 Cache-DiT 在少步数下都测不出收益--minimax-h3-adaln-online:10.67 vs 10.74 s,五次重复,差 0.65%。Cache-DiT 测到 5.5%,但那是跨容器比较而容器波动约 11%,落在噪声里。两者的原理都是跨步复用,而我们只有 3–4 步可跳。measured
--direct-gpu-weight-loading 没有可测量的收益131.4 s,对比同配置的 133.3 / 136.3 s。flag 确实生效(RunAI streamer 的日志消失),时间没动。measured
Modal 上买不到非抢占式 GPUGPU function 不支持该选项,任何价格都不行。published

6.1 被推翻的自有假设

都是这个仓库自己写下过、后来被实测证伪的。列出来是因为下游的成本模型还引用着它们。

原假设断言值实测值影响
固定开销2.65s3.844s来自 4×H200 分片运行;单卡不分片,所有 4 步预测偏乐观
首帧条件倍数2.711×1.147× / fal 自己 1.034×决定 1× 实时要 4 张卡还是 14 张卡
时长成本线性线性duration^1.59「用长片段减少接缝」反而贵 38%

7 · 没测什么

一份只列出「发现了什么」的报告,读起来会比它实际的完整度更完整。这里是明确的空白。

缺口影响说明
风格判据的基准是坏的估计参考图本身是扁平 2D 卡通插画——生成它的 prompt 写了 photorealistic,拿回来的是卡通——而 DRAMA 的 prompt 写的是 Live-action。两者冲突,所有输出都落在这条冲突线上,所以「哪个更写实」不是有效判据。换写实参考图是比本报告任何一个轴都大的杠杆,且未做。
从未生成过一个真实的直播片段估计所有数字都来自对空闲服务器的单次请求。缓冲、推流、段间衔接、抢占恢复,一行都没写。web/ 的房间能构建、能服务端渲染、类型检查干净,但从未真正生成过一段视频。
画质只看了抽帧,没看动态推导身份一致性和量化伪影是按 t=2s / t=8s 两帧判断的,结论是身份在所有配置下保留、fp8 无可见损失。运动连贯性、音画同步、口型,两帧答不了。
冷启动的 78% 没有插桩推导sglang 记录的模型加载只占启动的 22%,其余在第一条日志之前或最后一个标记之后。同配置启动实测 120–295 s,波动就住在这段里,所以任何 n=1 的 flag 对比都是在读噪声。
其中最要紧的一条:作者看不了视频。 这份报告能保证同 prompt、同种子、同输出规格(已用 ffprobe 逐个核对:两边都是 1344×768 / 24fps / 124 帧 / AAC 立体声 32kHz),但「哪个更好看」只能你自己点开判断。任何我给出的画质结论都会是编的。

8 · 方法与复现

全部可复现,命令在仓库里:

modal run -m src.lab::bench8 --steps 5,9 --durations 5 — 8 卡延迟
modal run -m src.lab::bench --steps 5 --log-level debug — 分阶段拆解
modal run -m src.samples::fal_reference — fal 对照臂
modal run -m src.samples::our_matrix --variant current — 画面矩阵

每条臂同 prompt 同种子(20260829)。步数字段数的是含末尾零的 sigma 网格点,所以字段 5 = 4 次去噪求值,字段 9 = 8 次——这一点由进度条 0/48/8 直接确认。

共 81 段视频 · 6 张输入素材 · 实测于 2026-08-29 / 08-30 · MiniMax-H3 在 Modal B200 上,SGLang diffusion 后端