起因是代码注释里一句「权重常驻比 group-offload 快约 5 倍」。实测把它证伪了,而且顺带发现改动前的生产模式才是最慢的那个。
唯一变量是权重放置。三种模式的量化、编译、attention 后端、H3_MEMOPT=1、--denoise-evict-vae、--vae-fp16 全部相同。
| 分辨率 | 模式 | 端到端 | 去噪每步(稳态) | 峰值显存 | vs 三相 |
|---|---|---|---|---|---|
| 768×1376 16:9 |
三相 | 137.6s | 20.9s | 26.8 GiB | — |
| 真常驻 | 105.0s | 21.0s | 29.8 GiB | −23.7% | |
| 流式 | 105.5s | 21.3s | 10.9 GiB | −23.3% | |
| 480×832 | 三相 | 55.1s | 5.07s | 22.2 GiB | — |
| 真常驻 | 39.0s | 5.07s | 27.8 GiB | −29.2% | |
| 流式 | 41.5s | 5.73s | 8.9 GiB | −24.7% |
三种模式的去噪每步时间几乎相同(768p 20.9 / 21.0 / 21.3s;480p 5.07 / 5.07 / 5.73s)。差别根本不在算力,全在 job 级的搬运开销:
那 5 倍是哪来的?最可能是 bf16 时代量的:不量化时权重 62 GiB,要搬的量是现在的 3.2 倍,而每步算力不变 —— 那种情况下 480p 出现数倍差距是合理的。fp8 之后这个成本基本消失了。
h3mc 生产此前跑的命令行里没有 --offload,走的是代码里的另一条分支 —— 三相换相,不是常驻。真正的常驻模式(--resident,权重进卡就不动)是 fl2va 上迭代出来的,这次才回移到 h3mc。
if args.offload: enable_group_offload(...) # 流式,逐块+重叠预取
elif args.resident: transformer.to("cuda") 永久驻留 # ← 本次才补上
else: 每 job 整块 20 GiB 搬上搬下 # ← 改动前生产走这条
所以切到流式之后 768p 5s 从 137.6s → 105.5s、480p 5s 从 55.1s → 41.5s,不但没变慢,还快了约四分之一。我此前说「短片变慢了」是错的。
流式省下的那 19 GiB,换来的就是这个:768p 从只能 5s 变成能做 15s。以下均为 362 帧 = 15.083s,单进程实测。
| 几何 | 比例 | 打包序列 | 峰值显存 | 结果 |
|---|---|---|---|---|
| 768×1312 | ≈9:16 | 213,104 行 | 23.1 GiB | 通过 |
| 768×1376 | 16:9 | 218,240 行 | 23.5 GiB | 通过 |
| 1792×768 | 21:9 · 参考降 480p | 202,511 行 | 23.9 GiB | 通过 |
| 1792×768 | 21:9 · 参考不降 | 290,144 行 | — | OOM |
规则据此定为:16:9 及更方的比例用 768p 参考;超过 16:9 时把视频参考降到 480 短边(输出分辨率不动)。依据是视频参考占了打包序列的约 88%,而参考画布跟着目标长边走 —— 撑爆显存的是它,不是输出。
--resident 真常驻模式 —— h3mc 此前没有,一直在用三相。本次最有价值的一项。--denoise-evict-vae、H3_MEMOPT=1(位级不变)、--max-duration、--vae-fp16、--vae-tile、--refencode-evict-transformer、--trim-cond、stats/per-NFE 计时。PR_SET_THP_DISABLE)+ faulthandler —— 治「解码前挂死」,挂死时可 kill -USR1 抓栈。--wide-ref-short-edge 宽比例降参考规则。还没做完的:--quantized-ckpt(fp8 .pt 直载,worker 冷启动 ready 41s→19s)。它只影响启动、不影响单条速度,所以没有阻塞这次测试。