- 人工智能
- 大模型
- 模型优化
- 模型量化
- 模型压缩
【免费下载链接】Model-Optimizer
A unified library of SOTA model optimization techniques like quantization, distillation, pruning, neural architecture search, speculative decoding, etc. It compresses deep learning models for downstream deployment frameworks like TensorRT-LLM, TensorRT, vLLM, etc. to optimize inference speed.
导读
本文讲解 Model-Optimizer 仓库中 examples/windows/accuracy_benchmark/fvd_metrics 目录下的 FVD(Fréchet Video Distance)评估工具:它使用预训练 I3D 网络(Kinetics-400 RGB 流)提取视频的 1024 维特征,以分布距离量化两组视频(真实参考 vs 模型生成)的相似度,是视频生成模型量化/剪枝后质量验证的标准手段。读完本文,你将掌握完整的安装、命令行用法、全部参数语义、输出格式,并理解从视频解码、clip 采样、I3D 特征提取到 PCA 与 Fréchet 距离计算的完整源码级实现链路,以及如何将 FVD 用于 PTQ/QAD 量化方案的横向对比。
一、为什么在模型优化流程中需要 FVD
FVD(Fr'echet Video Distance)由 Unterthiner 等人于 2019 年提出,是一种分布级(distribution-level)指标:它不逐帧比对两段视频的像素差异,而是把"参考视频集"和"生成视频集"各自视为一个特征分布,用 Fréchet 距离衡量这两个分布有多接近。值越低代表分布越相似,FVD = 0 表示两集合在特征空间完全一致。
在 Model-Optimizer 的语境下,这个工具对应三类典型使用场景(见 fvd_metrics/README.md):
- 模型优化验证(Model Optimization Validation)——验证量化/剪枝后的视频生成模型是否仍保持输出质量;
- 精度分析(Precision Analysis)——横向比较同一模型在 BF16 / INT8 / INT4 等不同精度下生成视频的差异;
- 框架对比(Framework Comparison)——评估不同推理后端(如 ONNX Runtime、TensorRT 等)输出的一致性。
该工具与仓库 Windows 精度基准套件中的另外两个指标(KL 散度、Perplexity)并列,共同构成量化模型的精度验证矩阵,详见 examples/windows/accuracy_benchmark/README.md 的 "Additional Metrics" 一节;而 examples/windows/Benchmark.md 中记录了该工具的实际基准产出(LTX-2.3 视频生成模型 PTQ 与 QAD 对比),具体数据见本文第六节。
二、工具组成与核心组件
| 脚本 | 用途 |
|---|---|
compute_fvd.py | 主脚本——加载视频、提取 I3D 特征、计算 FVD |
i3d_model.py | I3D(Inflated 3D ConvNet,Inception-v1 三维化)模型结构与权重加载 |
依赖清单见 requirements.txt:numpy、opencv-python-headless、scipy、torch>=2.0.0、tqdm,并配置了--extra-index-url https://download.pytorch.org/whl/cu129以便获取 CUDA 版 PyTorch。
I3D 模型细节
- 架构:Inception-v1 扩展为 3D 卷积(Carreira & Zisserman 在 CVPR 2017 提出的 I3D);
- 权重:
rgb_imagenet.pt(约 49 MB),首次运行自动下载; - 特征维度:1024(取自最后一个平均池化层);
- 输入:16 帧 clip,中心裁剪到 224×224,像素归一化到 [-1, 1]。
从 i3d_model.py 源码看,模型主体由Unit3D(Conv3d + BatchNorm3d + ReLU)、InceptionModule(四条并行分支:1×1 卷积分支、1×1→3×3 卷积分支、1×1→3×3 卷积分支、MaxPool3d 后接 1×1 卷积分支,在通道维拼接)以及InceptionI3d(从Conv3d_1a_7x7到Mixed_5c的完整 I3D 主干)构成,末端为AdaptiveAvgPool3d((1,1,1))后 flatten,输出 (B, 1024)。值得注意的是模型不包含分类头——load_i3d在加载权重时会跳过conv3d_0c_1x1(logits 层)相关的键,这正是它作为特征提取器而非分类器的设计。
权重加载函数load_i3d支持两种格式:
- piergiaj/pytorch-i3d 的
rgb_imagenet.pt(PascalCase 键名、bn前缀)——主脚本默认使用的格式; - TorchScript 归档
i3d_pretrained_400.pt(小写键名、batch3d前缀)——通过_map_torchscript_keys完成键名映射(conv3d_*→Conv3d_*、batch3d→bn、branch_0→b0、branch_1.0/1.1→b1a/b1b等)。
加载策略上,源码优先尝试torch.jit.load走 TorchScript 路径,失败后再尝试torch.load(..., weights_only=True)的安全反序列化;仅当传入的权重文件被认定为"可信、经校验"时才允许weights_only=False回退(该开关由allow_unsafe_pickle控制,主脚本仅在非用户自供权重的自动下载场景下启用,详见下文权重校验一节)。加载后还会严格校验missing/unexpected键,任何非分类头部分的键不匹配都会抛出异常,防止加载到不匹配的 checkpoint。
三、安装与依赖
1. 创建并激活虚拟环境(推荐)
python -m venv fvd_env source fvd_env/bin/activate # Linux/macOS # .\fvd_env\Scripts\Activate.ps1 # Windows PowerShell2. 安装依赖
pip install -r requirements.txt如需 GPU 加速,按 requirements.txt 中的 index-url 安装带 CUDA 支持的 PyTorch:
pip install torch --index-url https://download.pytorch.org/whl/cu129说明:requirements.txt 已将 cu129 index 配置为
--extra-index-url,即执行普通pip install -r requirements.txt时即可自动从该源拉取匹配的 PyTorch;单独指定 index-url 的命令适用于需要显式控制 PyTorch 构建版本的场景。
四、命令行用法
快速开始:对比两个视频目录
python compute_fvd.py \ --ref-dir /path/to/reference/videos \ --gen-dir /path/to/generated/videosI3D 权重(约 49 MB)会在首次运行时自动下载并缓存到~/.cache/fvd/rgb_imagenet.pt。
将结果保存为 JSON
python compute_fvd.py \ --ref-dir /path/to/reference/videos \ --gen-dir /path/to/generated/videos \ --output results.json使用本地下载好的 I3D checkpoint
python compute_fvd.py \ --ref-dir /path/to/reference/videos \ --gen-dir /path/to/generated/videos \ --weights ./rgb_imagenet.pt增加采样量:每段视频采样多个 clip
python compute_fvd.py \ --ref-dir /path/to/reference/videos \ --gen-dir /path/to/generated/videos \ --clips-per-video 4 \ --output results.json指定设备与批大小
python compute_fvd.py \ --ref-dir ./real --gen-dir ./fake \ --device cuda \ --batch-size 16显式指定 PCA 维度
python compute_fvd.py \ --ref-dir ./real --gen-dir ./fake \ --pca-dim 64 \ --output results.json支持的视频格式
.mp4、.avi、.mov、.mkv、.webm、.flv、.m4v。脚本会递归发现指定目录(及其子目录)下的所有视频文件。源码中该集合定义于compute_fvd.py的VIDEO_EXTS,且list_videos使用Path(folder).rglob("*")做大小写不敏感后缀匹配(p.suffix.lower()),找不到任何视频时抛出ValueError。
五、参数总览
必选参数
| 参数 | 说明 |
|---|---|
--ref-dir | 参考(真实)视频所在目录 |
--gen-dir | 生成视频所在目录 |
可选参数
| 参数 | 说明 | 默认值 |
|---|---|---|
--weights | I3D 权重文件路径 | 自动下载的rgb_imagenet.pt |
--device | Torch 设备(cuda、cpu、cuda:0等) | 自动检测(有 CUDA 用 cuda,否则 cpu) |
--clip-length | 每个 clip 的帧数 | 16 |
--clips-per-video | 每段视频采样的 clip 数量 | 1 |
--batch-size | I3D 推理批大小 | 8 |
--pca-dim | 特征 PCA 维度(0 表示禁用;当 clip 数 < 1024 时自动选择) | 自动 |
--output | JSON 结果保存路径 | 无(打印到控制台) |
参数背后的实现细节(源码佐证)
- 类型校验:
--clip-length、--clips-per-video、--batch-size使用positive_int类型(必须 > 0),--pca-dim使用non_negative_int(必须 ≥ 0),非法值会在参数解析阶段直接报错(见compute_fvd.py的main()与两个 argparse 类型函数)。 - 设备选择:
--device缺省时,torch.device(args.device or ("cuda" if torch.cuda.is_available() else "cpu"))自动探测;日志会首先打印Device: cuda/Device: cpu。 - clip 采样策略:
get_clips先用 OpenCV 获取视频总帧数CAP_PROP_FRAME_COUNT;若总帧数小于clip_length,则所有采样起点均为 0(并在加载时通过重复最后一帧补齐不足帧数,见load_video_clip中的frames += [frames[-1]] * (clip_length - len(frames)));否则用np.linspace(0, max_start, num=clips_per_video)在视频内均匀分布地取起点,保证多个 clip 覆盖整段视频而非集中在开头。 - 预处理管线(
preprocess_clip):先把最短边缩放到 256(保持宽高比,INTER_LINEAR),再按 224×224 中心裁剪,最后tensor / 127.5 - 1.0归一化到 [-1, 1],输出形状为 (3, T, H, W) 的 float32 张量,与 I3D 期望的输入格式一一对应。 - 权重安全下载:自动下载路径
DEFAULT_CACHE = ~/.cache/fvd/rgb_imagenet.pt;下载完成后计算 SHA-256 并与硬编码值2609088c2e8c868187c9921c50bc225329a9057ed75e76120e0b4a397a2c7538比对,不匹配则删除文件并报错,杜绝被篡改的权重被加载。若用户显式传入--weights,则校验文件存在后直接使用,且此时allow_unsafe_pickle=False(用户文件不允许走非安全反序列化路径)。
六、预期输出
控制台输出示例
2025-01-15 10:30:00 | INFO | Device: cuda 2025-01-15 10:30:02 | INFO | I3D model loaded from rgb_imagenet.pt (1024-dim features) 2025-01-15 10:30:02 | INFO | Reference videos: 100 2025-01-15 10:30:02 | INFO | Generated videos: 100 Loading ref: 100%|██████████| 100/100 [00:15<00:00, 6.5video/s] Loading gen: 100%|██████████| 100/100 [00:14<00:00, 6.8video/s] 2025-01-15 10:30:32 | INFO | Total clips — ref: 100, gen: 100 Extracting ref features: 100%|██████████| 13/13 [00:08<00:00, 1.5it/s] Extracting gen features: 100%|██████████| 13/13 [00:07<00:00, 1.6it/s] 2025-01-15 10:30:48 | INFO | FVD = 12.3456日志格式由logging.basicConfig(format="%(asctime)s | %(levelname)s | %(message)s")定义,两阶段进度条(Loading *视频解码、Extracting * features特征提取)分别来自get_clips与extract_features中的tqdm。
JSON 输出示例
{ "fvd": 12.3456, "ref_dir": "/path/to/reference/videos", "gen_dir": "/path/to/generated/videos", "num_ref_clips": 100, "num_gen_clips": 100, "clip_length": 16, "clips_per_video": 1, "feature_dim": 1024, "pca_dim": null, "model": "I3D (Kinetics-400, 1024-dim pool)" }注意:JSON 中
feature_dim记录的是 PCA 应用之后的特征维度(源码在apply_pca之后取ref_feats.shape[1]),因此当自动/手动启用 PCA 时该字段会变为 PCA 维度而非 1024;pca_dim字段如实记录实际生效的 PCA 维度(未启用时为null)。--output指定的路径若包含不存在的目录,脚本会自动创建(os.makedirs(out_dir, exist_ok=True))。
七、基准结果:LTX-2.3 视频生成模型 PTQ vs QAD
该工具在仓库中的真实基准场景是评估LTX-2.3 视频生成模型量化方案的质量:以BF16 输出为参考基线,分别比较 PTQ(Post-Training Quantization,后训练量化)与 QAD(Quantization-Aware Distillation,量化感知蒸馏)量化模型的生成结果,覆盖 VBench 的 11 个评估维度(详见 examples/windows/Benchmark.md)。数值越低越好。
| Category | FVD: PTQ vs BF16 ↓ | FVD: QAD vs BF16 ↓ |
|---|---|---|
| Temporal Flickering | 31.92 | 21.97 |
| Subject Dynamic Motion | 23.44 | 16.28 |
| Multiple Objects | 35.35 | 22.47 |
| Human Action | 30.08 | 21.82 |
| Object Class | 51.51 | 26.86 |
| Color | 36.52 | 25.09 |
| Spatial Relationship | 25.07 | 18.41 |
| Scene Background | 64.92 | 35.69 |
| Appearance Style | 31.08 | 20.82 |
| Temporal Style | 23.61 | 15.85 |
| Overall Consistency | 25.03 | 18.85 |
| Average | 34.41 | 22.19 |
要点解读:
- QAD 在全部 11 个 VBench 维度上均优于 PTQ,平均 FVD 为22.19vs34.41(低约 35%);
- 差距最大的是Scene Background(64.92 vs 35.69)与Object Class(51.51 vs 26.86),说明 PTQ 对空间细节保真度的退化比 QAD 更明显;
- 两种方法在Temporal Style与Subject Dynamic Motion上表现最好,提示时间动态特征对量化相对更稳健。
八、关键洞察(如何得到可信的 FVD)
- 越低越好:FVD = 0 表示两分布完全相同;
- 样本量至关重要:clip 数低于 ~256 时 FVD 估计噪声很大;若要发表/上线决策级结论,建议至少 2048+ clip。用
--clips-per-video提升采样量是首选手段。源码在min(len(ref_clips), len(gen_clips)) < 256时会在日志中显式告警 "FVD estimates are noisy below ~256 clips"; - PCA 自动选择:当 clip 数小于特征维度(1024)时自动启用 PCA,避免协方差矩阵奇异(rank-deficient)。源码逻辑为:
--pca-dim缺省时pca_dim = min(n_clips - 1, 64) if n_clips < feat_dim else None(即 clip 不足 1024 时降维到 min(样本数-1, 64));显式传 0 则完全禁用;显式传正整数则强制执行该维度。apply_pca在合并后的特征上做 SVD 并投影两组特征,且会把维度裁剪到不超过两组样本数减一(n_components = min(n_components, feats_a.shape[0]-1, feats_b.shape[0]-1, feats_a.shape[1])); - 最少样本数限制:两组各至少需要 2 个 clip 才能计算协方差(
compute_fvd与main中均做了>= 2校验),否则直接退出。
数学内核:Fréchet 距离的计算方式
compute_fvd.py将两组特征各自拟合为多元高斯(均值向量 + 协方差矩阵),然后计算两高斯分布间的 Fréchet 距离:
FVD = ||mu1 - mu2||^2 + Tr(Sigma1) + Tr(Sigma2) - 2 * Tr(sqrtm(Sigma1 @ Sigma2))实现上有两处数值稳健性处理:当scipy.linalg.sqrtm产生非有限值时,向协方差矩阵对角线加eps=1e-6后重试;当结果出现虚部时,若虚部最大幅值超过 1e-3 会记录告警,随后只取实部参与计算。这些细节保证了大维度协方差在浮点运算下仍能得到稳定、可复现的分数。
九、故障排查
CUDA 显存不足(CUDA Out of Memory)
解决方案:
- 降低批大小:
--batch-size 2 - 改用 CPU:
--device cpu - 关闭其他占用 GPU 的应用
找不到视频(No Videos Found)
确认视频文件扩展名在支持列表内(.mp4、.avi等),且位于指定目录或其子目录下——脚本是递归搜索的(rglob),且后缀匹配不区分大小写(如.MP4同样会被识别)。
FVD 数值波动 / 不稳定
如果多次运行之间 FVD 值差异显著,大概率是 clip 样本数过少。提高采样量:
python compute_fvd.py --ref-dir ./real --gen-dir ./fake --clips-per-video 8也可以将参考集与生成集各自多准备一些视频文件(--clips-per-video是从单段视频内采样,视频数量与每视频 clip 数共同决定总样本量)。若单视频过短(总帧数 < 16),脚本会通过重复最后一帧补齐,但短视频本身会降低 clip 内容多样性,建议优先保证视频时长与数量。
权重文件问题
- 自动下载后校验 SHA-256 失败:脚本会删除损坏文件并提示重试或手动下载;
- 手动传入不存在的路径:报
FileNotFoundError: Weights not found: <path>; - 传入与 I3D 主干不匹配的 checkpoint:
load_state_dict的 strict 校验会报Checkpoint does not match the I3D backbone(缺失/多余的键名会列出)。
十、进一步探索
- 主 README:examples/windows/accuracy_benchmark/README.md(MMLU 等更多基准的 Windows 环境评估指引);
- 相关指标:KL 散度工具见 examples/windows/accuracy_benchmark/kl_divergence_metrics,Perplexity 工具见 examples/windows/accuracy_benchmark/perplexity_metrics;
- 基准结果汇总:examples/windows/Benchmark.md(含 FVD、Perplexity、KL-divergence 与 MMLU 的多模型对照表);
- 量化感知蒸馏(QAD)在仓库中的工程落地可参考 examples/alpamayo/qad.py(基于
modelopt.torch.quantization.plugins.transformers_trainer的QADTrainer)与 examples/diffusers/README.md 中关于 QAD 与 QAT 的介绍,理解"为什么 QAD 能比 PTQ 更接近 BF16 基线"背后的训练与蒸馏机制。
- 人工智能
- 大模型
- 模型优化
- 模型量化
- 模型压缩
【免费下载链接】Model-Optimizer
A unified library of SOTA model optimization techniques like quantization, distillation, pruning, neural architecture search, speculative decoding, etc. It compresses deep learning models for downstream deployment frameworks like TensorRT-LLM, TensorRT, vLLM, etc. to optimize inference speed.
相关推荐
Fréchet Video Distance(FVD)视频生成质量评估实战指南:基于 I3D 嵌入的距离度量
Fréchet Video Distance(FVD)视频生成质量评估实战指南:基于 I3D 嵌入的距离度量 FVD(Fréchet Video Distanc
人工智能深度学习NLP计算机视觉强化学习基于 DeepSpeech2 特征空间的 FDSD 语音质量评估:google-research ged_tts 中 Fréchet Deep Speech Distance 重实现的原理与实战
基于 DeepSpeech2 特征空间的 FDSD 语音质量评估:google research ged_tts 中 Fréchet Deep Speech D
人工智能深度学习NLP计算机视觉强化学习TensorLayer视频生成评估:FVD与LPIPS指标计算
TensorLayer视频生成评估:FVD与LPIPS指标计算 你是否还在为视频生成模型的质量评估而烦恼?面对生成的视频,如何客观量化其与真实视频的差距?本文将
人工智能深度学习机器学习强化学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考