深度學習模型部署(四)——RKNN

一、RKNN部署及工具包安裝

參考1:https://blog.csdn.net/qq_40280673/article/details/136211086#/
參考2:瑞芯微官方教程
RKNN部署針對瑞芯微芯片優化,支持NPU硬件加速,需要安裝rknn-toolkit,用于將pytorch模型轉換為RKNN模型
以下操作均在ubuntu中進行
運行環境要求如下:
在這里插入圖片描述

1、安裝python及相關依賴

sudo apt-get install python3 python3-dev python3-pip
sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc

2、創建虛擬環境

# 創建虛擬環境
conda create -n your_env_name
# 激活虛擬環境
conda activate your_env_name

3、下載系統依賴及rknn-tookit安裝包

系統依賴的庫:requirements_cpxx-1.5.0.txt;
rknn-toolkit2安裝包:rknn_toolkit2-1.5.0+fa95b5c-cpxx-linux_x86_64.whl
上述兩個文件自取:
通過網盤分享的文件:libpackages
鏈接: https://pan.baidu.com/s/10xjTZ2Wr8CgGFV80tfXmZA 提取碼: wwzn
【注】 cpxx取決于安裝的python版本,如我的環境是ubuntu22.04,python版本3.10,因此我需要安裝的是requirements_cp310-1.5.0.txt和rknn_toolkit2-1.5.0+fa95b5c-cp310-linux_x86_64.whl

4、安裝系統依賴及rknn-toolkit2

激活需要安裝的虛擬環境,運行以下指令時,執行目錄須為txt文件和whl文件所在目錄,也可以指定文件所在路徑

pip install -r requirements_cp310-1.5.0.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
pip install rknn_toolkit2-1.5.0+1fa95b5c-cp310-cp310-linux_x86_64.whl -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

【注】 安裝過程中可能有包下載不成功,可以手動pip安裝,多試幾個鏡像源,或者爬梯子安裝,一定要確保所有包安裝成功

二、pytorch模型轉換為rknn模型

我的文件結構如下:
在這里插入圖片描述
datasets.txt的內容為
在這里插入圖片描述

1、torch.nn.module——>rknn

參考1:https://blog.csdn.net/qq_40280673/article/details/136229500#/ 大佬的公眾號有源碼包,可以下載后執行
我參考著導出了一下yolov11n-cls模型:
【注】 要使用相同版本的pytorch導出模型并轉為RKNN模型,否則會因為前后版本不一致導致RKNN轉換失敗。

# yolov11n-cls.pt轉rknn模型
'''
1、導入RKNN包
2、實例化RKNN對象
3、定義數據預處理和量化方法
4、加載pytorch模型,即'.pt'文件
5、構建rknn模型
6、導出rknn模型
7、釋放RKNN對象
'''
from rknn.api import RKNNif __name__=="__main__":rknn = RKNN()'''初始化RKNN對象時,可以設置verbose和verbose_file參數:verbose:是否在屏幕上打印詳細的日志信息verbose_file:日志文件示例:將詳細日志信息輸出到屏幕,并寫入到build.log文件中rknn=RKNN(verbose=True,verbose_file='./build.log')'''rknn.config(mean_values=[[0.0, 0.0, 0.0]], std_values=[[1.0, 1.0, 1.0]],target_platform='rk3588')'''def config(mean_values: Any | None = None, 輸入的均值,用于數據預處理中的normalization,如mean_values=[128, 128, 128]]表示輸入的三個通道的值減去128std_values: Any | None = None, 輸入的標準差,用于數據預處理中的normalization,如std_values=[[128, 128, 128]]表示輸入的三個通道減去均值后再除以128quantized_dtype: str = 'asymmetric_quantized-8',量化類型,目前支持asymmetric_quantized-8、asymmetric_quantized-16quantized_algorithm: str = 'normal',計算每一層的量化參數時采用的量化算法,目前支持normal、mmse和kl_divergencenormal:速度快,推薦量化數據量一般為20-100張左右mmse:暴力迭代方式,速度較慢,但精度比normal要高,推薦量化數據量20-50張左右kl_divergence:所有時間比normal多,比mmse少,適用于feature分布不均勻的場景,推薦量化數據量20-100張左右quantized_method: str = 'channel',目前支持layer、channellayer:每層的weight只有一套量化參數channel:每層的weight的每個通道都有一套量化參數,因此channel會比layer精度高target_platform: Any | None = None,指定RKNN模型是基于那個目標芯片平臺生成的,目前支持‘rk3566’、‘rk3588’等quant_img_RGB2BGR: bool = False,表示在加載量化圖像時是否需要先做RGB2BGR的操作(一般用在Caffe模型上)。如果有多個輸入,則用列表包括起來,如[True, True, False]該配置只對jpg/jpeg/png/bmp格式的圖片有效該配置僅用于量化階段(build接口)讀取量化圖像或量化精度分析(accuracy_analysis接口),并不會保存在最終的RKNN模型中,因此如果模型的輸入為bgr,則調用toolkit2的inference或C-API的run函數之前需要保證傳入的圖像數據為BGR格式float_dtype: str = 'float16',用于制定非量化情況下的浮點的數據類型,目前只支持float16optimization_level: int = 3,模型優化等級,通過修改該值可以關掉部分或全部模型轉換過程中使用到的優化規則optimization_level=3:打開所有優化選項optimization_level=1或2:關閉一部分可能會對部分模型精度產生影響的優化選項optimization_level=0:關閉所有優化選項custom_string: Any | None = None,添加自定義字符串信息到RKNN模型,可以在runtime時通過query查詢到該信息,方便部署時根據不同的RKNN模型做特殊處理remove_weight: bool = False,去除conv等權重以生成一個RKNN的從模型,該從模型可以與帶完整權重的RKNN模型共享權重以減少內存消耗compress_weight: bool = False,壓縮模型權重,可以減小RKNN模型的大小inputs_yuv_fmt: Any | None = None,single_core_mode: bool = False,是否僅生成單核模型,可以減小RKNN模型的大小和內存消耗,目前僅對RK3588生效dynamic_input: Any | None = None,用于根據用戶制定的多組輸入shape,來模擬動態輸入的功能,格式為[[input0_shapeA, input1_shapeA, ...], [input0_shapeB, input1_shapeB, ...], ...]假設原始模型只有一個輸入,shape為[1, 3, 224, 224],但需要該模型支持3種不同的輸入shape,如[1, 3, 224, 224], [1, 3, 192, 192]和[1, 3, 160, 160]可以設置dynamic_input=[1, 3, 224, 224], [1, 3, 192, 192]和[1, 3, 160, 160],轉換成RKNN模型后進行推理時,需要傳入對應shape的數據【注】需要原始模型支持動態輸入才可以開啟此功能model_pruning: bool = False,對模型進行無損剪枝,對于權重稀疏的模型,可以減小轉換后RKNN模型的大小和計算量op_target: Any | None = None,用于指定OP的具體執行目標(如NPU/CPU/GPU等)格式為{'op0_output_name':'cpu', 'op1_output_name':'npu',...}'op0_output_name'和'op1_output_name'對應op的輸出tensor名,可以通過精度分析(accuracy_analysis)返回結果中獲取'cpu'和'npu'表示該tensor對應的op的執行目標是CPU或NPU**kwargs: Any)無返回值'''rknn.load_pytorch(model = "yolov11n-cls.pt",input_size_list = [[1, 3, 480, 480]])'''def load_pytorch(model: Any,pytorch模型文件(.pt)路徑,必須是torchscript格式的input_size_list: Any每個輸入節點對應的shape,所有輸入shape存放在一個列表中)   返回值:0:導入成功;-1;導入失敗'''rknn.build(do_quantization=True,dataset='datasets.txt')'''def build(do_quantization: bool = True,是否對模型進行量化dataset: Any | None = None,用于量化校正的數據及,目前僅支持文本文件格式,用戶可以把用于校正的圖片(jpg、bmp或png格式)放到一個.txt文件中,文本文件中每一方存放一條路徑信息,如a.jpg如果有多個輸入,每個輸入對應的文件用空格隔開,如a.jpg b.jpgrknn_batch_size: Any | None = None模型的輸入batch參數調整,如果設置為大于1,則可以在一次推理中同時推理多幀輸入圖像或輸入數據會同時改變輸入和輸出的batch)返回值:0:構建成功;-1:構建失敗'''rknn.export_rknn(export_path="yolov11n-cls.rknn")'''def export_rknn(export_path: Any,導出模型文件的路徑cpp_gen_cfg: Any | None = None,是否生成C++部署示例,生成文件:模型路徑同文件夾下,生成rknn_deploy_demo文件夾、說明文檔;支持驗證模型推理是,各CAPI接口耗時;驗證推理結果的余弦精度;支持常規API接口;支持圖片/NPY輸入**kwargs: Any)返回:0:導出成功;-1:導出失敗'''print("finisned")rknn.release()

2、torch.nn.module——>onnx——>rknn

可以通過onnx作為中轉解決pytorch導出和轉換rknn模型的版本不一致問題
參考2:瑞芯微的官方教程
可以看出,onnx轉rknn的程序與torch模型轉rknn唯一的不同就是在加載模型時,使用load_onnx()
【注】 onnx的opset版本需要注意,如果導出失敗可以根據報錯提示,去修改導出onnx文件中的opset的版本號,如報錯信息為ValueError: Unsupport onnx opset 17, need <= 12!,在導出onnx文件中設置model.export(format=“onnx”, opset=11) 即可

from rknn.api import RKNNif __name__=='__main__':rknn = RKNN()rknn.config(mean_values=[[0.0, 0.0, 0.0]],std_values=[[1.0, 1.0, 1.0]],target_platform='rk3588')rknn.load_onnx('yolov11n-cls.onnx')'''def load_onnx(model: Any,onnx模型文件路徑inputs: Any | None = None,模型輸入節點(tensor名),支持多個輸入節點,所有輸入節點名放在一個列表中input_size_list: Any | None = None,每個輸入節點對應的shape,所有輸入shape放在一個列表中。如果inputs有設置,input_size_list也需要設置input_initial_val: Any | None = None,設置模型輸入的初始值,格式為ndarray的列表。主要用于將某些輸入固化為常量,對于不需要固化為常量的輸入可以設置為Noneoutputs: Any | None = None模型的輸出節點(tensor名),支持多個輸出節點,所有輸出節點名放在一個列表中)返回值:0:導入成功;-1:導入失敗'''rknn.build(do_quantization=True,dataset='datasets.txt')rknn.export_rknn('yolov11n-cls.rknn')rknn.release()

三、模型推理

模型推理有兩種方式:
1、在PC上運行非RKNN模型
2、在NPU上運行RKNN模型

1、在PC上運行非RKNN模型

在這里插入圖片描述

實現步驟為:

'''
1、實例化RKNN對象
2、調用Config接口設置模型的預處理參數
3、調用load_pytorch、load_onnx接口導入pytorch\onnx模型等
4、調用build接口構建RKNN模型
5、調用ini_runtime接口初始化運行環境,注意設置target=None,表示在模擬器上運行
6、導入要推理的數據并預處理數據
7、調用inference接口進行推理,獲取推理結果
8、釋放RKNN對象
'''

實現代碼如下:

from rknn.api import RKNN
import cv2
import numpy as npif __name__=='__main__':rknn = RKNN()rknn.config(mean_values=[[0.0, 0.0, 0.0]], std_values=[[1.0, 1.0, 1.0]],target_platform='rk3588')# rknn.load_pytorch('yolov11n-cls.pt',#                   input_size_list=[[1, 3, 480, 480]])rknn.load_onnx('yolov11n-cls.onnx',input_size_list=[[1, 3, 480, 480]])rknn.build(do_quantization=True, dataset='datasets.txt', rknn_batch_size=-1)rknn.init_runtime(target=None,# target='rk3588',target_sub_class=None,device_id=None,perf_debug=False,eval_mem=False,async_mode=False,core_mask=RKNN.NPU_CORE_AUTO,)img = cv2.imread(filename='A6_6499.bmp')img = cv2.resize(img, (480, 480))cv2.cvtColor(img, cv2.COLOR_BGR2RGB)outputs = rknn.inference(inputs=[img],data_format="nhwc",'''cv2.imread()讀取的圖像數據的layout為NHWC,data_format的默認值為NHWC,如果模型的輸入不是通過cv2.imread()讀取,需要設置正確的data_format值''')print(np.array(outputs[0][0]))rknn.release()

2、在NPU上運行RKNN模型

2.1 推理前的準備工作

1)確保開發板的USB OTG連接到PC,并正確識別到設備。可以通過adb device命令查詢相應設備,也可調用rknn-toolkit2的list_devices接口查詢相應設備。

rknn = RKNN()
rknn.list_devices()
'''
def list_devices():無參數,返回adb_devices列表和ntb_devices列表,如果設備為空,則返回空列表
'''
rknn.release()輸出為:
*************************
all device(s) with adb mode:
VD46C3KM6N
*************************

2)參考https://github.com/rockchip-linux/rknpu2/blob/master/rknn_server_proxy.md說明更新開發板的runtime庫和rknn_server庫,并確保rknn_server服務已經啟動(大部分平臺需要手動通過串口啟動)
3)調用init_runtime接口初始化運行環境時需要指定target參數(開發平臺,如target=‘rk3588’)和device_id參數(由步驟2list_devices中獲取,如本例程中device_id=‘VD46C3KM6N’)。

2.2 模型推理實現步驟
在這里插入圖片描述

'''
運行RKNN模型,不需要設置模型預處理參數,也不需要構建RKNN模型,推理流程:
1、實例化RKNN對象
2、調用load_rknn導入RKNN模型
3、調用init_runtime初始化,注意設置target='rk3588', device_id的值需要通過rknn.list_devices獲取
4、導入要處理的數據并處理成需要的輸入格式
5、調用inference進行推理并獲取推理結果
6、釋放RKNN對象
'''

實現代碼:

from rknn.api import RKNN
import cv2 
import numpy as npif __name__=="__main__":rknn = RKNN()rknn.load_rknn('yolov11n-cls.rknn')rknn.init_runtime(target='rk3588',device_id='VD46C3KM6N')img = cv2.imread(filename='A6_6499.bmp')img = cv2.resize(img, (480, 480))cv2.cvtColor(img, cv2.COLOR_BGR2RGB)outputs = rknn.inference(inputs=[img],data_format="nhwc", '''cv2.imread()讀取的圖像數據的layout為NHWC,data_format的默認值為NHWC,如果模型的輸入不是通過cv2.imread()讀取,需要設置正確的data_format值''')print(np.array(outputs[0][0]))rknn.release()

四、模型量化

RKNN模型量化是一種將深度學習模型從浮點精度(如FP32)轉換為低比特整數(如INT8)的技術,旨在減少模型體積、提升推理速度并降低功耗。量化對象:權重量化(模型參數從浮點轉為整數)、激活量化(推理時中間特征圖的數值轉換)
4.1 量化原理:

1)線性量化原理

  • 使用比例因子scale和零點zero_point將浮點值映射到整數區間, quantized_value = round(float_value / scale) + zero_point
  • 反量化是還原近似原始值,float_value ≈ (quantized_value - zero_point) * scale

2)校準過程(PTQ)

  • 通過校準數據集統計各層激活值的動態范圍,確定最優scale和zero_point
  • 關鍵作用:減少量化誤差,避免數值溢出或截斷

3)量化類型

  • 對稱量化:零點為0,適合權重分布對稱的場景
  • 非對稱量化,零點非0,適合偏態分布數據
  • 混合精度量化:敏感層保留FP16,其他層用INT8

4.2 量化精度分析

重點函數為accuracy_analysis()
【注】 該接口只能在build和hybrid_quantization_step2之后調用。
【注】 如未制定target,且原始模型應該為已量化的模型,否則會調用失敗
【注】 該接口使用的量化方式與config中制定的一致。

4.2.1 量化精度分析步驟

  • 實例化RKNN對象
  • 設置模型預處理和量化參數
  • 調用load_onnx等接口導入模型
  • 調用build構建模型
  • 調用accuracy_analysis進行量化精度分析
  • 釋放RKNN對象

4.2.2 代碼實現

from rknn.api import RKNNif __name__=="__main__":rknn = RKNN()rknn.config(mean_values=[[0.0, 0.0, 0.0]],std_values=[[1.0, 1.0, 1.0]],target_platform='rk3588')rknn.load_onnx('yolov11n-cls.onnx')rknn.build(do_quantization=True, dataset='datasets.txt')rknn.accuracy_analysis(inputs=['A6_6499.bmp'],output_dir='snapshot',target=None,         # 如果連接了開發板,target='rk3588', device_id=設備編號device_id=None)'''推理并產生快照,也就是dump出每一層的tensor數據,會dump出包括fp32和quant兩種數據類型的快照,用于計算量化誤差。def accuracy_analysis(inputs: Any,圖像(jpg/png/bmp/npy等)路徑listoutput_dir: str = './snapshot',輸出目錄,所有快照都保存在該目錄下,默認值為'./snapshot'如果沒有設置target,在output_dir下會輸出:1、simulator目錄:保存整個量化模型在simulator上完整運行時每一層的結果(已經轉成float32)2、golden目錄:保存整個浮點模型在simulator上完整跑下來時每一層的結果3、error_analysis.txt:記錄simulator上量化模型逐層運行時每一層的結果與golden浮點模型逐層運行時每一層的結果的余弦距離(entire_error cosine),以及量化模型取上一層的浮點結果作為輸入時,輸出與浮點模型的余弦距離(single_error cosine)如果有設置target,則在output_dir里還會多輸出:1、runtime目錄:保存整個量化模型在NPU上完整運行時每一層的結果(已轉成float32)2、error_analysis.txt:在上述記錄內容的基礎上,還會記錄量化模型在simulator上逐層運行時每一層的結果的余弦距離target: Any | None = None,目標硬件平臺,如果設置了target,則會獲取NPU運行時每一層的結果,并進行精度分析device_id: Any | None = None設備編號,如果pc連接多臺設備時,需要指定該參數)返回值:0:成功;-1:失敗'''rknn.release()

4.2.3 輸出

在這里插入圖片描述
在這里插入圖片描述
上圖右側有兩列數值輸出,其中entire表示simulator上量化模型逐層運行時每一層的結果與golden浮點模型逐層運行時每一層的結果的余弦距離,即量化模型整體輸出與原始浮點模型(golden)的誤差,反映端到端的累計誤差;sigle表示量化模型取上一層的浮點結果作為輸入時,輸出與浮點模型的余弦距離,反映單層量化精度。值越接近于1表示誤差越小。
【警惕關鍵現象1】 誤差值范圍,越接近1 表示量化誤差越小,若出現顯著下降(如0.99以下)須警惕精度損失
【警惕關鍵現象2】 NaN值,表示張量全零或數值極端,可能由無法激活或量化溢出導致。若存在須檢查校準數據或量化參數。

4.2.4 優化建議

1)敏感層定位:對比entire和single誤差差異較大層,優先采用混合量化
2)校準數據優化:若誤差集中在前幾層,需檢查輸入數據預處理是否與訓練一致
3)量化策略調整:對誤差突增層嘗試非對稱量化或調整量化粒度

4.3 混合量化

量化功能可能會使模型特殊模型的精度下降,為了在性能和精度之間做更好的平衡,混合優化功能,可以根據用用戶的手動指定某些層是否進行量化。

4.3.1 混合量化步驟

  • 生成混合量化配置文件,hybrid_quatization_step1()
  • 修改第一步生成的量化配置文件(.quantization.cfg)
  • 生成新的RKNN模型,hybrid_quantization_step2()

4.3.2 生成混合量化配置文件

重要API為hybrid_quatization_step1(),執行以下代碼會生成臨時模型文件(.model)、數據文件(.data)和量化配置文件(.quantization.cfg)
步驟為:

  • 實例化RKNN對象
  • 設置模型預處理參數config
  • 加載模型文件, onnx等
  • 調用hybrid_quantization_step1()
  • 釋放RKNN對象
from rknn.api import RKNNif __name__=="__main__":rknn = RKNN()rknn.config(mean_values=[[0.0, 0.0, 0.0]],std_values=[[1.0, 1.0, 1.0]],target_platform='rk3588')rknn.load_onnx('./yolov11n-cls.onnx')rknn.hybrid_quantization_step1(dataset='./datasets.txt',proposal=True,)'''用于生成臨時模型文件(.model)、數據文件(.data)和量化配置文件(.quantization.cfg)def hybrid_quantization_step1(dataset: Any | None = None,量化用的數據集rknn_batch_size: Any | None = None,模型的輸入batch參數的調整proposal: bool = False,產生混合量化的配置建議proposal_dataset_size: int = 1proposal使用的dataset的張數,默認為1.因proposal功能比較耗時,所以默認只是用1張,也就是dataset里的第一張)'''rknn.release()

yolov11n-cls.quatization.cfg文件內容如下

custom_quantize_layers:/model.0/conv/Conv_output_0: float16/model.0/act/Mul_output_0: float16/model.1/conv/Conv_output_0: float16/model.2/m.0/cv1/conv/Conv_output_0: float16/model.2/m.0/cv1/act/Mul_output_0: float16/model.2/m.0/Add_output_0: float16/model.2/Concat_output_0: float16/model.4/m.0/cv2/conv/Conv_output_0: float16/model.4/m.0/cv2/act/Mul_output_0: float16/model.4/m.0/Add_output_0: float16/model.4/Concat_output_0: float16/model.4/cv2/conv/Conv_output_0: float16/model.4/cv2/act/Mul_output_0: float16/model.5/conv/Conv_output_0: float16/model.6/m.0/m/m.0/cv1/act/Mul_output_0: float16/model.6/m.0/m/m.0/cv2/conv/Conv_output_0: float16/model.6/m.0/m/m.0/cv2/act/Mul_output_0: float16/model.6/m.0/m/m.0/Add_output_0: float16/model.6/m.0/cv3/act/Mul_output_0: float16/model.6/Concat_output_0: float16/model.8/m.0/m/m.0/cv1/act/Mul_output_0: float16/model.8/m.0/m/m.0/cv2/conv/Conv_output_0: float16/model.8/m.0/m/m.0/cv2/act/Mul_output_0: float16/model.8/m.0/m/m.0/Add_output_0: float16/model.8/m.0/m/m.1/cv1/conv/Conv_output_0: float16/model.8/m.0/m/m.1/Add_output_0: float16/model.8/m.0/m/m.1/cv1/act/Mul_output_0: float16/model.8/m.0/m/m.1/cv2/conv/Conv_output_0: float16/model.8/m.0/m/m.1/cv2/act/Mul_output_0: float16/model.8/m.0/Concat_output_0: float16/model.8/m.0/cv3/conv/Conv_output_0: float16/model.8/m.0/cv3/act/Mul_output_0: float16/model.8/Concat_output_0: float16/model.8/cv2/conv/Conv_output_0: float16/model.8/cv2/act/Mul_output_0: float16/model.9/cv1/conv/Conv_output_0: float16/model.9/cv1/act/Mul_output_0: float16/model.9/Split_output_0: float16/model.9/Concat_output_0: float16/model.9/Split_output_1: float16/model.9/m/m.0/attn/qkv/conv/Conv_output_0: float16/model.9/m/m.0/Add_output_0: float16/model.9/m/m.0/attn/Reshape_output_0: float16/model.9/m/m.0/attn/Split_output_0: float16/model.9/m/m.0/attn/Softmax_output_0: float16/model.9/m/m.0/attn/Transpose_1_output_0: float16/model.9/m/m.0/attn/MatMul_1_output_0: float16/model.9/m/m.0/attn/Reshape_1_output_0: float16/model.9/m/m.0/attn/Add_output_0: float16/model.9/m/m.0/attn/proj/conv/Conv_output_0: float16/model.9/m/m.0/ffn/ffn.0/act/Mul_output_0: float16/model.9/m/m.0/ffn/ffn.1/conv/Conv_output_0: float16/model.9/cv2/act/Mul_output_0: float16/model.10/conv/conv/Conv_output_0: float16/model.10/conv/act/Mul_output_0: float16/model.10/pool/GlobalAveragePool_2conv_0: float16/model.10/pool/GlobalAveragePool_output_0: float16/model.10/linear/Gemm_output_0_conv: float16
quantize_parameters:images:qtype: asymmetric_quantizedqmethod: layerdtype: float32min:-   0.0max:-   255.0scale: []zero_point: []ori_min:-   0.0ori_max:-   255.0...

其中,custom_quatize_layers是一個自定義量化tensor字典,用戶可以將tensor名和相應的量化類型添加到該字典中,即可實現將該tensor作為輸出的層的運算類型改為指定的運算類型。上面的文件是我的rknn導出的cfg文件,可以看出custom_quatize_layers已經列了一些優化層了。
quantize_parameters:是模型中每個tensor的量化參數,每一個tensor都是一個字典,每個字典的key為tensor的名,字典的value為量化參數,如果沒有經過量化,dtype值為float16

4.3.3 修改第一步生成的量化配置文件(.quantization.cfg)
為了測試一下混合量化,我自己修改了一下我的cfg文件,在上一步量化精度分析中,下面兩層的entire和single誤差差值有一點點大

[exSwish] /model.4/cv1/act/Mul_output_0                          0.999917  0.999983       
[Split] /model.4/Split_output_0                                  			0.999907  0.999983

因此修改yolov11n-cls.quatization.cfg文件如下
【注】 custom_quantize_layers格式問題,官方文檔給的是custom_quantize_layers:{x:float16, x2:float16},但是我這邊會報錯,改成YAML格式的就好了,不曉得為啥。YAML不需要{},也不需要,作為分割,只要縮進做好就可,詳細請參考下述代碼

custom_quantize_layers:/model.4/cv1/act/Mul_output_0:float16/model.4/Split_output_0:float16# 將/model.4/cv1/act/Mul_output_0,/model.4/Split_output_0設置為float16,即不進行量化quantize_parameters:images:qtype: asymmetric_quantizedqmethod: layerdtype: float32min:-   0.0max:-   255.0scale: []zero_point: []ori_min:-   0.0ori_max:-   255.0/model.0/conv/Conv_output_0:qtype: asymmetric_quantizedqmethod: layerdtype: int8min:-   -15024.08984375max:-   9862.2978515625scale:-   97.59367723651961zero_point:-   26ori_min:-   -15024.08984375ori_max:-   9862.2978515625

4.3.4 生成新的RKNN模型,hybrid_quantization_step2()
步驟為:

  • 實例化RKNN對象
  • 調用hybrid_quantization_step2()
  • 調用accuracy_analysis()再次評估模型,驗證混合量化效果
  • 導出RKNN模型
  • 釋放RKNN模型
# 混合量化前
[exSwish] /model.4/cv1/act/Mul_output_0                          0.999917  0.999983       
[Split] /model.4/Split_output_0                                  0.999907  0.999983# 混合量化后
[exSwish] /model.4/cv1/act/Mul_output_0                          0.999791  1.000000       
[Split] /model.4/Split_output_0                                  0.999786  1.000000 

五、模型部署

待更新

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82011.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82011.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82011.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

重構研發效能:項目管理引領軟件工廠邁向智能化

1.項目管理智能化&#xff0c;激活軟件工廠新引擎 在高速發展的軟件開發時代&#xff0c;企業如何高效管理多個項目、協調團隊合作、優化資源配置&#xff0c;已成為推動技術進步的關鍵。尤其是在多任務、多項目并行的復雜環境下&#xff0c;智能項目組合管理工具正成為軟件工…

小米汽車二期工廠下月將竣工,產能提升助力市場拓展

在新能源汽車市場競爭日益激烈的當下&#xff0c;小米汽車傳來重要進展消息。據多方信息顯示&#xff0c;小米汽車二期工廠下月即將竣工&#xff0c;這一關鍵節點的到來&#xff0c;有望為小米汽車的產能提升與市場布局帶來重大突破。? 小米汽車二期工廠位于北京亦莊&#xff…

Python 爬蟲實戰:電競比賽直播數據實時抓取與可視化分析

一、引言 在電競行業快速發展的今天,電競比賽直播數據成為了電競愛好者、分析師和商業機構關注的焦點。實時抓取電競比賽直播數據并進行分析,不僅可以幫助觀眾更好地理解比賽,還能為戰隊戰術優化、選手表現評估以及賽事運營提供重要參考。 本文將詳細介紹如何使用Python爬…

零基礎設計模式——創建型模式 - 生成器模式

第二部分&#xff1a;創建型模式 - 生成器模式 (Builder Pattern) 前面我們學習了單例、工廠方法和抽象工廠模式&#xff0c;它們都關注如何創建對象。生成器模式&#xff08;也常被稱為建造者模式&#xff09;是另一種創建型模式&#xff0c;它專注于將一個復雜對象的構建過程…

Debezium快照事件監聽器系統設計

Debezium快照事件監聽器系統設計 1. 系統概述 1.1 設計目標 為 Debezium 的快照過程提供可擴展的事件監聽機制允許外部系統在快照過程中執行自定義邏輯提供線程安全的事件分發機制確保監聽器的異常不會影響主快照流程1.2 核心功能 表快照開始事件監聽表快照完成事件監聽行數據…

手術機器人行業新趨勢:Kinova多機械臂協同系統如何突破復雜場景適應性瓶頸?

機器人手術歷經多階段技術演進&#xff0c;已成為現代醫療重要方向。其需求增長源于醫療機構對高精度低風險手術方案的需求、微創手術普及及技術進步帶來的復雜場景適應性提升。Kinova 輕型機械臂憑借模塊化設計與即插即用功能&#xff0c;可快速適配不同手術環境&#xff0c;為…

力扣面試150題-- 二叉樹展開為鏈表

Day 46 題目描述 思路 初次做法&#xff1a;由于我直接考慮O&#xff08;1&#xff09;級別的空間復雜度&#xff0c;于是采取了以下做法&#xff1a; 接下來的內容就是遞歸函數如果該節點為空&#xff0c;就返回null將此時的current作為頭節點&#xff0c;left和right作為孩…

【Python】開發工具uv

文章目錄 1. uv install1.1 下載安裝腳本來安裝1.2 使用pipx安裝uv1.3 補充 2. 考慮在離線系統上安裝uv2.1 下載并上傳安裝包2.2 用戶級安裝uv&#xff08;~/.local/bin/&#xff09;2.3 補充 3. uv 管理Python解釋器4. uv 管理依賴5. uv運行代碼5.1 uv不在項目下執行腳本5.2 u…

zabbix批量主機維護腳本兼容性更新

最近做新老版本zabbix監控主機遷移發現zabbix6.0后api安全有了效大升級&#xff0c;批量主機維護腳本出現認證兼容性問題&#xff0c;以下為腳本更新token支持&#xff1a;在這里插入代碼片&#xff1a; # /usr/bin/env python3 # -*- coding:utf-8 -*- import requests impor…

Java中static關鍵字深度解析:從入門到高階實戰

Java中static關鍵字深度解析&#xff1a;從入門到高階實戰 目錄 static的本質與核心特性靜態變量 vs 實例變量&#xff1a;底層對比靜態方法的設計哲學與應用場景高級用法&#xff1a;突破常規的static技巧 4.1 靜態代碼塊&#xff1a;類加載的“初始化引擎”4.2 靜態內部類&…

基于RT-Thread的STM32F4開發第五講——軟件模擬I2C

文章目錄 前言一、RT-Thread工程創建二、AT24C02三、函數編寫1.I2C_soft.c2.I2C_soft.h3.main.h 四、效果展示五、資源分享總結 前言 本章是基于RT-Thread studio實現軟件模擬I2C&#xff0c;開發板是正點原子的STM32F4探索者&#xff0c;使用的RT-Thread驅動是5.1.0&#xff0…

49、c# 能?foreach 遍歷訪問的對象需滿足什么條件?

在 C# 中&#xff0c;要使用 foreach 循環遍歷一個對象&#xff0c;該對象必須滿足以下條件之一&#xff1a; 1. 實現 IEnumerable 或 IEnumerable 接口 非泛型版本&#xff1a;System.Collections.IEnumerable public class MyCollection : IEnumerable {private int[] _da…

推客小程序系統開發:全棧式技術解決方案與行業賦能實踐?

? 在數字化營銷深度滲透各行業的當下&#xff0c;傳統推廣模式已難以滿足企業精細化運營與高效獲客的需求。專業的推客小程序系統憑借其強大的裂變傳播能力與靈活的推廣機制&#xff0c;成為企業構建私域流量池、提升推廣效能的核心工具。我們基于多年技術沉淀與行業洞察&…

WPF布局系統詳解:掌握界面設計的核心藝術

掌握界面設計的核心藝術 1. WPF布局系統概述2. Grid布局詳解2.1 基本行列定義2.2 單元格定位與跨行跨列 3. StackPanel布局4. DockPanel布局5. WrapPanel與Canvas5.1 WrapPanel自動換行布局 5. Canvas絕對定位6. 布局嵌套與綜合應用7. 布局性能優化8. 響應式布局技巧9. 實戰&am…

labview實現LED流水燈的第一種方法

目的&#xff1a;寫一個跑馬燈程序&#xff0c;7個燈從左到右不停的輪流點亮&#xff0c;閃爍間隔由滑動條調節。 一、方法1&#xff1a;使用順序結構 使用順序結構&#xff0c;平鋪式順序結構與創建局部變量實現LED流水燈 具體步驟如下&#xff1a; 第一步&#xff0c;選擇…

uniapp如何設置uni.request可變請求ip地址

文章目錄 簡介方法一&#xff1a;直接在請求URL中嵌入變量方法二&#xff1a;使用全局變量方法三&#xff1a;使用環境變量方法四&#xff1a;服務端配置方法五&#xff1a;使用配置文件&#xff08;如config.js&#xff09;:總結 簡介 在uni-app中&#xff0c;uni.request 用…

深度學習篇---LSTMADF軌跡預測

文章目錄 前言LSTM 軌跡預測原理應用在行人軌跡預測方面在自動駕駛車輛的軌跡預測中優點缺點APF 軌跡預測原理應用在船舶運動規劃在無人駕駛車輛避障軌跡跟蹤優點缺點示例代碼前言 本文簡單介紹LSTM(長短期記憶網絡)和ADF(人工勢場法)這兩種不同的軌跡預測方法。 LSTM 軌跡…

python實現Web請求與響應

目錄 一&#xff1a;什么是Web請求與響應&#xff1f; 1&#xff1a;Web請求 2&#xff1a;Web響應 3&#xff1a;HTTP協議概述 4&#xff1a;常見的HTTP狀態碼包括&#xff1a; 二&#xff1a;python的requests庫 1&#xff1a;安裝requests庫 2&#xff1a;發送GET請…

Unity使用sherpa-onnx實現說話人識別

網友軟綿綿的面包人推薦&#xff0c;模型3dspeaker_speech_eres2net_base_200k_sv_zh-cn_16k-common.onnx的效果比3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx要好 具體代碼 using System; using System.Collections.Generic; using System.IO; using Sherpa…

ElasticSearch-集群

本篇文章依據ElasticSearch權威指南進行實操和記錄 1&#xff0c;空集群 即不包含任何節點的集群 集群大多數分為兩類&#xff0c;主節點和數據節點 主節點 職責&#xff1a;主節點負責管理集群的狀態&#xff0c;例如分配分片、添加和刪除節點、監控節點故障等。它們不直接…