【RK3588】模型精度优化指南和精度问题查找

编程入门 行业动态 更新时间:2024-10-24 22:31:04

【RK3588】模型<a href=https://www.elefans.com/category/jswz/34/1769184.html style=精度优化指南和精度问题查找"/>

【RK3588】模型精度优化指南和精度问题查找

在对模型进行转化的过程中,会存在模型测试精度的下降。那么,究竟是哪个环节造成了精度的的降低?

采用什么方式可以快速的定位精度降低的点,以及快速调整,对非量化模型做对比呢?本文就是参照官方给出的内容,对这部分进行汇总。

本篇博客参考文档:

  1. 瑞芯微官方B站教程:RKNN模型精度优化指南
  2. RKNN SDK和官方文档下载:ROC-RK3588S-PC NPU使用

一、精度排查流程

二、模型精度优化


模拟器精度排查,遵循两个“正确的前提”:

  1. 模拟器结果的正确是板端模型推理正确的前提;
  2. “fp16 模型” 的结果正确同样是“ 量化模型” 精度正确的前提

根据两个前提,“量化模型” 精度问题排查顺序:

  1. 需要在使用 rknnbuild 接口时, 将 do_quantization 参数设置为 False, 即可以将原始模型转换为“fp16 模型” 。如果“fp16 模型” 输出结果错误, 则需进行以下排查:

    • rknn 的 config 这个接口里:mean_values / std_values、input_size_list、inputs / outputs
    • rknninference 这个接口里: inputs 和 data_format。python 环境下,图像数据都是通过cv2.imread读取的,图像格式为 BGR,大部分的 caffe 模型不用改;其他的一般输入为 RGB,需要cv2.cvtColor(img, cv2.COLOR_BGR2RGB)将图像数据转为 RGB, 才可以传给rknninference接口进行推理。
    • 通过 cv2.imread 读取的图像数据的 layout 为 NHWC, 因为 data_format 的默认值为 NHWC, 因此不需要设置 data_format 参数;而如果模型的输入数据不是通过 cv2.imread 读取,此时用户就必须清楚知道输入数据的 layout 并设置正确的 data_format 参数,如果是图像数据,也要保证其 RGB 顺序与模型的输入 RGB 顺序一致
  2. 在经过“ fp16 模型” 的精度验证后, 排除了“ fp16 模型” 的错误可能, 就可以对模型进行量化, 并进一步对“ 量化模型” 进行精度分析。 如果在“量化模型” 遇到精度问题,将主要从以下几个方面进行排查:

    • quantized_dtype量化类型的选择,Toolkit2-1.3.0,默认值为 asymmetric_quantized-8asymmetric_quantized-16目前版本暂不支持。16-bit 量化和非量化(float16) 的运算性能差异不大,因此建议选择 fp16(rknn 的 build 接 口 的 do_quantization 设 为 False )的运算方式来代替16-bit量化;
    • quant_img_RGB2BGR,一般用于caffe 模型;
    • dataset,rknn 的 build 接口的量化校正集配置。 如果选择了和实际部署场景不大一致的校正集,则可能会出现精度下降的问题, 或者校正集的数量过多或过少都会影响精度( 一般选择 50~200张)
    • quantized_algorithm
    • quantized_method
    • optimization_level

更多内容,参考文档 NPU使用 Rockchip_User_Guide_RKNN_Toolkit2_CN-1.3.0.pdf第46页

2.1、精度分析工具


注意:

  1. 该接口只能在 build hybrid_quantization_step2 之后调用;
  2. load 原始模型应该为非量化的模型, 否则会调用失败
# Build modelprint('--> Building model')ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET)  # DATASET来自于训练集,或验证集if ret != 0:print('Build model failed!')exit(ret)print('done')# Accuracy analysisprint('--> Accuracy analysis')Ret = rknn.accuracy_analysis(inputs=['./data/0000010_20200929_F_045Y57.jpeg'],target='rk3588')if ret != 0:print('Accuracy analysis failed!')exit(ret)print('done')

rknn.build是为了构建 RKNN 模型,rknn.accuracy_analysis目的是对比fp32quant后,前后两种数据之间的量化误差。所以,原始的模型,作为参照物,应该使用非量化的模型。

terminal 打印内容( 一般认为余弦相似度低于 0.99 存在少许不一致, 低于 0.98 几乎可以认为该层结果就是错误的):

--> Accuracy analysis
Analysing : 100%|████████████████████████████████████████████████| 295/295 [00:00<00:00, 320.01it/s]
Preparing : 100%|████████████████████████████████████████████████| 295/295 [00:01<00:00, 209.50it/s]
AccuracyAnalysising : 100%|███████████████████████████████████████| 295/295 [01:40<00:00,  3.91it/s]
I target set by user is: rk3588
I Starting ntp or adb, target is RK3588
I Start adb...
I Connect to Device success!
I NPUTransfer: Starting NPU Transfer Client, Transfer version 2.1.0 (b5861e7@2020-11-23T11:50:36)
D NPUTransfer: Transfer spec = local:transfer_proxy
D NPUTransfer: Transfer interface successfully opened, fd = 3
D RKNNAPI: ==============================================
D RKNNAPI: RKNN VERSION:
D RKNNAPI:   API: 1.3.0 (121b661 build: 2022-04-29 11:07:20)(null)
D RKNNAPI:   DRV: rknn_server: 1.3.0 (121b661 build: 2022-04-29 11:11:57)
D RKNNAPI:   DRV: rknnrt: 1.3.0 (c193be371@2022-05-04T20:16:22)
D RKNNAPI: ==============================================
D NPUTransfer: Transfer client closed, fd = 3
adbd is already running as root
/data/dumps/: 897 files pulled. 35.7 MB/s (1749757536 bytes in 46.729s)
Save Tensors to txt: 100%|████████████████████████████████████████| 299/299 [00:34<00:00,  8.73it/s]
Calculate Distance: 100%|█████████████████████████████████████████| 296/296 [02:11<00:00,  4.17it/s]# quant_error: calculate the quantize errors.
#              entire: errors between 'golden' and 'simulator'.
#              per_layer: compare to 'entire', the input of each layer is come from 'golden'
# runtime_error: calculate the runtime errors.
#              simu_err: errors between 'simulator' and 'runtime'.
#              golden_err: errors between 'golden' and 'runtime'.layer_name     quant_error              runtime_error   entire    per_layer      simu_err  golden_err     
--------------------------------------------------------
images     1.000000  1.000000       1.000000  1.000000       
254        1.000000  1.000000       1.000000  1.000000       
256        1.000000  1.000000       0.999999  0.999999       
257        0.999999  1.000000       0.999990  0.999991       
259        1.000000  1.000000       0.999993  0.999993       
260        1.000000  1.000000       0.999994  0.999994       
262        1.000000  1.000000       0.999995  0.999995       
263        1.000000  1.000000       0.999994  0.999994       
265        1.000000  1.000000       0.999993  0.999993       
266        1.000000  1.000000       0.999994  0.999995       
268        0.999999  1.000000       0.999994  0.999994       
269        1.000000  1.000000       0.999997  0.999998 

2.2、检查数据输入

2.3、检查rknn.config配置参数和量化方法


2.4、量化配置参数精度对比

  • FP32也叫做 float32,两种叫法是完全一样的,全称是Single-precision floating-point(单精度浮点数)
  • FP16也叫做 float16,两种叫法是完全一样的,全称是Half-precision floating-point(半精度浮点数),

注意:

  • toolkit2-1.3.0下,量化默认就是int8,不支持float16(目前最高版本是1.5.0, 2023.07.04发布,同样不支持float16);
  • 不启用量化do_quantization=False,就是fp16 精度;
  • rknn.configquantized_algorithm、、quantized_method、optimization_level目前都是使用的默认值,这个也可以进行修改,用处是提高精度。

2.5、混合量化



也可以设定proposal,会自动选择可能需要混合量化的层,如下设定:


三、QAT(Quantization Aware Training,量化感知训练)

如果混合量化后的精度,还是不够,或者运行性能不足,可以采用量化感知的方式,得到一个量化后的模型。再将这个模型转换成RKNN模型。

量化感知训练(Quantization Aware Training)是在模型中插入伪量化模块(fake_quant
module)模拟量化模型在推理过程中进行的舍入(rounding)和钳位(clamping)操作,从而在训练过程中提高模型对量化效应的适应能力,获得更高的量化模型精度 。

在这个过程中,所有计算(包括模型正反向传播计算和伪量化节点计算)都是以浮点计算实现的,在训练完成后才量化为真正的int8模型。

Pytorch官方从1.3版本开始提供量化感知训练API,只需修改少量代码即可实现量化感知训练。

四、总结

在上一篇RKNN的文章中,对量化与非量化的模型进行了占用内存和效率的对比,发现非量化的模型,占用内存更多和推理时间更长。

但是,非量化的结果,会比量化的精度降低更少。而对于由于量化降低的模型精度,可以参照本篇文章,一一排查,确认降低精度的点。

可以知道:
1.在3588的toolkit2-1.3.0下,量化默认就是int8,不支持float16,但是,非量化下,是可以到fp16的;(目前最高版本是1.5.0, 2023.07.04发布,同样不支持float16
2.rknn.configquantized_algorithm、quantized_method、optimization_level目前都是使用的默认值,这个也可以进行修改,用处是提高精度

2种方式可以改:

  1. 使用非量化的模型,这样就是fp16的版本,在非量化下,build后的模型accuracy_analysis准确度分析,能做到0.9999,与onnx版本基本一致,采用非量化rknn模型与预测,与本地pytorch做对比;
  2. 调整配置config内的quantized_algorithm、quantized_method、optimization_level参数

本篇只是做一个记录,对于实践测试发现的问题,也会在这里进行记录。如果你也关注这个问题,欢迎收藏、点赞。

更多推荐

【RK3588】模型精度优化指南和精度问题查找

本文发布于:2024-02-27 08:33:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1705895.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:精度   模型   指南

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!