-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[Frontend][TFlite] Add parser support for relu6, leaky_relu, relu_n1_to_1, log_softmax #4805
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Relu and Clip implementation does not look right.
We can keep the computation in integer domain. The way to do that is to subtract the input zero point, and then call Relu, then requantize to the output scale (only if output scale/zero point are different from input scale/zero point).
return out | ||
|
||
def convert_leaky_relu(self, op): | ||
"""Convert TFLite LEAKY_RELU""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not important, I think it should be """Convert TFLite Leaky_ReLU"""
to align with """One iteration of Leaky_ReLU"""
.
return out | ||
|
||
def convert_relu_n1_to_1(self, op): | ||
"""Convert TFLite RELU_N1_TO_1""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not important, I think it should be """Convert TFLite ReLU_n1_to_1"""
to align with """One iteration of ReLU_n1_to_1"""
.
@inadob please followup to address the review comments :) |
That's fine for the standard ReLU op but I am not entirely sure whether we can follow this logic when we apply ReLU6 and ReLU1. Is there a way to recreate them in Relay without clip?. What I did, in this case, was to shift the data by subtracting the zero point, do clip, shift back and finally requantize if needed. The problem here was that |
Can you show me code example here? I have typically used float numbers like 1.0 or 6.0 to work with |
Expr ClipQnnCanonicalize(const Attrs& attrs, const Array<Expr>& new_args,
const Array<tvm::relay::Type>& arg_types) {
CHECK_EQ(new_args.size(), 7);
auto& input_tensor = new_args[0];
auto& input_scale = new_args[1]; // in fp
auto& input_zero_point = new_args[2]; // in int32
auto& clip_min = new_args[3]; // value is in fp
auto& clip_max = new_args[4]; // value is in fp
auto& output_scale = new_args[5];
auto& output_zero_point = new_args[6];
// Get the input dtype and shape.
CHECK_EQ(arg_types.size(), 8);
auto tensor_type = arg_types[0].as<TensorTypeNode>();
CHECK(tensor_type != nullptr);
auto input_dtype = tensor_type->dtype;
auto input_shape = tensor_type->shape;
// shift the input by subtracting the input zero_point
auto shifted_input = Subtract(Cast(input_tensor, DataType::Int(32)), input_zero_point);
// do the clipping in int32
// auto clipped_tensor = Clip(shifted_input, clip_min, clip_max)
auto clipped_tensor = Clip(shifted_input, Cast(clip_min, DataType::Float(64)), Cast(clip_max, DataType::Float(64)))
// shift the input back by adding the zero_point
clipped_tensor = Add(clipped_tensor, input_zero_point);
// requantize the output if needed
auto requantized_output = clipped_tensor;
if (!IsEqualScalar(input_scale, output_scale) ||
!IsEqualScalar(input_zero_point, output_zero_point)) {
requantized_output = Requantize(clipped_tensor, input_shape, input_scale, input_zero_point, output_scale,
output_zero_point, DataType::Int(32));
}
// Go back to lower precision.
auto q_min = GetQmin(input_dtype);
auto q_max = GetQmax(input_dtype);
requantized_output = Clip(requantized_output, q_min, q_max);
return Cast(requantized_output, input_dtype);
} And I am getting a complaint about double dtype...
The commented out line where I directly do clip() without casting to float64 didn't work too. |
@anijain2305 @inadob please followup :) |
ping |
@anijain can you please help me with the quantized operators |
Ping @inadob Let us know if you are working on this. Or else I can take a chance at this. |
@anijain2305 Yes, I am working on it - I will be ready in the next few days. Sorry for the delay |
@inadob Your changes look better now. Can you please rebase? ( |
It seems you still have old `3rdparty/dmlc-core'. You can check that by clicking on "Files changed" tab. |
It's fixed now. |
@inadob Can you please fix the CI error? |
Ping @inadob :) |
Glad that it is moving, @anijain2305 please manage this PR |
…g_softmax * add implementation in parser * add qnn tests for each operator
* add 'clip' as in the quantized fused operations * remove redundant assertions and imports
4781b9e
to
126361c
Compare
@anijain2305 |
Thanks @inadob This is merged! |
…to_1, log_softmax (apache#4805) * [Frontend][TFLite]Add support for relu6, leaky_relu, relu_n1_to_1, log_softmax * add implementation in parser * add qnn tests for each operator * Implement clip operation for quantized relu6, relu1 * add 'clip' as in the quantized fused operations * remove redundant assertions and imports * Fix floating value quantization for RELU6 and RELU1
…to_1, log_softmax (apache#4805) * [Frontend][TFLite]Add support for relu6, leaky_relu, relu_n1_to_1, log_softmax * add implementation in parser * add qnn tests for each operator * Implement clip operation for quantized relu6, relu1 * add 'clip' as in the quantized fused operations * remove redundant assertions and imports * Fix floating value quantization for RELU6 and RELU1
This patch is made on top of #4789.