联发科MT8666-NNAPI移植

1、adb常用指令

python 复制代码
adb --s [device] push src dst
adb --s [device] shell
adb --s [device] pull src dst

2、模型适配过程中onnx模型修改

#加载ONNX模型

model = onnx.load("test.onnx")

#保存ONNX模型
onnx.save(model, 'save_path.onnx')

#OP节点列表,是List, 可以增删改查
model.graph.node

#输入节点名称
model.graph.input

#输出节点名称
model.graph.output

#参数节点
model.graph.initializer
for tensor in model.graph.initializer:
if tensor.name == "attrinet.conv_2_dw.conv.bias":
tensor.raw_data = np.ones(16, dtype=np.int32).tobytes()

#改变任意OP名称或者属性
model.graph.node0.name= '自定义'
model.graph.node0.op_type= '自定义'
#改变输入的batch,例如 1x100x100x3 -> 1x3x100x100
model.graph.input0.type.tensor_type.shape.dim1.dim_value=3

#也可以采用下面方法创建新的节点插入
model.graph.input0.type.tensor_type.shape.dim3.dim_value=100
#改变输入的类型,详情参见GitHub onnx/onnx/onnx-ml.proto TensorProto DataType枚举,1--float 2--uint8 3--int8 7--int64
model.graph.input0.type.tensor_type.elem_type=3
#ONNX模型采用tensor与node(op)将整个网络构建起来,node中输入输出为tensor的名称,用来连接各个tensor,中间的节点tensor不用创建,网络的输入输出节点需要创建tensor。Tensor常用的2种创建方法,样例如下:
(1) onnx.helper.make_tensor_value_info(name=output, elem_type=type, shape=\[\]), #仅根据形状创建,用于输入输出节点
onnx.helper.make_tensor_value_info("out_1", TensorProto.FLOAT, 1,3,224),

(2) onnx.helper.make_tensor(name='const_tensor', data_type, dims=values.shape, vals=values.flatten()),#根据numpy数据创建

#构建OP节点,
conv_node = onnx.helper.make_node(op_type='Conv2dInt', inputs=input_names, outputs=output_names, name='Conv2dInt_1', **attribute)
input_names、output_names 是字符串数组,为tensor的名称,例如:input_names='name1', 'name2'
attribute是字典,如:
attribute = {
"data_bits": xxx,
"group": xxx,
"scale_o": xxx,
...
}

#增加OP节点
model.graph.node.append(conv_node)
model.graph.node.insert(insert_pos, conv_node)
#增加输入、输出tensor节点
output_node = onnx.helper.make_tensor_value_info("out_1", TensorProto.FLOAT, 1,3,224)
model.graph.output.append(output_node) // or input
#增加参数节点
conv_node_bias = onnx.numpy_helper.from_array(bias_data, name="conv_node_bias_name")
model.graph.initializer.append(conv_node_bias)
其中bias_data可从原conv节点取得:
bias_name = node.input2
for data in module.graph.initializer:
if data.name == bias_name:
bias_data = onnx.numpy_helper.to_array(data)

#特殊节点-constant增加,data_type参见GitHub onnx/onnx/onnx-ml.proto TensorProto DataType枚举
value=onnx.helper.make_tensor(name='const_tensor', data_type=1, dims=numpy_data.shape, vals=numpy_data.flatten())
constant_node = onnx.helper.make_node(op_type='Constant', inputs=\[\], outputs=output_name, name='constant1', value = value)

#读取ONNX的参数tensor格式,转换为numpy
#constant节点:
onnx.numpy_helper.to_array(onnx_node.attribute0.t)
constant_value = onnx_node.attribute0.t.raw_data
dims = onnx_node.attribute0.t.dims
dtype = onnx_node.attribute0.t.data_type

#initialize的参数:
onnx.numpy_helper.to_array(params)
特别数值,若数值为1个数,则导出的非numpy格式,也是一个数值

#获取节点数量
def getNodeNum(model):
return len(model.graph.node)

#获取节点类型
def getNodetype(model):
op_name = \[\]
for i in range(len(model.graph.node)):
if model.graph.nodei.op_type not in op_name:
op_name.append(model.graph.nodei.op_type)
return op_name

#获取节点名列表
def getNodeNameList(model):
NodeNameList = \[\]
for i in range(len(model.graph.node)):
NodeNameList.append(model.graph.nodei.name)
return NodeNameList

#获取模型的输入信息
def getModelInputInfo(model):
return model.graph.input0

#获取模型的输出信息
def getModelOutputInfo(model):
return model.graph.output0

#Xlite指定位置切子图
xlite/tools/xlite/layout_convert/layout_convert.py line 170:
if node.name in'node_name' //node_name以后将会被切掉

#debug看子图信息的地方
xlite/tools/xlite/packer/nnapi.py line 213:
graph, max_sub_graph = _get_layout_optimizer(g, config'layout_out')

#升维、降维
unsqueeze、squeeze

3、Mtk8666 android npu模型

a、打包报错:

复制代码
RuntimeError:This is an invalid model. Error in Node:OnnxInferDeQuant-814_815:No Op registered for OnnxInferDeQuant with domain_verion of 12

原因:domain位置不对,需要更新模型

b、引擎效率获取命令:

cat log/xxx.log |grep average

4、引擎集成

摄像头规格:

图像格式:gray

图像大小:640*480

帧率:30fps

8666平台: 8核

a、集成过程

(1) 只需要视觉DMS,其他不需要

(2) 使用MTK8666配置文件 MTK8666.json

(3) 拷贝npu版本库里的模型及库文件至工程

(4) 编译部署:build_android.bat → delivery.bat

(5)摄像头无法获取图像而导致卡住的问题已提相关同事处理。

b、车机部署

(1) target部署至/data/local/tmp/bin下

(2) 车机需要联网(引擎需要权限)

(3) 需要先运行Carcorder APK,再运行DMS APK

c、运行

复制代码
#su
#cd /data/local/tmp/bin/
#./test.sh
相关推荐
To_OC8 小时前
手搓一个迷你版 Cursor:从零实现能自动写代码的编程 Agent
人工智能·langchain·llm
hboot8 小时前
AI工程师第五课 - 大语言模型基础
python·llm·fastapi
民乐团扒谱机8 小时前
【全流程实战】LibTV节点式AI视频工作流落地教程|从剧本到成片可复用流水线,新手/开发者双版本
人工智能·音视频
AOwhisky8 小时前
Python 学习笔记(第一期与第二期)——基础语法——核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发
天空'之城9 小时前
Linux 系统编程 22:五种 IO 模型全解
linux
STLearner9 小时前
ICML 2026 | LLM×Graph论文总结[1]【图基础模型,文本属性图,多模态属性图,图对齐,图提示学习,关系深度学习
论文阅读·人工智能·python·深度学习·学习·机器学习·数据挖掘
冬奇Lab9 小时前
MCP 系列(05):Resources 和 Prompts 进阶——动态数据、参数化 URI 与多轮模板
人工智能·llm·mcp
冬奇Lab10 小时前
开源项目第158期:cangjie-skill — 把书、视频、播客里的方法论蒸馏成可调用的 AI Skills
人工智能·开源·资讯
小张成长计划..10 小时前
【Linux】10:冯·诺依曼体系结构和操作系统
linux·运维·服务器
习明然11 小时前
我的本地化AI项目(三)
人工智能·python·electron·c#·avalonia