4、帧率测试方法:掌握帧率(FPS)的定义、测试方法(单线程/多线程、批处理)、测试场景(不同分辨率、不同模型)以及如何排除干扰因素

帧率(Frames Per Second,FPS)是衡量RKNN模型在NPU上推理实时性的核心指标,直接决定了部署方案能否满足实际业务场景的响应要求。在RKNN部署验收中,帧率测试并非简单地跑一个计时循环,而是需要明确测试边界、控制变量、区分不同运行模式,并识别出影响帧率数据的隐性干扰因素。本节将系统讲解帧率的定义与计算口径、单线程/多线程与批处理的测试方法、不同分辨率和模型下的场景化测试策略,以及干扰因素的排除与数据可信度评估。

RKNN 帧率测试方法体系 FPS 定义与口径 • 单帧耗时 = 预处理+推理+后处理 • 纯NPU推理FPS(不含前后处理) • 端到端FPS(含图像采集与显示) • 平均FPS vs 稳定FPS(P95/P99) 测试方法 • 单线程串行:逐帧推理,最接近真实调用 • 多线程并行:流水线/多路并发 • 批处理:batch=1/2/4/8 吞吐对比 • 预热轮数 + 正式计时轮数 测试场景 • 不同分辨率:320×240 / 640×480 / 1920×1080 • 不同模型:轻量级 / 中量级 / 重量级 • 不同NPU频率:normal / high / boost • 单路 vs 多路视频流 干扰因素排除与数据可信度 CPU 频率锁定 NPU 频率锁定 DDR 带宽占用 温度降频 后台进程干扰 • 使用 performance governor • 通过 sysfs 节点固定 NPU 频率 • 关闭无关 GPU/编解码任务 • 监控 SoC 温度,控制测试时长 • 最小化系统服务,重复多次取中位数 • 预热 10~30 轮,待 NPU 达到稳态 • 记录每帧耗时,计算均值/中位数/P95 • 剔除首帧和异常值(如调度抖动) • 对比多次测试结果,标准差 < 5% • 输出测试环境快照(温度/频率/负载) 帧率测试 = 明确定义 + 控制变量 + 场景覆盖 + 数据统计

4.1 帧率定义与计算口径

帧率在RKNN部署语境下并非一个单一数值,而是根据测试目的不同存在多种计算口径。最基础的定义是单位时间内完成的推理次数,即 FPS = 总帧数 / 总耗时。但在实际工程中,需要区分以下三种口径:

  • 纯NPU推理FPS:仅统计rknn_run接口的耗时,不包含图像预处理(resize、cvtColor、归一化)和后处理(NMS、解码)。该指标反映NPU本身的算力表现,适合评估模型在硬件上的理论性能。
  • 端到端FPS:从输入图像获取到最终输出结果的全链路耗时,包括图像解码、预处理、NPU推理、后处理以及必要的拷贝操作。该指标更接近实际部署效果,是验收时最常使用的口径。
  • 稳定FPS vs 平均FPS:平均FPS是总帧数除以总时间,而稳定FPS通常取P95或P99分位值,用于衡量在长时间运行下帧率的波动情况。对于视频流处理场景,稳定FPS比平均FPS更具参考价值。

在测试报告中,必须明确标注所采用的帧率口径。例如,某模型在RK3588上纯NPU推理可达120 FPS,但端到端仅45 FPS,两者差异主要来自预处理和后处理的开销。若验收标准要求端到端达到30 FPS,则纯NPU的120 FPS并不能作为通过依据。

经验提醒:建议在测试脚本中同时输出三种口径的FPS值,并记录每帧耗时的分布情况。这样既能定位性能瓶颈在NPU还是CPU侧,也能为后续优化提供数据支撑。

4.2 单线程、多线程与批处理测试方法

RKNN推理的调用方式直接影响帧率表现。根据实际业务场景,需要选择对应的测试方法:

4.2.1 单线程串行测试

单线程串行是最基础的测试方式,即逐帧执行“预处理 → 推理 → 后处理”流程,每帧完成后才开始下一帧。这种方式模拟了最简单的调用逻辑,适合评估模型在无并发压力下的真实耗时。测试时需要注意:

  1. 预热阶段:先运行10~30帧,让NPU驱动完成初始化、内存分配和频率提升,避免首帧耗时拉低平均值。
  2. 正式计时:连续运行至少100帧或持续5秒以上,记录总耗时并计算FPS。
  3. 内存复用:在循环外预先分配输入输出缓冲区,避免每帧重复malloc/free带来的额外开销。
// 单线程测试伪代码
rknn_init(&ctx, model_path, 0);
rknn_query(ctx, &input_attr, RKNN_QUERY_INPUT_ATTR);
// 预热
for (int i = 0; i < 20; i++) {
    rknn_run(ctx, &input, &output);
}
// 正式计时
uint64_t start = get_time_us();
for (int i = 0; i < 200; i++) {
    preprocess(frame[i], &input);   // 预处理
    rknn_run(ctx, &input, &output); // NPU推理
    postprocess(&output, result);   // 后处理
}
uint64_t end = get_time_us();
double fps = 200.0 / ((end - start) / 1e6);

4.2.2 多线程并行测试

多线程测试用于模拟真实业务中的并发场景,常见有两种模式:

  • 流水线模式:使用三个线程分别负责预处理、NPU推理、后处理,通过队列传递数据。这种模式可以隐藏预处理和后处理的耗时,提升整体吞吐量。测试时需关注队列是否为空(表示处理速度跟不上)或队列是否积压(表示上游过快)。
  • 多路并发模式:同时开启多个推理线程,每个线程独立处理一路视频流。此时需要关注NPU的资源争抢情况,以及RKNN驱动是否支持多实例并发。测试结果应记录每路视频的独立FPS和总体FPS。

多线程测试的难点在于线程同步和资源竞争。建议使用条件变量或原子操作控制任务分发,避免使用sleep进行粗略同步。测试时需记录CPU占用率,确保多线程开销不会成为瓶颈。

4.2.3 批处理测试

RKNN支持将多张图像打包为一个batch进行推理,从而提升NPU利用率。批处理测试的步骤如下:

  1. 分别测试batch=1、2、4、8时的FPS和单帧平均耗时。
  2. 计算吞吐量(FPS × batch),评估批处理带来的收益。
  3. 注意内存占用:batch越大,输入输出缓冲区占用越多,需确认板卡内存是否充足。
Batch大小 单帧平均耗时 (ms) 端到端FPS 吞吐量 (帧/s) 内存占用 (MB)
1 22.5 44.4 44.4 128
2 18.2 27.5 55.0 210
4 15.8 15.8 63.2 380
8 14.1 8.9 71.2 720

从上表可以看出,batch=4时吞吐量较batch=1提升约42%,但单帧延迟从22.5ms降至15.8ms(单帧延迟 = 批处理总耗时 / batch)。实际部署时需权衡延迟和吞吐量的需求:若对单帧延迟敏感(如实时交互),应选择小batch;若追求最大吞吐(如离线批量处理),可适当增大batch。

4.3 不同分辨率与不同模型的测试场景

帧率并非固定值,而是随输入分辨率和模型复杂度动态变化。验收测试必须覆盖目标场景中的典型配置。

4.3.1 不同分辨率测试

输入分辨率直接影响NPU的计算量。以YOLOv5s为例,在RK3588上不同分辨率的实测帧率如下:

输入分辨率 NPU计算量 (GMACs) 纯NPU推理FPS 端到端FPS
320×320 4.2 185 92
640×640 16.8 62 38
1280×1280 67.2 18 12

测试时需注意:分辨率改变后,预处理中的resize耗时也会变化,且NPU内部可能对非对齐尺寸进行padding,导致实际计算量高于理论值。建议测试分辨率覆盖:最低分辨率(保证帧率上限)、目标分辨率(验收基准)、最高分辨率(评估性能余量)。

4.3.2 不同模型测试

不同模型的结构差异(如卷积核大小、通道数、是否含注意力机制)会导致NPU利用率不同。测试时应选择具有代表性的模型:

  • 轻量级模型:如MobileNetV3、ShuffleNetV2,用于评估NPU在低计算量下的调度效率。
  • 中量级模型:如YOLOv5s、ResNet50,作为主流业务的性能基准。
  • 重量级模型:如YOLOv8x、DeepLabV3+,用于评估NPU的峰值算力。

测试结果应记录每个模型的FPS、NPU利用率(可通过rknn_query查询)和内存占用。若发现某模型FPS异常低,需检查是否因模型中的某些算子(如动态shape、自定义op)导致NPU无法完全加速。

风险提示:不要只测试单一分辨率和单一模型。实际部署中,摄像头输入分辨率、ROI裁剪尺寸、模型输入要求都可能变化。建议建立“分辨率 × 模型”的测试矩阵,至少覆盖3种分辨率 × 3种模型,共9组测试,才能全面评估帧率表现。

4.4 干扰因素排除与数据可信度评估

帧率测试结果的可信度取决于对干扰因素的控制。以下因素会显著影响测试数据,必须在测试过程中加以排除或记录:

4.4.1 频率与功耗干扰

RK3588等平台的CPU和NPU频率受调频策略影响,默认情况下会随负载动态变化。测试前需执行以下操作:

# 锁定CPU频率为最高性能
echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 锁定NPU频率(以RK3588为例)
echo "1000000000" > /sys/class/devfreq/fdab0000.npu/userspace/set_freq
echo "userspace" > /sys/class/devfreq/fdab0000.npu/governor

同时需监控SoC温度,当温度超过85°C时,NPU可能触发降频保护,导致帧率骤降。建议测试环境温度控制在25°C±5°C,并使用散热风扇或散热片保证温度稳定。

4.4.2 系统负载干扰

后台进程(如日志服务、看门狗、网络同步)会占用CPU和DDR带宽,间接影响NPU推理速度。测试前应:

  • 关闭不必要的系统服务:systemctl stop rsyslog、systemctl stop NetworkManager等。
  • 使用taskset将测试进程绑定到指定CPU核心,避免调度抖动。
  • 检查DDR带宽占用:可通过perf stat或rknn_benchmark工具观察内存带宽使用率。

4.4.3 数据统计方法

即使控制了上述因素,单次测试仍可能存在随机波动。正确的统计方法如下:

  1. 每组测试重复至少3次,每次测试间隔30秒以上,让NPU温度回落。
  2. 计算每次测试的FPS,取中位数作为最终结果,而非平均值(平均值易受极端值影响)。
  3. 记录P95和P99分位值,评估帧率稳定性。若P95与中位数差异超过15%,说明存在明显的帧率抖动。
  4. 计算多次测试的标准差,若标准差超过5%,需检查测试环境是否一致。
案例拆解:某安防项目在RK3588上部署YOLOv5s,验收标准为1080P分辨率下端到端FPS≥25。初次测试结果为平均FPS=28,看似达标。但进一步分析发现:P95 FPS仅为19,且测试过程中SoC温度从55°C升至82°C,NPU频率从1.0GHz降至800MHz。通过锁定NPU频率并加强散热后,重新测试得到:平均FPS=31,P95 FPS=28,标准差2.1%,数据稳定达标。复盘经验:仅看平均FPS会掩盖降频和抖动问题,必须结合温度监控和分位值统计才能真实反映部署性能。

4.5 常见误区与总结复盘

在帧率测试中,以下误区需要特别注意:

  • 误区一:只测纯NPU推理FPS。纯NPU推理无法反映真实部署性能,必须结合预处理和后处理耗时。
  • 误区二:忽略预热直接计时。首帧包含模型加载和内存初始化,耗时可能是正常帧的5~10倍,会严重拉低平均值。
  • 误区三:使用平均值而非中位数。平均值对异常值敏感,一次调度抖动就可能使平均值偏离真实水平。
  • 误区四:不记录测试环境。温度、频率、系统负载都会影响结果,不记录环境参数导致测试不可复现。
  • 误区五:批处理测试只测batch=1。若业务场景支持批量推理,应测试不同batch下的吞吐量,找到最优配置。

总结复盘时,建议输出一份完整的帧率测试报告,包含:测试平台信息(芯片型号、固件版本、RKNN Toolkit版本)、测试环境(温度、频率设置、系统负载)、测试矩阵(分辨率×模型×batch)、原始数据(每帧耗时分布)、统计结果(均值/中位数/P95/P99)、以及结论(是否满足验收标准)。只有数据完整、方法规范,帧率测试才能真正为RKNN部署验收提供可靠依据。