API 文档

root 2026-03-02 15:14:52 2026-03-02 15:16:12

aidqnn 高层 Python SDK 开发者指南

本指南旨在帮助开发者快速上手使用 aidqnn 高层 Python SDK。该 SDK 对底层的 aidlite C++ 接口进行了深度封装,提供了极其简化的 API 来加载和运行各种 AI 模型(ONNX、TFLite、QNN),并自动处理了设备调度、输入输出形状推导以及张量轴(Axis)转换等繁琐工作。


1. 核心特性

  • 极简加载:支持通过单行代码直接从模型文件或 aimo(模型优化平台)下载的文件夹中加载模型。
  • 多框架支持:无缝支持 ONNX (cpu)、TFLite (cpu, gpu) 和 QNN (cpu, gpu, npu)。
  • 智能排布修正:QNN 优化模型时可能会改变张量的轴顺序(例如 NCHW 变成 NHWC),SDK 能够根据配置文件自动在后台完成转置(Transpose),开发者无需修改预处理/后处理代码。
  • 环境自适应:自动识别 AidLux 社区版(normal)与企业版,智能切换 QNN 的 Remote 与 Local 推理模式。

2. 快速入门:懒人加载模式 (from_path)

对于大部分从 aimo 平台 导出的 QNN 模型,最推荐、也是最简单的使用方式是使用 AutoModel.from_path

⚠️注意:传给 from_path 的文件夹必须是直接从 aimo 平台下载并解压后的原始文件夹,切勿随意重命名或删除其中的任何文件。SDK 会依赖文件夹内的文件结构(如 ctx.bin.so_net.json 等)自动推断最佳配置。

import numpy as np
from aidqnn import AutoModel

model = AutoModel.from_path("./model_save_path")

# 2. 准备输入数据
# 注意:ONNX 和 TFLite 均不支持动态形状(Dynamic Shapes),必须严格匹配模型要求的固定尺寸。
# QNN 模型强制要求输入数据格式为 np.float32,无论是否量化。
input_data = np.random.randn(1, 3, 224, 224).astype(np.float32)

# 3. 运行推理
output = model(input_data)

print("推理成功,输出形状:", output.shape)


3. 进阶使用:常规加载模式 (AutoModel)

如果你手上只有单独的模型文件(比如单个 .tflite.onnx 文件),可以直接使用 AutoModel 类来进行实例化。SDK 会根据文件后缀名自动判断框架类型。

from aidqnn import AutoModel
import numpy as np

# -------- 加载 TFLite 模型 --------
# 默认情况下,TFLite 会尝试使用 GPU
tflite_model = AutoModel("model.tflite", device="gpu")
output = tflite_model(np.random.randn(1, 224, 224, 3).astype(np.float32))

# -------- 加载 ONNX 模型 --------
# ONNX 目前仅支持 CPU 设备
onnx_model = AutoModel("model.onnx", device="cpu")
output = onnx_model(np.random.randn(1, 3, 224, 224).astype(np.float32))

3.1 手动加载 QNN 模型时的注意事项

如果是手动指定 QNN 模型文件(.so.bin),强烈建议同时传入 model_config 参数(即 _net.json 文件的路径)。config 文件可以在 aimo 导出的文件夹中找到,通常是文件大小最大的那个 .json 文件。

为什么? QNN 框架在优化时经常会做通道排布的转换(Channel Last 优化,例如把 NCHW 转换为 NHWC,NCF 转换为 NFC)。如果不传 Config 文件,你需要自己手动做 np.transpose;如果传入了 Config 文件,SDK 的 AidModel 会自动解析 axis_format,并在推理前后为你自动完成输入数据的转置和输出数据的复原。

# 手动加载 QNN 并在参数中补充 config 路径,确保轴顺序自动纠正
qnn_model = AutoModel(
    model_path="model_aarch64.ndk.so", 
    model_config="model_net.json", # 强烈建议传入!
    device="gpu"
)


4. 推理传参方式

SDK 提供了非常灵活的调用方式,支持多输入模型的灵活传参。重载的 __call__ 方法允许你以位置、字典或关键字参数的形式输入数据。

假设你的模型有两个输入,名字分别为 "input_1""input_2"

input1_data = np.random.randn(1, 3, 224, 224).astype(np.float32)
input2_data = np.random.randn(1, 3, 224, 224).astype(np.float32)

# 方式一:位置传参 (需确保顺序与模型要求的输入顺序一致)
out = model(input1_data, input2_data)

# 方式二:字典传参(名字需要和模型输入名字一直,可在aimo转换时手动指定)
out = model({"input_1": input1_data, "input_2": input2_data})

# 方式三:关键字传参 (Kwargs)
out = model(input_1=input1_data, input_2=input2_data)

关于多输出:

  • 如果模型只有 1 个输出,返回值直接是 np.ndarray
  • 如果模型有多个输出,返回值是一个包含多个 np.ndarray 的元组 Tuple[np.ndarray, ...]
out = single_output_model(input_data)  # 单输出模型直接返回一个 np.ndarray

out1, out2 = multi_output_model(input_data)  # 多输出模型返回一个元组

5. 开发者必读须知

  1. 静态形状限制 (Static Shapes Only) 无论是 ONNX、TFLite 还是 QNN,当前均不支持动态形状。你喂给模型的数据 shape 必须与模型导出时固化的 shape 完全一致,否则 SDK 会抛出 ValueError
  2. 社区版 vs 企业版 QNN (Local/Remote 模式) AidLux 的 QNN 推理分为 Remote 模式和 Local 模式:
  • 社区版:手机上下载的 AidLux 版本为社区版。受限于系统架构和权限问题,仅支持以 Remote 模式运行 QNN。手动指定非量化模型需选中 aimo 中带有 ndk 关键词的 .so 文件。
  • 企业版:支持 Local 和 Remote 两种模式。推荐使用 Local 模式以获得更低的延迟和更高的性能,手动指定模型时需选中 aimo 中带有 gcc9_4 关键词的 .so 文件。
  • 量化模型:无论 Local 和 Remote 模式,量化模型手动指定模型时都只用选中带有 ctx.bin 关键词的文件。
  • SDK 处理逻辑:通常 SDK 会自动试图确定是否为社区版,开发者通常不需要操心这一点后端实现,只用确保正确选择模型文件即可。
  1. 数据类型安全 在处理 QNN 模型时,底层 API 严格要求输入数据为 32 位浮点数,请确保使用 .astype(np.float32) 进行预处理。对于量化模型,虽然模型内部是量化的,但输入数据仍需为 float32,SDK 会在底层自动进行量化处理。

最终的输出数据类型也是 float32

在使用 aimo 转换模型到 qnn 格式的时候,注意尽量确保模型输入输出的数据类型为 float32,以避免在 SDK 层出现不可预料的结果和潜在的精度损失。