评估FID与CLIP分数 本节摘要:每个生成模型排行榜都引用 FID、CLIP 分数、以及来自人类偏好竞技场的胜率。每个数字都有一种「坚定的研究者能钻空子」的失败模式。如果你不知道这些失败模式,你就分不清「真正的改进」和「刷分」。本节讲透三大存活指标:FID(在 Inception 特征空间里衡量真实/生成两个分布的 Fréchet 距离,越小越好)、CLIP 分数(生成图的 CLIP 图像嵌入与提示的 CLIP 文本嵌入的余弦相似度,衡量提示遵从度)、人类偏好(两两对比聚合为 Elo)。
本节摘要:每个生成模型排行榜都引用 FID、CLIP 分数、以及来自人类偏好竞技场的胜率。每个数字都有一种「坚定的研究者能钻空子」的失败模式。如果你不知道这些失败模式,你就分不清「真正的改进」和「刷分」。本节讲透三大存活指标:FID(在 Inception 特征空间里衡量真实/生成两个分布的 Fréchet 距离,越小越好)、CLIP 分数(生成图的 CLIP 图像嵌入与提示的 CLIP 文本嵌入的余弦相似度,衡量提示遵从度)、人类偏好(两两对比聚合为 Elo)。我们会逐一拆解它们的失败模式——FID 在小 N 下有偏、依赖 ImageNet 域;CLIP 有组合推理盲点、对短提示有偏;Elo 受提示分布与 LLM 评委作弊影响——并给出 CMMD、HPSv2、ImageReward 等修正方案,以及「单一指标都是谎言,三指标交叉验证 + 定性复核才算结论」的生产评估协议。
对应原课程:Phase 08 · Lesson 14 ·
evaluation-fid-clip-score(原英文phases/08-generative-ai/14-evaluation-fid-clip-score/docs/en.md)。
阅读完本节,你应当能够:
||μ_r−μ_g||² + Tr(Σ_r+Σ_g−2(Σ_rΣ_g)^0.5)),并说出它三大失败模式(小 N 有偏、依赖 ImageNet 域、可被刷分)。生成模型按样本质量与条件遵从度被评判。两者都没有闭式度量。你的模型要渲染 1 万张图;有东西要给它们打分;你要信任这些分数能跨模型家族、跨分辨率、跨架构。三个指标活过了 2014-2026 的考验:
你还会看到:IS(Inception Score,基本退役)、KID、CMMD、ImageReward、PickScore、HPSv2、MJHQ-30k。每一个都修正了前一个的某种失败。
Heusel 等(2017)。步骤:
μ_r, μ_g 和协方差 Σ_r, Σ_g。FID = ||μ_r − μ_g||² + Tr(Σ_r + Σ_g − 2·(Σ_r·Σ_g)^0.5)。解释:特征空间里两个多元高斯的 Fréchet 距离。越低 = 分布越相似。
失败模式:
Radford 等(2021)。对一张生成图 + 提示:
clip_score = cos_sim( CLIP_image(x_gen), CLIP_text(prompt) )
在 3 万张生成图上平均 → 一个可跨模型比较的标量。
失败模式:
CMMD(Jayasumana 等,2024)修正了部分:用 CLIP 特征而非 Inception,用最大均差异(MMD)而非 Fréchet。在检测细微质量差异上更好。
选一批提示。用模型 A 和 B 各生成。把成对图给人类(或强 LLM 评委)看,把胜负聚合成 Elo 或 Bradley-Terry 分。基准:
失败模式:
一份生产评估报告应包含:
💡 核心原则:任何单一指标都是谎言。三个相互印证的指标 + 定性复核,才算一个结论。这也是为什么 2026 年的论文如果只报 FID,基本会被审稿人要求补 CLIP + 人类评估——单一指标既容易刷分,也无法刻画「质量」这个多面体。
code/main.py 在合成「特征向量」(用 4 维向量当 Inception 特征的替身)上实现 FID、CLIP 风格分数、Elo 聚合。你会看到:
def fid(real_features, gen_features): mu_r, cov_r = mean_and_cov(real_features) mu_g, cov_g = mean_and_cov(gen_features) mean_diff = sum((a - b) ** 2 for a, b in zip(mu_r, mu_g)) trace_term = trace(cov_r) + trace(cov_g) - 2 * sqrt_cov_product(cov_r, cov_g) return mean_diff + trace_term
def clip_like(image_feat, text_feat): dot = sum(a * b for a, b in zip(image_feat, text_feat)) norm = math.sqrt(dot_self(image_feat) * dot_self(text_feat)) return dot / max(norm, 1e-8)
def elo_update(r_a, r_b, winner, k=32): expected_a = 1 / (1 + 10 ** ((r_b - r_a) / 400)) actual_a = 1.0 if winner == "a" else 0.0 r_a_new = r_a + k * (actual_a - expected_a) r_b_new = r_b - k * (actual_a - expected_a) return r_a_new, r_b_new
N=1000 的 FID:N < 1 万时启发式不可靠。报低 N FID 的论文在刷分。
跨分辨率比 FID:Inception 的 299×299 缩放改变特征分布。只在匹配分辨率下比较。
只报一个种子:最少跑 3 个种子,报标准差。
负向提示抬 CLIP 分数:有些流水线通过过拟合提示来抬 CLIP。检查是否有视觉饱和。
Elo 受提示重叠偏置:如果两个模型在训练时都见过某基准提示,Elo 无意义。用留出提示集。
人类评估众包偏置:Prolific、MTurk 标注者偏年轻 / 技术友好。与招募的艺术/设计专家混合。
⚠️ FID 在小 N 下「虚低」的数学:FID 的协方差项
Tr(Σ)是d=2048维协方差的迹。当N < d(比如 N=1000 < 2048),经验协方差矩阵是秩亏的,会系统性低估真实协方差,于是Tr(Σ_r + Σ_g − ...)偏小,FID 虚低。这就是为什么「N ≥ 10000」是硬性要求,不是建议。
| 支柱 | 最低 | 推荐 |
|---|---|---|
| 样本质量 | 1 万样本对留出真实的 FID | + 5k 上 CMMD + 按类别子集 FID |
| 提示遵从 | 3 万上 CLIP 分数 | + HPSv2 + ImageReward + VQA 式问答 |
| 偏好 | 200 对盲选对基线 | + 2000 对人类 + LLM 评委 + Chatbot Arena |
| 失败分析 | 50 张手工标记 | + 500 张手工标记 + 自动安全分类器 |
四支柱齐全才算结论;任何单一支柱都是营销。
在 1 万样本上跑 FID 意味着生成 1 万张图。对 50 步 SDXL base、1024²、单卡 L4,那是约 11 小时的单请求推理。评估预算是真的,框架正是离线推理场景(最大化吞吐,忽略 TTFT):
硬批处理,忘掉延迟:离线评估 = 内存能装下的最大静态批。pipe(...).images 配 num_images_per_prompt=8 在 80GB H100 上比单请求快 4-6 倍墙上时钟。
缓存真实特征:对真实参考集的 Inception(FID)或 CLIP(CLIP 分数、CMMD)特征提取只跑一次,存成 .npz。不要每次评估重算。
CI / 回归门:每个 PR 在 500 样本子集上跑 FID + CLIP 分数(~30 分钟);每晚跑完整 1 万 FID + HPSv2 + Elo。
本节产出一个评估报告技能文件(位于原课程 outputs/skill-eval-report.md)。
skill-eval-report.md:输入新模型 checkpoint + 基线,输出完整评估计划:样本量、指标、失败模式探针、签字标准。简单。 跑 code/main.py。在同一合成分布上比较 N=100 vs N=1000 的 FID。报告偏差幅度。
中等。 用合成 CLIP 风格特征实现 CMMD(公式见 Jayasumana 等,2024)。比较它对质量差异的敏感度 vs FID。
困难。 复现 HPSv2 设置:从 Pick-a-Pic 子集取 1000 个图像-提示对,在偏好上微调一个小 CLIP 评分器,测量它与留出集的一致度。
下一节(原第 19 节),我们回到第 01 节五大家族的「桶 5」——视觉自回归 VAR:用 VQ-VAE 把图像压成离散 token,再用「粗到细的多尺度 token」而非「逐 token」自回归,把 Transformer 的扩展律带进图像生成,挑战扩散的统治地位。