AI NPU 模块

支持的芯片:[RTL8735C]

概述

该平台集成了专用神经网络处理单元(Neural Processing Unit,NPU),可将深度神经网络(Deep Neural Network,DNN)计算从主 CPU 卸载出来,以较低功耗实现实时 AI 推理,例如目标检测、人脸检测与人脸识别。

在 600 MHz 工作频率下,NPU 在 INT8 精度下可提供约 1 TOPS 的算力。芯片侧提供 256 KB 片上 SRAM (VIP_SRAM)用于中间张量,并在 DDR 中预留 12 MB 专用区域 用于模型权重与 I/O buffer,详情请参考 NN 内存布局

关于硬件架构、支持的 layer 类型、量化格式以及软件栈,请参考 NPU 硬件参考

集成概述

所有 NN 示例都采用类似的集成方式。应用程序打开一路 V5 视频通道作为 RGB(或 NV12)输入源,将帧数据送入 VIPNN 模块进行 NPU 推理,并通过结果回调函数接收结构化的后处理结果。

[Video V5: RGB NN_WIDTH x NN_HEIGHT @ fps] --> SISO --> [VIPNN module]
                                                              |
                                                       nn_display_cb()

运行 NN 的基本步骤:

  1. SDK Model Zoo 中选择一个预编译模型,或联系 Realtek 申请自定义模型转换,详情请参考 自定义模型转换

  2. .nb 模型文件放到设备文件系统中,详情请参考 部署模型到设备

  3. 在应用程序中配置 VIPNN 模块,详情请参考 VIPNN 模块

  4. 实现结果回调函数,并根据推理输出执行显示或业务逻辑。若需要 OSD 或隐私 mosaic overlay,请参考 Video NN 工具函数

SDK Model Zoo

SDK Model Zoo 中提供以下预编译 .nb 模型文件:

component/soc/<soc>/video/nn/app/nn_model/binary/

使用模型前,需要确保对应 .nb 文件在应用运行前已经存在于设备文件系统中。关于如何烧录或复制模型文件,请参考 部署模型到设备

目标检测

YOLO 系列

YOLO(You Only Look Once)是常用的实时目标检测算法。SDK 提供以下模型:

Model object

Binary filename

Input size

Quantised

yolov4_tiny

yolov4_tiny_asymu8.nb

416 x 416

uint8

yolov7_tiny

yolov7_tiny_576x320_asymu8.nb

576 x 320

uint8

yolov7_tiny

yolov7_tiny_640x480_asymu8.nb

640 x 480

uint8

yolov9_tiny

yolov9_tiny_dfpi16.nb

416 x 416

int16 DFP

在编译期包含对应头文件,并选择模型对象:

#include "model_yolo.h"    // yolov4_tiny, yolov7_tiny
#include "model_yolov9.h"  // yolov9_tiny

#define NN_MODEL_OBJ    yolov7_tiny
#define NN_MODEL_NAME   "vfs:/yolov7_tiny_576x320_asymu8.nb"
#define NN_WIDTH        576
#define NN_HEIGHT       320

每个检测目标的输出保存在 objdetect_res_t 中:

typedef struct objdetect_res_s {
    union {
        float result[6];   // [class_id, score, top_x, top_y, bot_x, bot_y]
        detobj_t res;
    };
} objdetect_res_t;

坐标均相对于逻辑检测输入尺寸归一化到 [0.0, 1.0]。通常该尺寸等于网络张量尺寸。如果 .nb 模型内部包含预处理或缩放 layer,应用可在 nn_data_param_t 中提供 model_width / model_height,使 YOLO 后处理按逻辑检测尺寸解码框坐标。YOLO 模型基于 COCO 数据集(80 类)训练。

更多信息: https://github.com/AlexeyAB/darknet

人脸检测

SCRFD

SCRFD(Sample and Computation Redistribution for Face Detection)是一种轻量级、高精度人脸检测模型,可输出人脸框和 5 点人脸关键点。

Model object

Binary filename

Input size

Quantised

scrfd

scrfd_500m_bnkps_shape576x320.nb

576 x 320

uint8

#include "model_scrfd.h"

#define NN_MODEL_OBJ    scrfd
#define NN_MODEL_NAME   "vfs:/scrfd_500m_bnkps_shape576x320.nb"
#define NN_WIDTH        576
#define NN_HEIGHT       320

检测结果保存在 facedetect_res_t 中:

typedef struct facedetect_res_s {
    union {
        float result[6];    // [class_id, score, top_x, top_y, bot_x, bot_y]
        detobj_t res;
    };
    landmark_t landmark;    // 5 facial landmark points (x, y) normalised to [0.0, 1.0]
} facedetect_res_t;

更多信息: https://github.com/deepinsight/insightface/tree/master/detection/scrfd

人脸识别

MobileFaceNet

MobileFaceNet 是一个轻量级人脸识别模型,使用 ArcFace(Additive Angular Margin Loss)训练。模型输入为裁剪并对齐后的人脸图像,输出 128 维特征向量,用于身份匹配。

MobileFaceNet 通常与 SCRFD 组合成级联的人脸检测加识别流程:SCRFD 先在完整画面中检测并定位人脸,再由 MobileFaceNet 对每个人脸区域提取 embedding,并与已保存的人脸特征数据库进行比对。VIPNN 的相关配置请参考 级联模式

Model object

Binary filename

Input size

Quantised

mbfacenet_fwfs

mobilefacenet_pcqsymi8.nb

112 x 112

int8 sym

#include "model_mobilefacenet.h"

识别结果保存在 face_feature_res_t 中:

#define MAX_FACE_FEATURE_DIM 128
typedef struct face_feature_res_s {
    union {
        float result[6];
        detobj_t res;
    };
    float feature[MAX_FACE_FEATURE_DIM];  // 128-dim face embedding
} face_feature_res_t;

更多信息: https://github.com/deepinsight/insightface/tree/master/recognition

模型内存与文件大小参考

下表列出 SDK 中各模型的内存占用。DDR memory usage 表示 NPU runtime 所需内存(模型权重 + I/O tensor buffer)。所有模型均可放入 12 MB NN_DDR 区域。

类别

模型文件

输入尺寸

量化格式

DDR 内存占用

文件大小

目标检测

yolov4_tiny_asymu8.nb

416 x 416

uint8

6.51 MB

3.59 MB

目标检测

yolov7_tiny_576x320_asymu8.nb

576 x 320

uint8

7.25 MB

3.96 MB

目标检测

yolov7_tiny_640x480_asymu8.nb

640 x 480

uint8

10.13 MB

3.83 MB

目标检测

yolov9_tiny_dfpi16.nb

416 x 416

int16 DFP

10.22 MB

4.73 MB

人脸检测

scrfd_500m_bnkps_shape576x320.nb

576 x 320

uint8

2.28 MB

0.75 MB

人脸识别

mobilefacenet_pcqsymi8.nb

112 x 112

int8 sym

2.06 MB

1.40 MB

备注

同时运行两个模型时(例如 SCRFD + MobileFaceNet 的检测加识别流程),需要确保合计 DDR 占用不超过 12 MB NN_DDR 预算。SCRFD + MobileFaceNet 组合约占用 4.3 MB。


部署模型到设备

VIPNN 模块在运行时通过路径前缀加载模型文件:

  • vfs:/ - 从内部 LittleFS flash 分区(VFS1)读取

  • sd:/ - 从 SD 卡读取

快速验证时,可以将 .nb 文件复制到 SD 卡根目录,并将模型路径设置为 sd:/model.nb,无需额外打包步骤。对于量产或无 SD 卡槽的设备,建议使用下文的 vfs: 路径。

烧录模型到 LittleFS(VFS1)

VFS1 是 Flash 布局中配置的 LittleFS flash 分区(通过 menuconfig CONFIG User Config > Flash Layout Configuration 配置)。目前 SDK 会将 Wi-Fi、BT 与 NN 数据放在同一个 LittleFS 区域,因为 runtime 仅支持一个 LittleFS flash region:

{VFS1, 0x088A3000, 0x08EA2FFF}   /* VFS region 1: wifi/BT/NN data (6 MB) */
{VFS2, 0xFFFFFFFF, 0xFFFFFFFF}

备注

上述地址范围仅供参考。烧录前请在 menuconfig(CONFIG User Config > Flash Layout Configuration)中确认实际的 VFS1 分区地址和大小,因为 flash layout 可能会随固件配置变化。

备注

SDK 已内置一个打包好以下三个示例模型的 LittleFS 映像,可直接烧录用于快速测试:

component/soc/amebapro3/video/nn/app/nn_model/binary/nn_model_lfs/nn_model_lfs.bin

其中包含 yolov4_tiny_asymu8.nb (YOLO 目标检测)、scrfd_500m_bnkps_shape576x320.nb (SCRFD 人脸检测)与 mobilefacenet_pcqsymi8.nb (MobileFaceNet 人脸识别)。若只需直接烧录测试,可跳到 步骤 3 - 烧录映像;若需要自行打包模型,请继续阅读下文。

步骤 1 - 准备模型目录

tools/image_scripts 下创建本地目录,并将要打包的模型文件复制进去:

cd tools/image_scripts
mkdir -p nn_dir
cp ../../component/soc/<soc>/video/nn/app/nn_model/binary/mobilefacenet_pcqsymi8.nb nn_dir/
cp ../../component/soc/<soc>/video/nn/app/nn_model/binary/scrfd_500m_bnkps_shape576x320.nb nn_dir/
cp ../../component/soc/<soc>/video/nn/app/nn_model/binary/yolov4_tiny_asymu8.nb nn_dir/

以上命令会把三个常用示例模型打包到同一个 LittleFS 映像中:

  • mobilefacenet_pcqsymi8.nb:MobileFaceNet 人脸 embedding 模型

  • scrfd_500m_bnkps_shape576x320.nb:SCRFD 人脸检测模型

  • yolov4_tiny_asymu8.nb:YOLO 目标检测模型

步骤 2 - 生成 LittleFS 映像

LittleFS 映像现在改由 vfs.py 脚本生成,请在 tools/image_scripts 目录下执行:

python vfs.py -t LITTLEFS -dir nn_dir/ -out nn_model_lfs.bin -s 4096 -c 1536

参数

说明

-t LITTLEFS

要生成的文件系统类型

-dir nn_dir/

要打包的输入目录

-out nn_model_lfs.bin

输出的 LittleFS 映像文件

-s 4096

block size,单位为 byte,需匹配 SDK 挂载 VFS1 时使用的 block size,请保持 4096 不变

-c 1536

block count。与 -s 共同决定映像大小(block size x block count):4096 x 1536 = 6 MB,正好对应默认的 VFS1 分区大小。若 VFS1 分区大小不同,可调整 -c 来改变映像大小,例如 -c 512 对应 2 MB 映像

映像生成后,可将其解包出来确认模型文件已被正确打包:

python vfs.py -t LITTLEFS -dir nn_model_lfs.bin -s 4096 -u nn_dir_check
ls nn_dir_check

备注

由于 -s (block size)需固定匹配 flash 硬件,实际能决定映像大小的是 -c (block count):先依据期望的映像大小选定 -c,再确认要打包的文件能放入该大小。vfs.py 会先估算打包所需的最小 block count:将所有文件的总大小加上 LittleFS 的 metadata 开销后,再乘上一个动态安全系数(LittleFS 大约在 1.03 ~ 1.5 之间,平均文件越小系数越高)。如果 -c 小于这个估算值,vfs.py 会打印警告并自动把 block count 调大,此时最终生成的映像会大于 -s x -c 计算出的大小。为了让映像大小符合预期,请确保放入目录的文件总大小在乘上该安全系数后,仍在 -s x -c 的预算范围内。各预编译模型文件大小请参考 模型内存与文件大小参考,安全系数的具体计算方式可参考 tools/image_scripts/vfs.py

步骤 3 - 烧录映像

使用 image download tool 将 nn_model_lfs.bin 烧录到 VFS1 起始地址(0x088A3000)。烧录成功后,应用即可通过 vfs: 前缀访问模型文件:

#define FACEDET_MODEL_NAME   "vfs:/scrfd_500m_bnkps_shape576x320.nb"
#define FACENET_MODEL_NAME   "vfs:/mobilefacenet_pcqsymi8.nb"
#define OBJDET_MODEL_NAME    "vfs:/yolov4_tiny_asymu8.nb"

备注

打包出的映像大小(-s x -c)不能超过 VFS1 分区大小(默认 6 MB)。上述三个模型的文件总大小约为 5.74 MB,可以放入默认的 6 MB / -c 1536 映像中。各预编译模型文件大小请参考 模型内存与文件大小参考


VIPNN 模块

NN MMF 模块 vipnn 可接收视频管线中的 RGB 或 NV12 帧,在 NPU 上执行推理,并通过回调函数将结构化的后处理结果传给应用。

每个模型对象(nnmodel_t)中已经绑定对应的预处理与后处理逻辑。因此添加新模型时,通常只需要提供新的 model object,VIPNN 模块本身无需修改。

VIPNN 模块上下文

VIPNN 模块内部上下文如下:

typedef struct vipnn_ctx_s {
    void *parent;
    vip_network network;                              // NPU network handle
    vip_buffer_create_params_t vip_param_in[MAX_IO_NUM];
    vip_buffer_create_params_t vip_param_out[MAX_IO_NUM];
    vip_buffer input_buffers[MAX_IO_NUM];
    vip_buffer output_buffers[MAX_IO_NUM];
    vipnn_params_t params;                            // module parameters
    vipnn_status_t status;
    char network_name[64];
    int input_count;
    int output_count;
    vipnn_preproc_t  pre_process;                    // custom pre-process hook
    vipnn_postproc_t post_process;                   // custom post-process hook
    disp_postprcess_t disp_postproc;                 // result display callback
    vipnn_cascaded_mode_t cas_mode;
    bool module_out_en;
    vipnn_measure_t measure;                         // inference FPS measurement
} vipnn_ctx_t;

模块参数

vipnn_params_t 结构体保存模块运行时参数:

typedef struct vipnn_param_s {
    char     model_file[64];    // model file path on file system (e.g. "vfs:/model.nb")
    uint8_t *model_mem;         // pointer to model in memory (alternative to file path)
    uint32_t model_size;        // model size in bytes (when using model_mem)
    int      fps;               // target inference FPS (0 = unlimited)
    int      out_res_size;      // sizeof one result structure
    int      out_res_max_cnt;   // maximum number of results per frame
    int      save_out_tensor;   // set to 1 to dump raw output tensors for offline debugging
    nn_data_param_t *in_param;  // input image parameters
    nnmodel_t       *model;     // pointer to the model object
} vipnn_params_t;

nn_data_param_t 中的图像参数用于描述 VIPNN 消费的视频帧:

typedef struct nn_data_param_s {
    union {
        struct {
            int width, height;
            int model_width, model_height;  // optional logical detector size
            landmarki_t landmark;
        } img;
        /* audio fields omitted */
    };
    uint32_t codec_type;
    void *priv;
    int size_in_byte;
} nn_data_param_t;

备注

save_out_tensor 设置为 1 后,模块会将 NPU 原始输出 tensor dump 到文件中,便于在 PC 上开发或验证自定义后处理逻辑。量产版本建议关闭该选项。

model_mem 非 NULL 时,模块会从该内存指针加载模型,而不是从文件系统加载。这适用于将模型二进制直接嵌入固件的场景。

完整模块初始化

static nn_data_param_t nn_input_params = {
    .img = {
        .width  = NN_WIDTH,
        .height = NN_HEIGHT,
    },
    .codec_type = AV_CODEC_ID_RGB888
};

vipnn_ctx = mm_module_open(&vipnn_module);
if (vipnn_ctx) {
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_MODEL,           (int)&NN_MODEL_OBJ);
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_MODEL_FILE_NAME, (int)nn_model_file_name);
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_IN_PARAMS,       (int)&nn_input_params);
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_DISPPOST,        (int)nn_display_cb);
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_RES_SIZE,        sizeof(objdetect_res_t));
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_RES_MAX_CNT,     32);
    mm_module_ctrl(vipnn_ctx, CMD_VIPNN_APPLY,               0);
}

设置输入图像参数

使用 CMD_VIPNN_SET_IN_PARAMS 描述传给 VIPNN 的输入帧:

nn_data_param_t nn_input_params = {
    .img = {
        .width      = NN_WIDTH,   // incoming RGB/NV12 frame width
        .height     = NN_HEIGHT,  // incoming RGB/NV12 frame height
    },
    .codec_type = AV_CODEC_ID_RGB888   // or AV_CODEC_ID_NV12
};
mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_IN_PARAMS, (int)&nn_input_params);

如果模型内部包含预处理或缩放 layer,V5 RGB 输入帧尺寸可以与逻辑检测输入尺寸不同。此时 width / height 应保持为真实输入帧尺寸,并通过 model_width / model_height 指定后处理使用的检测尺寸:

#define V5_RGB_WIDTH   1280
#define V5_RGB_HEIGHT  720
#define NN_WIDTH       416
#define NN_HEIGHT      416

nn_data_param_t nn_input_params = {
    .img = {
        .width = V5_RGB_WIDTH,
        .height = V5_RGB_HEIGHT,
        .model_width = NN_WIDTH,
        .model_height = NN_HEIGHT,
    },
    .codec_type = AV_CODEC_ID_RGB888
};

备注

codec_type 必须与上游 V5 video module 的输出格式一致。需要 RGB 输入的模型应使用 VIDEO_RGB + AV_CODEC_ID_RGB888widthheight 表示完整输入帧;ROI 不再通过 nn_data_param_t 配置。如果输入帧尺寸与网络张量尺寸不同且模型本身没有预处理 layer,则模型预处理代码会在推理前对完整帧进行 resize。

设置 NN 模型

每个支持的模型都由一个 nnmodel_t 对象表示,其中绑定了模型二进制、预处理函数和后处理函数。

#include "model_yolo.h"
#define NN_MODEL_OBJ    yolov4_tiny
#define NN_MODEL_NAME   "vfs:/yolov4_tiny_asymu8.nb"

mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_MODEL,           (int)&NN_MODEL_OBJ);
mm_module_ctrl(vipnn_ctx, CMD_VIPNN_SET_MODEL_FILE_NAME, (int)NN_MODEL_NAME);

设置结果回调

使用 CMD_VIPNN_SET_DISPPOST 注册回调,以便在每帧推理完成后接收结果。该回调在 VIPNN task 上下文中执行,应尽量保持简短且避免阻塞。

static void nn_display_cb(void *p, void *img_param)
{
    vipnn_out_buf_t *out = (vipnn_out_buf_t *)p;
    objdetect_res_t *res = (objdetect_res_t *)&out->res[0];
    int obj_num = out->res_cnt;

    for (int i = 0; i < obj_num; i++) {
        RTK_LOGI(TAG, "class=%d score=%.2f [%.2f %.2f %.2f %.2f]\r\n",
                 (int)res[i].result[0], res[i].result[1],
                 res[i].result[2], res[i].result[3],
                 res[i].result[4], res[i].result[5]);
    }
}

设置检测阈值

目标检测和人脸检测模型通常通过两个后处理阈值过滤结果:

  • CMD_VIPNN_SET_CONFIDENCE_THRES:置信度阈值

  • CMD_VIPNN_SET_NMS_THRES:NMS 阈值

过滤 Class ID

如需只保留特定类别,可在后处理或显示回调中根据 class_id 过滤输出结果。目标检测模型的类别 ID 与训练数据集保持一致,例如 YOLO COCO 模型使用 COCO 80 类 ID。

Video NN 工具函数

SDK 提供共享的 video_nn_utils component,用于将 NN 结果转换成 video overlay。它是 SDK source tree 中的共用代码,不是某个 example 私有的代码:

component/soc/amebapro3/sw/video_sw/video_nn_utils/
  nn_coord_map/
  nn_osd/
  nn_mosaic/

AP media example 的 CMake include path 已包含该目录。基于 ap_media_example 开发的 user application 可直接 include 这些 helper header:

#include "nn_coord_map/nn_coord_map.h"
#include "nn_osd/nn_osd.h"
#include "nn_mosaic/nn_mosaic.h"

使用这些 API 的示例位于:

component/soc/amebapro3/sw/media_example/ap_media_example/video_example_src/

开发时可把这些文件当作集成参考:它们展示了 stream setup、VIPNN module 配置、callback 注册、model selection macro,以及如何在 nn_display_cb() 或类似 draw callback 中调用这些 helper API。

坐标映射

nn_coord_map 会将归一化 NN 输出坐标映射回 stream pixel 坐标。当用户看到的 stream 与 NN 输入不是完全相同的 resolution / aspect ratio 时,都应该使用它。若 NN 输入是按 stream aspect ratio 拉伸后的画面,使用 NN_COORD_MAP_SCALE_STRETCH;若推理前保留原始 aspect ratio 并带有 padding,则使用 NN_COORD_MAP_SCALE_LETTERBOX

nn_coord_map_t map;
nn_coord_map_init(&map, stream_w, stream_h, img_param,
                  NN_COORD_MAP_SCALE_LETTERBOX);
nn_coord_map_bbox(&map, rx0, ry0, rx1, ry1,
                  &xmin, &ymin, &xmax, &ymax);

OSD 绘制

nn_osd_group 为每个颜色 layer 管理一个 1bpp bitmap canvas,分配 hardware OSD index,绘制矩形、点与 ASCII label,并将更新后的 overlay region flush 到 encoder。目标检测、人脸检测、人脸识别与 joint-test 示例都会使用该 helper。

在应用代码中,通常为每个输出 stream / layer set 定义一个 static nn_osd_group_t,并在 NN 结果 callback 中执行 lock、clear、绘制当前所有结果、flush、unlock。如果物体消失后 NN callback 可能停止触发,请启用 watchdog 版本,避免旧框残留在画面上。

隐私 mosaic

nn_mosaic_group 用于管理 NN detection 对应的 encoder mosaic region。它会预先分配 hardware overlay index,对 pixel-space box 进行裁剪并对齐 codec / mosaic block 边界,为有效 region 调用 video_set_mosaic(),并在当前 callback 的对象数量少于上一帧时关闭过期 region。

static nn_mosaic_group_t mosaic_group;
nn_mosaic_config_t cfg = {
    .stream_id = V1_STREAM_ID,
    .stream_width = 1920,
    .stream_height = 1080,
    .max_regions = 11,
    .mosaic_size = NN_MOSAIC_SIZE_16x16,
    .codec_align = 16,
};
nn_mosaic_group_init(&mosaic_group, &cfg);

nn_mosaic_group_set_bbox(&mosaic_group, slot, xmin, ymin, xmax, ymax);
nn_mosaic_group_commit(&mosaic_group, active_count);

Mosaic block size 宏使用明确尺寸命名:NN_MOSAIC_SIZE_8x8NN_MOSAIC_SIZE_16x16NN_MOSAIC_SIZE_32x32NN_MOSAIC_SIZE_64x64NN_MOSAIC_SIZE_128x128

备注

OSD 与 mosaic 在每个 encoder channel 上共用 12 个 hardware overlay index。如果应用同时使用两者,应先初始化 OSD group,或自行保留 index,避免两个功能使用同一个 hardware slot。非 NN 场景可直接使用较底层的 video API:video_alloc_overlay_index()video_free_overlay_index()video_set_mosaic()video_disable_mosaic()

级联模式

级联模式将两个 VIPNN 模块实例串联起来。第一阶段模型(例如 SCRFD 人脸检测)的输出可直接作为第二阶段模型(例如 MobileFaceNet 人脸识别)的输入,从而形成检测后识别的流程,无需在两个阶段之间编写额外 glue code。

SDK 人脸识别示例会使用以下 VIPNN 控制项:

  • CMD_VIPNN_SET_OUTPUT:使能模块输出

  • MM_CMD_SET_DATAGROUP:设置 data group 的起点或终点

  • CMD_VIPNN_SET_CASCADE_MODE:设置级联模式,例如 VIPNN_CMODE_ALL_ROI

facerecog 模块

facerecog_module 用于保存、加载并比对人脸特征。模块会将 MobileFaceNet 输出的 128 维 embedding 与已注册的人脸数据库进行相似度比较,并通过 OSD 回调显示识别结果。

模块命令参考

常用控制命令如下:

命令

说明

CMD_VIPNN_SET_MODEL

设置 nnmodel_t 模型对象

CMD_VIPNN_SET_MODEL_FILE_NAME

设置 .nb 模型文件路径

CMD_VIPNN_SET_IN_PARAMS

设置输入图像参数

CMD_VIPNN_SET_DISPPOST

设置推理结果显示或处理回调

CMD_VIPNN_SET_RES_SIZE

设置单个结果结构体大小

CMD_VIPNN_SET_RES_MAX_CNT

设置每帧最多输出结果数量

CMD_VIPNN_APPLY

应用配置并初始化 NPU network

关于 NN 媒体示例的使用方式,请参考 媒体示例

NN 内存布局

NPU 在 DDR 中使用专用区域保存模型权重、输入/输出 tensor 以及中间计算 buffer。NN DDR 窗口在 linker script ameba_layout.ld 中定义:

NN_DDR (rwx) : ORIGIN = 0x87400000, LENGTH = 12M

Address range: 0x87400000 - 0x87FFFFFF  (12 MB)

完整 DDR 内存映射如下:

Region

Base

Size

Usage

AP_DDR

0x80420000

~28 MB

Application code, heap, stack

EN_DDR

0x82000000

32 MB

Encoder (H.264/HEVC) working memory

VP_DDR

0x84000000

48 MB

Video processor (ISP) working memory

TG_DDR

0x87000000

4 MB

Tile scaler / graphics engine

NN_DDR

0x87400000

12 MB

NPU model + tensor buffers


NPU 硬件参考

计算性能

Data type

MACs / cycle

Notes

INT8

768 MACs -> ~1 TOPS

默认格式,吞吐最高

INT16 (DFP)

192 MACs

适用于更高数值精度需求

FP16 / BF16

384 MACs

浮点格式,可用于 PPU 侧执行的 layer

NPU 架构

NPU 包含三个与软件开发相关的计算子系统:

Neural Network Engine (NNE)

并行 MAC 阵列,包含多个卷积核心,负责 convolution、depthwise convolution 和 GEMM(fully-connected)等运算,是标准 DNN layer 的主要加速单元。支持 INT8、INT16、FP16 和 BF16。

Parallel Processing Unit (PPU)

SIMD 可编程执行单元,主要用于:

  • 前处理与后处理 kernel(OpenCL / OpenVX)

  • NNE 不原生支持的自定义 NN layer

  • activation、normalisation、reshape 等轻量级算子

  • IEEE 32-bit floating-point pipeline

Vision Engine (EVIS)

硬件加速图像处理单元,支持 3x3 filtering、bilinear interpolation(Lerp)、histogram、packed image load/store 以及 dot product 等操作。runtime driver 会使用该单元进行输入格式转换。

NPU 通过 AXI bus 与 SoC 通信,并支持 32-bit 物理地址的虚拟内存机制。

支持的量化格式

格式

说明

使用场景

asymu8

非对称 unsigned INT8

吞吐最高,大多数模型的默认格式

dfpi16

对称 INT16(Dynamic Fixed Point)

需要更高精度时使用

fp16

IEEE 16-bit floating point

混合精度或 PPU 执行的 layer

bfp16

Brain floating-point 16-bit tensor format

由 SDK 工具解析的浮点输出

支持的输入图像格式

NPU 可原生处理以下图像格式,无需额外转换成本:

格式

说明

VX_DF_IMAGE_RGB

24-bit RGB888,3-channel interleaved(BT.709)

VX_DF_IMAGE_NV12

YUV 4:2:0 semi-planar,ISP 原生输出格式

VX_DF_IMAGE_RGBX

32-bit RGBX(R, G, B + don't-care byte)

VX_DF_IMAGE_U8

Unsigned 8-bit single-channel

VX_DF_IMAGE_S16

Signed 16-bit single-channel

在此视频管线中,V5 ISP 通道输出 RGB888 帧,可直接送入 VIPNN 模块,无需额外转换。

支持的 NN layer 类型

NNE 可加速所有标准 DNN layer。不支持或自定义的 layer 会回退到 PPU 执行。

类别

操作

卷积 (Convolution)

CONV3D, CONV2D, CONV1D, DECONVOLUTION, DECONVOLUTION1D, GROUPED_CONV2D, FCL2

激活 (Activation)

RELU, LEAKY_RELU, PRELU, SIGMOID, TANH, SOFTMAX, LOG_SOFTMAX, SWISH, MISH, ELU, HARD_SIGMOID, CLIP, EXP, LOG, SQRT, RSQRT, ABS, NEG, LINEAR, SIN, ERF

逐元素运算 (Elementwise)

ADD, SUBTRACT, MULTIPLY, DIVIDE, MAXIMUM, MINIMUM, POW, FLOORDIV, MATRIXMUL, RELATIONAL_OPS, LOGICAL_OPS, SELECT, ADDN

归一化 (Normalisation)

BATCH_NORM, LAYER_NORM, INSTANCE_NORM, GROUP_NORM, L2_NORMALIZE, MOMENTS

形状 / 张量操作 (Reshape / Tensor)

CONCAT, SLICE, SPLIT, RESHAPE, SQUEEZE, PERMUTE, PAD, REVERSE, SPACE2DEPTH, DEPTH2SPACE, BATCH2SPACE, STRIDED_SLICE, REDUCE, ARGMAX, ARGMIN, SHUFFLECHANNEL, RESIZE, EXPAND_BROADCAST

循环网络 (Recurrent / RNN)

LSTMUNIT, GRUCELL, GRU, SVDF

池化 (Pooling)

MAX_POOL, AVG_POOL, ROI_POOL, POOLWITHARGMAX, UPSAMPLE

其他 (Miscellaneous)

PROPOSAL, VARIABLE, DROPOUT, STACK, UNSTACK, REORG, GATHER, SCATTER_ND, ONE_HOT, CAST

软件栈

NPU runtime 向应用软件提供以下 API:

  • OpenVX 1.3 + OpenVX 1.2 Neural Network Extension :主要 NN 推理 API

  • OpenCL 3.0 / 1.2 Full Profile :用于 PPU 上的自定义计算 kernel

  • Proprietary Extensions for CNN :用于 NN 加速与自定义 layer 的 vendor extension

  • VIP Lite APIvip_lite.h):底层 NPU 控制接口,vipnn_module 内部会使用该接口

使用常见 AI 框架(Keras、TensorFlow、TFLite、PyTorch、Caffe、ONNX、Darknet)训练的神经网络模型,需要离线通过 Acuity Toolkit 转换为编译后的网络二进制文件(.nb),然后在运行时从 LittleFS flash 分区(vfs:)或 SD 卡(sd:)加载。


自定义模型转换

如果需要将自训练模型转换为 NPU 可运行的 .nb 格式,请联系 Realtek 业务或技术支持窗口获取进一步协助。