FVMD
fvmd(Fréchet Video Motion Distance)衡量一批预测视频与一批参考视频在运动模式分布上的差距。它来自 FVMD [Liu et al., 2024]:先用点跟踪模型抽出关键点轨迹,再由轨迹的速度与加速度构造显式运动特征,最后在这组特征上算 Fréchet 距离。
WorldAtlas 通过 fvmd backend 调用仓内的 DSL-Lab/FVMD-frechet-video-motion-distance 官方实现(thirdparty/FVMD-frechet-video-motion-distance)。它是 suite 级分布指标,不是逐样本指标:整个 suite 只出一个分数,而不是每个视频一个分数。
这个指标测什么
Section titled “这个指标测什么”- 预测视频集合的运动动态分布是否接近参考视频集合。
- 时序不一致:位置或姿态的突变、物体的骤然形变与模糊、抖动式运动——这些都会表现为关键点轨迹的紊乱,也就是速度与加速度的异常跳变。
- 不测逐样本的对齐程度:它没有”这一条视频得几分”的概念,只有”这一批视频作为一个分布离参考分布有多远”。
- 不测 prompt 遵循、物体身份或语义正确性。
引入显式运动特征的动机是:已有的分布级视频指标都不直接看运动。FID-VID 只比较帧的视觉质量,完全忽略运动;FVD 虽然用 I3D 引入了时序信息,但它的特征偏向逐帧内容(content bias),对时序失真不够敏感。VBench 的 temporal flickering 与 motion smoothness 又倾向于奖励平滑甚至静止的视频,会连带惩罚舞蹈、运动这类本身就有大幅高质量运动的样本。
FVMD 的切入点是:符合物理规律的运动不应该出现加速度的突然变化。因此,与其依赖某个动作识别网络的隐式特征,不如直接把运动写出来——跟踪关键点,算出速度场与加速度场,再统计它们的分布。这样得到的特征是显式、可解释的,而且它关心的正是”运动是否连贯”,而不是”每一帧是否好看”。
在 WorldAtlas 里还有一层动机:FVMD 与 motion_smoothness、motion_magnitude 这类逐样本运动读数互补。后者回答单条视频的运动幅度和平滑度,FVMD 回答整个模型输出的运动分布是否偏离参考语料。
- WorldAtlas 收集当前 suite 的全部 prediction 视频。参考侧是动态参考语料库(见 参考语料库),而不是每个样本自己的真值,因此两侧是规模不同的独立集合。
- 每个视频先重采样到
sample_fps = 8,再切成 16 帧、 的 clip,即固定 2 秒窗口(clip_frame_count = 16、analysis_size = 256)。prediction 最多取 4 个不重叠窗口,语料视频同样最多 4 个。 - GPU 跟踪前,参考集先经过独立于模型的 CPU 预筛选:排除确认解码异常、原生帧率低于
sample_fps或采样后不足 16 帧的视频。完整清单与原因保存在reference_selection.json,绑定全部候选视频内容与采样协议,各模型复用同一清单。预测视频不使用此筛选;预测解码失败、或已入选参考视频在跟踪阶段失败,仍使本次评测失败,不能临时缩小集合后发布分数。与逐样本解码相同:若 OpenCV 容器帧数比实际解码帧数多 1,按实际帧数重采样,该视频仍进入集合。 - 两侧分别用 PIPs++ 在每个 clip 上跟踪 个网格关键点,得到轨迹 。
- 由轨迹的一阶差分得到速度场 ,再对速度场做一阶差分得到加速度场 。
- 把每个向量场切成 的小体积,在每个体积内统计 8 个角度 bin 的稠密 1D 直方图。
- 速度直方图与加速度直方图拼接成 1024 维 combined 运动特征。
- 在 combined 特征上按多元高斯假设计算 Fréchet 距离,得到 raw 分数。
- WorldAtlas 榜单保留线性高分段,并平滑延伸低分尾部:令
s = 1 - raw / 10000、p = 0.05;当s ≥ p时score = s,否则score = p*p / (2*p - s)。榜单显示为100 × score,越高越好。
raw 分数越低,说明两批视频的运动分布越接近。
榜单分数与原始距离
Section titled “榜单分数与原始距离”p = 0.05 表示仅调整原线性刻度 5 分以下的尾部,原来至少 5 分的结果完全不变。raw 为 0、9500、10000、20000 时,百分制分数分别为 100、5、2.5、约 0.227。连接点的数值和斜率均连续,距离越大分数越低,不设置统一保底分。参数固定在 config/leaderboard_fvmd.yaml,不随模型增减改变;它是显示约定,不是质量合格线或真实视频之间的距离基线。高距离仍对应很低的分数,而不是获得中等分数。
已有报告中的线性截断分数保留用于审计,发布时直接从 distribution_metric_details.json 的 raw 重新换算,不能从已截成零的 normalized 反推距离。无需重新提取特征或运行 GPU。计算失败仍然留空,不通过该公式制造数值。FVMD 较差可能来自运动不足、运动紊乱或其他分布差异,不能仅据此判断视频静止。
为什么不再走上游入口函数
Section titled “为什么不再走上游入口函数”WorldAtlas 直接驱动上游的子函数(tracking_fullseq、calc_hist、calculate_frechet_distance),而不是顶层的 fvmd(),因为后者无法表达”规模独立的参考集合”:
- 它的跟踪循环以
len(gen_dataset)为界,参考集更长时多出来的样本被静默截断,更短时会触发迭代器重启并静默重复取样; - 随后它用 prediction 的窗口数去 reshape 参考侧直方图,两侧不等长时直接是 shape 错误。
另外要注意:上游 fvmd() 在解包 build_dataset() 时把自己的 gen/gt 变量弄反了。因为 Fréchet 距离对称,最终分数不受影响,但这意味着写进 log_dir 的 velocity_gt.npy 里装的其实是生成侧的数据。
FVMD 的特征是逐帧像素位移,因此会随帧率缩放:同一个物理运动在 30 fps 下的位移大约只有 16 fps 下的一半。拿生成视频与帧率不同的真实素材比较,等于把帧率差异当成运动差异报告出来。
sample_fps 在切分任何 clip 之前先把两侧重采样到同一帧率,于是采样窗口是一个时长(2 秒)而不是一个帧数。上采样被拒绝而不是执行:复制帧会造出零运动片段,而 FVMD 会把它当作真实信号。原生帧率低于 sample_fps 的参考视频在预筛选中排除并计数;预测视频不允许静默排除。
参考视频的容器声明帧数不作为唯一依据:预筛选通过 ffprobe -count_frames 完整解码计数,要求无解码错误,再将核实后的实际帧数用于参考侧采样。跟踪阶段的实际解码数量仍必须与核实值一致。单条探测时限至少 600 秒,并按文件大小放大(上限 7200 秒),避免超长参考在 NFS 上被当成操作超时。存储故障、超时和工具故障会中止准备,不会被当成参考视频不合格写入清单。参考特征缓存绑定清单摘要,使用不同清单的历史分数必须统一重算后才能比较。
关键点轨迹与速度、加速度场
Section titled “关键点轨迹与速度、加速度场”对一个 帧的 clip,PIPs++ 输出 条轨迹 。速度场取相邻帧位置的一阶差分,并在首帧零填充以保持形状一致:
加速度场同理,是速度场的一阶差分:
这里 表示第 到第 帧(含两端)。之所以同时用速度和加速度:速度描述运动本身,加速度描述运动的变化率,而不自然的时序跳变在加速度上表现得最明显。
运动特征直方图
Section titled “运动特征直方图”设 为速度场或加速度场。对每一帧 和每个关键点 ,先算向量的模长与方向角:
方向角被均匀量化成 8 个 bin,每个 bin 覆盖 45 度。模长先截断到 ,再做 base-2 对数变换并量化——因为绝大多数向量的模长都很小,取对数可以避免少数大位移主导整个直方图:
接着把向量场切成 的小体积(实现取 、)。仿照 HOG 的做法,在每个体积内把量化后的模长权重直接累加到对应的角度 bin 上,得到一个 8 点直方图。所有体积的直方图拼接展平后,就是该 clip 的运动特征,形状为 ——在当前配置下即 。
论文同时提出了另一种量化 2D 直方图(角度 8 bin × 模长 9 bin,共 72 维),并通过消融实验确认稠密 1D 直方图更贴合人类判断。上游默认走 1D 路径,WorldAtlas 未改动这一选择。
Fréchet 距离
Section titled “Fréchet 距离”把速度特征与加速度特征拼成 combined 特征后,FVMD 沿用 FID 的做法,用多元高斯近似两个特征分布,从而得到闭式解:
其中 与 是各自 clip 集合上运动特征的经验均值与协方差。高斯假设在这里比在 I3D 特征空间上更容易接受:运动直方图是有界的低维统计量,而不是高维语义嵌入。
参考侧是 dynamic/{style}/videos/{motion_category}/ 下的采集动态视频语料,由 benchmark.reference_corpus 配置、经 worldatlas build-reference-corpus 建立索引。
FVMD 只用于动态 suite。静态场景的相机运动是由 prompt 指定的,而语料库里的静态相机运动是采集时的自然结果,两者的运动分布本来就不该匹配,算出来的距离没有解释力。
动态资产在语料目录结构中没有 environment 标签,且动态语料本身规模较小,因此它是单一不分层分组:分层结果会与主表数字完全相同,不重复计算。
由于语料库是 benchmark 的常量,其内容签名会记入 run_manifest.json 的 reference_corpus。换语料就改变了分数的含义,不同语料版本之间的数值不可比。
分布级评测与 shard 合并
Section titled “分布级评测与 shard 合并”fvmd 与 jedi 一同登记在 SUITE_LEVEL_METRICS 中,因此不会被实例化成逐样本 Metric 对象。它对分片评测的含义是:
- Shard worker 阶段:
run_eval_shards.py以run_suite_level_metrics=False调用run_benchmark,worker 只负责收集 prediction 视频,不在 shard 内部计算 FVMD。 - Merge 阶段:合并全部 shard 的逐样本分数后重建 prediction 集合,再对每个 suite 的完整集合各算一次 FVMD。
这个顺序是必要的:如果在 shard 内分别算再取平均,得到的均值和协方差只反映各分片的局部分布,无法代表整个模型的输出分布。分布指标不能按 shard 分解后再平均。
语料侧的运动特征缓存在 benchmark.reference_corpus.cache_dir,缓存键由语料文件身份与 clip 采样规格共同决定。因此跟踪器在语料上只跑一次,之后每个模型都复用,这也正是”语料库可以远大于 prediction 集合”在成本上可行的原因。
| 项目 | 当前实现 |
|---|---|
| 预测输入 | 当前 suite 内全部 prediction 视频,各取最多 4 个不重叠的 2 秒 clip |
| 参考输入 | 动态参考语料库,每个视频最多 4 个 clip,与 prediction 数量无关 |
| 标注输入 | 无 |
| 适用 suite | image_dynamic、video_dynamic |
| 聚合维度 | physics |
| Raw 输出 | 整个 suite 一个 FVMD 标量,越低越好 |
| 归一化输出 | 报告保留兼容的线性 normalized;榜单从 raw 按本页分段公式换算,5 分以上保持原线性刻度,5 分以下平滑衰减 |
| 结果落盘 | distribution_metric_details.json 的 <suite>.fvmd,含 raw、normalized、backend、details 与 groups;并在 distribution_group_breakdown.json 中汇总 |
| 细节字段 | prediction 与 reference 的 clip 构建报告(candidate_video_count、used_video_count、clip_count、skipped_video_count、skipped_videos_preview、source_fps_min/median/max)、prediction_clip_spec、reference_clip_spec、prediction_signature、reference_signature、reference_cache_hit、reference_cache_dir、feature_dim、prediction_window_count、reference_window_count、singular_covariance_sides、raw_direction、repo_root、torch_home |
| 无监督形式 | 当前 suite 没有 prediction 视频、没有对应参考分组、或 clip 数低于 metric_runtime.fvmd 的 min_prediction_clips / min_reference_clips(生产值为 1025)时记为 not_applicable |
| 失败形式 | 有效 clip 数少于 min_clip_count = 2 时整个指标失败并记入 failure_summary,不会被记为 0 |
| 运行依赖 | 需要 GPU;PIPs++ 权重 pips2_weights.pth 经 TORCH_HOME 解析到 ckpt/torch/hub/checkpoints/ |
当前集成是否足够严格
Section titled “当前集成是否足够严格”| 项目 | 结论 |
|---|---|
| 当前聚合状态 | 在 image_dynamic 与 video_dynamic 中,只要产出数值分数就是 official,并计入 physics 维度 |
| 论文可用性结论 | 主表可用,但必须标注它是分布级指标,且必须报告两侧的窗口数 |
- 它填补了一个真实的空白:在 WorldAtlas 现有的运动指标里,只有 FVMD 直接比较运动分布。论文在 TikTok 数据集上对五个模型做人类排名对比时,FVMD 与人类评分的 Pearson 相关性为 0.8469,高于 FVD 的 0.6708、FID-VID 的 0.3402 和 VBench 平均分的 0.7573;在更系统的 One Metric Equal 与 One Metric Diverse 实验中,FVMD 也是唯一在所有设置下都保持正相关的指标。
- 样本量是这个分数的硬约束。 combined 运动特征是 1024 维,而 Fréchet 距离要估计完整协方差,所以窗口数少于 1024 的一侧协方差是奇异的。借助上游的
eps正则化仍然能算出一个数,但严重有偏。details.singular_covariance_sides会点名处于这种状态的一侧。动态语料库约 961 条视频,这正是两侧max_clips_per_video取 4 而不是 1 的原因。跨模型比较前务必确认prediction_window_count与reference_window_count相当。 - 每视频多取窗口是用独立性换样本量。 论文以 stride 、即最大重叠的方式从整段视频切出 16 帧片段,并在消融中确认最大重叠优于不重叠。WorldAtlas 每个视频最多取 4 个不重叠窗口,比每视频一个 clip 更密,但仍稀于论文默认配置,因此本仓的 FVMD 数值不能与论文报告的数值直接对照。由于参考语料库是固定的,这一取样方式在参考侧引入的偏差对所有模型都是同一个常量。
- 要对着 real-vs-real 地板值读。
scripts/calibrate_distribution_metrics.py把语料库对半切开互相评分。两半都是真实视频,所以结果是完美模型能达到的地板值;主表分数应当理解为”高出该地板值多少”,而不是”高出 0 多少”。200 对 200 的探测跑出 raw3954,但两侧只有 694 / 648 个窗口,协方差都奇异,这个数不能当地板值。动态语料 961 条对半切开、每条最多 4 个窗口,才能把每侧顶过 1024。生产配置把min_prediction_clips/min_reference_clips提到 1025,子集评测会记为not_applicable而不是给出有偏分数。 - 它对时序噪声确实敏感。论文注入 local swap、global swap、interleaving、switching 四类时序噪声,FVMD 的取值随噪声强度单调上升,其中速度与加速度 combined 特征表现最好。
- 但它不是运动正确性指标。两批视频可以拥有相近的速度与加速度分布,却在运动方向、因果关系或对象身份上完全不同。应当与
motion_accuracy、camera_error等有真值约束的指标一起报告,而不是单独用来声称运动已经建模正确。
BibTeX
@inproceedings{liu2024fvmd, title = {Fr\'{e}chet Video Motion Distance: A Metric for Evaluating Motion Consistency in Videos}, author = {Liu, Jiahe and Qu, Youran and Yan, Qi and Zeng, Xiaohui and Wang, Lele and Liao, Renjie}, booktitle = {First Workshop on Controllable Video Generation at {ICML}}, year = {2024}, eprint = {2407.16124}, archivePrefix = {arXiv}, primaryClass = {cs.CV}, url = {https://arxiv.org/abs/2407.16124},}