跳到主要内容

MTNN 开发者指南

什么是 MTNN ?

MTNN (Moore Threads Neural Network) 是一组专为 摩尔线程长江 SoC(M1000) 平台设计的端侧 AI 推理工具链与运行时库。它帮助开发者将训练好的深度学习模型高效部署到 M1000 设备上,充分发挥其 NPU(神经网络处理单元)的硬件加速能力,实现低延迟、高能效的设备端机器学习。

工作流程

MTNN 的开发工作流清晰简洁,主要分为 模型转换 和 运行推理 两个阶段:

阶段一:模型转换

ONNX(Open Neural Network Exchange,开放神经网络交换)是一个开放的模型格式标准,被 PyTorch、TensorFlow 等几乎所有主流 AI 框架支持。

将模型先导出为 ONNX 格式,然后使用 MTNN 提供的 mtc_tool 工具将其转换为 M1000 专有的 .mtnn 模型格式。在此过程中,可以应用量化等优化措施。

无论您最初使用哪种框架训练模型,MTNN 的模型转换极大地简化了部署流程,避免了为每个训练框架单独开发转换器。

关于如何将 PyTorch、TensorFlow 框架的模型转为ONNX模型, 请参考各模型的官网。此外,您还可以使用PyTorch转ONNX的通用方法。

阶段二:运行推理

在 M1000 设备上,应用程序通过 MTNN Runtime C API 加载 .mtnn 模型,并执行推理任务, 从而实现部署。

支持的算子

MTNN 通过 ONNX 标准实现广泛的算子兼容性,支持以下常用算子:

类别支持的算子
基础数学AddSubMulDivAbsExpLogPowSqrtSinNegReciprocalSignModSumMean
激活函数ReluLeakyReluPReluSigmoidHardSigmoidHardSwishTanhSoftplusEluSoftsign
归一化BatchNormalizationInstanceNormalizationLRNMeanVarianceNormalization
池化与采样MaxPoolAveragePoolGlobalMaxPoolGlobalAveragePoolResizeUpsample
卷积与矩阵运算Conv2DConv2DTransposeGemmMatMul
张量操作ReshapeFlattenSqueezeUnsqueezeExpandTileTransposeConcatSplitSliceGatherGatherNDScatterNDWhereNonZeroReverseSequenceSizeShape
逻辑比较EqualGreaterLessGreaterOrEqualLessOrEquallogical_andXor
RNNLSTMGRU
规约操作ReduceSumReduceMeanReduceMaxReduceMinReduceL1ReduceL2ReduceLogSumReduceLogSumExpReduceProdReduceSumSquare
其他ClipCastCeluErfPadDropoutDepthToSpaceSpaceToDepthMaxRoiPoolArgMinArgMaxCeilFloor

快速上手

模型转换 (mtc_tool)

mtc_tool 是 MTNN 的核心转换工具,用于将 ONNX 模型转换为 .mtnn 格式。

步骤一:安装与准备

确保已安装 m1000-mtc-toolkit deb 包。

更多安装包, 请参见NPU SDK.

步骤二:编写配置文件 (model.yaml)

创建一个 YAML 配置文件来指定转换参数:

# model.yaml 示例
Name: "mobilenet_v2"
ModelPath: "./mobilenet_v2.onnx"
algorithm: 'normal'
quant_type: 'uint8'
quantizer: 'asymmetric_affine'
hybrid: false
static_quantization: false
force_fp32input_list: "false"
force_fp32output_list: "true"
perf_collect_enable: true
UseSingleCore: 1

步骤三:执行转换

mtc --config ./model.yaml

成功后,将在指定目录生成 mobilenet_v2.mtnn 文件。

步骤四:高级工具 (mtc_wrap)

mtc_wrap 是一个 Python 脚本,可自动化生成多种量化策略(如 int8, int16)的配置文件,批量调用 mtc 进行转换,并汇总结果到 CSV 报告中,极大简化模型选型过程:

# 示例:为 mobilenet_v2 生成多种量化模型
mtc_wrap --model_path=./mobilenet_v2.onnx --output_path=./output

更多关于 int6/int16 的 yaml 文件, 请参考 M1000 NPU Model Zoo

Runtime API

C 应用

以下是使用 MTNN C API 进行推理的完整示例。

1. 引用头文件

#include "mtnn_api.h"

2. 完整示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "mtnn_api.h"

// 错误处理宏
#define ONERROR(status, msg) \
do { \
if ((status) != MTNN_SUCC) { \
printf("Error: %s (code: %d)\n", msg, status); \
goto error_exit; \
} \
} while(0)

// 从文件加载模型
static unsigned char* load_model(const char* filename, size_t* model_size) {
FILE* fp = fopen(filename, "rb");
if (!fp) {
printf("Open file %s failed: %s.\n", filename, strerror(errno));
return NULL;
}
fseek(fp, 0, SEEK_END);
*model_size = ftell(fp);
rewind(fp);
unsigned char* data = (unsigned char*)malloc(*model_size);
if (fread(data, 1, *model_size, fp) != *model_size) {
free(data);
data = NULL;
}
fclose(fp);
return data;
}

int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: %s <mtnn_model_path>\n", argv[0]);
return -1;
}

const char* mtnn_path = argv[1];
unsigned char* model_data = NULL;
size_t model_data_size = 0;
mtnn_mgr network_mgr = NULL;
mtnn_input_output_num io_num = {0};
mtnn_tensor_mem* inputs_mem = NULL;
mtnn_tensor_mem* outputs_mem = NULL;
int status = MTNN_ERR_FAIL;

// 1. 读入模型
model_data = load_model(mtnn_path, &model_data_size);
if (!model_data) {
printf("Failed to load model.\n");
return -1;
}

// 2. 初始化模型上下文
mtnn_work_mode_t work_mode = {0};
work_mode.init_flag = 0; // 可设置 MTNN_FLAG_COLLECT_PERF_MASK 等
work_mode.e_npu_mode = NPU_MODE_SEPARATE;
work_mode.n_npu_device = 0;

status = mtnn_init(&network_mgr, (void*)model_data, model_data_size, &work_mode);
ONERROR(status, "mtnn_init failed.");

// 3. 获取输入/输出数量
status = mtnn_get(network_mgr, MTNN_GET_IN_OUT_NUM, &io_num, sizeof(io_num));
ONERROR(status, "mtnn_get MTNN_GET_IN_OUT_NUM failed.");

inputs_mem = (mtnn_tensor_mem*)calloc(io_num.n_input, sizeof(mtnn_tensor_mem));
outputs_mem = (mtnn_tensor_mem*)calloc(io_num.n_output, sizeof(mtnn_tensor_mem));

// 4. 获取输入 buffer 地址
status = mtnn_inputs_get(network_mgr, io_num.n_input, inputs_mem);
ONERROR(status, "mtnn_inputs_get failed.");

// 5. 填充输入数据 (此处省略具体数据加载逻辑)
// for (int i = 0; i < io_num.n_input; i++) {
// // load_file(input_name[i], inputs_mem[i].logical_addr);
// }

// 6. 设置输入 (使填充的数据生效)
status = mtnn_inputs_set(network_mgr, io_num.n_input, NULL);
ONERROR(status, "mtnn_inputs_set failed.");

// 7. 执行推理
status = mtnn_inference(network_mgr, NULL);
ONERROR(status, "mtnn_inference failed.");

// 8. 获取输出结果
status = mtnn_outputs_get(network_mgr, io_num.n_output, outputs_mem);
ONERROR(status, "mtnn_outputs_get failed.");

printf("Inference completed successfully!\n");

// ... 在此处处理 outputs_mem 中的结果 ...

error_exit:
if (inputs_mem) free(inputs_mem);
if (outputs_mem) free(outputs_mem);
if (network_mgr) mtnn_destroy(network_mgr);
if (model_data) free(model_data);
return (status == MTNN_SUCC) ? 0 : -1;
}

3. 编译与链接

确保链接 libmtnnrt.so 库:

gcc -o mtnn_demo demo.c -lmtnnrt

主要 API 

API功能
mtnn_init初始化上下文并加载 .mtnn 模型。
mtnn_get查询模型信息(如输入/输出数量、属性、性能详情、SDK版本等)。
mtnn_inputs_get获取模型输入张量的内存地址 (logical_addr)。
mtnn_inputs_set提交输入数据,通知运行时准备就绪。
mtnn_inference执行模型推理。
mtnn_outputs_get获取模型输出张量的内存地址。
mtnn_destroy卸载模型并销毁上下文。

关键结构体

  • mtnn_work_mode_t: 初始化时用于配置 NPU 模式(分离/合并)、设备 ID 等。

  • mtnn_tensor_mem: 描述张量的内存信息,包含虚拟地址 (logical_addr)、物理地址、大小等。

  • mtnn_tensor_attr: 描述张量的属性,如维度、数据类型 (float32int8 等)、量化类型等。

初始化标志 (init_flag)

  • MTNN_FLAG_COLLECT_PERF_MASK: 启用性能收集,可通过 mtnn_get 查询详细性能报告。

  • MTNN_FLAG_DUMP_LAYER_DATA_MASK: 启用逐层数据 dump,用于调试。

  • MTNN_FLAG_ASYNC_MASK: 启用异步模式,提高单线程帧率。


高级功能

混合量化

当全量化导致精度损失过大时,可使用混合量化,对网络中敏感的层保留更高精度。

  • 自动混合量化: 在 YAML 配置中设置 rebuild: truecompute_entropy: truehybrid: true。工具会自动分析各层熵值,并生成 entropy.txt 报告。

  • 手动混合量化: 根据 entropy.txt 报告,在 .quantize 配置文件中指定特定层的量化策略(如 dynamic_fixed_point-i16),并在 YAML 中通过 quantize_file 引用该文件。

模型可视化

mtc_tool 生成的中间 IR 文件(.mtnnir)可以使用定制版 Netron 打开,方便开发者可视化模型结构。

模型性能分析

mtc_tool 在转换后会进行软件仿真推理,并生成详细的性能分析报告(Excel 格式),包含每层的带宽、MAC 利用率、理论 FPS 等,用于指导模型和应用优化。

  • 报告路径${MTC_TOOL_INSTALL_DIR}/result/nets_mtc/excel/onnx/perf_result/

性能基准 (MLPerf Inference v4.0)

MTNN 在 M1000 NPU 上的 MLPerf 测试结果如下(精度均 >99% 基准值):

ModelM1000 NPU (Single Core) - Single Stream Latency (ms)M1000 NPU (Single Core) - Offline (Samples/s)
ResNet-50 (Image Classification)2.09486.051
Retinanet (Object Detection)728.8961.37
3D-Unet (Medical Imaging)77480.60.025
RNN-T (Speech-to-text)531.7153.34989
BERT (Natural Language Processing)569.7071.75485

相关文档

M1000 MTStream 开发者文档


版本信息

版本号修改日期修改说明
V1.32025/04/161. 支持 ONNX Static Quantization 模型。
2. 支持 Float32 类型的输入输出。
V1.22025/03/271. 完善混合量化操作的描述。
V1.12025/02/281. 增加 mtc 扩展工具 mtc_wrap 的使用介绍。
V1.02025/01/151. 优化 mtnnrt API 描述格式。
2. 完善 mtc_tool 工具使用描述。
3. 增加 NPU MLPerf 相关描述。
V0.92024/10/111. 增加支持算子列表。
2. 调整 mtnnrt API 描述,并增加示例。
V0.52024/06/09InitVersion

结语

MTNN 作为 M1000 SoC 软件栈的核心 AI 组件,为开发者提供了从云端训练模型到端侧高效部署的完整解决方案。通过其强大的模型转换能力和高度优化的运行时库,MTNN 能够充分释放 M1000 NPU 的潜能,赋能千行百业的智能边缘应用。

我们诚邀开发者社区积极参与反馈与贡献!