INT8 Bmodel转化
Last updated
Last updated
在BM1684算力板上,目前已经支持int8模型的部署。在通用流程中,需要先借助于bitmain提供的量化工具对fp32模型进行量化。 Qantization-Tools是比特大陆自主开发的网络模型量化工具,它解析各种已训练好的32bit浮点网络模型,生成8bit的定点网络模型。该8bit定点网络模型,可用于比特大陆SOPHON系列AI运算平台。在SOPHON运算平台上,网络各层输入、输出、系数都用8bit来表示,从而在保证网络精度的基础上,大幅减少功耗,内存,传输延迟,大幅提高运算速度。
Quantization-Tools工具架构如下:
基于开源框架(caffe, tensorflow,pytorch,mxnet)的模型首先需要借助于量化工具转换成为fp32umodel,成为bitmain量化平台私有的格式。基于fp32umodel,后续量化流程已经跟开源框架解耦,作为通用流程执行量化校准。 Bitmain量化平台框架参考caffe框架,因此天然支持caffemodel,在caffemodel无需借助工具,可以直接作为int8校准的输入即可。但是tensorflow、pytorch、mxnet等必须首先转换为fp32umodel.
原生支持caffemodel,可以直接把.caffemodel当做.fp32umodel作为输入。
在BM1684平台,支持TF int8模型的部署运行,需要对TF标准模型模型(*.pb)进行量化操作,首先都需要转换为fp32umodel,之后就使用标准量化流程。如下介绍如何使用Quantization-tools提供的工具把TF模型转换成fp32umodel。
量化工具包提供了名为:pb_to_umodel的python工具 例如在pb_to_fp32umodel的示例中,演示如何把TF resnet50_v2.pb转换为fp32umodel:
在docker环境下,直接执行:
在当前文件夹下,新生成 compilation 文件夹,存放新生成的.fp32umodel 与.prototxt
pb_to_umodel的命令参数:
详细文件可以参考pb_to_fp32umodel的示例.
暂未发布
暂未发布
此流程从fp32umodel转换为int8umodel,即为量化过程。
基于fp32umodel网络模型进行int8的量化,主要骤如下:
2.1 准备lmdb数据集
2.2 生成int8umodel
2.3 精度测试(optional)
原始数据集合转换成lmdb格式,供后续校准量化使用。
lmdb数据集合的生成,有两种方式:一是通过convert_imageset工具直接针对测试图片集合生成,二是通过u_framework框架接口来生成,主要针对级联网络,后级网络的输入依赖前级网络的输出,例如mtcnn.
当前主要介绍convert_imageset工具如何生成数据集合,此方式是通用方式。u_framework生成级联网络所需要的lmdb在mtcnn demo中详细介绍。
SDK工具包包括了将图像转换成lmdb的工具,convert_imageset,类似于caffe框架中的使用方式。
其中ROOTFOLDER为图像集的根目录,LISTFILE 为列表文件,该文件中记录了图像集中的各图样的路径和相应的标注,DB_NAME为要生成的数据库的名字。
参数说明:
参考sdk中示例:
为了使用刚生成的 lmdb 数据集,需要对网络的*.prototxt 文件作以下三方面的修改:
使用 Data layer 作为网络的输入
使 Data layer 的参数 data_param 指向生成的 lmdb 数据集的位置
修改 Data layer 的 transform_param 参数以对应网络对图片的预处理
例如:
完成上述步骤就可以配置完lmdb.
另外,在配置prototxt的datalayer参数时,提供了灵活的方式按照网络实际输入特征配置,支持的transform_paramters:
需要注意:
在编译 prototxt 文件时,transform_op 中定义的参数与 transform_op 外定义的参数只能二选一。例如上图左右,一个是transform_op的参数,另外一个则没有。
transform_op 中定义的参数按其在 prototxt 定义的顺序来执行,适用于灵活的数据预处理组合。
transform_op 外定义的参数其执行顺序是固定的。 预处理的先后顺序如下:
transform_parameter支持的参数如下:
ResizeParameter定义:
transform_parameter中的transform_op的定义如下:
以上步骤主要是为准确配置prototxt的datalayer参数,如何使用lmdb.
对于检测网络来说,其 label 不仅仅是个数字,它包括类别,检测框的位置等复杂信息。对于这种情况,分两种情况处理:
1.如果lmdb已经生成存在,并且带有Annotated信息,那么在prototxt中需要使用AnnotatedData layer来加载lmdb,
例如:
2.如果lmdb还没有生成,那么在使用convert_imageset工具的时候,修改filelist中的label信息为随机数即可(<1000),正常使用Data layer来加载此lmdb文件。(在量化网络过程中,annotated信息,例如label, bbox坐标都不是必须的,只需要保证生成lmdb的图片集合是正样本即可)
SDK提供工具,直接可以把fp32umodel(.caffemodel)转换成bitmain私有的中间临时模型(int8umodel)。 量化工具中使用calibration_use_pb来执行校准操作,命令使用如下:
例如示例中的SSD模型转换的步骤:
运行正常后会产生输出部分:
*.int8umodel即量化生成的int8格式的网络系数文件
*_deploy_int8_unique_top.prototxt为int8格式的网络结构文件,
*_deploy_fp32_unique_top.prototxt为fp32格式的网络结构文件,int8_unique_top.prototxt文件作为后续部署生成bmodel使用, fp32为对比二者的区别。由于为部署文件,此prototxt不包含Datalayer,而是Input layer,同时各layer的输出blob是唯一的,不存在in-place的情况。
*_test_int8_unique_top.prototxt & *_test_fp32_unique_top.prototxt分别是int8/fp32的网络结构文件,此两个文件作为精度比较时使用,验证量化的结果。相对应地,此两文件包含Datalayer。
deploy_int8_*.prototxt与test_int8_*.prototxt的内容主要区别例如:
注意deployint8.prototxt比testint8.prototxt在第一层之前多了一个int8_scale的参数,该参数在部署算法推理的时候需要对Input data做scale处理。 int8_scale的含义是:在原有的float32网络的数据预处理的基础上,乘以int8_scale,四舍五入求整后,再送给int8网络。
上述量化校准后生成的文件都存放在fp32umodel的同级目录下。 最终量化后,提供给下一步所需要的文件为: deploy_int8_unique_top.prototxt & *.int8umodel
args
Description
-m
指向*.pb文件的路径
-i
输入tensor的名称
-o
输出tensor的名称
-s
输入tensor的维度,(N,H,W,C)
-d
输出文件夹的名字
-n
网络的名字
-p
数据预处理类型,预先定义了VGG,INCEPTION,SSD_V,SSD_I几种,没有合适的随意选一个,然后在手动编辑prototxt文件的时候,根据实际的预处理来添加
-D
lmdb数据集的位置,没有的话,可以暂时随意填个路径,然后在手动编辑prototxt文件的时候,根据实际的路径来添加
-a
加上该参数,会在生成的模型中添加top1,top5两个accuracy层
-t
固定参数
args
description
-backend
The backend (lmdb, leveldb) for storing the result. type: string default: "lmdb"
-check_size
When this option is on, check that all the datum have the same size. type: bool default: false
-encode_type
optional: What type should we encode the image as ('png','jpg',...). type: string default: ""
-encoded
When this option is on, the encoded image will be save in datum. type: bool default: false
-gray
When this option is on, treat images as grayscale ones. type: bool default: false
-resize_height
Height images are resized to. type: int32 default: 0
-resize_width
Width images are resized to. type: int32 default: 0
-shuffle
(Randomly shuffle the order of images and their labels. type: bool default: false