迁移公告
本文档中心已迁移至
新域名(https://document.nationalchip.com/)
,当前文档中心维护有效期至 2025年6月30日。
请更新您的书签或外部链接,感谢您的支持!
NPU 模型格式说明*
- 在 NPU编译器使用 这章节中,我们知道跑在 GX8002 上的模型文件是用
gxnpuc config.yaml
生成。 - 本文对模型文件的结构做一个简单的说明
model.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
// This file is automatically generated by NPU compiler. // 模式的输入输出大小+模型运行所占用的空间:sizeof(in_out) + sizeof(cmd_content) + sizeof(weight_content) + sizeof(data_content) + sizeof(tmp_content) const unsigned int total_size = 151550; // 模型运行所占用的空间:sizeof(cmd_content) + sizeof(weight_content) + sizeof(data_content) + sizeof(tmp_content) const unsigned int npu_size = 147018; // gxnpuc 编译器版本 const char *version = "1.5.3rc7"; // 模型对应的 pb 文件的 md5 值 const char *pb_md5 = "bfe0140daa3d0440c768eda50ed40265"; const char *npu_unit = "NPU32"; // 模型编译的时间 const char *model_info = "(20220212154001)"; typedef unsigned short npu_data_t; // 模型的输入结构 struct input { npu_data_t Feats[1][15][40]; npu_data_t State_c0[1][3][64]; npu_data_t State_c1[1][4][64]; npu_data_t State_c2[1][5][64]; } __attribute__ ((packed)); // 模型的输出结构 struct output { npu_data_t State_c0_out[1][3][64]; npu_data_t State_c1_out[1][4][64]; npu_data_t State_c2_out[1][5][64]; float phone_prob[1][1][65]; } __attribute__ ((packed)); // 模型的输入+输出结构,对于循环网络来说,方案上依据该结构图设立两个以上的buffer,其中一个buffer作为模型的输入地址, 下一个buffer的 State_c0 作为模型的输出地址,这样可以节省一次模型输出拷贝到下一时刻输入的这个拷贝动作。 struct in_out { npu_data_t Feats[1][15][40]; npu_data_t State_c0[1][3][64]; npu_data_t State_c1[1][4][64]; npu_data_t State_c2[1][5][64]; float phone_prob[1][1][65]; } __attribute__ ((packed)); // 模型的指令数组,只读 const unsigned char cmd_content[5172] __attribute__ ((aligned(4))) = { 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x02, 0x00, 0x00, 0x28, 0x0f, 0x10, 0x00, 0x28, 0x00, ...... 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x40, 0x05, 0x10, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; // 模型的权重数组,只读 const unsigned char weight_content[128166] __attribute__ ((aligned(4))) = { 0x66, 0x3a, 0x6b, 0x40, 0x00, 0x44, 0x7f, 0x45, 0x41, 0x46, 0x49, 0x46, 0x6b, 0x46, 0xc9, 0x46, 0x3d, 0x47, 0xfc, 0x46, 0xa6, 0x46, 0xc1, 0x46, 0x9d, 0x46, 0x85, 0x46, 0xbe, 0x46, ...... 0x10, 0x54, 0x00, 0x3c, 0x00, 0x3c, 0x10, 0x54, 0x00, 0x3c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x45, 0x80, 0x4a, 0x00, 0xbc, 0x00, 0x45, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x3c, }; // 一般为空,只读 unsigned char *tmp_content = (void*)0; // 一般为空 const unsigned char ops_content[0] __attribute__ ((aligned(4))) = { }; // 模型运行时所需要临时空间 unsigned char data_content[13680] __attribute__ ((aligned(4)));