未验证 提交 255fc7d8 编写于 作者: 王明冬 提交者: GitHub

add the auto scan test for TensorRT convert,test=develop (#34980)

上级 26213a77
......@@ -38,4 +38,5 @@ set_tests_properties(test_trt_dynamic_shape PROPERTIES TIMEOUT 120)
set_tests_properties(test_trt_pool_op PROPERTIES ENVIRONMENT FLAGS_fraction_of_gpu_memory_to_use=0.1 TIMEOUT 45)
set_tests_properties(test_trt_reduce_mean_op PROPERTIES TIMEOUT 60)
set_tests_properties(test_trt_tile_op PROPERTIES TIMEOUT 60)
set_tests_properties(test_trt_convert_conv2d PROPERTIES TIMEOUT 100)
endif()
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
import unittest
import abc
import paddle
import paddle.fluid as fluid
from paddle.fluid.initializer import NumpyArrayInitializer
import paddle.fluid.core as core
from paddle import compat as cpt
import paddle.inference as paddle_infer
from typing import Optional, List, Callable, Dict, Any, Set
from program_config import TensorConfig, OpConfig, ProgramConfig, create_fake_model
class AutoScanTest(unittest.TestCase):
def __init__(self, methodName='runTest'):
paddle.enable_static()
super(AutoScanTest, self).__init__(methodName)
self.threshold = 1e-5
@abc.abstractmethod
def sample_program_configs(self) -> List[ProgramConfig]:
'''
Generate all config with the combination of different Input tensor shape and
different Attr values.
'''
raise NotImplementedError
@abc.abstractmethod
def sample_predictor_configs(self) -> List[paddle_infer.Config]:
raise NotImplementedError
def run_test_config(self, model, params, prog_config, pred_config,
feed_data) -> Dict[str, np.ndarray]:
'''
Test a single case.
'''
pred_config.set_model_buffer(model, len(model), params, len(params))
predictor = paddle_infer.create_predictor(pred_config)
for name, _ in prog_config.inputs.items():
input_tensor = predictor.get_input_handle(name)
input_tensor.copy_from_cpu(feed_data[name])
predictor.run()
result = {}
for out_name in prog_config.outputs:
result[out_name] = predictor.get_output_handle(
out_name).copy_to_cpu()
return result
def assert_tensors_near(self,
threshold: float,
tensors: List[Dict[str, np.array]]):
assert len(tensors) > 1
first = tensors[0]
for group in tensors[1:]:
for key, arr in group.items():
self.assertTrue(
np.allclose(
first[key], arr, atol=threshold),
"Output has diff between GPU and TensorRT. ")
def run_test(self):
for prog_config in self.sample_program_configs():
model, params = create_fake_model(prog_config)
for batch_size in self.batch_size_set:
feed_data = {}
for name, tensor_config in prog_config.inputs.items():
tensor_shape = tensor_config.shape.copy()
tensor_shape[0] = batch_size
feed_data[name] = np.random.random(tensor_shape).astype(
tensor_config.dtype)
results: List[Dict[str, Tensor]] = []
for pred_config in self.sample_predictor_configs():
results.append(
self.run_test_config(model, params, prog_config,
pred_config, feed_data))
self.assert_tensors_near(
threshold=self.threshold, tensors=results)
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Optional, List, Callable, Dict, Any, Set
import numpy as np
import paddle
import paddle.fluid as fluid
import paddle.fluid.core as core
from paddle import compat as cpt
from paddle.fluid.initializer import NumpyArrayInitializer
from paddle.fluid.framework import convert_np_dtype_to_dtype_
class TensorConfig:
'''
A config builder for a input or a weight.
InputVar's shape can be [-1, xxx], batch_size
'''
def __init__(self,
shape: [List[int]],
dtype: [str]="float32",
data: Optional[np.array]=None):
'''
shape: The shape of the tensor.
dtype: The data type of the tensor.
data: The value of WeightVar. for input, it should be None
'''
self.shape = shape
self.dtype = dtype
self.data = data
class OpConfig:
''' A config builder for generating a Op. '''
def __init__(self,
type: str,
inputs: Dict[str, List[str]],
outputs: Dict[str, List[str]],
attrs: Dict[str, Any]):
self.type = type
self.inputs = inputs
self.outputs = outputs
self.attrs = attrs
class ProgramConfig:
''' A config builder for generating a Program. '''
def __init__(self,
ops: List[OpConfig],
weights: Dict[str, TensorConfig],
inputs: Dict[str, TensorConfig],
outputs: List[str]):
self.ops = ops
self.weights = weights
self.inputs = inputs
self.outputs = outputs
def create_fake_model(program_config):
''' Create a Paddle model(in memory) according to the given config. '''
paddle.enable_static()
main_program_desc = core.ProgramDesc()
util_program = fluid.Program()
main_block_desc = main_program_desc.block(0)
var_desc = main_block_desc.var(cpt.to_bytes("feed"))
var_desc.set_type(core.VarDesc.VarType.FEED_MINIBATCH)
var_desc.set_persistable(True)
index = 0
for name, tensor_config in program_config.inputs.items():
var_desc = main_block_desc.var(cpt.to_bytes(name))
var_desc.set_type(core.VarDesc.VarType.LOD_TENSOR)
var_desc.set_dtype(convert_np_dtype_to_dtype_(tensor_config.dtype))
var_desc.set_shape(tensor_config.shape)
var_desc.set_need_check_feed(True)
op_desc = main_block_desc._prepend_op()
op_desc.set_type("feed")
op_desc.set_input('X', ["feed"])
op_desc.set_output('Out', [name])
op_desc._set_attr("col", index)
index = index + 1
save_var_map = {}
for name, tensor_config in program_config.weights.items():
var_desc = main_block_desc.var(cpt.to_bytes(name))
var_desc.set_type(core.VarDesc.VarType.LOD_TENSOR)
var_desc.set_dtype(convert_np_dtype_to_dtype_(tensor_config.dtype))
var_desc.set_shape(tensor_config.shape)
var_desc.set_persistable(True)
save_var_map[name] = util_program.global_block().create_parameter(
dtype=tensor_config.dtype,
shape=tensor_config.shape,
type=core.VarDesc.VarType.LOD_TENSOR,
name=name,
initializer=NumpyArrayInitializer(tensor_config.data))
in_vars = []
for name in sorted(save_var_map.keys()):
in_vars.append(save_var_map[name])
out_var = util_program.global_block().create_var(
type=core.VarDesc.VarType.RAW, name="out_var_0")
out_var.desc.set_persistable(True)
util_program.global_block().append_op(
type='save_combine',
inputs={'X': in_vars},
outputs={'Y': out_var},
attrs={'file_path': '',
'save_to_memory': True})
for op_config in program_config.ops:
op_desc = main_block_desc.append_op()
op_desc.set_type(op_config.type)
for name, values in op_config.inputs.items():
op_desc.set_input(name, values)
for name, values in op_config.attrs.items():
op_desc._set_attr(name, values)
for name, values in op_config.outputs.items():
op_desc.set_output(name, values)
var_desc = main_block_desc.var(cpt.to_bytes(name))
var_desc.set_type(core.VarDesc.VarType.LOD_TENSOR)
op_desc.infer_var_type(main_block_desc)
op_desc.infer_shape(main_block_desc)
for index, name in enumerate(program_config.outputs):
var_desc = main_block_desc.var(cpt.to_bytes("fetch"))
var_desc.set_type(core.VarDesc.VarType.FETCH_LIST)
var_desc.set_need_check_feed(True)
op_desc = main_block_desc.append_op()
op_desc.set_type("fetch")
op_desc.set_input('X', [name])
op_desc.set_output('Out', ["fetch"])
op_desc._set_attr("col", index)
main_program_desc._set_version()
paddle.fluid.core.save_op_version_info(main_program_desc)
model = main_program_desc.serialize_to_string()
util_program._sync_with_cpp()
place = fluid.CPUPlace()
executor = fluid.Executor(place)
scope = fluid.Scope()
with fluid.scope_guard(scope):
executor.run(util_program)
params = scope.find_var("out_var_0").get_bytes()
return model, params
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from trt_layer_auto_scan_test import TrtLayerAutoScanTest
from program_config import TensorConfig
import numpy as np
class TrtConvertConv2dTest(TrtLayerAutoScanTest):
def setUp(self):
self.ops_config = [{
"op_type": "conv2d",
"op_inputs": {
"Input": ["input_data"],
"Filter": ["conv2d_weight"]
},
"op_outputs": {
"Output": ["conv_output_data"]
},
"op_attrs": {
"data_format": ["NCHW"],
"dilations": [[1, 1]],
"padding_algorithm": ["EXPLICIT"],
"groups": [1],
"paddings": [[0, 3], [3, 1]],
"strides": [[1, 1], [2, 2]],
}
}, {
"op_type": "relu",
"op_inputs": {
"X": ["conv_output_data"]
},
"op_outputs": {
"Out": ["relu_output_data"]
},
"op_attrs": {}
}]
self.batch_size_set = [1, 2, 4]
def update_program_input_and_weight_with_attr(self, op_attr_list):
weight = np.random.randn(24, 3, 3, 3).astype("float32")
filter = TensorConfig(shape=[24, 3, 3, 3], data=weight)
if op_attr_list[0]["data_format"] == "NCHW":
input_data = TensorConfig(shape=[-1, 3, 64, 64])
else:
input_data = TensorConfig(shape=[-1, 64, 64, 3])
self.program_weights = {"conv2d_weight": filter}
self.program_inputs = {"input_data": input_data}
self.program_outputs = ["relu_output_data"]
def test_check_output(self):
self.run_test()
if __name__ == "__main__":
unittest.main()
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import numpy as np
import unittest
import itertools
import abc
import paddle
import paddle.fluid as fluid
import paddle.fluid.core as core
import paddle.inference as paddle_infer
from paddle import compat as cpt
from typing import *
from program_config import TensorConfig, OpConfig, ProgramConfig
from auto_scan_test import AutoScanTest
class TrtLayerAutoScanTest(AutoScanTest):
class TensorRTParam:
'''
TensorRT subgraph engine parameters.
'''
def __init__(self, workspace_size, max_batch_size, min_subgraph_size,
precision, use_static, use_calib_mode):
self.workspace_size = workspace_size
self.max_batch_size = max_batch_size
self.min_subgraph_size = min_subgraph_size
self.precision = precision
self.use_static = use_static
self.use_calib_mode = use_calib_mode
def __init__(self, methodName='runTest'):
super(TrtLayerAutoScanTest, self).__init__(methodName)
self.trt_param = self.TensorRTParam(
workspace_size=0,
max_batch_size=4,
min_subgraph_size=0,
precision=paddle_infer.PrecisionType.Float32,
use_static=False,
use_calib_mode=False)
def update_program_input_and_weight_with_attr(self, op_attr_list):
raise NotImplementedError
@abc.abstractmethod
def sample_program_configs(self):
all_op_attrs_keys = []
all_op_attrs_values = []
for op_config in self.ops_config:
all_op_attrs_keys.append(list(op_config["op_attrs"].keys()))
all_op_attrs_values.extend(list(op_config["op_attrs"].values()))
if len(all_op_attrs_values) == 0:
all_op_attrs_values.append([None])
for attrs_sample in itertools.product(*all_op_attrs_values):
op_attr_list = []
index = 0
ops = []
for op_config in self.ops_config:
op_attr = dict(
zip(
list(op_config["op_attrs"].keys()), attrs_sample[
index:index + len(op_config["op_attrs"])]))
op_attr_list.append(op_attr)
index = index + len(op_config["op_attrs"])
ops.append(
OpConfig(
type=op_config["op_type"],
inputs=op_config["op_inputs"],
outputs=op_config["op_outputs"],
attrs=op_attr))
self.update_program_input_and_weight_with_attr(op_attr_list)
program_config = ProgramConfig(
ops=ops,
weights=self.program_weights,
inputs=self.program_inputs,
outputs=self.program_outputs)
yield program_config
def create_program_config(
self, use_trt=True,
precision_mode=paddle_infer.PrecisionType.Float32):
config = paddle_infer.Config()
config.enable_use_gpu(100, 0)
if use_trt:
config.enable_tensorrt_engine(
max_batch_size=self.trt_param.max_batch_size,
workspace_size=self.trt_param.workspace_size,
min_subgraph_size=self.trt_param.min_subgraph_size,
precision_mode=precision_mode,
use_static=self.trt_param.use_static,
use_calib_mode=self.trt_param.use_calib_mode)
return config
@abc.abstractmethod
def sample_predictor_configs(self):
yield self.create_program_config(use_trt=False)
yield self.create_program_config(
use_trt=True, precision_mode=self.trt_param.precision)
if self.trt_param.precision == paddle_infer.PrecisionType.Float32:
yield self.create_program_config(
use_trt=True, precision_mode=paddle_infer.PrecisionType.Half)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册