BMNETC 使用

编译Caffe模型

BMNETC是针对caffe的模型编译器,可将某网络的caffemodel和prototxt编译 成BMRuntime所需要的文件。而且在编译的同时,支持每一层的NPU模型计算结 果都会和CPU的计算结果进行对比,保证正确性。下面介绍该编译器的使用方式。

  1. 安装需求

    • python 3.x

    • linux

  2. 配置步骤

    参见bmnnsdk初始化步骤(https://sophgo-doc.gitbook.io/bmnnsdk2-bm1684/)

  3. 使用方法

    1. 方式一:命令形式

    Command name: bmnetc - BMNet compiler command for Caffe model

    /path/to/bmnetc [--model=<path>] \
                    [--weight=<path>] \
                    [--shapes=<string>] \
                    [--net_name=<name>] \
                    [--opt=<value>] \
                    [--dyn=<bool>] \
                    [--outdir=<path>] \
                    [--target=<name>] \
                    [--cmp=<bool>] \
                    [--mode=<string>] \
                    [--enable_profile=<bool>] \
                    [--show_args] \
                    [--list_ops]
    

    参数介绍如下:

    其中mode为compile表示编译float模型。 为GenUmodel表示生成SOPHGO定义的统一model,可后续通过SOPHGO定点化工具进行INT8定点化生成INT8 model。 为check表示检查网络graph算子是否支持。

    GenUmodel模式下,参数opt、dyn、target、cmp将没有意义,无需指定。

    参数dyn=false表示使用静态编译,dyn=true表示使用动态编译。静态编译意思是model编译后,在runtime时只能运行编译所设置的shapes。 动态编译意思是model编译后,runtime时可以运行任意shapes,只要实际shapes中的数值小于等于编译所设置shapes中的数值。 一般来说,动态编译后神经网络在芯片上的性能要小于等于静态编译。所以一般建议动态编译用于实际网络的shapes会大范围变化的情况, 如果shapes固定或者只需要几种shapes,建议采用静态编译。关于静态编译下如何支持若干种shapes,请见bmodel说明。

    表 1 bmnetc参数说明

    args

    type

    Description

    model

    string

    Necessary. Caffe prototxt path

    weight

    string

    Necessary. Caffemodel(weight) path

    shapes

    string

    Optional. Shapes of all inputs, default use the shape in prototxt, format [x,x,x,x],[x,x]…, these correspond to inputs one by one in sequence

    net_name

    string

    Optional. Name of the network, default use the name in prototxt

    opt

    int

    Optional. Optimization level. Option: 0, 1, 2, default 2.

    dyn

    bool

    Optional. Use dynamic compilation, default false.

    outdir

    string

    Necessary. Output directory

    target

    string

    Necessary. Option: BM1682, BM1684; default: BM1682

    cmp

    bool

    Optional.Check result during compilation. Default: true

    mode

    string

    Optional. Set bmnetc mode. Option: compile, GenUmodel, check. Default: compile.

    enable_profile

    bool

    Optional. Enable profile log. Default: false

    show_args

    Optional. Display arguments passed to bmnetc compiler.

    list_ops

    Optional. List bmnetc supported ops.

    examples:

    以下是编译float32的caffe model命令示例

    /path/to/bmnetc --model=/path/to/prototxt --weight=/path/to/caffemodel --shapes=[1,3,224,224] --net_name=resnet18 --outdir=./resnet18 target=BM1684
    

    以下是生成Umodel的示例

    /path/to/bmnetc --mode=GenUmodel --model=/path/to/prototxt --weight=/path/to/caffemodel --shapes=[1,3,224,224] --net_name=resnet18 --outdir=./resnet18
    
    1. 方式二:python接口

    bmnetc的python接口如下, 需要 pip3 install --user bmnetc-x.x.x-py2.py3-none-any.whl

    以下是编译float32的caffe model的python接口。

    import bmnetc
    ## compile fp32 model
    bmnetc.compile(
      model = "/path/to/prototxt",    ## Necessary
      weight = "/path/to/caffemodel", ## Necessary
      target = "BM1684",              ## Necessary
      outdir = "xxx",                 ## optional, default 'compilation'
      shapes = [[x,x,x,x], [x,x,x]],  ## optional, if not set, default use shape in prototxt
      net_name = "name",              ## optional, if not set, default use the network name in prototxt
      opt = 2,                        ## optional, if not set, default equal to 2
      dyn = False,                    ## optional, if not set, default equal to False
      cmp = True,                     ## optional, if not set, default equal to True
      enable_profile = False          ## optional, if not set, default equal to False
    )
    

    以下是生成Umodel的python接口。

    import bmnetc
    ## Generate SOPHGO U model
    bmnetc.GenUmodel(
      model = "/path/to/prototxt",    ## Necessary
      weight = "/path/to/caffemodel", ## Necessary
      outdir = "xxx",                 ## optional, default 'compilation'
      shapes = [[x,x,x,x], [x,x,x]],  ## optional, if not set, default use shape in prototxt
      net_name = "name"               ## optional, if not set, default use the network name in prototxt
    )
    

    以下是使用bmnetc python的例子:

    import bmnetc
    
    model = r'../../../nnmodel/caffe_models/lenet/lenet_train_test_thin_4.prototxt'
    weight = r'../../../nnmodel/caffe_models/lenet/lenet_thin_iter_1000.caffemodel'
    target = r"BM1684"
    export_dir = r"./compilation"
    shapes = [[1,1,28,28],[1]]
    
    bmnetc.compile(model = model, weight = weight, target = target, outdir = export_dir, shapes = shapes)
    bmnetc.GenUmodel(weight = weight, model = model, net_name = "lenet")
    

    以下是list_ops的python接口。

    import bmnetc
    ## List all supported ops
    bmnetc.list_ops()
    

    以下是check_graph的python接口。

    import bmnetc
    ## Check supported ops in model
    bmnetc.check_graph(MODEL_FILE)
    
    1. bmnetc输出和log

    bmnetc若成功,输出的log最后会看到以下信息。

    ######################################
    # Store bmodel of BMCompiler.
    ######################################
    

    bmnetc成功后,将在指定的文件夹中生成一个compilation.bmodel的文件,该文件则是转换成功的bmodel,用户可以重命名。

    若用户在bmnetc时使用了cmp=true模式,则会在指定的文件夹中生成一个input_ref_data.dat和一个output_ref_data.dat, 分别是Caffe产生的网络输入参考数据和网络输出参考数据,可用于bmrt_test验证生成的bmodel在芯片运行时结果是否正确。

    若没有上述信息,则bmnetc失败。目前失败的话,用户可以修改opt优化选项,可能其它优化级别会成功,从而不会耽误用户部署。 然后请用户将失败的问题告知我们的客户支持。

实现Caffe自定义Layer

详细请见BMNETC插件工具 BMNET 前端插件

常见问题

  1. Upsample算子支持问题?

    通常Upsample是将yolo系列模型由darknet转换为caffe模型格式时出现的。 如果转换报错是因为我们内部用的是UpsampeCopy,之前的Upsample被另一层占用了, 需要把Upsample换成UpsampleCopy,把upsample_param换成upsamplecopy_param

    layer {
    bottom: "layer104-conv"
    top: "layer105-upsample"
    name: "layer105-upsample"
    type: "UpsampleCopy"
       upsamplecopy_param {
          scale:2
       }
    }