From f0dba857d64d094d482dad2fff97aa9278901939 Mon Sep 17 00:00:00 2001 From: wuyefeilin <30919197+wuyefeilin@users.noreply.github.com> Date: Tue, 26 May 2020 14:10:30 +0800 Subject: [PATCH] fix quant online bug (#268) --- contrib/HumanSeg/models/humanseg.py | 117 ++++++++++++++------------ contrib/HumanSeg/models/load_model.py | 15 ++-- deploy/python/README.md | 7 +- pdseg/export_model.py | 2 +- 4 files changed, 76 insertions(+), 65 deletions(-) diff --git a/contrib/HumanSeg/models/humanseg.py b/contrib/HumanSeg/models/humanseg.py index 0452f7ab..413be892 100644 --- a/contrib/HumanSeg/models/humanseg.py +++ b/contrib/HumanSeg/models/humanseg.py @@ -25,6 +25,7 @@ import time import tqdm import cv2 import yaml +import shutil import paddleslim as slim import utils @@ -243,30 +244,11 @@ class SegModel(object): if self.status == 'Normal': fluid.save(self.train_prog, osp.join(save_dir, 'model')) + model_info['status'] = 'Normal' elif self.status == 'Quant': - float_prog, _ = slim.quant.convert( - self.test_prog, self.exe.place, save_int8=True) - test_input_names = [ - var.name for var in list(self.test_inputs.values()) - ] - test_outputs = list(self.test_outputs.values()) - fluid.io.save_inference_model( - dirname=save_dir, - executor=self.exe, - params_filename='__params__', - feeded_var_names=test_input_names, - target_vars=test_outputs, - main_program=float_prog) + fluid.save(self.test_prog, osp.join(save_dir, 'model')) + model_info['status'] = 'QuantOnline' - model_info['_ModelInputsOutputs'] = dict() - model_info['_ModelInputsOutputs']['test_inputs'] = [ - [k, v.name] for k, v in self.test_inputs.items() - ] - model_info['_ModelInputsOutputs']['test_outputs'] = [ - [k, v.name] for k, v in self.test_outputs.items() - ] - - model_info['status'] = self.status with open( osp.join(save_dir, 'model.yml'), encoding='utf-8', mode='w') as f: @@ -308,40 +290,57 @@ class SegModel(object): logging.info("Model for inference deploy saved in {}.".format(save_dir)) def export_quant_model(self, - dataset, - save_dir, + dataset=None, + save_dir=None, batch_size=1, batch_nums=10, - cache_dir="./.temp"): - self.arrange_transform(transforms=dataset.transforms, mode='quant') - dataset.num_samples = batch_size * batch_nums - try: - from utils import HumanSegPostTrainingQuantization - except: - raise Exception( - "Model Quantization is not available, try to upgrade your paddlepaddle>=1.7.0" - ) - is_use_cache_file = True - if cache_dir is None: - is_use_cache_file = False - post_training_quantization = HumanSegPostTrainingQuantization( - executor=self.exe, - dataset=dataset, - program=self.test_prog, - inputs=self.test_inputs, - outputs=self.test_outputs, - batch_size=batch_size, - batch_nums=batch_nums, - scope=None, - algo='KL', - quantizable_op_type=["conv2d", "depthwise_conv2d", "mul"], - is_full_quantize=False, - is_use_cache_file=is_use_cache_file, - cache_dir=cache_dir) - post_training_quantization.quantize() - post_training_quantization.save_quantized_model(save_dir) - if cache_dir is not None: - os.system('rm -r' + cache_dir) + cache_dir=".temp", + quant_type="offline"): + if quant_type == "offline": + self.arrange_transform(transforms=dataset.transforms, mode='quant') + dataset.num_samples = batch_size * batch_nums + try: + from utils import HumanSegPostTrainingQuantization + except: + raise Exception( + "Model Quantization is not available, try to upgrade your paddlepaddle>=1.8.1" + ) + is_use_cache_file = True + if cache_dir is None: + is_use_cache_file = False + post_training_quantization = HumanSegPostTrainingQuantization( + executor=self.exe, + dataset=dataset, + program=self.test_prog, + inputs=self.test_inputs, + outputs=self.test_outputs, + batch_size=batch_size, + batch_nums=batch_nums, + scope=None, + algo='KL', + quantizable_op_type=["conv2d", "depthwise_conv2d", "mul"], + is_full_quantize=False, + is_use_cache_file=is_use_cache_file, + cache_dir=cache_dir) + post_training_quantization.quantize() + post_training_quantization.save_quantized_model(save_dir) + if cache_dir is not None: + shutil.rmtree(cache_dir) + else: + float_prog, _ = slim.quant.convert( + self.test_prog, self.exe.place, save_int8=True) + test_input_names = [ + var.name for var in list(self.test_inputs.values()) + ] + test_outputs = list(self.test_outputs.values()) + fluid.io.save_inference_model( + dirname=save_dir, + executor=self.exe, + params_filename='__params__', + feeded_var_names=test_input_names, + target_vars=test_outputs, + main_program=float_prog) + model_info = self.get_model_info() model_info['status'] = 'Quant' @@ -593,6 +592,16 @@ class SegModel(object): 'Current evaluated best model in eval_dataset is epoch_{}, miou={}' .format(best_model_epoch, best_miou)) + if quant: + if osp.exists(osp.join(save_dir, "best_model")): + fluid.load( + program=self.test_prog, + model_path=osp.join(save_dir, "best_model"), + executor=self.exe) + self.export_quant_model( + save_dir=osp.join(save_dir, "best_model_export"), + quant_type="online") + def evaluate(self, eval_dataset, batch_size=1, epoch_id=None): """评估。 diff --git a/contrib/HumanSeg/models/load_model.py b/contrib/HumanSeg/models/load_model.py index 0ac62698..dadaa2b5 100644 --- a/contrib/HumanSeg/models/load_model.py +++ b/contrib/HumanSeg/models/load_model.py @@ -34,7 +34,7 @@ def load_model(model_dir): raise Exception("There's no attribute {} in models".format( info['Model'])) model = getattr(models, info['Model'])(**info['_init_params']) - if status == "Normal": + if status in ["Normal", "QuantOnline"]: startup_prog = fluid.Program() model.test_prog = fluid.Program() with fluid.program_guard(model.test_prog, startup_prog): @@ -42,11 +42,16 @@ def load_model(model_dir): model.test_inputs, model.test_outputs = model.build_net( mode='test') model.test_prog = model.test_prog.clone(for_test=True) + if status == "QuantOnline": + print('test quant online') + import paddleslim as slim + model.test_prog = slim.quant.quant_aware( + model.test_prog, model.exe.place, for_test=True) model.exe.run(startup_prog) - import pickle - with open(osp.join(model_dir, 'model.pdparams'), 'rb') as f: - load_dict = pickle.load(f) - fluid.io.set_program_state(model.test_prog, load_dict) + fluid.load(model.test_prog, osp.join(model_dir, 'model')) + if status == "QuantOnline": + model.test_prog = slim.quant.convert(model.test_prog, + model.exe.place) elif status in ['Infer', 'Quant']: [prog, input_names, outputs] = fluid.io.load_inference_model( diff --git a/deploy/python/README.md b/deploy/python/README.md index cd4fdb83..4e9792ba 100644 --- a/deploy/python/README.md +++ b/deploy/python/README.md @@ -44,7 +44,7 @@ yum install -y libXext libSM libXrender ### 5.1 准备模型 请使用[模型导出工具](../../docs/model_export.md) 导出您的模型, 或点击下载我们的[人像分割样例模型](https://bj.bcebos.com/paddleseg/inference/human_freeze_model.zip)用于测试。 -模型导出的目录通常包括三个文件: +模型导出的目录通常包括三个文件: ``` ├── model # 模型文件 ├── params # 参数文件 @@ -79,7 +79,7 @@ DEPLOY: ### 5.2 执行预测程序 在终端输入以下命令进行预测: ```bash -python infer.py --conf=/path/to/deploy.yaml --input_dir/path/to/images_directory --use_pr=False +python infer.py --conf=/path/to/deploy.yaml --input_dir/path/to/images_directory ``` 参数说明如下: @@ -87,9 +87,6 @@ python infer.py --conf=/path/to/deploy.yaml --input_dir/path/to/images_directory |-------|-------|----------| | conf | Yes|模型配置的Yaml文件路径 | | input_dir |Yes| 需要预测的图片目录 | -| use_pr |No|是否使用优化模型,默认为False| - -* 优化模型:使用`PaddleSeg 0.3.0`版导出的为优化模型, 此前版本导出的模型即为未优化版本。优化模型把图像的预处理以及后处理部分融入到模型网络中使用`GPU` 完成,相比原来`CPU` 中的处理提升了计算性能。 **注意**: 如果硬件支持且安装的是从源码编译集成`TensorRT`的`PaddlePaddle`, 则可以使用参数`--trt_mode=fp16` 表示开启`FP16` 精度优化, 使用`trt_mode=fp32` 表示使用`FP32` 精度。 diff --git a/pdseg/export_model.py b/pdseg/export_model.py index ae71d43b..e0beceb3 100644 --- a/pdseg/export_model.py +++ b/pdseg/export_model.py @@ -53,7 +53,7 @@ def parse_args(): def export_inference_config(): deploy_cfg = '''DEPLOY: USE_GPU : 1 - USE_PR : 1 + USE_PR : 0 MODEL_PATH : "%s" MODEL_FILENAME : "%s" PARAMS_FILENAME : "%s" -- GitLab