SwiftVR 5B 生成式 CDA-VSR 3.11M 判别式 各含官方配置 + 自研优化 20 条标准片源 × 4 组 = 80 次运行 RTX 5090 32G
统一任务:输入 768p,输出 2× 放大。20 条片源覆盖 5 种宽高比、每个比例 4 个不同的人、73–362 帧不等。 全部 80 次运行零失败。四组产出同一目标分辨率,可直接并排对比。
| 配置 | 20 条总耗时 | 自身优化幅度 | 显存峰值上限 | 显存中位 | 相对最快 |
|---|---|---|---|---|---|
| SwiftVR 官方 | 892.9 s | 基线 | 29.68 GiB | 29.00 | 2.91× 慢 |
| SwiftVR 优化 | 306.5 s | 2.91× | 22.11 GiB | 19.72 | 最快 |
| CDA-VSR 官方 | 1015.7 s | 基线 | 5.16 GiB | 3.94 | 3.31× 慢 |
| CDA-VSR 优化 | 443.3 s | 2.29× | 4.85 GiB | 3.70 | 1.45× 慢 |
横轴按帧数排序。片子越长四条线越收敛 —— 两边的固定 warmup 开销都被摊薄了。
五条片源,每条给出输入(bicubic 2× 放到同一画布,仅作参照)和四组输出。四组产出分辨率完全相同。 网页版统一截取前 5 秒并重新编码,细节有损失;判画质请用机器上的原始输出。
2× 任务没有 ground truth,所以算不了 PSNR/SSIM。下面两个是代理量, 只能横向比同一条片子的不同配置,不能当作画质分数 —— 锐度既会因真实细节上升、也会因振铃和过锐上升;闪烁里混着真实运动。
restore_video 的四线程流水线,改单线程顺序驱动(官方 Space 的
app.py 用的就是后者)。又快又省 3–4 GiB,还绕开了下面那个死锁 bug。ModulatedDeformConv2d 换成 torchvision 原生 deform_conv2d。
最关键的一步:mmcv 是 C 扩展,dynamo 无法追踪、必然 graph break;换成原生算子后 torch.compile
才能吃下整图。该替换经过逐位等价验证(整网 max|diff| = 0.000e+00),不是「能跑就行」。Conv2d(num_feat,48)+PixelShuffle(4),
发布的权重按 ×4 训练。要原生 ×2 得改重建头并重训或微调 —— 不在本次范围内。
所以它走「真实 768p → 原生 ×4 → 3072p → 降到 1536p」,额外算力如实计入。basicsr/models/video_recurrent_model.py:310 的 t = 100 是写死的字面量,
在 REDS4 上看不出来(每 clip 正好 100 帧)。我们的片子是 73–362 帧:73 帧的会 IndexError,
241/362 帧的会静默只算前 100 帧。改成 t = len(frames),其余一字未动。
注意这是发布脚本的问题,不是模型的限制 —— 模型是在线递归的,可处理任意长度流。runner.py 的
record_error() 用阻塞式 q.put() 往 maxsize=3 的有界队列发停止信号,
OOM 时队列必满 → put 永不返回 → 主线程卡死在 join()。表现是 GPU 0% 占着显存挂住,
而不是崩溃退出。已打补丁;改用单线程驱动可整个绕开。fi % 25 == 0 判 I 帧。所以 LR 必须重编码成 GOP=25、I 帧落在 25 的倍数上、且无 B 帧
(-bf 0 -refs 1 -sc_threshold 0)。这一步的重编码是第二代压缩,计入了 CDA-VSR 的输入质量。
测试机 viggle_new_5090(8×RTX 5090 32G,驱动 580.159.03)· SwiftVR:conda swiftvr,
torch 2.10.0+cu130,官方 H-oliday/SwiftVR 权重 bf16 未量化 · CDA-VSR:conda cdavsr,
torch 2.10.0+cu128,mmcv 2.2.0 源码编译(sm_120),官方 best.pth,权重 0 missing / 0 unexpected ·
片源为 MiniMax-H3 历史输出,20 条覆盖 5 种宽高比 · 2026-08-21