2、性能测试指标体系:帧率(FPS)、延迟(Latency)、功耗(Power)、内存占用(Memory)、模型精度(Accuracy)
好,咱们直接进入正题。性能测试,说白了就是回答一个问题:这个模型在端上到底能不能用?
我见过太多团队,模型在服务器上跑得飞起,一部署到摄像头模组上就卡成PPT。为什么?因为端侧的资源是有限的,CPU、内存、电池,样样都得省着用。
所以,我们需要一套完整的指标体系。我个人习惯把这五个指标称为「端侧五维」:帧率、延迟、功耗、内存、精度。缺一个,你的测试报告就不完整。
2.1 帧率(FPS)—— 流畅度的硬指标
帧率,就是每秒能处理多少帧图像。单位是fps。
为什么重要?
你想想看,如果做实时人脸检测,帧率低于15fps,画面就会明显卡顿。做工业质检,帧率低了,产线就得停。
我的经验阈值:
- 实时交互(如人脸解锁):≥ 30fps
- 视频监控分析:≥ 15fps
- 静态图像分析(如扫码):≥ 5fps 即可
怎么测?
我一般用两种方法。一种是直接读推理引擎的API返回,另一种是用高帧率相机拍摄屏幕,数帧数。后者更真实,因为包含了显示延迟。
// 伪代码示例:计算FPS
int frameCount = 0;
long startTime = getCurrentTimeMs();
while (running) {
processFrame(cameraFrame);
frameCount++;
long elapsed = getCurrentTimeMs() - startTime;
if (elapsed >= 1000) {
float fps = frameCount / (elapsed / 1000.0f);
printf("Current FPS: %.2f\n", fps);
frameCount = 0;
startTime = getCurrentTimeMs();
}
}
避坑指南:我曾经遇到过一个问题——测试时帧率很高,但实际体验很卡。后来发现是推理引擎内部做了帧缓存,返回的FPS是「处理帧率」,不是「显示帧率」。所以,我建议你同时测「处理FPS」和「显示FPS」两个值。
2.2 延迟(Latency)—— 响应速度的生命线
延迟,就是从图像输入到结果输出的总耗时。单位是毫秒(ms)。
帧率和延迟是「表兄弟」,但不一样。帧率高不一定延迟低。举个例子:一个模型可以每秒处理30帧,但每一帧的处理延迟可能是100ms。这在某些场景下是不能接受的。
延迟的分解:
我个人习惯把延迟拆成三部分:
- 预处理延迟:图像缩放、归一化、颜色空间转换。这部分容易被忽略,但往往占大头。
- 推理延迟:模型前向计算的时间。这是核心。
- 后处理延迟:NMS(非极大值抑制)、解码、结果格式化。
注意:在端侧,预处理和后处理的耗时可能比推理本身还长。我见过一个项目,模型推理只用了20ms,但图像预处理用了80ms。优化了模型,但整体延迟没降下来。白费功夫。
怎么测?
用高精度计时器。在代码里埋点,分别记录每个阶段的开始和结束时间。
// 伪代码:延迟分解
uint64_t t0 = getTimeUs(); // 开始
preprocess(image); // 预处理
uint64_t t1 = getTimeUs();
inference(model, input); // 推理
uint64_t t2 = getTimeUs();
postprocess(output); // 后处理
uint64_t t3 = getTimeUs();
printf("Preprocess: %ld us\n", t1 - t0);
printf("Inference: %ld us\n", t2 - t1);
printf("Postprocess: %ld us\n", t3 - t2);
printf("Total: %ld us\n", t3 - t0);
2.3 功耗(Power)—— 续航的隐形杀手
端侧设备,尤其是电池供电的,功耗是硬约束。模型再准,如果跑10分钟就没电了,那也没用。
怎么测?
我常用的方法有两种:
- 硬件方式:用高精度电流计(如I2C接口的INA219)串联在电源路径上,实时采集电流和电压。
- 软件方式:读取芯片内部的功耗寄存器(如高通平台的msm_power_stats)。
关键指标:
| 指标 | 说明 | 我的建议 |
|---|---|---|
| 平均功耗 | 一段时间内的平均功率 | 用于评估续航 |
| 峰值功耗 | 瞬间最大功率 | 用于评估散热和电源设计 |
| 能效比 | FPS / 功耗(fps/W) | 我最看重的指标,越高越好 |
我的经验:我曾经优化一个模型,把FPS从20提升到了30,但功耗从2W涨到了3.5W。能效比反而下降了。所以,不要只看FPS,要看「每瓦特能跑多少帧」。这才是端侧的真功夫。
2.4 内存占用(Memory)—— 资源的紧箍咒
端侧设备的内存通常很有限。几百MB甚至几十MB。模型一加载,内存就爆了。
需要关注的内存类型:
- 模型大小:模型文件在磁盘上的大小。影响下载和存储。
- 运行时内存:模型加载到内存后占用的空间。包括权重、中间激活值、输入输出缓冲区。
- 峰值内存:推理过程中内存使用的最大值。这个最危险,容易导致OOM(内存溢出)。
怎么测?
在Linux端侧设备上,我常用 /proc/self/status 或 smem 工具。在Android上,用 dumpsys meminfo。
# 命令行查看进程内存
cat /proc/$(pidof my_app)/status | grep VmRSS
# 输出示例:VmRSS: 245680 kB
注意:内存占用不是一成不变的。不同的输入分辨率、不同的batch size,内存占用差异很大。我建议你测试「最坏情况」——最大分辨率、最大batch size下的内存峰值。
2.5 模型精度(Accuracy)—— 一切的基础
精度是根本。帧率再高、延迟再低,如果识别不准,一切都是零。
端侧精度测试的特殊性:
模型从服务器移植到端侧,精度往往会下降。原因包括:
- 量化误差:FP32转INT8,精度损失不可避免。
- 算子差异:端侧推理引擎的算子实现可能与训练框架不完全一致。
- 输入差异:端侧摄像头的图像质量、光照条件与训练数据不同。
我的测试方法:
我习惯准备一套标准的测试集(至少1000张图片),在服务器上跑出基准精度,然后在端侧跑同样的测试集,对比精度差异。
| 精度指标 | 适用场景 | 端侧可接受偏差 |
|---|---|---|
| mAP(平均精度均值) | 目标检测 | ≤ 2% |
| Top-1 Accuracy | 分类任务 | ≤ 1% |
| IoU(交并比) | 语义分割 | ≤ 3% |
核心原则:这五个指标不是孤立的。它们互相制约。你优化了帧率,可能牺牲了精度;你降低了功耗,可能增加了延迟。所以,测试时一定要做「联合分析」。我通常的做法是:固定精度要求,然后去优化其他四个指标。精度是底线,不能妥协。
嗯,这五个指标,就是端侧AI视觉测试的「五脏六腑」。下一章,我会讲具体的测试工具和平台搭建。到时候咱们再细聊。