20200913
Plan
- the relationship between tensorflow and tf lite
- tensorflow quantization
Notes
The relationship between tf and tf lite
一直听闻 tf lite 和 tf 有一些区别,今天打算多方面比较一下。
定位上: tensorflow lite 的描述是一个用于部署 machine learning 模型到移动以及 iot 设备进行推理的深框架学习。 tensorflow 则是号称一个 end-to-end 的开源机器学习平台。
工作流上: tensorflow lite:选择模型 -> 转换模型 -> 部署 -> 优化 tensorflow:构建模型 -> 训练模型 -> 选择平台 -> 部署 -> 优化
整体上来看,tf lite 实际上就是一个轻量化的 inference engine,其目标是方便的提供用户在低算力平台上运行 AI 的能力。他和 tensorflow 的关系,与 paddlepaddle 与 anakin 的关系类似。
tensorflow quantization
对于 tf 有两种量化方式,post-training quantization 和 training aware quantization。顾名思义,前者是在训练后,针对高精度模型直接进行量化推理,这种方式使用更为简单;后者则是训练的过程中,就进行量化,这种量化方式虽然通常精度更高,但更为复杂,对算法研究人员的要求更高。
training aware quantization
训练可感知量化的内核在于,在训练时模拟量化的行为过程,训练出来的模型,可以直接让后续的业务进行量化推理。量化推理的收益主要体现在两点:1. 模型变小,内存占用减少;2. 速度加快,延迟降低;在量化训练的过程中,用户可以自定义一些量化参数,例如量化位宽等。但是目前 tensorflow 尚未承诺量化训练相关的 api 是稳定兼容的。 可以参考的资料是 QAT 介绍 blog。
QAT 的核心思想,是在训练时,在正向计算的过程中模拟低精度量化的行为。谷歌号称自己的移动视觉团队最先提出了这个想法,其原理在于量化带来的误差,同样可以作为一个训练过程中的噪声,纳入到全局的损失中,而训练的过程就是降低这一损失。在实际操作中,针对需要量化的 op ,其输入的 tensor 会经过一个 fakequant op,这个 op 完成了 float-point 数据到 fixed-point 数据的转换;而在需要量化计算的 op 计算完成后,会有同样一个反量化 op 将量化 tensor 转回到高精度 tensor。这个过程,假设所有的误差损失都在 fakequant op 中发生,而量化 op 计算没有误差损失。
tensorflow lite 的量化 spec 参考链接是 tf lite quant spec。 在 keras api 中,可以用一个简单的函数,对固定的 layer 和整个 model 做量化。
fake quant op
fake quant op 在 tensorflow 中有很多类似的,文档中,是以 tensorflow::ops::FakeQuantWithMinMaxVars 为例,进行的叙述。原始的输入的数据范围是 [min, max],在 narrow_range 为 false 时候,量化为 [0; 2^num_bits - 1],否则,则是 [1; 2^num_bits - 1]。num_bits 则是 2 到 16 的量化带宽。在量化之前,需要保障 min <= 0 <= max。如果出现 min 和 max 都大于 0 或者都小于 0,则对齐数据范围。对于已经满足条件的数据,则 scale = (max - min) / (2^num_bits - 1), min_adj = scale * round(min / scale) , max_adj = max + min_adj - min;其中 round 在 tf 中是按照数据四舍五入。
tf lite quant spec
数学公式与数据类型
tf-lite 中给出的是一个量化 spec,在不同硬件上,结合深度学习的本质,确实可能存在损失。具体的数学公式是:
real_value = (int8_value - zero_point) * scale
每轴(也就是 Conv ops 中的每通道)或每张量权重用 int8 表示,int8_value 范围 [-127, 127],zero_point 等于 0。每张量激活/输入用 int8 表示,int8_value 范围 [-128, 127],zero_point 在 [-128, 127]。
之所以 tf_lite 里面,用 int8 来表示量化数据,一是为了方便与对称量化契合,二是有很多硬件针对 int8 x int8 进行了优化。
per axis 量化
tf_lite 中支持两种量化方式,Per-axis 与 per-tensor 。前者是 tensor 的每个 channel 一套量化参数,后者则是一整个 tensor 一套量化参数。前者在事件中证明可以有效的提高量化精度。
对称与非对称量化
激活非对称,权值是对称的。可参考文献 Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference
post-training quantization
post-training 在 tf_lite 中提供了一个工具进行支持,在 tf 中分了几种:
- dynamic range quantization
- integer quantization
- float16 quantization
- integer quantization with int16 activations
More
https://www.tensorflow.org/model_optimization/guide/quantization/training_comprehensive_guide