Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
9 changes: 8 additions & 1 deletion lite/core/optimizer/mir/fusion/quant_dequant_op_fuser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,15 @@ void QuantDequantOpFuser::InsertNewNode(SSAGraph* graph,
auto op_info = *quantized_node->stmt()->op_info();
op_info.UpdateAllInputs(output_var_name, input_var_name);
op_info.SetAttr<int>("bit_length", bit_length);

#ifndef LITE_WITH_FPGA
op_info.SetAttr("enable_int8", true);
std::vector<std::string> input_activation_quant_op = {"matmul"};
Copy link
Collaborator

Choose a reason for hiding this comment

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

这个放在头文件,作为私有成员变量使用

std::string op_type = op_info.Type();
if (std::find(input_activation_quant_op.begin(),
input_activation_quant_op.end(),
op_type) != input_activation_quant_op.end()) {
op_info.SetAttr("enable_int8", true);
}
#endif

if (input_var_is_activation) {
Expand Down
13 changes: 10 additions & 3 deletions lite/kernels/arm/mul_compute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,16 @@ void MulCompute<PRECISION(kInt8), PRECISION(kFloat)>::Run() {

scale_.resize(n_);
scale_one.resize(m_);
for (int i = 0; i < n_; i++) {
param.output_scale = param.input_scale * param.weight_scale[i];
scale_[i] = param.output_scale;
if (param.weight_scale.size() == 1) {
param.output_scale = param.input_scale * param.weight_scale[0];
for (int i = 0; i < n_; i++) {
scale_[i] = param.output_scale;
}
} else {
for (int i = 0; i < n_; i++) {
param.output_scale = param.input_scale * param.weight_scale[i];
scale_[i] = param.output_scale;
}
}
for (int i = 0; i < m_; i++) {
scale_one[i] = 1;
Expand Down
1 change: 1 addition & 0 deletions lite/tests/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ if(LITE_WITH_ARM)
lite_cc_test_with_model_and_data(test_squeezenet_fp32_arm MODEL squeezenet DATA ILSVRC2012_500)
lite_cc_test_with_model_and_data(test_transformer_with_mask_fp32_arm MODEL transformer_with_mask_fp32)
lite_cc_test_with_model_and_data(test_mobilenet_v1_int8_arm MODEL mobilenet_v1_int8_for_arm DATA ILSVRC2012_500)
lite_cc_test_with_model_and_data(test_mobilenet_v1_int8_per_layer_arm MODEL mobilenet_v1_int8_per_layer DATA ILSVRC2012_500)
lite_cc_test_with_model_and_data(test_mobilenet_v2_int8_arm MODEL mobilenet_v2_int8_for_arm DATA ILSVRC2012_500)
lite_cc_test_with_model_and_data(test_resnet50_int8_arm MODEL resnet50_int8_for_arm DATA ILSVRC2012_500)
lite_cc_test_with_model_and_data(test_ocr_lstm_int8_arm MODEL ocr_rec_quant_mul_lstm_for_arm DATA ocr_rec_img_txt)
Expand Down
110 changes: 110 additions & 0 deletions lite/tests/api/test_mobilenet_v1_int8_per_layer_arm.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright (c) 2019 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.

#include <gflags/gflags.h>
#include <gtest/gtest.h>
#include <vector>
#include "lite/api/paddle_api.h"
#include "lite/api/test/lite_api_test_helper.h"
#include "lite/api/test/test_helper.h"
#include "lite/tests/api/ILSVRC2012_utility.h"
#include "lite/utils/log/cp_logging.h"

DEFINE_string(data_dir, "", "data dir");
DEFINE_int32(iteration, 100, "iteration times to run");
DEFINE_int32(batch, 1, "batch of image");
DEFINE_int32(channel, 3, "image channel");

namespace paddle {
namespace lite {

TEST(MobileNetV1, test_mobilenet_v1_int8_per_layer_arm) {
std::shared_ptr<paddle::lite_api::PaddlePredictor> predictor = nullptr;
// Use the full api with CxxConfig to generate the optimized model
lite_api::CxxConfig cxx_config;
cxx_config.set_model_dir(FLAGS_model_dir);
cxx_config.set_valid_places(
{lite_api::Place{TARGET(kARM), PRECISION(kFloat)},
lite_api::Place{TARGET(kARM), PRECISION(kInt8)}});
predictor = lite_api::CreatePaddlePredictor(cxx_config);
predictor->SaveOptimizedModel(FLAGS_model_dir,
paddle::lite_api::LiteModelType::kNaiveBuffer);
// Use the light api with MobileConfig to load and run the optimized model
paddle::lite_api::MobileConfig mobile_config;
mobile_config.set_model_from_file(FLAGS_model_dir + ".nb");
mobile_config.set_threads(FLAGS_threads);
mobile_config.set_power_mode(
static_cast<lite_api::PowerMode>(FLAGS_power_mode));
predictor = paddle::lite_api::CreatePaddlePredictor(mobile_config);

std::string raw_data_dir = FLAGS_data_dir + std::string("/raw_data");
std::vector<int> input_shape{
FLAGS_batch, FLAGS_channel, FLAGS_im_width, FLAGS_im_height};
auto raw_data = ReadRawData(raw_data_dir, input_shape, FLAGS_iteration);

int input_size = 1;
for (auto i : input_shape) {
input_size *= i;
}

for (int i = 0; i < FLAGS_warmup; ++i) {
auto input_tensor = predictor->GetInput(0);
input_tensor->Resize(
std::vector<int64_t>(input_shape.begin(), input_shape.end()));
auto* data = input_tensor->mutable_data<float>();
for (int j = 0; j < input_size; j++) {
data[j] = 0.f;
}
predictor->Run();
}

std::vector<std::vector<float>> out_rets;
out_rets.resize(FLAGS_iteration);
double cost_time = 0;
for (size_t i = 0; i < raw_data.size(); ++i) {
auto input_tensor = predictor->GetInput(0);
input_tensor->Resize(
std::vector<int64_t>(input_shape.begin(), input_shape.end()));
auto* data = input_tensor->mutable_data<float>();
memcpy(data, raw_data[i].data(), sizeof(float) * input_size);

double start = GetCurrentUS();
predictor->Run();
cost_time += GetCurrentUS() - start;

auto output_tensor = predictor->GetOutput(0);
auto output_shape = output_tensor->shape();
auto output_data = output_tensor->data<float>();
ASSERT_EQ(output_shape.size(), 2UL);
ASSERT_EQ(output_shape[0], 1);
ASSERT_EQ(output_shape[1], 1000);

int output_size = output_shape[0] * output_shape[1];
out_rets[i].resize(output_size);
memcpy(&(out_rets[i].at(0)), output_data, sizeof(float) * output_size);
}

LOG(INFO) << "================== Speed Report ===================";
LOG(INFO) << "Model: " << FLAGS_model_dir << ", threads num " << FLAGS_threads
<< ", warmup: " << FLAGS_warmup << ", batch: " << FLAGS_batch
<< ", iteration: " << FLAGS_iteration << ", spend "
<< cost_time / FLAGS_iteration / 1000.0 << " ms in average.";

std::string labels_dir = FLAGS_data_dir + std::string("/labels.txt");
float out_accuracy = CalOutAccuracy(out_rets, labels_dir);
ASSERT_GE(out_accuracy, 0.55f);
}

} // namespace lite
} // namespace paddle
2 changes: 1 addition & 1 deletion tools/ci_tools/ci_android_unit_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ skip_list=("test_model_parser" "test_mobilenetv1" "test_mobilenetv2" \
"test_resnet50" "test_inceptionv4" "test_light_api" "test_apis" \
"test_paddle_api" "test_cxx_api" "test_gen_code" \
"test_mobilenetv1_int8" "test_subgraph_pass" \
"test_transformer_with_mask_fp32_arm" \
"test_transformer_with_mask_fp32_arm" "test_mobilenet_v1_int8_per_layer_arm" \
"test_mobilenetv1_int16" "test_mobilenetv1_opt_quant" \
"test_fast_rcnn" "test_inception_v4_fp32_arm" "test_mobilenet_v1_fp32_arm" \
"test_mobilenet_v2_fp32_arm" "test_mobilenet_v3_small_x1_0_fp32_arm" \
Expand Down