未验证 提交 f0dba857 编写于 作者: W wuyefeilin 提交者: GitHub

fix quant online bug (#268)

上级 7bcd8b1d
...@@ -25,6 +25,7 @@ import time ...@@ -25,6 +25,7 @@ import time
import tqdm import tqdm
import cv2 import cv2
import yaml import yaml
import shutil
import paddleslim as slim import paddleslim as slim
import utils import utils
...@@ -243,30 +244,11 @@ class SegModel(object): ...@@ -243,30 +244,11 @@ class SegModel(object):
if self.status == 'Normal': if self.status == 'Normal':
fluid.save(self.train_prog, osp.join(save_dir, 'model')) fluid.save(self.train_prog, osp.join(save_dir, 'model'))
model_info['status'] = 'Normal'
elif self.status == 'Quant': elif self.status == 'Quant':
float_prog, _ = slim.quant.convert( fluid.save(self.test_prog, osp.join(save_dir, 'model'))
self.test_prog, self.exe.place, save_int8=True) model_info['status'] = 'QuantOnline'
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['_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( with open(
osp.join(save_dir, 'model.yml'), encoding='utf-8', osp.join(save_dir, 'model.yml'), encoding='utf-8',
mode='w') as f: mode='w') as f:
...@@ -308,40 +290,57 @@ class SegModel(object): ...@@ -308,40 +290,57 @@ class SegModel(object):
logging.info("Model for inference deploy saved in {}.".format(save_dir)) logging.info("Model for inference deploy saved in {}.".format(save_dir))
def export_quant_model(self, def export_quant_model(self,
dataset, dataset=None,
save_dir, save_dir=None,
batch_size=1, batch_size=1,
batch_nums=10, batch_nums=10,
cache_dir="./.temp"): cache_dir=".temp",
self.arrange_transform(transforms=dataset.transforms, mode='quant') quant_type="offline"):
dataset.num_samples = batch_size * batch_nums if quant_type == "offline":
try: self.arrange_transform(transforms=dataset.transforms, mode='quant')
from utils import HumanSegPostTrainingQuantization dataset.num_samples = batch_size * batch_nums
except: try:
raise Exception( from utils import HumanSegPostTrainingQuantization
"Model Quantization is not available, try to upgrade your paddlepaddle>=1.7.0" except:
) raise Exception(
is_use_cache_file = True "Model Quantization is not available, try to upgrade your paddlepaddle>=1.8.1"
if cache_dir is None: )
is_use_cache_file = False is_use_cache_file = True
post_training_quantization = HumanSegPostTrainingQuantization( if cache_dir is None:
executor=self.exe, is_use_cache_file = False
dataset=dataset, post_training_quantization = HumanSegPostTrainingQuantization(
program=self.test_prog, executor=self.exe,
inputs=self.test_inputs, dataset=dataset,
outputs=self.test_outputs, program=self.test_prog,
batch_size=batch_size, inputs=self.test_inputs,
batch_nums=batch_nums, outputs=self.test_outputs,
scope=None, batch_size=batch_size,
algo='KL', batch_nums=batch_nums,
quantizable_op_type=["conv2d", "depthwise_conv2d", "mul"], scope=None,
is_full_quantize=False, algo='KL',
is_use_cache_file=is_use_cache_file, quantizable_op_type=["conv2d", "depthwise_conv2d", "mul"],
cache_dir=cache_dir) is_full_quantize=False,
post_training_quantization.quantize() is_use_cache_file=is_use_cache_file,
post_training_quantization.save_quantized_model(save_dir) cache_dir=cache_dir)
if cache_dir is not None: post_training_quantization.quantize()
os.system('rm -r' + cache_dir) 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 = self.get_model_info()
model_info['status'] = 'Quant' model_info['status'] = 'Quant'
...@@ -593,6 +592,16 @@ class SegModel(object): ...@@ -593,6 +592,16 @@ class SegModel(object):
'Current evaluated best model in eval_dataset is epoch_{}, miou={}' 'Current evaluated best model in eval_dataset is epoch_{}, miou={}'
.format(best_model_epoch, best_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): def evaluate(self, eval_dataset, batch_size=1, epoch_id=None):
"""评估。 """评估。
......
...@@ -34,7 +34,7 @@ def load_model(model_dir): ...@@ -34,7 +34,7 @@ def load_model(model_dir):
raise Exception("There's no attribute {} in models".format( raise Exception("There's no attribute {} in models".format(
info['Model'])) info['Model']))
model = getattr(models, info['Model'])(**info['_init_params']) model = getattr(models, info['Model'])(**info['_init_params'])
if status == "Normal": if status in ["Normal", "QuantOnline"]:
startup_prog = fluid.Program() startup_prog = fluid.Program()
model.test_prog = fluid.Program() model.test_prog = fluid.Program()
with fluid.program_guard(model.test_prog, startup_prog): with fluid.program_guard(model.test_prog, startup_prog):
...@@ -42,11 +42,16 @@ def load_model(model_dir): ...@@ -42,11 +42,16 @@ def load_model(model_dir):
model.test_inputs, model.test_outputs = model.build_net( model.test_inputs, model.test_outputs = model.build_net(
mode='test') mode='test')
model.test_prog = model.test_prog.clone(for_test=True) 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) model.exe.run(startup_prog)
import pickle fluid.load(model.test_prog, osp.join(model_dir, 'model'))
with open(osp.join(model_dir, 'model.pdparams'), 'rb') as f: if status == "QuantOnline":
load_dict = pickle.load(f) model.test_prog = slim.quant.convert(model.test_prog,
fluid.io.set_program_state(model.test_prog, load_dict) model.exe.place)
elif status in ['Infer', 'Quant']: elif status in ['Infer', 'Quant']:
[prog, input_names, outputs] = fluid.io.load_inference_model( [prog, input_names, outputs] = fluid.io.load_inference_model(
......
...@@ -44,7 +44,7 @@ yum install -y libXext libSM libXrender ...@@ -44,7 +44,7 @@ yum install -y libXext libSM libXrender
### 5.1 准备模型 ### 5.1 准备模型
请使用[模型导出工具](../../docs/model_export.md) 导出您的模型, 或点击下载我们的[人像分割样例模型](https://bj.bcebos.com/paddleseg/inference/human_freeze_model.zip)用于测试。 请使用[模型导出工具](../../docs/model_export.md) 导出您的模型, 或点击下载我们的[人像分割样例模型](https://bj.bcebos.com/paddleseg/inference/human_freeze_model.zip)用于测试。
模型导出的目录通常包括三个文件: 模型导出的目录通常包括三个文件:
``` ```
├── model # 模型文件 ├── model # 模型文件
├── params # 参数文件 ├── params # 参数文件
...@@ -79,7 +79,7 @@ DEPLOY: ...@@ -79,7 +79,7 @@ DEPLOY:
### 5.2 执行预测程序 ### 5.2 执行预测程序
在终端输入以下命令进行预测: 在终端输入以下命令进行预测:
```bash ```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 ...@@ -87,9 +87,6 @@ python infer.py --conf=/path/to/deploy.yaml --input_dir/path/to/images_directory
|-------|-------|----------| |-------|-------|----------|
| conf | Yes|模型配置的Yaml文件路径 | | conf | Yes|模型配置的Yaml文件路径 |
| input_dir |Yes| 需要预测的图片目录 | | input_dir |Yes| 需要预测的图片目录 |
| use_pr |No|是否使用优化模型,默认为False|
* 优化模型:使用`PaddleSeg 0.3.0`版导出的为优化模型, 此前版本导出的模型即为未优化版本。优化模型把图像的预处理以及后处理部分融入到模型网络中使用`GPU` 完成,相比原来`CPU` 中的处理提升了计算性能。
**注意**: 如果硬件支持且安装的是从源码编译集成`TensorRT``PaddlePaddle`, 则可以使用参数`--trt_mode=fp16` 表示开启`FP16` 精度优化, 使用`trt_mode=fp32` 表示使用`FP32` 精度。 **注意**: 如果硬件支持且安装的是从源码编译集成`TensorRT``PaddlePaddle`, 则可以使用参数`--trt_mode=fp16` 表示开启`FP16` 精度优化, 使用`trt_mode=fp32` 表示使用`FP32` 精度。
......
...@@ -53,7 +53,7 @@ def parse_args(): ...@@ -53,7 +53,7 @@ def parse_args():
def export_inference_config(): def export_inference_config():
deploy_cfg = '''DEPLOY: deploy_cfg = '''DEPLOY:
USE_GPU : 1 USE_GPU : 1
USE_PR : 1 USE_PR : 0
MODEL_PATH : "%s" MODEL_PATH : "%s"
MODEL_FILENAME : "%s" MODEL_FILENAME : "%s"
PARAMS_FILENAME : "%s" PARAMS_FILENAME : "%s"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册