量化精度评估指标:量化前后精度对比方法、余弦相似度、KL散度、Top-1/Top-5准确率
做量化部署,最怕什么?
怕模型跑得飞快,但精度掉得一塌糊涂。我见过不少团队,模型量化后推理速度翻倍,结果上线一看,用户反馈全是「这AI是不是傻了?」——说白了,精度评估没做到位。
今天咱们就聊聊量化精度评估这件事。我个人习惯把这部分分成四个维度来看:全局指标(Top-1/Top-5)、分布相似度(余弦相似度、KL散度)、逐层对比,以及业务指标兜底。嗯,一个一个来。
1. Top-1 / Top-5 准确率:最直观的「体检报告」
这是最常用的指标,没有之一。你训练一个分类模型,量化前后各跑一遍验证集,对比一下准确率变化,心里就有底了。
Top-1 = 预测概率最高的类别 == 真实标签 ? 1 : 0
Top-5 = 真实标签是否在预测概率前5的类别中 ? 1 : 0
我在项目中遇到过一件事:某个模型量化后Top-1掉了2.3%,团队差点就要回退方案。后来我让他们看了Top-5,只掉了0.4%。这说明什么?模型其实没「傻」,只是第一选择有点犹豫,但候选集里正确答案还在。这种场景下,业务上完全可以接受。
2. 余弦相似度:逐层「照镜子」
准确率是宏观指标,但有时候模型精度没掉,中间层的特征分布却已经「变形」了。这时候就需要余弦相似度。
说白了,余弦相似度就是衡量两个向量方向是否一致。量化前后,同一层的输出特征向量,如果余弦值接近1,说明量化没怎么破坏特征表达;如果掉到0.9以下,就要警惕了。
import torch
import torch.nn.functional as F
def cosine_similarity(tensor_a, tensor_b):
# tensor_a: 量化前输出, tensor_b: 量化后输出
a_flat = tensor_a.view(tensor_a.size(0), -1)
b_flat = tensor_b.view(tensor_b.size(0), -1)
cos_sim = F.cosine_similarity(a_flat, b_flat, dim=1)
return cos_sim.mean().item()
# 示例:对比某层输出
float_out = torch.randn(64, 256) # 模拟浮点输出
quant_out = float_out * 0.97 # 模拟量化后微小偏差
sim = cosine_similarity(float_out, quant_out)
print(f"余弦相似度: {sim:.4f}")
你想想看,如果某一层的余弦相似度突然降到0.85以下,那这一层大概率是「精度瓶颈」。我曾经排查过一个模型,发现第7层卷积的余弦相似度只有0.82,其他层都在0.95以上。后来针对这一层做了混合精度(保留浮点),整体精度就回来了。
3. KL散度:量化前后的「信息损失」
KL散度衡量的是两个概率分布之间的差异。在量化场景里,我们用它来对比浮点模型和量化模型的输出分布。
公式长这样:
DKL(P || Q) = Σ P(x) · log(P(x) / Q(x))
值越小,说明量化后的分布越接近原始分布。我个人习惯在校准阶段就用KL散度来选量化参数——比如TensorRT的INT8校准,默认用的就是KL散度。
import numpy as np
from scipy.special import kl_div
def kl_divergence(p, q):
# p: 浮点模型输出概率分布
# q: 量化模型输出概率分布
p = np.clip(p, 1e-10, 1.0) # 避免log(0)
q = np.clip(q, 1e-10, 1.0)
return np.sum(kl_div(p, q))
# 示例
float_probs = np.array([0.1, 0.2, 0.3, 0.4])
quant_probs = np.array([0.12, 0.19, 0.28, 0.41])
kl_val = kl_divergence(float_probs, quant_probs)
print(f"KL散度: {kl_val:.6f}")
这里有个坑:KL散度是非对称的。也就是说,DKL(P||Q) 和 DKL(Q||P) 不一样。我曾经在项目里用反了方向,结果发现量化后的「异常层」怎么都找不对。后来改成以浮点分布为基准P,量化分布为Q,才定位到问题。
4. 综合评估流程:我的「三板斧」
在实际项目中,我不会只依赖某一个指标。我的流程一般是这样的:
- 先跑Top-1/Top-5:快速判断量化后模型是否「可用」。如果掉点超过1%,进入下一步。
- 逐层计算余弦相似度:找出「异常层」。通常余弦值低于0.9的层需要重点关注。
- 对异常层计算KL散度:确认分布偏移程度。如果KL散度大于0.01(经验值),考虑混合精度或调整量化参数。
- 业务指标兜底:比如检测任务的mAP、推荐任务的AUC。这些才是最终说了算的。
5. 一张图总结:量化精度评估体系
下面这张图是我自己总结的评估体系,每次做量化项目都会贴在墙上。你感受一下:
6. 一些实战中的「小九九」
最后分享几个我踩过的坑,希望能帮你省点时间:
- 校准集要覆盖真实分布:我见过有人用100张猫图去校准一个包含狗、车、人的模型。结果KL散度算出来很好看,上线后直接崩。校准集一定要有代表性。
- 不要只看均值:余弦相似度平均0.97,但可能有某几个batch只有0.6。建议同时看最小值和方差。
- Top-1掉点0.5%以内,通常不用管:这是经验值。如果业务要求极高(比如医疗影像),那另当别论。
- 量化后精度反而提升?:别高兴太早。有时候量化引入的噪声恰好「正则化」了过拟合的模型。这种情况在验证集上可能好看,但泛化性不一定好。建议多测几个数据集。
| 层名 | 余弦相似度 | KL散度 | Top-1变化 | Top-5变化 | 结论 |
|---|---|---|---|---|---|
| Conv_1 | 0.998 | 0.0003 | -0.1% | -0.02% | 正常 |
| Conv_7 | 0.823 | 0.0150 | -1.8% | -0.5% | 需修复 |
| FC_out | 0.971 | 0.0021 | -0.3% | -0.1% | 正常 |
嗯,量化精度评估这件事,说白了就是「用合适的尺子,量对的地方」。Top-1/Top-5是宏观尺子,余弦相似度和KL散度是微观放大镜。结合起来用,你就能精准定位问题,而不是盲目调参。
希望这些经验对你有帮助。下次遇到量化精度掉点,别慌,按这个流程走一遍,大概率能找到根因。
公众号:蓝海资料掘金营,微信deep3321