×

签到

分享到微信

打开微信,使用扫一扫进入页面后,点击右上角菜单,

点击“发送给朋友”或“分享到朋友圈”完成分享

【经验总结】caffe模型精度问题排查 yehongjuan2021-08-10 19:12:45 回复 1 查看 经验交流
【经验总结】caffe模型精度问题排查
分享到:

本文是作者在调试caffe模型精度中总结的一些方法,供大家参考。

拿到一个模型,先看一下int16的精度有没有问题。

如果int16精度异常了,那先查查原因吧~

首先逐层比对,那么如何逐层比对呢?

我们的caffe中增加了一个参数“debug_info”,如果在prototxt文件中设置为“true”,mlu/cpu推理运行时将会把每层输出数据自动保存到文件。

编译caffe后,我们可以使用caffe/tools下的test_forward_online工具来推理并dump出每层数据,输入是随机的。

>>> 使用方式:

./caffe/tools/test_forward_online proto_file model_file mlu_option mcore output_file

其中:

  - proto_file为模型结构.prototxt所在路径;

  - model_file为模型权值.caffemodel所在路径;

  - mlu_option选择推理运行模式,0为cpu运行模式,1为mlu逐层运行模式,2为mlu融合运行模式;

  - mcore为调试板卡型号,一般为MLU270;

  - output_file为输出数据保存文件路径。

使用:

    ① 可以先运行cpu模式,dump cpu逐层数据:

./caffe/tools/test_forward_online ./model.prototxt ./weights.caffemodel 0 MLU270 outcpu

    运行后,在当前路径下会得到多个 "tmp_layer_000" 开头的cpu逐层数据,为了方便对比,我们可以将这些数据批量 mv 到同一个目录下:

mkdir cpu_layers
mv tmp_layer_000* ./cpu_layers

    ② 再dump mlu逐层数据:

./caffe/tools/test_forward_online ./model.prototxt ./weights.caffemodel 1 MLU270 outmlu

    运行后,在当前路径下会得到多个 "tmp_layer_000" 开头的mlu逐层数据,为了方便对比,我们可以将这些数据批量 mv 到同一个目录下:

mkdir mlu_layers
mv tmp_layer_000* ./mlu_layers

除了test_forward_online工具,我们也可以使用caffe/tools下的caffe test来推理运行,该方式输入是真实数据

>>> 使用方式:

首先,量化时将配置文件中的use_firstconv设置为1,量化后prototxt中首层conv层会增加“mean_value”和“std”信息;

其次,将首层data层按如下方式修改:

image.png

改成:

image.png

其中,source为真实数据所在路径list。

使用:

    ① 先运行cpu模式,dump cpu逐层数据:

./caffe/tools/caffe test --model ./model.prototxt --weights ./weights.caffemodel --iterations 1

    运行后,在当前路径下会得到多个 "tmp_layer_000" 开头的cpu逐层数据,为了方便对比,我们可以将这些数据批量 mv 到同一个目录下:

mkdir cpu_layers
mv tmp_layer_000* ./cpu_layers

    ② 再dump mlu逐层数据:

./caffe/tools/caffe test --model ./model.prototxt --weights ./weights.caffemodel --iterations 1 --mmode MLU --mcore MLU270

    运行后,在当前路径下会得到多个 "tmp_layer_000" 开头的mlu逐层数据,为了方便对比,我们可以将这些数据批量 mv 到同一个目录下:

mkdir mlu_layers
mv tmp_layer_000* ./mlu_layers

分别获得cpu和mlu的逐层数据信息后,可通过提供的mse算法来逐层比对,如下所示:

image.png

>>> 使用方式:

python ./caffe/src/caffe/test/cmpDirData.py ./cpu_layers ./mlu_layers

也可以根据实际需求增加比对算法,如下所示是通过余弦相似度算法比对的信息:

image.png

上图所示精度正常,如果遇到某层精度明显下降,可以看看是量化还是算子问题导致。

那么如何判断是量化还是算子问题?我们有cpu模拟量化工具去判定,当然我们也可以通过将量化算子放到cpu上运行,来判定是否是量化问题导致的精度异常。

如何将量化算子放到cpu上运行?有两种方式:

    - 第一种方式,在prototxt指定层中增加“engine:CAFFE”,表示该层在cpu运行,这个方式适合算子比较少的情况,如果算子多了,一层一层地去添加太麻烦了;

    - 第二种方式,修改 _factory.cpp,让mlu运行的算子实际走的是cpu的实现,这种方式可以把某类算子都先用cpu算子实现,快速定位是哪一类算子的问题,如下所示(注意:修改 _factory.cpp后需重新编译caffe):

image.png

比如,通过第二种方式,将量化层放到cpu上运行,精度正常了,可以考虑是由于量化方式导致的精度异常,通过使用我们提供的其他量化方式重新量化并推理,看精度是否达标。如果是非量化层放到cpu上运行,精度正常了,可以考虑是算子的问题,可及时与我们联系沟通解决。

大家可以根据实际需求去选择方式。

通过以上的方式可以定位到int16量化精度异常问题的原因了。

如果int16精度正常,而int8精度异常呢?其实int8精度问题定位和int16的方式一致。先根据逐层dump数据比对,定位到哪层精度开始下降,再去确定是量化导致还是算子实现问题。

以上就是这次分享的全部内容了,后续如有新方式或改动会及时更新。

版权所有 © 2024 寒武纪 Cambricon.com 备案/许可证号:京ICP备17003415号-1
关闭