操作说明
Lyngor主要包括2个使用场景:
首次构建引擎
重复加载引擎
备注
在获得引擎后,执行推理的操作相同。
Lyngor的简化操作流程如图所示。

图 Lyngor操作流程
首次构建引擎
如首次构建计算图的推理引擎,在构建完成后,保存引擎,便于后续重复使用该引擎,进行计算图推理, 避免重复编译计算图。
导入Lyngor库,以便后续使用Lyngor接口进行计算图相关操作。具体操作参见 导入Lyngor库 。
备注
在使用Lyngor接口前,须确认已导入Lyngor库。
判断是否已有模型:
否:使用Lyngor算子构建计算图。具体操作参见 构建计算图 。
是:采用以下2种方式之1,导入模型转换计算图。
使用Lyngor接口,具体操作参见 导入模型转换成计算图 。
使用编译模型工具,具体操作参见 模型编译工具 。
注意
在导入模型转换计算图时,如模型中存在Lyngor无法支持的算子,会产生报错。 在这种情况下,可通过开发Lyngor自定义算子,实现相应功能。
Lyngor支持的算子参见:《Lyngor算子说明书》
开发Lyngor自定义算子参见:《Lyngor自定义算子开发指南》
(可选)如需加速模型推理,减少模型的权重体积,则需要增加量化校准过程,提供校准数据。具体操作参见 量化校准 。
构建推理引擎。支持以下2种方式:
备注
如需包含量化校准参数,在构建推理引擎时,传入量化配置,具体操作参见 包含量化校准参数 。
反序列化引擎。具体操作参见 反序列化引擎 。
执行推理。具体操作参见 执行推理 。
重复加载引擎
如已构建计算图的推理引擎,可加载已保存的引擎,避免重复编译计算图。
前提条件:已序列化引擎。具体操作参见 构建推理引擎 。
INT8量化原理
量化运算的定义
对于一个取值范围为(\(x_{\min},\ x_{\max}\))的浮点变量,将其量化到范围为(0, \(N_{levels} - 1\))需要求出两个参数:量化因子(\(\mathrm{\Delta}\))和零点(\(z\))。
此时,量化计算为:
其中
反量化操作为
\(x_{Q}\)为量化后数据,\(x_{float}\)为反量化后的数据,对于8比特精度 而言\(N_{levels} = 256\)。
使用零点,可以更准确的量化任意数据范围的浮点变量,但是零点的引入也会导致更大的计算 量,对于神经网络而言,激活数据很多情况下近似为0均值的正态分布,所以我们可以省略零点 (设置零点为0)来简化运算,这种量化方式也称为对称量化。
此时,计算公式变为
在Lyngor中我们只考虑有符号的情况和对称量化。
量化参数计算
对于INT8对称量化,\(\mathrm{\Delta}\)是唯一需要确定的参数。
对于卷积算子而言,有两种数据需要量化,输入数据和权重数据。这两种数据有着 不同的特性导致它们的量化方法也不一样。通过给模型大量不同的输入(校准数据集), 我们可以获取很多的卷积输入数据,这样我们可以使用统计的方法来求卷积输入的量化 参数;而模型参数数量却是固定的,往往不具备统计特性,只能使用较简单直接的方法 来计算卷积权重的量化参数。
卷积权重量化参数计算使用一种较直接的方法:\(\mathrm{\Delta} = \frac{x_{\max} - x_{\min}}{N_{level} - 1}\)。 由于只考虑INT8的对称量化,可以设\(x_{\max} > 0,\ x_{\max} = - x_{\min}\)。 所以,只需要考虑如何确定\(x_{\max}\)。 在Lyngor中我们实现了POW2和MAX两种方法来计算\(x_{\max}\)。 在MAX方法中\(x_{\max} = max(abs(w))\); 而在POW2的方法中\(x_{\max} = 2^{ceil(\log_{2}(max(abs(w))))}\)。
而对于卷积输入,则使用基于KL散度的统计方法来计算量化参数。
计算权重量化参数时使用的那种简单方法,有一个很大的弊端就是没有考虑数据的分布。 举个简单的例子,比如大量的数据分布在(0,10)的区间范围内,仅有个别野点在区间(90,100), 这时使用上述简单方法就会造成较大的量化误差。基于KL散度的方法由于考虑了数据的统计分布, 就能有效地解决上面的问题。
离散KL散度的计算公式为:\({KL}_{divergence(P,\ Q)} = \sum_{i}^{}{P\lbrack i\rbrack*\log_{2}\frac{P\lbrack i\rbrack}{Q\lbrack i\rbrack}}\), 其中P、Q为离散概率分布。在量化参数计算中,分别对应原始数据的离散概率分布、量化后再 反量化的离散概率分布。离散概率分布可以通过直方图统计。量化+反量化的效果类似于取平 均值,比如假设1个量化间隔由3个统计区间(直方图统计)组成,每个统计区间的数据分别为 3、4、5,那么量化+反量化后的直方图就变为了4、4、4。
量化精度调优
权重数据量化参数计算
权重量化可以采用Per-Layer和Per-Channel两种模式,它们的不同之处在于计算\(max(abs(w))\)时\(w\)的取值范围。Per-Layer模式下,取值范围为整个输入权重tensor,计算出的量化参数为一个标量;而在Per-Channel模式下,取值范围为每个输出Channel对应的权重数据,计算出的量化参数为一个tensor。
比如,一个权重tensor的Layout为HWIO,形状为(3, 3, 49, 204),在Per-Layer模式 下就是在\(3*3*49*204\)个数中取最大值;而在Per-Channel模式下就是 在\(3*3*49\)个数中取最大值,得到一个最大值tensor,形状为(204), 而最后计算出的量化参数的形状也为(204)。
Per-Channel模式能够在一定程度上应对离群点的问题,所以效果更好,是Lyngor权重量化的默认方式。
输入数据量化参数计算
在量化输入数据时,需要考虑该输入数据的分布是否适合量化?如果该数据分布天然就 对量化不友好,即使使用KL散度来求量化参数,也会使模型性能有较大地损失。所以我 们需要有一种方法来识别量化不友好的分布,当输入出现这种分布时,该Conv2D算子就 不进行量化。
目前我们基于三个准则来判断一个输入是否是量化友好的。一是该输入分布计算出的KL 散度相比起其它KL散度值是否显著的大,二是输入数据的动态范围是否比INT8可表示范 围大很多(远远大于128),三是数据分布是否存在相距较远的波峰。如果这三个条件都 满足,我们就认为其是量化不友好的,该Conv2D不进行量化。