Skip to content

NPU Model Format Description*

  • In the NPU Compiler Usage chapter, we learned that model files running on GX830X are generated using gxnpuc config.yaml.
  • This document provides a brief explanation of the model file structure.
    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    // This file is automatically generated by NPU compiler.
    // Total size of model input/output plus runtime space: sizeof(in_out) + sizeof(cmd_content) + sizeof(weight_content) + sizeof(data_content) + sizeof(cache_content)
    const unsigned int total_size = 570774;
    
    // Runtime space occupied by the model: sizeof(cmd_content) + sizeof(weight_content) + sizeof(data_content) + sizeof(cache_content)
    const unsigned int npu_size = 561864;
    
    // gxnpuc compiler version
    const char *version = "1.6.0rc2";
    
    // MD5 value of the corresponding pb file for the model
    const char *pb_md5 = "96bc67e9594bd5d73eb95c10f00782bb";
    
    // Model compilation time
    const char *model_info = "(20240327095040)";
    
    // Quantization Q values for model input and output
    #define FEATS_Q 12
    #define STATE_C0_Q 10
    #define STATE_C1_Q 10
    #define STATE_C2_Q 11
    #define STATE_C3_Q 10
    #define STATE_C0_OUT_Q 10
    #define STATE_C1_OUT_Q 10
    #define STATE_C2_OUT_Q 11
    #define STATE_C3_OUT_Q 10
    #define MODEL_RNN_OUT_Q 10
    
    typedef short npu_data_t;
    
    // Model input structure
    struct input {
        npu_data_t Feats[1][25][40];
        npu_data_t State_c0[1][4][96];
        npu_data_t State_c1[1][4][96];
        npu_data_t State_c2[1][4][96];
        npu_data_t State_c3[1][5][96];
    } __attribute__ ((packed));
    
    // Model output structure
    struct output {
        npu_data_t State_c0_out[1][4][96];
        npu_data_t State_c1_out[1][4][96];
        npu_data_t State_c2_out[1][4][96];
        npu_data_t State_c3_out[1][5][96];
        npu_data_t Model_rnn_out[1][1][191];
    } __attribute__ ((packed));
    
    // Combined model input+output structure. For recurrent networks, the design recommends allocating two or more buffers based on this structure. One buffer serves as the model input address, and the State_c0 of the next buffer serves as the model output address. This saves the copy operation of copying the model output to the input of the next time step.
    struct in_out {
        npu_data_t Feats[1][25][40];
        npu_data_t State_c0[1][4][96];
        npu_data_t State_c1[1][4][96];
        npu_data_t State_c2[1][4][96];
        npu_data_t State_c3[1][5][96];
        npu_data_t Model_rnn_out[1][1][191];
    } __attribute__ ((packed));
    
    // Model instruction array, read-only
    const unsigned char cmd_content[2084] __attribute__ ((aligned(4))) = {
        0x47, 0x00, 0x00, 0x00, 0xf2, 0x0a, 0x00, 0xc0, 0x00, 0x02,
        0x02, 0x00, 0x28, 0x00, 0x19, 0x00, 0x01, 0x00, 0x00, 0x00,
        0x05, 0x00, 0x05, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00,
        ......
        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
        0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00,
        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x0e, 0x00, 0x10,
        0x00, 0x09, 0x00, 0x40,
    };
    
    // Model weight array, read-only
    const unsigned char weight_content[128166] __attribute__ ((aligned(4))) = {
        0x00, 0x02, 0x00, 0xfe, 0x00, 0x50, 0x00, 0x02, 0x20, 0x00,
        0xe0, 0xff, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
        0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x54, 0x00, 0x01,
        ......
        0x06, 0x06, 0xda, 0xe3, 0x32, 0xf3, 0x27, 0xe8, 0x74, 0xe8,
        0xc9, 0x2d, 0x58, 0xeb, 0x27, 0x28, 0x3d, 0xfe, 0xb1, 0x13,
        0x5f, 0x01, 0x56, 0xfd, 0x7d, 0x15, 0x73, 0x0d, 0x5c, 0x05,
        0xff, 0x08, 0xa0, 0x3f,
    };
    
    // Temporary space required during model runtime
    unsigned char data_content[13680] __attribute__ ((aligned(4)));
    
    // Memory size allocated in SRAM for storing weights and data during model runtime
    unsigned char cache_content[0] __attribute__ ((aligned(4)));