4、数据量选择:最小数据量原则、数据量对精度的影响曲线、如何确定最佳数据量
聊到校准数据集的大小,我见过不少同学一上来就问:「用 1000 张图够不够?」或者「是不是越多越好?」
嗯,这个问题其实没那么简单。数据量选少了,校准出来的模型精度掉得厉害;选多了,不仅浪费时间,还可能过拟合到校准集上。说白了,这里有个「最小数据量原则」在起作用。
4.1 最小数据量原则:够用就好,别贪多
我个人习惯把校准数据集看作「模型在低精度下的一个参考样本」。你想想看,我们做 PTQ 的本质,就是用一小批数据去模拟模型在 FP32 下的激活分布,然后把这个分布量化到 INT8 上。
所以,数据量只要能稳定地反映出真实分布就够了。我在项目中遇到过,有时候 32 张图就能达到 512 张图 95% 以上的效果。再多,边际收益就急剧下降。
那什么叫「够用」?我一般看两个指标:
- 分布稳定性: 不同批次的数据,算出来的 scale 和 zero_point 波动小于 1%
- 精度收敛性: 再增加数据量,模型精度不再明显提升
4.2 数据量对精度的影响曲线
这个曲线我画过很多次了。说白了,它就是一个典型的「饱和曲线」。
下面这张图是我根据实际项目数据绘制的,你可以直观感受一下:
从这张图你可以看到几个关键阶段:
- 快速上升区(4~64 张): 每增加几张图,精度提升非常明显。这个阶段,数据量是瓶颈。
- 过渡区(64~256 张): 精度提升变缓,但仍有收益。我一般会在这个区间做最终选择。
- 饱和区(256 张以上): 曲线几乎平了。再加数据,精度可能反而因为过拟合而轻微下降。
4.3 如何确定最佳数据量
那具体怎么找这个「最佳点」?我分享一个我自己常用的方法,分三步走:
步骤一:做一次小规模扫描
选几个典型的数据量,比如 [4, 16, 64, 256, 1024],分别做一次 PTQ 校准,然后评估精度。别嫌麻烦,这一步花不了多少时间,但能给你一个直观的「精度-数据量」曲线。
# 伪代码示例
data_sizes = [4, 16, 64, 256, 1024]
results = {}
for size in data_sizes:
calib_loader = create_calib_loader(dataset, batch_size=size)
quantized_model = ptq_calibrate(model, calib_loader)
acc = evaluate(quantized_model, val_loader)
results[size] = acc
print(f"Data size {size}: accuracy = {acc:.4f}")
# 找到精度变化小于 0.1% 的最小数据量
best_size = find_elbow_point(results)
print(f"Recommended data size: {best_size}")
步骤二:找「肘点」
画出曲线后,找到那个「拐弯」的地方。说白了,就是再增加数据量,精度提升已经不明显了。我一般用这个规则:连续两次增加数据量,精度提升都小于 0.1%,那当前的数据量就是最佳点。
步骤三:验证稳定性
找到候选数据量后,别急着定下来。用不同的随机种子,重新采样 3~5 次,看看精度波动大不大。如果波动超过 0.3%,说明数据量还不够,需要再加一些。
| 数据量 | 第1次 | 第2次 | 第3次 | 均值 | 波动范围 | 结论 |
|---|---|---|---|---|---|---|
| 32 | 98.2% | 98.5% | 97.9% | 98.2% | 0.6% | 波动偏大 |
| 64 | 98.8% | 98.9% | 98.7% | 98.8% | 0.2% | ✅ 稳定 |
| 128 | 99.0% | 99.0% | 98.9% | 99.0% | 0.1% | ✅ 非常稳定 |
从这张表你可以看到,64 张已经足够稳定了。128 张虽然更稳,但精度提升只有 0.2%,性价比不高。
4.4 一些实战中的坑
最后,我分享几个我在项目中踩过的坑,希望能帮你避开:
- 坑一:数据分布不均衡。 我曾经只用白天场景的图片做校准,结果模型在夜间场景下精度直接掉了 5%。所以,校准数据一定要覆盖你关心的所有场景。
- 坑二:重复数据。 校准集里如果有大量重复或高度相似的图片,相当于有效数据量被稀释了。我一般会用哈希去重,确保每张图都是独特的。
- 坑三:只看精度不看速度。 数据量越大,校准时间越长。如果你用的是 1000 张图,每次校准要跑 10 分钟,那迭代效率就太低了。在精度和速度之间找个平衡点。
公众号:蓝海资料掘金营,微信deep3321