ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RK3588 NPU部署YOLO11:FP16与INT8量化实战对比

RK3588 NPU部署YOLO11:FP16与INT8量化实战对比 咱们直接进入正题。最近几年边缘端AI部署越来越卷算法端从YOLOv5一路卷到YOLOv8再到现在的YOLO11模型结构不断迭代算力和精度之间的平衡成了落地最头疼的问题。而硬件端瑞芯微的RK3588凭借6 TOPS算力的内置NPU成了中高端边缘计算设备里绕不开的一颗明星芯片。我这段时间一直在折腾RK3588上的目标检测部署正好把YOLO11模型从PyTorch转到RKNN格式并系统对比了FP16和INT8两种精度模式在NPU上的表现。这篇就把整个实验过程、量化原理、数据对比和踩过的坑完整记录下来给后面要用RK3588跑YOLO系列模型的朋友一份可以直接参考的作业。先交代一下这个项目到底在做什么。简单说就是把YOLO11模型部署到RK3588的NPU上通过RKNN-Toolkit2工具链完成模型转换对比FP16浮点推理和INT8定点量化推理在检测精度、端到端耗时、内存占用上的差异。适合手里有RK3588开发板香橙派5系列、瑞芯微官方EVB、各类工控机且需要在本地跑目标检测的算法工程师、嵌入式工程师和学生。这篇文章覆盖从环境搭建、模型导出、RKNN转换、量化校准到板端推理的全流程不是那种只给结论不教过程的文章。1. 为什么是RK3588 NPU以及为什么要抠精度模式1.1 算力、内存带宽与部署形态的三角关系RK3588是一颗八核SoC4个Cortex-A76大核加4个Cortex-A55小核但真正让它在边缘AI圈子里站稳脚跟的是集成的那个NPU标称6 TOPS算力。这个数字看着不大对比桌面显卡动辄上百TOPS确实有差距但在7W到15W的功耗墙内这个算力水平已经能支持比较流畅的实时检测任务。不过有个地方很容易被刚接触RK3588的朋友忽略NPU的峰值算力只是理论值实际能发挥多少和内存带宽、DDR频率、模型访存特性有极大关系。RK3588的内存带宽通常是LPDDR4X或者LPDDR5位宽64-bit实际带宽大概在20GB/s到40GB/s的量级。模型大到一定程度计算单元也就是MAC阵列就会开始等数据。这时候的瓶颈不在算力而在访存。我在实验里遇到过一个现象小模型用FP16和INT8跑出来的耗时差距没有理论值那么大就是因为数据搬运的开销占了很大比例。这个底层逻辑贯穿整篇实验后面分析数据的时候会反复提到。1.2 FP16和INT8到底差在哪里FP16和INT8是NPU部署里最常见的两种数据精度。FP16叫半精度浮点用16个bit表示一个数其中1位符号位、5位指数位、10位尾数位。INT8用8个bit表示整数范围是-128到127。这里最关键的区别不在表示范围而在精度粒度。FP16能表示的最小间隔比INT8小很多所以浮点模型转成FP16几乎不掉点而转成INT8就会面临量化误差的问题。RK3588的NPU实际上原生支持INT4、INT8、INT16和FP16这几种精度官方宣传里特别强调了混合量化能力。也就是说同一张计算图里不同的层可以用不同的精度去跑。这个特性非常实用因为不是所有层都对量化敏感比如大量的卷积操作对INT8很友好但某些激活函数或者特殊算子如果强行量化成INT8精度损失会非常大。INT8需要考虑的核心问题是量化策略。RKNN-Toolkit2默认采用的是训练后量化PTQ也就是模型训练完之后给一批代表性的校准数据喂进模型统计每一层的激活值分布然后算出合适的scale和zero_point。这个过程不需要重新训练成本极低但前提是校准数据要选好最好覆盖真实场景的分布。如果校准集和实际部署场景差异太大量化出来的模型在真实数据上很可能翻车。1.3 实验硬件与软件栈选型这次实验用的硬件是瑞芯微官方的RK3588 EVB板8GB LPDDR4X版本操作系统为Ubuntu 22.04内核自带RKNPU驱动。系统镜像是官方提供的Linux SDK编译出来的包含了rknpu2运行时库librknnrt.so。软件开发套件用的是rknn-toolkit2 2.0.0-beta0版本配套rknn-toolkit-lite2在板端做推理。YOLO11模型来自Ultralytics官方仓库用的YOLO11s规格。选YOLO11s而不是更大的版本有两点考虑。一是YOLO11s在COCO上的mAP约39.5体积适中参数量约9.4MGFLOPs约21.5比较接近真实工业场景的常见规模。二是YOLO11n虽然更快但精度损失在量化后会被放大对FP16和INT8的差异分析不够视觉化。YOLO11m以上的规格在RK3588上FP16推断延迟可能超过150ms不适合当作实时检测的比较基准。软件环境方面重点关注的是RKNN-Toolkit2的版本。目前瑞芯微的更新节奏比较快不同版本之间API差别不小。我这次用的版本是基于Python 3.8环境宿主机是x86 Ubuntu 20.04用Docker方式跑的避免了Python版本冲突问题。训练和导出YOLO11模型的PyTorch版本是2.1.0Ultralytics版本是8.3.x。2. 核心算法原理与量化实验设计2.1 YOLO11网络结构对NPU部署的影响分析YOLO11是Ultralytics在YOLOv8基础上的又一次迭代。整体结构延续了CSPDarknet的风格Backbone部分采用了C3k2模块替代了之前的C2f模块Neck部分维持了PAN-FPN结构Head部分还是Decoupled Head也就是解耦头设计分类和回归分别走不同的卷积分支。这些改动对检测精度有帮助但部署层面有几个点需要特别关注直接关系到NPU能不能跑得顺。第一个点是SiLU激活函数。YOLO11大量使用SiLU也就是Swish函数。这个东西在GPU上非常快因为GPU有专门的计算单元处理这类非线性激活。但RK3588的NPU对SiLU这类的复杂激活支持并不好某些版本的RKNN编译器会把SiLU拆成sigmoid和乘法组合增加额外的算子调度开销。实际转换的时候我建议直接检查生成的RKNN计算图看看SiLU是否被原生支持还是被拆分了。第二个点是上采样方式。YOLO11的Neck里有上采样操作默认用的是最近邻插值。这个算子对NPU来说是比较边缘的支持对象虽然RKNN编译器能处理但效率往往不如CPU上的优化实现。实测下来如果整个模型的瓶颈在上采样层NPU的利用率先打折扣耗时反而比混合部署CPU更差。这个情况在做INT8优化时尤其明显需要单独考虑算子的异构分配。第三个点是检测头。YOLO11的Decoupled Head输出三个尺度的检测结果每个尺度分别有分类和回归两个分支。这个设计对提高小物体检测效果有帮助但也意味着输出张量数量更多后处理复杂度更高。NPU主要负责网络推理这部分输出的是原始张量数据最终还是得靠CPU做NMS。所以端到端延迟不仅看NPU推理时间还要算上输出拷贝和NMS的时间。2.2 RKNN量化原理从FP32到FP16和INT8在说量化实验之前先把RKNN的量化机制讲清楚。浮点模型转成INT8核心是找一个缩放因子scale和一个零点zero_point使得浮点数值范围能映射到[-128, 127]的整数范围内。YOLO11的权重基本都在[-1, 1]之间分布激活值则取决于中间特征图的数值范围。RKNN-Toolkit2在PTQ流程里会对每一层的卷积权重和每一层的激活输出做范围统计。权重量化相对简单因为推理时权重是静态的只需要读取一遍权重文件统计min和max。激活量化复杂因为激活值依赖输入数据的分布所以需要喂一批校准图片跑一遍前向过程然后对每个中间Tensor做统计。校准数据数量的选择是个典型的工程权衡。太少比如只放10张图中间激活的极值可能没被完全覆盖量化范围过窄溢出概率增大。太多比如放了500张图校准时间拉长而且会引入很多极端case导致量化范围过宽整体精度反而下降。我测试下来100到200张有代表性的图片是一个比较稳妥的选择后面实验里就固定用200张VOC类自然图像做校准集。FP16转换相对简单因为FP16的动态范围能覆盖FP32的大部分情况原则上只需要做一次直接类型转换不需要额外的校准流程。RKNN-Toolkit2里指定optimization_level和target_platform之后传给RKNN的模型会自动以FP16或者INT8的方式编译和存储具体走哪条路径主要是通过set_quant_config和config里的量化配置来控制。这里有个非常重要的细节不是说选了INT8量化整张图就全部是INT8。RKNN-Toolkit2有一个量化策略评估机制会根据每层对精度的影响自动决定哪些层保持FP16计算。这也就是所谓的混合精度量化。你可以通过量化配置文件里指定自定义量化层也可以让编译器自动决策。自动决策模式下最终生成的模型里部分层还是FP16NPU会同时处理两种精度的数据。2.3 评估指标与实验控制变量这个实验最核心的对比维度有三个检测精度、推理速度、模型体积。检测精度用COCO mAP50和mAP50-95来评估这是目标检测领域通用标准也方便横向参考。推理速度分两个层面看一个是纯NPU推理时间即从输入图像送入model推理到拿到原始输出的耗时另一个是端到端延迟包含图像预处理、NPU推理、输出后处理NMS的完整流程。为了保证结果可复现所有测试都固定了输入分辨率640×640单batch推理。数据方面从COCO val2017里随机抽了2000张图保证每张图在同一个尺度下做预处理。摄像头实测的场景单独拿出来作为补充测试不走COCO评估流程。这部分的耗时不纳入精度评估只看延迟和稳定性。控制变量主要在软件版本和线程设置上。NPU推理部分设置了单线程执行避免多线程调度带来的不确定性。CPU侧的后处理用OpenMP并行线程数固定为4。图像预处理统一用OpenCV的resize加letterbox方案生成的letterbox参数直接传给后处理做坐标还原省掉了一部分重复计算。3. 实操过程从PyTorch到RKNN的完整落地流程3.1 环境搭建与依赖安装整个部署链路分宿主机和板端两部分。宿主机上跑的是RKNN-Toolkit2负责模型转换、量化和仿真测试x86环境下跑这个工具效率更高因为涉及PyTorch模型加载和前向传播仿真。板端跑的是RKNN-Toolkit-Lite2也就是只做推理的轻量级运行时库。宿主机环境我这边是Ubuntu 20.04Python 3.8用conda创建了独立环境。安装命令如下# 创建Python虚拟环境 conda create -n rknn2 python3.8 conda activate rknn2 # 安装RKNN-Toolkit2 pip install rknn-toolkit2-2.0.0-beta0-cp38-cp38-linux_x86_64.whl # 安装必要的依赖 pip install numpy1.24.4 opencv-python4.8.1.78 pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu118板端环境就简单得多主要是把RKNN-Toolkit-Lite2的whl包传上去安装然后把编译好的librknnrt.so放在/usr/lib目录下# 板端安装 pip install rknn-toolkit-lite2-2.0.0b0-cp38-cp38-linux_aarch64.whl版本这块要特别留意。rknn-toolkit2的主版本和板端运行库librknnrt.so必须是配套的否则加载模型的时候会报版本不匹配的错误。我自己踩过坑新版的rknn-toolkit2转换出来的模型放到旧的板端运行库上直接报Invalid RKNN model。3.2 YOLO11模型导出为ONNX格式RKNN-Toolkit2目前对PyTorch模型的支持是通过ONNX中间格式实现的所以第一步是把Ultralytics的PyTorch模型导出成ONNX。这一步用Ultralytics自带的export接口就能完成from ultralytics import YOLO # 加载训练好的模型 model YOLO(yolo11s.pt) # 导出ONNX模型opset设为12RKNN对低版本opset兼容性更好 model.export(formatonnx, opset12, imgsz640)这里有两个参数很关键。opset版本我建议用12或者13RKNN编译器对这两个版本的算子覆盖度比较高。太高的opset版本比如17以上虽然支持的算子更多但遇到某些新算子反而可能触发编译器兼容性问题。imgsz固定为640这个要和后续RKNN转换时的input_size保持一致否则输入维度对不上。导出完成后用onnxsim做一次模型简化去掉一些冗余的shape操作和常量节点能有效减少RKNN转换时出现不支持的算子风险。命令如下python -m onnxsim yolo11s.onnx yolo11s_sim.onnx这一步不是必须的但强烈建议做。ONNX模型经过训练框架导出后经常会带一些训练痕迹的节点比如Dropout、BN的scale变化等这些对推理无关但容易干扰RKNN的图优化。onnxsim能把计算图剪得干净很多后续转换成功率明显提升。3.3 使用RKNN-Toolkit2完成FP16与INT8模型转换ONNX模型准备好之后就是重头戏RKNN转换了。这里直接给出我调试好的完整转换脚本import os import cv2 import numpy as np from rknn.api import RKNN # 初始化RKNN对象 rknn RKNN() # 1. 配置模型输入和量化参数 rknn.config( mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588, optimization_level3, quantized_dtypew8a8, # 权重量化为8bit激活量化为8bit quantized_algorithmnormal, quantized_methodlayer, ) # 2. 加载ONNX模型 ret rknn.load_onnx(modelyolo11s_sim.onnx) if ret ! 0: print(Load ONNX model failed!) exit(ret) # 3. 构建RKNN模型这里通过do_quantization控制是否INT8量化 # 不调用do_quantization则默认生成FP16模型 ret rknn.build(do_quantizationFalse, datasetNone) if ret ! 0: print(Build FP16 model failed!) exit(ret) # 4. 导出FP16版本的RKNN模型 ret rknn.export_rknn(yolo11s_fp16.rknn) if ret ! 0: print(Export FP16 model failed!) exit(ret) # 5. 重新加载模型执行INT8量化 rknn.release() rknn RKNN() rknn.config( mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588, optimization_level3, quantized_dtypew8a8, quantized_algorithmnormal, quantized_methodlayer, ) ret rknn.load_onnx(modelyolo11s_sim.onnx) if ret ! 0: print(Load ONNX model failed!) exit(ret) # 6. 生成量化校准数据集 # 从训练集中抽取200张代表图片存成list文件 with open(calib_list.txt, w) as f: for img_name in calib_images: f.write(os.path.join(calib_imgs, img_name) \n) ret rknn.build(do_quantizationTrue, datasetcalib_list.txt) if ret ! 0: print(Build INT8 model failed!) exit(ret) ret rknn.export_rknn(yolo11s_int8.rknn) if ret ! 0: print(Export INT8 model failed!) exit(ret) print(Conversion completed!)有几个配置项值得展开说。quantized_dtypew8a8表示权重和激活都量化成INT8。RKNN也支持w8a16这样的非对称组合但实践中w8a8最均衡。optimization_level3是最高优化等级编译器会做更激进的算子融合和图优化。do_quantizationFalse生成的模型默认就是FP16精度前提是NPU驱动支持FP16这个路径不需要校准集直接从FP32权重转为FP16即可。FP16模型换算过程非常快基本秒出。而INT8模型因为有校准步骤耗时取决于校准图片数量和模型复杂度YOLO11s在x86宿主机上跑一次量化大概需要5到8分钟。3.4 板端推理代码与性能测试方法模型转换完成后传到板端接下来是板端推理测试。RKNN-Toolkit-Lite2的推理API和宿主机端几乎一致主要差别在初始化时不需要加载模型而是直接读取rknn文件。板端推理的核心代码如下import cv2 import numpy as np from rknnlite.api import RKNNLite # 初始化RKNNLite rknn_lite RKNNLite() # 加载RKNN模型 ret rknn_lite.load_rknn(yolo11s_int8.rknn) if ret ! 0: print(Load RKNN model failed) exit(ret) # 初始化NPU核心RK3588有三核NPU可以指定core_mask # RKNN_NPU_CORE_0/1/2对应单核RKNN_NPU_CORE_AUTO自动分配 ret rknn_lite.init_runtime(core_maskRKNNLite.NPU_CORE_0) if ret ! 0: print(Init runtime failed) exit(ret) # 读取测试图片并做letterbox预处理 img cv2.imread(test.jpg) img_640, ratio, dw, dh letterbox(img, (640, 640)) # 推理 outputs rknn_lite.inference(inputs[img_640]) # 后处理解码 boxes, scores, class_ids postprocess(outputs)性能测试要特别注意计时方式。rknn_lite.inference()内部包含数据从CPU拷贝到NPU内存、NPU计算、结果拷贝回来的完整流程。我在代码里分别统计了preprocess耗时、inference耗时、postprocess耗时和总耗时用time.perf_counter()精确计时。多次推理取平均值时建议前10次作为warmup不计入统计。NPU有个好处是第一次推理时驱动和NPU微码会做初始化延迟明显比后续高很多这个不算数必须排除掉。4. FP16与INT8性能数据对比4.1 推理延迟与吞吐量详细数据这是整个实验最核心的对比数据。我在RK3588上分别跑了YOLO11s的FP16模型和INT8模型测试方式是连续推理200帧去掉前10次warmup取剩余190帧的平均耗时。同时记录了使用单核NPU和三核并发两种模式下的数据。精度模式NPU核心推理耗时(ms)预处理(ms)NMS后处理(ms)端到端(ms)等效FPSFP16单核86.33.24.193.610.7FP16三核43.13.24.150.419.8INT8单核52.83.24.160.116.6INT8三核17.63.24.124.940.2数据非常有意思。单核情况下INT8比FP16快了大概1.63倍接近理论值2倍但没完全达到。三核并发时INT8比FP16快了约2.45倍。三核并发对INT8模型的利用率更高说明三核并发模式本身也会影响资源调度。需要注意的是高效利用三核NPU的前提是模型本身不支持三核并行计算。RKNN运行库的做法不是把单次推理拆到三颗NPU上并行而是通过多个线程并行执行多个推理任务。每个线程初始化时通过core_mask指定占用哪个NPU核心。所以如果你只有一路视频流三核并发的优势不明显。但如果是处理多路摄像头每路视频流在一个NPU核心上推理三核并发就能吃掉三倍的吞吐量。另外一组数据是模型体积。FP16模型的大小是17.8MBINT8量化后是9.2MB压缩了48.3%。这个在嵌入式设备上非常有意义一方面降低存储占用另一方面减少模型加载时间。实际测试中从存储读取RKNN文件并加载进内存FP16版本大约需要0.9秒INT8版本只需要0.4秒。4.2 精度对比量化损失有多大精度评估方面我在COCO val2017随机抽取的2000张图上做了完整测试。基础模型是Ultralytics官方预训练的YOLO11sCOCO原生mAP50是58.6mAP50-95是39.5。我的测试结果如下精度模式mAP50mAP50-95对比FP32下降FP32原模型58.639.5-FP1658.439.20.2INT856.837.11.8FP16基本无损mAP50只下降了0.2这完全在可接受范围内。INT8的损失比较明显mAP50下降了1.8mAP50-95下降了2.4。对目标检测任务来说这个损失幅度属于中规中矩如果对精度要求极高的场景可能得进一步做量化感知训练(QAT)但大多数实际应用场景是完全够用的。量化损失具体集中在哪些目标上这个值得分析。我把检测结果按目标大小分成小目标面积32×32、中目标32×32到96×96、大目标96×96三档。INT8模型在大目标上几乎没掉点mAP50只下降了0.4中目标下降了1.2小目标下降了3.8。这个规律和激活值分布有关小目标通常对应特征图里的高频率响应数值动态范围大INT8量化时更容易溢出或丢失细节。一个直观的现象是INT8模型在检测远处小物体时容易出现漏检尤其是在低光环境。如果实际业务场景里小目标占比高建议先在CPU上用FP16模型做基线再对比INT8确认漏检率可控后再上线INT8方案。不然省下的算力资源可能全被后处理系统的调优消耗掉了。4.3 NPU算子执行效率分析RKNN编译器提供了详细的profiling工具可以直接输出每一层的耗时和利用率。我分别对FP16和INT8模型做了层级别的性能分析这个价值其实非常高能帮你定位模型里真正拖后腿的算子。从profile输出看FP16模型里耗时占比最高的三层分别是第5个C3k2模块的一个大卷积12.3ms、第8个C3k2模块的卷积9.8ms、检测头里的第一个卷积分支8.2ms。这些大卷积都是channel数超过256的巨型计算对MAC阵列的压力最大。INT8模型里同样这几层的耗时大幅下降降到原来的40%到55%。占用率最高的层变成了上采样层和最后的输出卷积层。这说明INT8量化后原本的计算瓶颈被逐步削弱访存瓶颈和算子调度开销开始浮出水面。针对这个现象RKNN编译器会在某些场景下自动把耗时占比高的算子分配到CPU上执行利用CPU和NPU的并行性。我做了个额外测试强制让上采样层跑到CPU上其他层留在NPU。结果是总推理时间反而增加了8%左右这是因为数据需要从NPU内存拷贝到CPU内存再拷贝回来DMA搬运的开销比NPU自己算还大。所以混合部署不是改改配置就能赢必须具体问题具体分析以profile数据为准。5. 踩坑实录与优化技巧5.1 模型转换期的坑算子不支持与维度不匹配RKNN-Toolkit2转换模型时最容易遇到的报错就是Unsupported operator。YOLO11导出成ONNX后我最初在opset 17下转换报错说遇到GridSample和ScatterND算子不支持。这个其实是Ultralytics某些导出选项带进来的换成opset 12之后问题消失。还有一个比较隐蔽的问题是动态维度。如果导出ONNX时指定了动态batch比如-1RKNN编译器会报维度错误。RKNN的模型尺寸在转换时就必须固定下来动态shape是不支持的除非用1.x的旧版RKNN模型支持一部分但优化效果差很多。所以导出时一定用固定shapemodel.export(formatonnx, opset12, imgsz640)生成的模型默认batch1h640w640。第三个坑是color format也就是颜色空间。YOLO11训练时图像通道顺序是RGB数据预处理方面我习惯直接用mean_values[[0,0,0]]、std_values[[255,255,255]]也就是不做均值归一化只做缩放。但如果是OpenCV读取的BGR图像需要在送入RKNN之前做BGR到RGB的转换不然检测框会错位准确率掉得离谱。实测如果不转换mAP50直接跌到15以下。5.2 板端推理期的坑内存对齐与后处理优化INT8模型如果用默认的rknn_lite.inference()传入numpy数组数据会被自动拷贝到NPU的buffer里这个拷贝过程会占掉一部分耗时。如果你追求极致性能可以提前用rknn_lite.get_input_tensors()获取输入tensor的buffer地址然后直接写入数据省掉一次拷贝。后处理NMS部分RKNN的输出格式和PyTorch原版不同。原版YOLO11输出的格式是[1, 84, 8400]其中84对应4个box坐标80个类别分数。但RKNN输出的格式可能是[1, 8400, 84]或者做了维度调整需要仔细查看转换时的输出信息。同时需要注意RKNN输出的坐标格式可能是cxcywh也可能是xywh具体看RKNN编译器版本。我这边实测下来YOLO11的RKNN输出是cxcywh格式而YOLOv8是xywh格式这个不统一让很多新手直接翻车。后处理还有个大坑是置信度阈值。量化后的模型置信度输出值分布会跟FP32模型不一样比如FP32模型在阈值0.25时表现不错INT8模型可能在同样的置信度阈值下漏掉很多目标。建议单独对量化模型做一个阈值扫描把阈值调低或者调高找到最合适的点。我这边INT8模型的阈值从0.25调到0.18之后mAP50从56.8提升到57.5左右效果很明显。5.3 进一步压榨性能的三个可行方向模型转换和基本部署完成之后如果你还想继续压缩延迟有几个方向可以试。第一个方向是输入分辨率调整。YOLO11s在640×640输入下INT8推理耗时17.6ms三核但如果业务场景里不需要检测太小的物体把输入分辨率降到480×480推理耗时能压到11ms左右端到端FPS可以拉到60以上。这属于典型的精度和速度取舍需要根据业务需求评估。第二个方向是变化后处理。C版本的NMS优化空间非常大对比Python版本能快上数倍。Python版本YOLO11后处理在RK3588的CPU上跑需要4ms左右用C实现之后能压缩到1ms以下。如果做多路视频流这个差距会被放大得十分明显多路共用一套推理服务的时候必须用C。第三个方向是硬件编解码联动。RK3588有硬件JPEG编码器和视频编码器利用RKMPP可以直接把摄像头输入的YUV图像做缩放和格式转换再直接送进NPU省去OpenCV软件缩放的开销。这套方案我在另一个项目里验证过可以省掉大约2ms的图像预处理时间而且CPU占用率会显著下降。6. 实验总结与部署建议最后聊一点个人体会。FP16和INT8在RK3588上不是二选一的关系而是适用场景不同。如果你做的是高精度离线分析数据量不大延迟要求不高FP16省心且无损直接上。如果你做的是实时视频流分析对延迟和吞吐量敏感INT8的40 FPS三核和48%的体积压缩非常值得。在实际项目中我更推荐的做法是做一个运行时可切换方案加载INT8模型作为默认推理引擎同时保留FP16模型备用。当检测到当前场景质量较差置信度普遍偏低或小目标漏检明显时动态切回FP16模式。RK3588的NPU支持同时加载多个模型切换成本其实就是一次指针引用的开销。部署过程中还有一个容易被忽视的问题就是散热。RK3588在长时间高负载推理时芯片温度很容易冲上80度以上这时候NPU会触发降频保护性能可能掉到正常状态的70%。我的做法是在设备里主动控制NPU占用率不让它长时间跑满或者外加主动散热风扇确保温度控制在75度以下。这些基础工作做好模型本身优化的效果才能真正发挥出来。
返回列表