零拷贝优化模型部署

固件类型:官方提供的固件
固件文件名称:b25912d8cb34/2412101631
固件下载地址:自行编译
Log日志:无日志文件.zip

我测试了rknn_model_zoo/examples/yolov5/程序,使用demo的图片和模型,跑出来一个结果,之后我将正程序修改成零拷贝方式,将图像直接拷贝到申请的缓存中,发现跑出来的结果和修改之前的结果一样,之后我把原始的程序的inputs[0].pass_through = 1;之后再调用rknn_inputs_set(app_ctx->rknn_ctx, app_ctx->io_num.n_input, inputs);,发现模型结果不一样了,按测试之前的想法,应该是零拷贝和inputs[0].pass_through = 1这两种情况,模型输入是一样的,这两种情况模型结果是一样才对,问一下这个测试结果为什么会这样
tchip_askquestions
无日志文件.zip (299 Bytes)

应该是因为,
1、“原始的程序的inputs[0].pass_through = 1”: 此时不会对你的输入数据做归一化和量化,直接输入到模型。
2、使用“零拷贝”接口归一化等转换数据在NPU运行。
所以实际上此时输入数据是不一样的

lanzj 发表于 2025-6-23 11:47
应该是因为,
1、“原始的程序的inputs[0].pass_through = 1”: 此时不会对你的输入数据做归一化和量化,直 …

您好,inputs[0].pass_through = 1,表示输入数据不会做归一化和量化,图像数据直接给模型了,我使用零拷贝的时候,我没有做归一化处理,所以也相当于是直接把数据给模型了,我这两种方式使用的是同一个模型文件,模型文件还能区分我的当前模式,选择性的做归一化和量化操作吗?我理解模型文件一样的情况,给什么数据,就用什么数据。

您好,顺便问一下,如果要在模型里面做归一化和量化,这两个功能怎么添加到模型文件中,是量化时的配置还是模型训练时候添加,麻烦指教一下。

一般情况下应该是rknn自动做归一化和量化的,无需自己完成。inputs[0].pass_through = 1就表示你输入的数据已经完成了归一化量化。可以查阅文档熟悉相关说明

lanzj 发表于 2025-6-23 14:27
一般情况下应该是rknn自动做归一化和量化的,无需自己完成。inputs[0].pass_through = 1就表示你输入的数据 …

现在我是要用零拷贝的方式,我把数据发给模型之前,还需要对数据进行归一化处理?还有一个问题,就是我之前问的,我测试了rknn_model_zoo/examples/yolov5/程序,使用demo的图片和模型,跑出来一个结果,之后我将程序修改成零拷贝方式,将图像直接拷贝到申请的缓存中,发现跑出来的结果和修改之前的结果一样,这说明发给模型的数据不需要归一化处理和量化处理,但是rknn_inputs_set(app_ctx->rknn_ctx, app_ctx->io_num.n_input, inputs);应该会做归一化处理,我直接拷贝给模型的数据是没有做归一化处理的,这个现象其实是矛盾的,您那边知道是怎么回事吗?

我前面说了呀,rknn自动完成归一化处理,你设了inputs[0].pass_through=1就表明你要自己归一化。所以不用设这个值。


零拷贝的方式也是也是自动完成归一化。

零拷贝并不等价于inputs[0].pass_through = 1
截图_选择区域_20250623160525.png

lanzj 发表于 2025-6-23 16:06
零拷贝并不等价于inputs[0].pass_through = 1

您好,感谢您的回复,再请教一个问题,我这边的线程接收到图像数据,图像数据结构图包含虚拟地址、物理地址和fd,我这边计划采用零拷贝的方式,当前测试是我先用rknn_create_mem函数申请内存,之后在接收到图像数据时,将图像数据拷贝到申请内存的虚拟地址里面,我现在看可以使用物理地址或者fd申请tensor,我这边的最优设计是不是应该是接收图像数据后,使用图像数据的物理地址或者fd作为rknn_create_mem_from_phys或者rknn_create_mem_from_fd函数参数申请tensor,之后使能模型运行,这样就不用把图像虚拟地址数据拷贝到tensor的虚拟地址里面了。

王玉周 发表于 2025-6-23 16:44
您好,感谢您的回复,再请教一个问题,我这边的线程接收到图像数据,图像数据结构图包含虚拟地址、物理地 …

您好,我这边做了一个测试,在零拷贝方式初始化时,model_info->in_attr[i].type = RKNN_TENSOR_UINT8;之后执行ret = rknn_set_io_mem(model_info->ctx, model_info->seg_input_mem[i], &model_info->in_attr[i]);,模型运行时间是4毫秒多,如果model_info->in_attr[i].type = RKNN_TENSOR_INT8;,修改成有符号,模型运行时间就是5毫秒多,差了1毫秒,执行结果没有问题,只是为什么?