发新帖

tensorflowLite的量化使用问题

[复制链接]
20020 95

快来加入 TensorFlowers 大家庭!

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
我想问下,现在很多企业都说使用了tensorflow lite,但他们使用的tensorflow lite是经过量化的吗?因为现在好多操作都不支持量化操作,比如tf.Abs,tf.tf.Square等等.如果是使用未量化的tensorflow lite,那这样速度比起量化后的pb文件在android手机上使用,速度有提高吗?提高多少?        还有一个问题.就是要使用toco工具生成量化的lite文件,是不是要求在训练过程中得先使用tf.contrib.quantize.create_training_graph和tf.contrib.quantize.create_eval_graph()进行伪量化训练?
麻烦各位大佬解答下.有没有大佬量化自己模型真正测试成功过的,回答下疑惑.或者能写下量化具体步骤教程.这还有一个我的相同的贴,可以一并回答tensorflowLite的量化使用问题https://www.tensorflowers.cn/t/7100
(出处: TensorFlow中文开发者社区)


我知道答案 回答被采纳将会获得10 金币 + 50 金币 已有95人回答
已有1人评分金币 理由
段德璋 + 27

查看全部评分 总评分:金币 +27 

本楼点评(1) 收起
  • 大当家tzp我实现tflite量化后,pc上跑结果是,遇到了情况,就是relu层不支持uint8得计算,请问有什么方法可以跑得时候,把tflite这一层设到浮点上计算。错误message是:
    RuntimeError: Only float32 is supported currently, got UINT8.Node number 28 (RELU) failed to invoke.
    2019-10-30 12:44 回复

精彩评论95

Zongjun  TF豆豆  发表于 2018-10-24 05:38:19 | 显示全部楼层
本帖最后由 Zongjun 于 2019-4-20 02:19 编辑

以下是我的个人理解,如果是在android 上,Tensorflow Lite (tflite) 可以利用hardware accelerator,应该是更快的。量化只是一个float32到uint8的过程,本质上是weights\bias大小的变化(是原来的25%),有的microcontroller太小,不量化根本就放不进去,并且mircocontroller大部分是8bit计算,float32非常昂贵,所以需要量化。
用toco生成的量化有两个途径:1.你提到的伪量化,这个确实在training时要调用你说的这两句。具体展开:要生成两个graph,一个用于training,在compute gradients前使用create_training_graph,因为forward和backward都需要模拟量化。这个过程其实是找到需要量化的变量,插入fake quantization nodes 来记录 min-max range information。再具体一点:见(*)。另一个graph用于eval,要在import_graph_def后,saver.restore前插入create_eval_graph。后面如何freeze如何调用toco,按照这个链接上说的即可:https://github.com/tensorflow/te ... ow/contrib/quantize
2. post-training quantization。顾名思义,无需伪量化,是toco拿过来一个pb file,直接把toco的post-training quantization flag设成true完成的。但是注意,这个方法只quantize weights,而1.是一个fully quantized model. 并且2.在inference时,会把uint8的weights再转换回float32来做矩阵乘法。所以,2.这个方法其实依然相当于没做quantization。它的存在应当只是便于用户转移model,计算时依然是个非量化model。链接:https://www.tensorflow.org/performance/post_training_quantization

(*):再往前几个版本,tensorflow其实有自己的量化,就叫做quantize。他不是用伪量化,也无需tflite介入。这个文件在现在的tensorflow github中已经不存在了(半个月前移除的,pete warden决心只搞tflite了)。但是他很好的解释了tensorlow 和 tflite量化的数学原理。如果不加入上述的fake quantize node,tensorflow quantize则需要requantize和dequantize的过程。其中requantize是必须的,因为8bit的两个整数相乘为16bit的数。int8的两个矩阵相乘会得出一个32bit的结果,即一个2d convolution layer的输出结果是int32的。但是下一个quantized op需要一个8bit的输入,这就需要记录float32的min 和max,从而对这个int32的中间结果进行requantization,重新获得8bit的数据继续往下传。当使用了fake quantization后,上述过程在训练过程中被模拟了。于是你会看到训练完了的图,不再存在requantization node和dequantization node。有的只是那些fake quantization nodes。值得注意的是,不加伪量化的量化,不是fully quantized model,因为其涉及到了利用float32 min和max转换。而伪量化不存在该问题。简言之,目前唯一可行的fully quantization method就是在tensorflow 下伪量化训练,再到tflite上转化。
(另外,之前还有一个做移动端的方法,即tensorflow mobile。但是它会在 early 2019 deprecate (应该是被tensorflow lite取代),如图:)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
本楼点评(19) 收起
  • OnceJune您好,请教一个问题,我在使用create_training_graph的时候,出现了Cannot use '%s' as input to '%s' because '%s' is in a while loop.这样的错。想请教一下在加fake quant node的时候,对于op的操作上面会和不加有什么区别吗?同样的结构直接训练是可以一路训通的。
    2019-1-29 18:51 回复
  • Zongjun回复 OnceJune :如果用的是底层tensorflow的api, ops比如conv2d这些layer,它们的写法和以前没有不同。只是在定义loss之后和定义optimizer之前加入create_training_graph()即可。这个函数会自动识别一些常用的op,然后训练时在这些op之前插入fake quant node。这个还和你Model的具体结构有关,比如rcnn有的op就不会被自动识别,需要手动插入fake quant nodes。
    你的这个报错我没有遇见过,估计是model结构不同吧。
    2019-1-30 02:02 回复
  • OnceJune回复 Zongjun :您好,感谢回答。我实际上是想对tacotron2的模型做量化,但是while op好像不被支持。手动插入fake quant nodes这块是在调用create_training_graph之前来操作吗?还是完全重新实现一套插入fake quant nodes的逻辑?或者说我可不可以通过某种方式在CheckInputFromValidContext这一步跳过不被支持的op呢?
    2019-2-1 18:05 回复
  • Zongjun回复 OnceJune :果然是模型的问题。tacotron2是不是还有LSTM的部分啊?这一部分官方的说法是自动插入fake quant nodes还没做到这一步。所以你除了create_training_graph之外(这个部分保留),还要在你定义graph的时候手动插入fake quant nodes。
    还有一种方法,和quantization aware training完全不同了。那就是用Tensorflow自带的 Graph Transform Tool. 链接: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms 重点看一下"Shrinking File Size"这里。还有这个链接:https://github.com/tensorflow/tensorflow/issues/7949,这个是有人问怎么量化LSTM(LSTM是不能自动识别添加fake quant node的),你看一下pete warden的官方回答。
    量化这方面,我的模型一直是自动插入fake quant node的,所以我也只能给这些建议了。希望能帮到你一丢丢哈。Good Luck!
    2019-2-2 06:22 回复
  • OnceJune回复 Zongjun :手动插入fake quant nodes的话是要完全抛弃create_training_graph()是吗?然后eval的时候再把手动插入的也手动删除?我看到有FakeQuantWithMinMaxArgs这个方法,具体操作是通过它来逐层修改还是要到更底层的地方啊?另外GraphTransform这个我也尝试过,模型的size确实和预期一样减小,但是本地运行的速度在avx2指令集下反而是慢了的,我理解这里也是一个fake quant吧,所以可能norm/denorm的运算开销冲抵了8bit带来的提升。
    2019-2-2 16:45 回复
  • Zongjun回复 OnceJune :手动插入我没用过,但是我觉得首先可以尝试保留create_training_graph()和create_eval_graph()。在它们无法检测到的层的地方手动加入fake quant node。看看会不会在create_eval_graph()的时候把所有的fake quant node都自动处理,不行的话再尝试手动删除。
    graph transform应该不是fake quant。所谓fake quant其本质是quantization-aware training,是train的过程中模拟量化。graph transform是你拿着一个训练好的模型给它,它再进行处理。读一下graph transform的Eight-bit Calculations部分,它上面也说了:on many platforms the quantized code may actually be slower than the float equivalents, but this is a way of increasing performance substantially when all the circumstances are right. 下面一段简单讲了一下怎么手动插入fake quant node。这一部分其实就是在说,如果想真正做到fully quantization,那就需要fake quant node,训练时就train好min 和 max,然后用它说的那个指令量化。但是这个看上去又和fake quantization之后在用tensorflow lite fully quanitze并没有什么区别。具体实现要看底层代码了。
    综上,只要你想fully quantize一个模型,那就必须手动插入fake quant node去训练。我建议你先放一放graph transform,手动插入训练成功以后直接用tensorflow lite转化试试。
    2019-2-5 02:09 回复
  • OnceJune回复 Zongjun :看了一下,确实是好简略一段啊……A full guide to optimizing for quantization is beyond the scope of this guide, but one thing that can help is using the FakeQuantWithMinMaxVars op after Conv2D or similar operations during training. This trains the min/max variables that control the range used for quantization, so that the range doesn't have to be calculated dynamically by RequantizationRange during inference.我改改建图的脚本试试吧。多谢回答~~
    2019-2-11 11:26 回复
  • OnceJune回复 Zongjun :今天上班又看了一下,发现有一个experimental_create_training_graph的等价方法,可以定义scope,应该可以作为一个解法。把支持的ops放在一个scope里面,不支持的比如lstm放在另一个里面,然后只transform支持的。
    2019-2-11 15:38 回复
  • Zongjun回复 OnceJune :嗯,你说的这个我也可以尝试一下哈!
    2019-2-12 03:33 回复
  • OnceJune回复 Zongjun :另外看到您下面的回复中提到了quant的论文,可以发一下链接吗?我的理解比较粗,想再看一下细节。另外tacotron我做了performance profiling,cost的大户还是在lstm上面……最后可能还得手动去做quant。
    2019-2-13 14:33 回复
Zongjun  TF豆豆  发表于 2018-11-6 08:49:44 | 显示全部楼层
对了,我补充一点,我debug的时候花了不少时间的一个地方:我用的是在linux下,安装tf.nightly,然后jupyter notebook里调用tf.lite.TFLiteConverter这个东西。因为是quantization,所以要求给出quantized_input_stats,这是一个tuple (med, std)平均值和标准差是要自己手动调的。我的是图片为输入,一开始给(128,128),结果很惨。我调来调去,最后是(128,73)给出的accuracy达到了fake quantization的效果。
本楼点评(4) 收起
  • 杨7277请教一下大神,quantized_input_stats中的mean/stddev的值的设定,有什么规律吗?如何正确 快速的接近合理的值?
    2019-4-15 16:50 回复
  • Zongjun回复 杨7277 :看这个链接:https://stackoverflow.com/questions/54261772/tensorflow-lite-toco-mean-values-std-values
    这个公式是谷歌官方的回答。
    2019-4-18 01:50 回复
  • 杨7277回复 Zongjun : 不好意思回复晚了,多谢大神的分享,我学习一下
    2019-4-25 15:43 回复
  • Zongjun回复 杨7277 :客气。这个也是我好不容易才搞来的公式。。。
    2019-4-26 00:45 回复
九幽  TF荚荚  发表于 2018-11-14 11:32:14 来自手机  | 显示全部楼层
Zongjun 发表于 2018-11-6 08:49
对了,我补充一点,我debug的时候花了不少时间的一个地方:我用的是在linux下,安装tf.nightly,然后jupyter  ...

您好,想请教您一个问题,我现在参照着官方的mobilenet训练例子在mnist里面加入了伪量化训练代码,但只加了Create_training_graph那部分,然后跑出了模型,但是在用工具转化tflite的时候,报错说不知道FakeQuantWithMinMaxVars的数据类型,这个是不是我训练的时候代码写错了?
我看了官方的两篇论文,还有各种社区的各种问题,但还是不确定步骤对不对,您是怎么做的怎么找的资料啊?还有什么我可以找的资料吗?或者您能把你的例子给我看一下吗?非常感谢~
本楼点评(0) 收起
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

快速回复 返回顶部 返回列表