非均匀量化
由于硬件约束,该版本不建议使用非均匀量化的功能,获取不到性能收益。
模型在昇腾AI处理器上推理时,可通过非均匀量化提高权重压缩率(需要与ATC工具配合,通过编译时使能权重压缩),降低权重传输开销,进一步提升推理性能。非均匀量化后,如果精度仿真模型在原始Caffe环境中推理精度不满足要求,可通过调整非均匀量化配置文件config.json中的参数来恢复模型精度,根据是否自动调整量化配置文件,非均匀量化又分为静态非均匀量化和自动非均匀量化。
- 静态非均匀量化:需要用户参见手工调优章节手动调整相应参数。详细量化过程请参见获取更多样例>静态非均匀量化。
- 自动非均匀量化:由AMCT自动搜索出一个量化配置,在满足给出的精度损失要求前提下使得量化后的模型压缩率更高。该场景下用户需要基于给出的自动非均匀量化基类(AutoNuqEvaluatorBase)实现一个子类,需要实现eval_model(self, model_file, weights_file, batch_num)和is_satisfied(self, original_metric, new_metric) 两个方法:
- eval_model根据输入的模型和batch_num进行数据前处理、模型推理、数据后处理,得到模型的评估结果,要求返回的评估结果唯一,如分类网络的top1, 检测网络的mAP等,同时也可以是指标的加权结果。
- is_satisfied用于判断量化后的模型是否达到了精度损失的要求,如果达到了则返回True, 否则返回 False;如分类网络的top1用小数表示,则判断条件可以写作if (original_metric - new_metric) * 100 < 1, 表示精度的损失要小于1个百分点。
详细量化示例请参见获取更多样例>自动非均匀量化。
非均匀量化支持量化的层以及约束如下:
量化方式 |
支持的层类型 |
约束 |
---|---|---|
非均匀量化 |
Convolution:卷积层 |
dilation为1、group为1、filter维度为4 |
InnerProduct:全连接层 |
transpose属性为false,axis为1 |
接口调用流程
非均匀量化接口调用流程如图1所示。非均匀量化不支持多个GPU同时运行。
下面以自动非均匀量化为例介绍主要流程,静态非均匀量化流程请参见均匀量化。
- 用户首先构造Caffe的原始模型,然后使用create_quant_config生成量化配置文件。
- 根据Caffe模型和量化配置文件,调用init接口,初始化工具,配置量化因子存储文件,将模型解析为图结构graph。
- 根据原始模型文件、通过ATC工具转换的json文件(该文件携带了支持weight压缩特性层的信息,通过fe_weight_compress字段识别)调用auto_nuq进行自动非均匀量化,该过程中会调用由用户传入的evaluator实例进行精度测试,得到原始模型精度。
简要流程如图2所示。
调用示例
- 导入AMCT包。
1 2
import amct_caffe as amct from amct_caffe.auto_nuq import AutoNuqEvaluatorBase
- 根据给定的AutoNuqEvaluatorBase基类实现一个子类,需要实现能够得到模型精度的评估方法eval_model和判断当前的量化后模型是否精度达标的is_satisfied方法。
1 2 3 4 5
class AutoNuqEvaluator(AutoNuqEvaluatorBase): # Auto Nuq Evaluator def __init__(self, evaluate_batch_num): super().__init__(self) self.evaluate_batch_num = evaluate_batch_num
- 实现模型精度评估方法eval_model。
eval_model根据输入的模型和batch_num进行数据前处理、模型推理、数据后处理,得到模型的评估结果,要求返回的评估结果唯一,如分类网络的top1, 检测网络的mAP等,同时也可以是指标的加权结果。
1 2
def eval_model(self, model_file, weights_file, batch_num): return do_benchmark_test(QUANT_ARGS, model_file, weights_file, batch_num)
- 实现精度损失的评估方法is_satisfied。
is_satisfied用于判断量化后的模型是否达到了精度损失的要求,如果达到了则返回True, 否则返回 False;如分类网络的top1用小数表示,则判断条件可以写作if (original_metric - new_metric) *100 < 1, 表示精度的损失要小于1个百分点。
- original_metric代表原始未量化模型精度。
- new_metric代表量化后fake quant模型精度,根据精度损失是否满足阈值返回True或False。
1 2 3 4 5
def is_satisfied(self, original_metric, new_metric): # the loss of top1 acc need to be less than 1% if (original_metric - new_metric) * 100 < 1: return True return False
- 实现模型精度评估方法eval_model。
- 生成量化配置文件。
1 2 3 4 5 6 7 8 9 10 11 12
config_json_file = os.path.join(TMP, 'config.json') skip_layers = [] batch_num = 2 activation_offset = True # do weights calibration with non uniform quantize configure amct.create_quant_config( config_json_file, args.model_file, args.weights_file, skip_layers, batch_num, activation_offset, args.cfg_define) scale_offset_record_file = os.path.join(TMP, 'scale_offset_record.txt') result_path = os.path.join(RESULT, 'ResNet50')
- 开始自动非均匀量化流程。
1 2 3 4 5 6 7 8
evaluator = AutoNuqEvaluator(args.iterations) amct.auto_nuq( args.model_file, args.weights_file, evaluator, config_json_file, scale_offset_record_file, result_path)
父主题: 手工量化