
089、视频超分实战基于BasicVSR与EDVR的基准测试与结果分析上周帮实验室跑一个视频超分对比实验客户要求“在1080P视频上做4倍超分PSNR不能低于32dB推理速度要快”。我心想这要求不算苛刻直接拿EDVR开搞。结果跑完一看PSNR 31.8dB差0.2dB客户那边直接甩过来一句“你们这模型是不是没调好”——得又得从头排查。后来换成BasicVSR同样的数据PSNR直接飙到32.5dB推理速度还快了将近一倍。这个坑让我意识到光看论文里的SOTA指标没用实际部署时模型选择、数据预处理、甚至batch size都会影响最终结果。今天这篇笔记就记录一下我在BasicVSR和EDVR上做基准测试时踩过的坑、调参的细节以及最终结果分析。不整虚的全是实战经验。环境搭建与数据准备别在预处理上翻车先说数据。我用的REDS数据集这是视频超分最常用的benchmark之一。但注意REDS官方给的train和val划分是固定的千万别自己乱切。我第一次跑EDVR时自作聪明把val集里的一些帧混进了train结果PSNR虚高后来被审稿人怼了。数据预处理这块BasicVSR和EDVR都要求输入是LR-HR对但它们的处理方式有细微差别。EDVR官方代码里LR图像是通过对HR做bicubic下采样得到的而BasicVSR用的是MATLAB风格的imresize。如果你用OpenCV的resize默认插值方式不同会导致PSNR差0.1-0.2dB。我建议统一用torch.nn.functional.interpolatemode设为’bicubic’align_corners设为False。这里踩过坑align_corners不设置的话默认是False但有些旧版代码里是True结果图像边缘会有1-2像素的偏移超分后边缘模糊。数据加载时视频超分需要连续帧。BasicVSR默认用5帧作为输入EDVR用7帧。别以为帧数越多越好——我试过把BasicVSR的帧数从5调到7PSNR反而掉了0.1dB因为冗余帧引入了噪声。经验是运动剧烈的场景比如体育视频用5帧静态场景监控视频可以加到9帧。模型配置BasicVSR的“轻”与EDVR的“重”BasicVSR的核心是双向光流传播和残差连接。它的设计哲学是“用光流对齐代替显式对齐”所以参数量比EDVR小很多。我实测BasicVSR的参数量约6.3MEDVR约20.5M。但别以为参数量少就弱——BasicVSR在REDS4上的PSNR是31.42dBEDVR是31.88dB差距不到0.5dB。但推理速度上BasicVSR在RTX 3090上处理720P视频能达到30fpsEDVR只有12fps。EDVR的优势在于它的PCDPyramid, Cascading and Deformable对齐模块能处理大位移运动。如果你要超分的视频里有快速移动的物体比如赛车、无人机航拍EDVR的细节保留能力明显强于BasicVSR。我做过一个对比一段F1赛车视频EDVR能清晰还原轮胎上的文字BasicVSR则糊成一团。配置时注意BasicVSR的默认光流网络是SPyNet别换成FlowNet2.0——后者精度高但速度慢而且训练不稳定。我试过用FlowNet2.0替换PSNR只提升了0.1dB但训练时间翻了三倍。EDVR的PCD模块里有个deformable convolution这玩意儿在PyTorch里需要单独安装mmcv或torchvision的扩展。别用pip直接装容易版本冲突。我建议用conda装conda install -c conda-forge mmcv-full版本选1.4.0以上。训练细节学习率、batch size和梯度裁剪训练时BasicVSR和EDVR的优化策略完全不同。BasicVSR用Adam优化器初始学习率1e-4每50个epoch衰减0.5。EDVR用AdamW初始学习率2e-4每30个epoch衰减0.8。别混用——我试过把BasicVSR的学习率调到2e-4结果loss直接炸了梯度爆炸。batch size方面BasicVSR可以设到16单卡RTX 3090EDVR只能设到4因为显存占用大。如果你显存不够别硬撑用梯度累积。我一般设accumulation_steps4等效batch size16。注意梯度累积时BN层的统计量会受影响建议用SyncBN或者干脆用GroupNorm替代。这里踩过坑EDVR的PCD模块里用了BN梯度累积后训练不稳定换成GN后收敛速度明显提升。梯度裁剪是必选项。BasicVSR的梯度范数容易超过100我设max_norm40。EDVR的梯度更夸张有时能到500我设max_norm80。别问我怎么知道的——第一次跑EDVR没加梯度裁剪loss直接变成NaN查了两天发现是梯度爆炸。基准测试别只看PSNR要看主观效果测试时我用了REDS4和Vid4两个数据集。REDS4是REDS的官方测试集包含4个视频片段每个100帧。Vid4是经典测试集包含4个低分辨率视频。注意测试时一定要用全帧别只取中间帧。有些论文为了刷指标只取中间50帧结果PSNR虚高0.3dB。结果如下4倍超分PSNR/SSIMBasicVSR on REDS4: 31.42dB / 0.893EDVR on REDS4: 31.88dB / 0.902BasicVSR on Vid4: 27.15dB / 0.817EDVR on Vid4: 27.35dB / 0.826看起来EDVR全面领先但注意Vid4上的差距只有0.2dB而REDS4上差距0.46dB。为什么因为REDS4是REDS的子集EDVR在训练时见过类似场景有数据泄露风险。如果你要做公平对比建议用Vid4或自定义数据集。主观效果上EDVR在纹理细节上更锐利但有时会引入伪影比如振铃效应。BasicVSR的画面更平滑但容易丢失高频信息。我让实验室的同学做盲测10个人里有7个更喜欢BasicVSR的结果因为“看起来更自然”。这说明PSNR高不等于视觉质量好。推理优化ONNX导出和TensorRT加速如果你要部署别直接用PyTorch推理。我试过把BasicVSR导出为ONNX然后用TensorRT加速。注意BasicVSR的光流网络SPyNet里用了torch.nn.functional.grid_sample这个操作在ONNX里支持不好需要手动实现一个自定义算子。我折腾了两天最后用onnxruntime的contrib_ops才搞定。EDVR的PCD模块更麻烦deformable convolution在TensorRT里不支持。我建议用mmdeploy工具链它提供了现成的转换脚本。但注意mmdeploy只支持EDVR的旧版本v1.0新版本v2.0的代码结构变了需要自己改。加速效果BasicVSR用TensorRT FP16推理速度从30fps提升到55fps。EDVR从12fps提升到20fps。如果你对速度要求高建议用BasicVSR配合TensorRT基本能实时处理720P视频。个人经验性建议别迷信SOTAEDVR在论文里吹得天花乱坠但实际部署时BasicVSR的性价比更高。除非你的场景有大量快速运动否则BasicVSR足够用。数据预处理是瓶颈我见过太多人花大量时间调模型结果数据预处理里一个插值方式不对PSNR直接掉0.5dB。建议统一用torch.nn.functional.interpolate别用OpenCV。测试集要独立别用训练集的子集做测试否则指标虚高。REDS4就是个坑很多论文用它刷分但实际泛化能力一般。主观评价更重要PSNR和SSIM只是参考最终用户看的是画面质量。建议每次实验后做一次盲测让非专业人士打分。别在单卡上死磕如果你有4张卡用DataParallel或DistributedDataParallel。BasicVSR在4卡上训练时间从3天缩短到1天。EDVR更夸张单卡训练要5天4卡只要1.5天。最后如果你在复现时遇到问题先检查数据预处理再检查梯度裁剪最后看学习率。这三个环节出问题的概率占80%。别问我怎么知道的——都是血泪教训。