Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hackathon NO.76] 为 Paddle-TRT 添加elementwise_mod 算子 #50974

Merged
merged 9 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions paddle/fluid/inference/api/analysis_predictor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2406,6 +2406,7 @@ USE_TRT_CONVERTER(elementwise_div_weight);
USE_TRT_CONVERTER(elementwise_min_weight);
USE_TRT_CONVERTER(elementwise_max_weight);
USE_TRT_CONVERTER(elementwise_pow_weight);
USE_TRT_CONVERTER(elementwise_mod_weight);
USE_TRT_CONVERTER(elementwise_floordiv_weight);
USE_TRT_CONVERTER(elementwise_add_tensor);
USE_TRT_CONVERTER(elementwise_sub_tensor);
Expand All @@ -2415,6 +2416,7 @@ USE_TRT_CONVERTER(elementwise_max_tensor);
USE_TRT_CONVERTER(elementwise_min_tensor);
USE_TRT_CONVERTER(elementwise_pow_tensor);
USE_TRT_CONVERTER(elementwise_floordiv_tensor);
USE_TRT_CONVERTER(elementwise_mod_tensor);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

elementwise_mod_weight也添加上

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已添加

USE_TRT_CONVERTER(less_than);
USE_TRT_CONVERTER(greater_than);
USE_TRT_CONVERTER(logical_or);
Expand Down
27 changes: 27 additions & 0 deletions paddle/fluid/inference/tensorrt/convert/elementwise_op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,25 @@ class ElementwiseTensorOpConverter : public OpConverter {
nvinfer1::ElementWiseOperation::kOR);

RreplenishLayerAndOutput(layer, "elementwise", {output_name}, test_mode);
} else if (op_type_ == "mod") {
auto* div_layer =
TRT_ENGINE_ADD_LAYER(engine_,
ElementWise,
*X,
*reshape_y_tensor,
nvinfer1::ElementWiseOperation::kFLOOR_DIV);
auto* mul_layer =
TRT_ENGINE_ADD_LAYER(engine_,
ElementWise,
*(div_layer->getOutput(0)),
*reshape_y_tensor,
nvinfer1::ElementWiseOperation::kPROD);
auto* layer = TRT_ENGINE_ADD_LAYER(engine_,
ElementWise,
*X,
*(mul_layer->getOutput(0)),
nvinfer1::ElementWiseOperation::kSUB);
RreplenishLayerAndOutput(layer, "elementwise", {output_name}, test_mode);
} else {
auto op_pair = ops.find(op_type_);
PADDLE_ENFORCE_NE(
Expand Down Expand Up @@ -271,6 +290,10 @@ class ElementwiseTensorLessEqualOpConverter
public:
ElementwiseTensorLessEqualOpConverter() { op_type_ = "less_equal"; }
};
class ElementwiseTensorModOpConverter : public ElementwiseTensorOpConverter {
public:
ElementwiseTensorModOpConverter() { op_type_ = "mod"; }
};
} // namespace tensorrt
} // namespace inference
} // namespace paddle
Expand All @@ -291,6 +314,8 @@ REGISTER_TRT_OP_CONVERTER(elementwise_pow_weight,
ElementwiseTensorPowOpConverter);
REGISTER_TRT_OP_CONVERTER(elementwise_floordiv_weight,
ElementwiseTensorFloorDivOpConverter);
REGISTER_TRT_OP_CONVERTER(elementwise_mod_weight,
ElementwiseTensorModOpConverter);

REGISTER_TRT_OP_CONVERTER(elementwise_add_tensor,
ElementwiseTensorAddOpConverter);
Expand All @@ -308,6 +333,8 @@ REGISTER_TRT_OP_CONVERTER(elementwise_pow_tensor,
ElementwiseTensorPowOpConverter);
REGISTER_TRT_OP_CONVERTER(elementwise_floordiv_tensor,
ElementwiseTensorFloorDivOpConverter);
REGISTER_TRT_OP_CONVERTER(elementwise_mod_tensor,
ElementwiseTensorModOpConverter);
REGISTER_TRT_OP_CONVERTER(less_than, ElementwiseTensorLessThanOpConverter);
REGISTER_TRT_OP_CONVERTER(greater_than,
ElementwiseTensorGreaterThanOpConverter);
Expand Down
4 changes: 2 additions & 2 deletions paddle/fluid/inference/tensorrt/convert/op_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ class OpConverter {
}
if (op_desc.Type().find("elementwise") != std::string::npos) {
static std::unordered_set<std::string> add_tensor_op_set{
"add", "mul", "sub", "div", "max", "min", "pow"};
"add", "mul", "sub", "div", "max", "min", "pow", "mod"};
static std::unordered_set<std::string> add_weight_op_set{
"add", "mul", "sub", "div", "max", "min", "pow"};
"add", "mul", "sub", "div", "max", "min", "pow", "mod"};
PADDLE_ENFORCE_EQ(op_desc.Input("Y").size(),
1UL,
platform::errors::InvalidArgument(
Expand Down
15 changes: 10 additions & 5 deletions paddle/fluid/inference/tensorrt/op_teller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,8 @@ struct SimpleOpTypeSetTeller : public Teller {
if (op_type == "elementwise_add" || op_type == "elementwise_mul" ||
op_type == "elementwise_sub" || op_type == "elementwise_div" ||
op_type == "elementwise_pow" || op_type == "elementwise_min" ||
op_type == "elementwise_max" || op_type == "elementwise_floordiv") {
op_type == "elementwise_max" || op_type == "elementwise_floordiv" ||
op_type == "elementwise_mod") {
if (desc.Input("X").size() != 1) {
VLOG(3) << "The input op's Input(\"X\").size() "
"should equal to 1, but received Input(\"X\").size() = "
Expand Down Expand Up @@ -1453,12 +1454,14 @@ struct SimpleOpTypeSetTeller : public Teller {
if (op_type == "elementwise_add" || op_type == "elementwise_mul" ||
op_type == "elementwise_sub" || op_type == "elementwise_div" ||
op_type == "elementwise_pow" || op_type == "elementwise_min" ||
op_type == "elementwise_max" || op_type == "elementwise_floordiv") {
op_type == "elementwise_max" || op_type == "elementwise_floordiv" ||
op_type == "elementwise_mod") {
if (x_var_desc->GetDataType() ==
paddle::framework::proto::VarType_Type::VarType_Type_BOOL) {
VLOG(3) << "These operations "
"(elementwise_add/mul/sub/div/pow/min/max/floordiv) do "
"not support boolean datatype.";
VLOG(3)
<< "These operations "
"(elementwise_add/mul/sub/div/pow/min/max/floordiv/mod) do "
"not support boolean datatype.";
return false;
}
}
Expand Down Expand Up @@ -2606,6 +2609,7 @@ struct SimpleOpTypeSetTeller : public Teller {
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
"equal",
"not_equal",
"less_than",
Expand Down Expand Up @@ -2758,6 +2762,7 @@ struct SimpleOpTypeSetTeller : public Teller {
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
"equal",
"not_equal",
"less_than",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ def generate_input(shape, op_type):
return np.random.randint(
low=1, high=10000, size=shape, dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=shape).astype(
np.float32
)
else:
return np.random.random(shape).astype(np.float32)

Expand All @@ -44,6 +48,10 @@ def generate_weight(op_type):
return np.random.randint(
low=1, high=10000, size=[1, 32, 1, 1], dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(
low=0.1, high=1.0, size=[1, 32, 1, 1]
).astype(np.float32)
else:
return np.random.randn(1, 32, 1, 1).astype(np.float32)

Expand All @@ -58,6 +66,7 @@ def generate_weight(op_type):
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
]:
for axis in [-1]:
self.dims = len(shape)
Expand Down Expand Up @@ -169,6 +178,10 @@ def generate_input(shape, op_type):
return np.random.randint(
low=1, high=10000, size=shape, dtype=np.int32
)
if op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=shape).astype(
np.float32
)
else:
return np.random.random(shape).astype(np.float32)

Expand All @@ -178,6 +191,10 @@ def generate_weight(op_type):
return np.random.randint(
low=1, high=10000, size=[1], dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=[1]).astype(
np.float32
)
else:
return np.random.randn(1).astype(np.float32)

Expand All @@ -191,6 +208,7 @@ def generate_weight(op_type):
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
]:
for axis in [-1]:
self.dims = len(shape)
Expand Down Expand Up @@ -290,6 +308,10 @@ def generate_input(shape, op_type):
return np.random.randint(
low=1, high=10000, size=shape, dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=shape).astype(
np.float32
)
else:
return np.random.random(shape).astype(np.float32)

Expand All @@ -299,6 +321,10 @@ def generate_weight(op_type):
return np.random.randint(
low=1, high=10000, size=[32], dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=[32]).astype(
np.float32
)
else:
return np.random.randn(32).astype(np.float32)

Expand All @@ -318,6 +344,7 @@ def generate_weight(op_type):
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
]:
for axis in [-1 if len(shape) == 1 else 1]:
self.dims = len(shape)
Expand Down Expand Up @@ -442,6 +469,10 @@ def generate_input(shape, op_type):
return np.random.randint(
low=1, high=10000, size=shape, dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=shape).astype(
np.float32
)
else:
return np.random.random(shape).astype(np.float32)

Expand All @@ -455,6 +486,7 @@ def generate_input(shape, op_type):
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
]:
for axis in [0, -1]:
self.dims = len(shape)
Expand Down Expand Up @@ -605,6 +637,10 @@ def generate_input(shape, op_type):
return np.random.randint(
low=1, high=10000, size=shape, dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=shape).astype(
np.float32
)
else:
return np.random.random(shape).astype(np.float32)

Expand Down Expand Up @@ -651,6 +687,7 @@ def generate_input(shape, op_type):
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
]:
for axis in axis_list[j][i]:
self.shape1 = input1_shape
Expand Down Expand Up @@ -763,6 +800,10 @@ def generate_input(shape, op_type):
return np.random.randint(
low=1, high=10000, size=shape, dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=shape).astype(
np.float32
)
else:
return np.random.random(shape).astype(np.float32)

Expand All @@ -772,6 +813,10 @@ def generate_weight(op_type):
return np.random.randint(
low=1, high=10000, size=[32], dtype=np.int32
)
elif op_type == "elementwise_mod":
return np.random.uniform(low=0.1, high=1.0, size=[32]).astype(
np.float32
)
else:
return np.random.rand(32).astype(np.float32)

Expand All @@ -791,6 +836,7 @@ def generate_weight(op_type):
"elementwise_min",
"elementwise_max",
"elementwise_floordiv",
"elementwise_mod",
Copy link
Contributor

@zhangjun zhangjun Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前单测精度上有问题,coverage ci无法通过。可能是因为包含有floordiv,需要对对应的输入做修改,如generate_input或者generate_weight,由于np.random.random范围为[0,1.0), 需将np.random.random替换为np.random.uniform。
参考如下,

        def generate_input(shape, op_type):
            # elementwise_floordiv is integer only
            if op_type == "elementwise_floordiv":
                return np.random.randint(
                    low=1, high=10000, size=shape, dtype=np.int32
                )
            elif op_type == "elementwise_mod":
                return np.random.uniform(low=0.1, high=1.0, size=shape).astype(np.float32)
            else:
                return np.random.random(shape).astype(np.float32)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已更新,正常通过单测

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

按照您说的修改后 coverage ci 还是无法通过

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_input或者generate_weight

看着还是有精度diff 是不是所有的generate_input或者generate_weight都需要修改,可以本地环境验证下(CUDA 10.2, TensorRT 7.2.3.4)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看着还是有精度diff 是不是所有的generate_input或者generate_weight都需要修改,可以本地环境验证下(CUDA 10.2, TensorRT 7.2.3.4)

本地 cuda11.7 tensorrt 8.4 的环境可以吗

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看着还是有精度diff 是不是所有的generate_input或者generate_weight都需要修改,可以本地环境验证下(CUDA 10.2, TensorRT 7.2.3.4)

本地 cuda11.7 tensorrt 8.4 的环境可以吗

11.7可以作为辅助 建议在https://hub.docker.com/r/paddlepaddle/paddle下拉取10.2环境,当前未通过ci是10.2

Copy link
Contributor Author

@AndSonder AndSonder Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

现在本地的单测已经不报错了,线上的也没有出现上面的精度问题,但是报了一个本地没有出现过的错误

]:
self.op_type = op_type
for axis in [-1 if len(shape) == 1 else 1]:
Expand Down Expand Up @@ -840,8 +886,8 @@ def generate_dynamic_shape(attrs):
# The input.dims[1] must be equal to the weight's length.
if self.dims == 1:
self.dynamic_shape.min_input_shape = {"input_data": [4]}
self.dynamic_shape.max_input_shape = {"input_data": [256]}
self.dynamic_shape.opt_input_shape = {"input_data": [16]}
self.dynamic_shape.max_input_shape = {"input_data": [64]}
self.dynamic_shape.opt_input_shape = {"input_data": [32]}
elif self.dims == 2:
self.dynamic_shape.min_input_shape = {"input_data": [1, 32]}
self.dynamic_shape.max_input_shape = {"input_data": [4, 32]}
Expand Down