Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
s920243400
PaddleOCR
提交
9be9fe8d
P
PaddleOCR
项目概览
s920243400
/
PaddleOCR
与 Fork 源项目一致
Fork自
PaddlePaddle / PaddleOCR
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleOCR
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9be9fe8d
编写于
10月 27, 2021
作者:
L
LDOUBLEV
浏览文件
操作
浏览文件
下载
差异文件
fix conflict
上级
cd55737d
e84b4a32
变更
9
显示空白变更内容
内联
并排
Showing
9 changed file
with
416 addition
and
154 deletion
+416
-154
deploy/lite/ocr_db_crnn.cc
deploy/lite/ocr_db_crnn.cc
+266
-42
test_tipc/configs/ppocr_det_mobile_params.txt
test_tipc/configs/ppocr_det_mobile_params.txt
+10
-0
test_tipc/docs/install.md
test_tipc/docs/install.md
+6
-81
test_tipc/docs/test_inference_cpp.md
test_tipc/docs/test_inference_cpp.md
+7
-7
test_tipc/docs/test_serving.md
test_tipc/docs/test_serving.md
+5
-5
test_tipc/docs/test_train_inference_python.md
test_tipc/docs/test_train_inference_python.md
+15
-15
test_tipc/prepare.sh
test_tipc/prepare.sh
+35
-1
test_tipc/readme.md
test_tipc/readme.md
+3
-3
test_tipc/test_lite.sh
test_tipc/test_lite.sh
+69
-0
未找到文件。
deploy/lite/ocr_db_crnn.cc
浏览文件 @
9be9fe8d
...
...
@@ -12,12 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "paddle_api.h" // NOLINT
#include <chrono>
#include "paddle_api.h" // NOLINT
#include "paddle_place.h"
#include "cls_process.h"
#include "crnn_process.h"
#include "db_post_process.h"
#include "AutoLog/auto_log/lite_autolog.h"
using
namespace
paddle
::
lite_api
;
// NOLINT
using
namespace
std
;
...
...
@@ -27,7 +29,7 @@ void NeonMeanScale(const float *din, float *dout, int size,
const
std
::
vector
<
float
>
mean
,
const
std
::
vector
<
float
>
scale
)
{
if
(
mean
.
size
()
!=
3
||
scale
.
size
()
!=
3
)
{
std
::
cerr
<<
"[ERROR] mean or scale size must equal to 3
\n
"
;
std
::
cerr
<<
"[ERROR] mean or scale size must equal to 3
"
<<
std
::
endl
;
exit
(
1
);
}
float32x4_t
vmean0
=
vdupq_n_f32
(
mean
[
0
]);
...
...
@@ -159,7 +161,8 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
std
::
vector
<
float
>
&
rec_text_score
,
std
::
vector
<
std
::
string
>
charactor_dict
,
std
::
shared_ptr
<
PaddlePredictor
>
predictor_cls
,
int
use_direction_classify
)
{
int
use_direction_classify
,
std
::
vector
<
double
>
*
times
)
{
std
::
vector
<
float
>
mean
=
{
0.5
f
,
0.5
f
,
0.5
f
};
std
::
vector
<
float
>
scale
=
{
1
/
0.5
f
,
1
/
0.5
f
,
1
/
0.5
f
};
...
...
@@ -226,7 +229,7 @@ void RunRecModel(std::vector<std::vector<std::vector<int>>> boxes, cv::Mat img,
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
RunDetModel
(
std
::
shared_ptr
<
PaddlePredictor
>
predictor
,
cv
::
Mat
img
,
std
::
map
<
std
::
string
,
double
>
Config
)
{
std
::
map
<
std
::
string
,
double
>
Config
,
std
::
vector
<
double
>
*
times
)
{
// Read img
int
max_side_len
=
int
(
Config
[
"max_side_len"
]);
int
det_db_use_dilate
=
int
(
Config
[
"det_db_use_dilate"
]);
...
...
@@ -234,6 +237,7 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
cv
::
Mat
srcimg
;
img
.
copyTo
(
srcimg
);
auto
preprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
std
::
vector
<
float
>
ratio_hw
;
img
=
DetResizeImg
(
img
,
max_side_len
,
ratio_hw
);
cv
::
Mat
img_fp
;
...
...
@@ -248,8 +252,10 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
std
::
vector
<
float
>
scale
=
{
1
/
0.229
f
,
1
/
0.224
f
,
1
/
0.225
f
};
const
float
*
dimg
=
reinterpret_cast
<
const
float
*>
(
img_fp
.
data
);
NeonMeanScale
(
dimg
,
data0
,
img_fp
.
rows
*
img_fp
.
cols
,
mean
,
scale
);
auto
preprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
// Run predictor
auto
inference_start
=
std
::
chrono
::
steady_clock
::
now
();
predictor
->
Run
();
// Get output and post process
...
...
@@ -257,8 +263,10 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
std
::
move
(
predictor
->
GetOutput
(
0
)));
auto
*
outptr
=
output_tensor
->
data
<
float
>
();
auto
shape_out
=
output_tensor
->
shape
();
auto
inference_end
=
std
::
chrono
::
steady_clock
::
now
();
// Save output
auto
postprocess_start
=
std
::
chrono
::
steady_clock
::
now
();
float
pred
[
shape_out
[
2
]
*
shape_out
[
3
]];
unsigned
char
cbuf
[
shape_out
[
2
]
*
shape_out
[
3
]];
...
...
@@ -287,14 +295,35 @@ RunDetModel(std::shared_ptr<PaddlePredictor> predictor, cv::Mat img,
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
filter_boxes
=
FilterTagDetRes
(
boxes
,
ratio_hw
[
0
],
ratio_hw
[
1
],
srcimg
);
auto
postprocess_end
=
std
::
chrono
::
steady_clock
::
now
();
std
::
chrono
::
duration
<
float
>
preprocess_diff
=
preprocess_end
-
preprocess_start
;
times
->
push_back
(
double
(
preprocess_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
inference_diff
=
inference_end
-
inference_start
;
times
->
push_back
(
double
(
inference_diff
.
count
()
*
1000
));
std
::
chrono
::
duration
<
float
>
postprocess_diff
=
postprocess_end
-
postprocess_start
;
times
->
push_back
(
double
(
postprocess_diff
.
count
()
*
1000
));
return
filter_boxes
;
}
std
::
shared_ptr
<
PaddlePredictor
>
loadModel
(
std
::
string
model_file
)
{
std
::
shared_ptr
<
PaddlePredictor
>
loadModel
(
std
::
string
model_file
,
std
::
string
power_mode
,
int
num_threads
)
{
MobileConfig
config
;
config
.
set_model_from_file
(
model_file
);
if
(
power_mode
==
"LITE_POWER_HIGH"
){
config
.
set_power_mode
(
LITE_POWER_HIGH
);
}
else
{
if
(
power_mode
==
"LITE_POWER_LOW"
)
{
config
.
set_power_mode
(
LITE_POWER_HIGH
);
}
else
{
std
::
cerr
<<
"Only support LITE_POWER_HIGH or LITE_POWER_HIGH."
<<
std
::
endl
;
exit
(
1
);
}
}
config
.
set_threads
(
num_threads
);
std
::
shared_ptr
<
PaddlePredictor
>
predictor
=
CreatePaddlePredictor
<
MobileConfig
>
(
config
);
return
predictor
;
...
...
@@ -354,60 +383,255 @@ std::map<std::string, double> LoadConfigTxt(std::string config_path) {
return
dict
;
}
int
main
(
int
argc
,
char
**
argv
)
{
if
(
argc
<
5
)
{
std
::
cerr
<<
"[ERROR] usage: "
<<
argv
[
0
]
<<
" det_model_file cls_model_file rec_model_file image_path "
"charactor_dict
\n
"
;
void
check_params
(
int
argc
,
char
**
argv
)
{
if
(
argc
<=
1
||
(
strcmp
(
argv
[
1
],
"det"
)
!=
0
&&
strcmp
(
argv
[
1
],
"rec"
)
!=
0
&&
strcmp
(
argv
[
1
],
"system"
)
!=
0
))
{
std
::
cerr
<<
"Please choose one mode of [det, rec, system] !"
<<
std
::
endl
;
exit
(
1
);
}
std
::
string
det_model_file
=
argv
[
1
];
std
::
string
rec_model_file
=
argv
[
2
];
std
::
string
cls_model_file
=
argv
[
3
];
std
::
string
img_path
=
argv
[
4
];
std
::
string
dict_path
=
argv
[
5
];
if
(
strcmp
(
argv
[
1
],
"det"
)
==
0
)
{
if
(
argc
<
9
){
std
::
cerr
<<
"[ERROR] usage:"
<<
argv
[
0
]
<<
" det det_model num_threads batchsize power_mode img_dir det_config lite_benchmark_value"
<<
std
::
endl
;
exit
(
1
);
}
}
//// load config from txt file
auto
Config
=
LoadConfigTxt
(
"./config.txt"
);
int
use_direction_classify
=
int
(
Config
[
"use_direction_classify"
]);
if
(
strcmp
(
argv
[
1
],
"rec"
)
==
0
)
{
if
(
argc
<
9
){
std
::
cerr
<<
"[ERROR] usage:"
<<
argv
[
0
]
<<
" rec rec_model num_threads batchsize power_mode img_dir key_txt lite_benchmark_value"
<<
std
::
endl
;
exit
(
1
);
}
}
if
(
strcmp
(
argv
[
1
],
"system"
)
==
0
)
{
if
(
argc
<
12
){
std
::
cerr
<<
"[ERROR] usage:"
<<
argv
[
0
]
<<
" system det_model rec_model clas_model num_threads batchsize power_mode img_dir det_config key_txt lite_benchmark_value"
<<
std
::
endl
;
exit
(
1
);
}
}
}
void
system
(
char
**
argv
){
std
::
string
det_model_file
=
argv
[
2
];
std
::
string
rec_model_file
=
argv
[
3
];
std
::
string
cls_model_file
=
argv
[
4
];
std
::
string
precision
=
argv
[
5
];
std
::
string
num_threads
=
argv
[
6
];
std
::
string
batchsize
=
argv
[
7
];
std
::
string
power_mode
=
argv
[
8
];
std
::
string
img_dir
=
argv
[
9
];
std
::
string
det_config_path
=
argv
[
10
];
std
::
string
dict_path
=
argv
[
11
];
if
(
strcmp
(
argv
[
5
],
"FP32"
)
!=
0
&&
strcmp
(
argv
[
5
],
"INT8"
)
!=
0
)
{
std
::
cerr
<<
"Only support FP32 or INT8."
<<
std
::
endl
;
exit
(
1
);
}
auto
start
=
std
::
chrono
::
system_clock
::
now
();
std
::
vector
<
cv
::
String
>
cv_all_img_names
;
cv
::
glob
(
img_dir
,
cv_all_img_names
);
auto
det_predictor
=
loadModel
(
det_model_file
);
auto
rec_predictor
=
loadModel
(
rec_model_file
);
auto
cls_predictor
=
loadModel
(
cls_model_file
);
//// load config from txt file
auto
Config
=
LoadConfigTxt
(
det_config_path
);
int
use_direction_classify
=
int
(
Config
[
"use_direction_classify"
]
);
auto
charactor_dict
=
ReadDict
(
dict_path
);
charactor_dict
.
insert
(
charactor_dict
.
begin
(),
"#"
);
// blank char for ctc
charactor_dict
.
push_back
(
" "
);
cv
::
Mat
srcimg
=
cv
::
imread
(
img_path
,
cv
::
IMREAD_COLOR
);
auto
boxes
=
RunDetModel
(
det_predictor
,
srcimg
,
Config
);
auto
det_predictor
=
loadModel
(
det_model_file
,
power_mode
,
std
::
stoi
(
num_threads
));
auto
rec_predictor
=
loadModel
(
rec_model_file
,
power_mode
,
std
::
stoi
(
num_threads
));
auto
cls_predictor
=
loadModel
(
cls_model_file
,
power_mode
,
std
::
stoi
(
num_threads
));
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
std
::
cout
<<
"The predict img: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
cv
::
Mat
srcimg
=
cv
::
imread
(
cv_all_img_names
[
i
],
cv
::
IMREAD_COLOR
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
double
>
det_times
;
auto
boxes
=
RunDetModel
(
det_predictor
,
srcimg
,
Config
,
&
det_times
);
std
::
vector
<
std
::
string
>
rec_text
;
std
::
vector
<
float
>
rec_text_score
;
std
::
vector
<
double
>
rec_times
;
RunRecModel
(
boxes
,
srcimg
,
rec_predictor
,
rec_text
,
rec_text_score
,
charactor_dict
,
cls_predictor
,
use_direction_classify
);
charactor_dict
,
cls_predictor
,
use_direction_classify
,
&
rec_times
);
auto
end
=
std
::
chrono
::
system_clock
::
now
();
auto
duration
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
microseconds
>
(
end
-
start
);
//// visualization
auto
img_vis
=
Visualization
(
srcimg
,
boxes
);
//// print recognized text
for
(
int
i
=
0
;
i
<
rec_text
.
size
();
i
++
)
{
std
::
cout
<<
i
<<
"
\t
"
<<
rec_text
[
i
]
<<
"
\t
"
<<
rec_text_score
[
i
]
<<
std
::
endl
;
}
}
}
void
det
(
int
argc
,
char
**
argv
)
{
std
::
string
det_model_file
=
argv
[
2
];
std
::
string
precision
=
argv
[
3
];
std
::
string
num_threads
=
argv
[
4
];
std
::
string
batchsize
=
argv
[
5
];
std
::
string
power_mode
=
argv
[
6
];
std
::
string
img_dir
=
argv
[
7
];
std
::
string
det_config_path
=
argv
[
8
];
if
(
strcmp
(
argv
[
3
],
"FP32"
)
!=
0
&&
strcmp
(
argv
[
3
],
"INT8"
)
!=
0
)
{
std
::
cerr
<<
"Only support FP32 or INT8."
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
cv
::
String
>
cv_all_img_names
;
cv
::
glob
(
img_dir
,
cv_all_img_names
);
//// load config from txt file
auto
Config
=
LoadConfigTxt
(
det_config_path
);
auto
det_predictor
=
loadModel
(
det_model_file
,
power_mode
,
std
::
stoi
(
num_threads
));
std
::
vector
<
double
>
time_info
=
{
0
,
0
,
0
};
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
std
::
cout
<<
"The predict img: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
cv
::
Mat
srcimg
=
cv
::
imread
(
cv_all_img_names
[
i
],
cv
::
IMREAD_COLOR
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
double
>
times
;
auto
boxes
=
RunDetModel
(
det_predictor
,
srcimg
,
Config
,
&
times
);
//// visualization
auto
img_vis
=
Visualization
(
srcimg
,
boxes
);
std
::
cout
<<
boxes
.
size
()
<<
" bboxes have detected:"
<<
std
::
endl
;
// for (int i=0; i<boxes.size(); i++){
// std::cout << "The " << i << " box:" << std::endl;
// for (int j=0; j<4; j++){
// for (int k=0; k<2; k++){
// std::cout << boxes[i][j][k] << "\t";
// }
// }
// std::cout << std::endl;
// }
time_info
[
0
]
+=
times
[
0
];
time_info
[
1
]
+=
times
[
1
];
time_info
[
2
]
+=
times
[
2
];
}
if
(
strcmp
(
argv
[
9
],
"True"
)
==
0
)
{
AutoLogger
autolog
(
det_model_file
,
0
,
0
,
0
,
std
::
stoi
(
num_threads
),
std
::
stoi
(
batchsize
),
"dynamic"
,
precision
,
power_mode
,
time_info
,
cv_all_img_names
.
size
());
autolog
.
report
();
}
}
void
rec
(
int
argc
,
char
**
argv
)
{
std
::
string
rec_model_file
=
argv
[
2
];
std
::
string
precision
=
argv
[
3
];
std
::
string
num_threads
=
argv
[
4
];
std
::
string
batchsize
=
argv
[
5
];
std
::
string
power_mode
=
argv
[
6
];
std
::
string
img_dir
=
argv
[
7
];
std
::
string
dict_path
=
argv
[
8
];
if
(
strcmp
(
argv
[
3
],
"FP32"
)
!=
0
&&
strcmp
(
argv
[
3
],
"INT8"
)
!=
0
)
{
std
::
cerr
<<
"Only support FP32 or INT8."
<<
std
::
endl
;
exit
(
1
);
}
std
::
vector
<
cv
::
String
>
cv_all_img_names
;
cv
::
glob
(
img_dir
,
cv_all_img_names
);
auto
charactor_dict
=
ReadDict
(
dict_path
);
charactor_dict
.
insert
(
charactor_dict
.
begin
(),
"#"
);
// blank char for ctc
charactor_dict
.
push_back
(
" "
);
auto
rec_predictor
=
loadModel
(
rec_model_file
,
power_mode
,
std
::
stoi
(
num_threads
));
std
::
shared_ptr
<
PaddlePredictor
>
cls_predictor
;
std
::
vector
<
double
>
time_info
=
{
0
,
0
,
0
};
for
(
int
i
=
0
;
i
<
cv_all_img_names
.
size
();
++
i
)
{
std
::
cout
<<
"The predict img: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
cv
::
Mat
srcimg
=
cv
::
imread
(
cv_all_img_names
[
i
],
cv
::
IMREAD_COLOR
);
if
(
!
srcimg
.
data
)
{
std
::
cerr
<<
"[ERROR] image read failed! image path: "
<<
cv_all_img_names
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
int
width
=
srcimg
.
cols
;
int
height
=
srcimg
.
rows
;
std
::
vector
<
int
>
upper_left
=
{
0
,
0
};
std
::
vector
<
int
>
upper_right
=
{
width
,
0
};
std
::
vector
<
int
>
lower_right
=
{
width
,
height
};
std
::
vector
<
int
>
lower_left
=
{
0
,
height
};
std
::
vector
<
std
::
vector
<
int
>>
box
=
{
upper_left
,
upper_right
,
lower_right
,
lower_left
};
std
::
vector
<
std
::
vector
<
std
::
vector
<
int
>>>
boxes
=
{
box
};
std
::
vector
<
std
::
string
>
rec_text
;
std
::
vector
<
float
>
rec_text_score
;
std
::
vector
<
double
>
times
;
RunRecModel
(
boxes
,
srcimg
,
rec_predictor
,
rec_text
,
rec_text_score
,
charactor_dict
,
cls_predictor
,
0
,
&
times
);
//// print recognized text
for
(
int
i
=
0
;
i
<
rec_text
.
size
();
i
++
)
{
std
::
cout
<<
i
<<
"
\t
"
<<
rec_text
[
i
]
<<
"
\t
"
<<
rec_text_score
[
i
]
<<
std
::
endl
;
}
}
// TODO: support autolog
if
(
strcmp
(
argv
[
9
],
"True"
)
==
0
)
{
AutoLogger
autolog
(
rec_model_file
,
0
,
0
,
0
,
std
::
stoi
(
num_threads
),
std
::
stoi
(
batchsize
),
"dynamic"
,
precision
,
power_mode
,
time_info
,
cv_all_img_names
.
size
());
autolog
.
report
();
}
}
int
main
(
int
argc
,
char
**
argv
)
{
check_params
(
argc
,
argv
);
std
::
cout
<<
"mode: "
<<
argv
[
1
]
<<
endl
;
std
::
cout
<<
"花费了"
<<
double
(
duration
.
count
())
*
std
::
chrono
::
microseconds
::
period
::
num
/
std
::
chrono
::
microseconds
::
period
::
den
<<
"秒"
<<
std
::
endl
;
if
(
strcmp
(
argv
[
1
],
"system"
)
==
0
)
{
system
(
argv
);
}
if
(
strcmp
(
argv
[
1
],
"det"
)
==
0
)
{
det
(
argc
,
argv
);
}
if
(
strcmp
(
argv
[
1
],
"rec"
)
==
0
)
{
rec
(
argc
,
argv
);
}
return
0
;
}
test_tipc/configs/ppocr_det_mobile_params.txt
浏览文件 @
9be9fe8d
...
...
@@ -98,3 +98,13 @@ null:null
--benchmark:True
null:null
null:null
===========================lite_params===========================
inference:./ocr_db_crnn det
infer_model:./models/ch_ppocr_mobile_v2.0_det_opt.nb|./models/ch_ppocr_mobile_v2.0_det_slim_opt.nb
--cpu_threads:1|4
--batch_size:1
--power_mode:LITE_POWER_HIGH|LITE_POWER_LOW
--image_dir:./test_data/icdar2015_lite/text_localization/ch4_test_images/|./test_data/icdar2015_lite/text_localization/ch4_test_images/img_233.jpg
--config_dir:./config.txt
--rec_dict_dir:./ppocr_keys_v1.txt
--benchmark:True
test_tipc/docs/install.md
浏览文件 @
9be9fe8d
##
1. 环境准备
##
环境配置
本教程适用于PTDN目录下基础功能测试的运行环境搭建。
推荐环境:
-
CUDA 10.1
/10.2
-
CUDNN 7.6
/cudnn8.1
-
TensorRT 6.1.0.5 / 7.1
/ 7.2
-
CUDA 10.1
-
CUDNN 7.6
-
TensorRT 6.1.0.5 / 7.1
环境配置可以选择docker镜像安装,或者在本地环境Python搭建环境。推荐使用docker镜像安装,避免不必要的环境配置。
## 2. Docker 镜像安装
推荐docker镜像安装,按照如下命令创建镜像,当前目录映射到镜像中的
`/paddle`
目录下
```
...
...
@@ -19,80 +16,7 @@ cd /paddle
# 安装带TRT的paddle
pip3.7 install https://paddle-wheel.bj.bcebos.com/with-trt/2.1.3/linux-gpu-cuda10.1-cudnn7-mkl-gcc8.2-trt6-avx/paddlepaddle_gpu-2.1.3.post101-cp37-cp37m-linux_x86_64.whl
```
## 3 Python 环境构建
非docker环境下,环境配置比较灵活,推荐环境组合配置:
-
CUDA10.1 + CUDNN7.6 + TensorRT 6
-
CUDA10.2 + CUDNN8.1 + TensorRT 7
-
CUDA11.1 + CUDNN8.1 + TensorRT 7
下面以 CUDA10.2 + CUDNN8.1 + TensorRT 7 配置为例,介绍环境配置的流程。
### 3.1 安装CUDNN
如果当前环境满足CUDNN版本的要求,可以跳过此步骤。
以CUDNN8.1 安装安装为例,安装步骤如下,首先下载CUDNN,从
[
Nvidia官网
](
https://developer.nvidia.com/rdp/cudnn-archive
)
下载CUDNN8.1版本,下载符合当前系统版本的三个deb文件,分别是:
-
cuDNN Runtime Library ,如:libcudnn8_8.1.0.77-1+cuda10.2_amd64.deb
-
cuDNN Developer Library ,如:libcudnn8-dev_8.1.0.77-1+cuda10.2_amd64.deb
-
cuDNN Code Samples,如:libcudnn8-samples_8.1.0.77-1+cuda10.2_amd64.deb
deb安装可以参考
[
官方文档
](
https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#installlinux-deb
)
,安装方式如下
```
# x.x.x表示下载的版本号
# $HOME为工作目录
sudo dpkg -i libcudnn8_x.x.x-1+cudax.x_arm64.deb
sudo dpkg -i libcudnn8-dev_8.x.x.x-1+cudax.x_arm64.deb
sudo dpkg -i libcudnn8-samples_8.x.x.x-1+cudax.x_arm64.deb
# 验证是否正确安装
cp -r /usr/src/cudnn_samples_v8/ $HOME
cd $HOME/cudnn_samples_v8/mnistCUDNN
# 编译
make clean && make
./mnistCUDNN
```
如果运行mnistCUDNN完后提示运行成功,则表示安装成功。如果运行后出现freeimage相关的报错,需要按照提示安装freeimage库:
```
sudo apt-get install libfreeimage-dev
sudo apt-get install libfreeimage
```
### 3.2 安装TensorRT
首先,从
[
Nvidia官网TensorRT板块
](
https://developer.nvidia.com/tensorrt-getting-started
)
下载TensorRT,这里选择7.1.3.4版本的TensorRT,注意选择适合自己系统版本和CUDA版本的TensorRT,另外建议下载TAR package的安装包。
以Ubuntu16.04+CUDA10.2为例,下载并解压后可以参考
[
官方文档
](
https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-713/install-guide/index.html#installing-tar
)
的安装步骤,按照如下步骤安装:
```
# 以下安装命令中 '${version}' 为下载的TensorRT版本,如7.1.3.4
# 设置环境变量,<TensorRT-${version}/lib> 为解压后的TensorRT的lib目录
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<TensorRT-${version}/lib>
# 安装TensorRT
cd TensorRT-${version}/python
pip3.7 install tensorrt-*-cp3x-none-linux_x86_64.whl
# 安装graphsurgeon
cd TensorRT-${version}/graphsurgeon
```
### 3.3 安装PaddlePaddle
安装的TensorRT版本需要和Paddle安装包中编译进去的TensorRT版本进行对应,带TensorRT的Paddle安装包可以从
[
链接
](
https://paddleinference.paddlepaddle.org.cn/user_guides/download_lib.html#python
)
下载带TRT的paddle:
这里选择下载 linux-cuda10.2-trt7-gcc8.2 Python3.7版本的Paddle:
```
# 从下载链接中可以看到是paddle2.1.1-cuda10.2-cudnn8.1版本
wget https://paddle-wheel.bj.bcebos.com/with-trt/2.1.1-gpu-cuda10.2-cudnn8.1-mkl-gcc8.2/paddlepaddle_gpu-2.1.1-cp37-cp37m-linux_x86_64.whl
pip3.7 install -U paddlepaddle_gpu-2.1.1-cp37-cp37m-linux_x86_64.whl
```
## 4. 安装PaddleOCR依赖
```
# 安装AutoLog
git clone https://github.com/LDOUBLEV/AutoLog
cd AutoLog
...
...
@@ -100,6 +24,7 @@ pip3.7 install -r requirements.txt
python3.7 setup.py bdist_wheel
pip3.7 install ./dist/auto_log-1.0.0-py3-none-any.whl
# 下载OCR代码
cd ../
git clone https://github.com/PaddlePaddle/PaddleOCR
...
...
@@ -120,4 +45,4 @@ A. 问题一般是当前安装paddle版本带TRT,但是本地环境找不到Te
```
export LD_LIBRARY_PATH=/usr/local/python3.7.0/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/paddle/package/TensorRT-6.0.1.5/lib
```
或者问题是下载的TensorRT版本和当前paddle中编译的TRT版本不匹配,需要下载版本相符的T
ensorRT重新安装
。
或者问题是下载的TensorRT版本和当前paddle中编译的TRT版本不匹配,需要下载版本相符的T
RT
。
test_tipc/docs/test_inference_cpp.md
浏览文件 @
9be9fe8d
...
...
@@ -15,15 +15,15 @@ C++预测功能测试的主程序为`test_inference_cpp.sh`,可以测试基于
## 2. 测试流程
### 2.1 功能测试
先运行
`prepare.sh`
准备数据和模型,然后运行
`test_inference_cpp.sh`
进行测试,最终在
```
PTDN
/output```
目录下生成
`cpp_infer_*.log`
后缀的日志文件。
先运行
`prepare.sh`
准备数据和模型,然后运行
`test_inference_cpp.sh`
进行测试,最终在
```
test_tipc
/output```
目录下生成
`cpp_infer_*.log`
后缀的日志文件。
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
"cpp_infer"
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
"cpp_infer"
# 用法1:
bash
PTDN/test_inference_cpp.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
bash
test_tipc/test_inference_cpp.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
# 用法2: 指定GPU卡预测,第三个传入参数为GPU卡号
bash
PTDN/test_inference_cpp.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'1'
bash
test_tipc/test_inference_cpp.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'1'
```
...
...
@@ -37,12 +37,12 @@ bash PTDN/test_inference_cpp.sh ./PTDN/configs/ppocr_det_mobile_params.txt '1'
#### 使用方式
运行命令:
```
shell
python3.7
PTDN/compare_results.py
--gt_file
=
./PTDN/results/cpp_
*
.txt
--log_file
=
./PTDN
/output/cpp_
*
.log
--atol
=
1e-3
--rtol
=
1e-3
python3.7
test_tipc/compare_results.py
--gt_file
=
./test_tipc/results/cpp_
*
.txt
--log_file
=
./test_tipc
/output/cpp_
*
.log
--atol
=
1e-3
--rtol
=
1e-3
```
参数介绍:
-
gt_file: 指向事先保存好的预测结果路径,支持
*.txt 结尾,会自动索引*
.txt格式的文件,文件默认保存在
PTDN
/result/ 文件夹下
-
log_file: 指向运行
PTDN
/test_inference_cpp.sh 脚本的infer模式保存的预测日志,预测日志中打印的有预测结果,比如:文本框,预测文本,类别等等,同样支持cpp_infer_
*
.log格式传入
-
gt_file: 指向事先保存好的预测结果路径,支持
*.txt 结尾,会自动索引*
.txt格式的文件,文件默认保存在
test_tipc
/result/ 文件夹下
-
log_file: 指向运行
test_tipc
/test_inference_cpp.sh 脚本的infer模式保存的预测日志,预测日志中打印的有预测结果,比如:文本框,预测文本,类别等等,同样支持cpp_infer_
*
.log格式传入
-
atol: 设置的绝对误差
-
rtol: 设置的相对误差
...
...
test_tipc/docs/test_serving.md
浏览文件 @
9be9fe8d
...
...
@@ -15,18 +15,18 @@ PaddleServing预测功能测试的主程序为`test_serving.sh`,可以测试
## 2. 测试流程
### 2.1 功能测试
先运行
`prepare.sh`
准备数据和模型,然后运行
`test_serving.sh`
进行测试,最终在
```
PTDN
/output```
目录下生成
`serving_infer_*.log`
后缀的日志文件。
先运行
`prepare.sh`
准备数据和模型,然后运行
`test_serving.sh`
进行测试,最终在
```
test_tipc
/output```
目录下生成
`serving_infer_*.log`
后缀的日志文件。
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
"serving_infer"
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
"serving_infer"
# 用法:
bash
PTND/test_serving.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
bash
test_tipc/test_serving.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
```
#### 运行结果
各测试的运行情况会打印在
`
PTDN
/output/results_serving.log`
中:
各测试的运行情况会打印在
`
test_tipc
/output/results_serving.log`
中:
运行成功时会输出:
```
...
...
@@ -44,7 +44,7 @@ Run failed with command - xxxxx
...
```
详细的预测结果会存在
PTDN
/output/ 文件夹下,例如
`server_infer_gpu_usetrt_True_precision_fp16_batchsize_1.log`
中会返回检测框的坐标:
详细的预测结果会存在
test_tipc
/output/ 文件夹下,例如
`server_infer_gpu_usetrt_True_precision_fp16_batchsize_1.log`
中会返回检测框的坐标:
```
{'err_no': 0, 'err_msg': '', 'key': ['dt_boxes'], 'value': ['[[[ 78. 642.]\n [409. 640.]\n [409. 657.]\n
...
...
test_tipc/docs/test_train_inference_python.md
浏览文件 @
9be9fe8d
...
...
@@ -46,42 +46,42 @@
### 2.2 功能测试
先运行
`prepare.sh`
准备数据和模型,然后运行
`test_train_inference_python.sh`
进行测试,最终在
```
PTDN
/output```
目录下生成
`python_infer_*.log`
格式的日志文件。
先运行
`prepare.sh`
准备数据和模型,然后运行
`test_train_inference_python.sh`
进行测试,最终在
```
test_tipc
/output```
目录下生成
`python_infer_*.log`
格式的日志文件。
`test_train_inference_python.sh`
包含5种运行模式,每种模式的运行数据不同,分别用于测试速度和精度,分别是:
-
模式1:lite_train_infer,使用少量数据训练,用于快速验证训练到预测的走通流程,不验证精度和速度;
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'lite_train_infer'
bash
PTDN/test_train_inference_python.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'lite_train_infer'
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'lite_train_infer'
bash
test_tipc/test_train_inference_python.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'lite_train_infer'
```
-
模式2:whole_infer,使用少量数据训练,一定量数据预测,用于验证训练后的模型执行预测,预测速度是否合理;
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'whole_infer'
bash
PTDN/test_train_inference_python.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'whole_infer'
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'whole_infer'
bash
test_tipc/test_train_inference_python.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'whole_infer'
```
-
模式3:infer,不训练,全量数据预测,走通开源模型评估、动转静,检查inference model预测时间和精度;
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'infer'
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'infer'
# 用法1:
bash
PTDN/test_train_inference_python.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'infer'
bash
test_tipc/test_train_inference_python.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'infer'
# 用法2: 指定GPU卡预测,第三个传入参数为GPU卡号
bash
PTDN/test_train_inference_python.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'infer'
'1'
bash
test_tipc/test_train_inference_python.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'infer'
'1'
```
-
模式4:whole_train_infer,CE: 全量数据训练,全量数据预测,验证模型训练精度,预测精度,预测速度;
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'whole_train_infer'
bash
PTDN/test_train_inference_python.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'whole_train_infer'
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'whole_train_infer'
bash
test_tipc/test_train_inference_python.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'whole_train_infer'
```
-
模式5:klquant_infer,测试离线量化;
```
shell
bash
PTDN/prepare.sh ./PTDN
/configs/ppocr_det_mobile_params.txt
'klquant_infer'
bash
PTDN/test_train_inference_python.sh PTDN
/configs/ppocr_det_mobile_params.txt
'klquant_infer'
bash
test_tipc/prepare.sh ./test_tipc
/configs/ppocr_det_mobile_params.txt
'klquant_infer'
bash
test_tipc/test_train_inference_python.sh test_tipc
/configs/ppocr_det_mobile_params.txt
'klquant_infer'
```
...
...
@@ -95,12 +95,12 @@ bash PTDN/test_train_inference_python.sh PTDN/configs/ppocr_det_mobile_params.tx
#### 使用方式
运行命令:
```
shell
python3.7
PTDN/compare_results.py
--gt_file
=
./PTDN/results/python_
*
.txt
--log_file
=
./PTDN
/output/python_
*
.log
--atol
=
1e-3
--rtol
=
1e-3
python3.7
test_tipc/compare_results.py
--gt_file
=
./test_tipc/results/python_
*
.txt
--log_file
=
./test_tipc
/output/python_
*
.log
--atol
=
1e-3
--rtol
=
1e-3
```
参数介绍:
-
gt_file: 指向事先保存好的预测结果路径,支持
*.txt 结尾,会自动索引*
.txt格式的文件,文件默认保存在
PTDN
/result/ 文件夹下
-
log_file: 指向运行
PTDN
/test_train_inference_python.sh 脚本的infer模式保存的预测日志,预测日志中打印的有预测结果,比如:文本框,预测文本,类别等等,同样支持python_infer_
*
.log格式传入
-
gt_file: 指向事先保存好的预测结果路径,支持
*.txt 结尾,会自动索引*
.txt格式的文件,文件默认保存在
test_tipc
/result/ 文件夹下
-
log_file: 指向运行
test_tipc
/test_train_inference_python.sh 脚本的infer模式保存的预测日志,预测日志中打印的有预测结果,比如:文本框,预测文本,类别等等,同样支持python_infer_
*
.log格式传入
-
atol: 设置的绝对误差
-
rtol: 设置的相对误差
...
...
test_tipc/prepare.sh
浏览文件 @
9be9fe8d
...
...
@@ -2,7 +2,7 @@
FILENAME
=
$1
# MODE be one of ['lite_train_infer' 'whole_infer' 'whole_train_infer', 'infer',
# 'cpp_infer', 'serving_infer', 'klquant_infer']
# 'cpp_infer', 'serving_infer', 'klquant_infer'
, 'lite_infer'
]
MODE
=
$2
...
...
@@ -136,3 +136,37 @@ if [ ${MODE} = "serving_infer" ];then
wget
-nc
-P
./inference https://paddleocr.bj.bcebos.com/dygraph_v2.0/ch/ch_ppocr_server_v2.0_rec_infer.tar
cd
./inference
&&
tar
xf ch_ppocr_mobile_v2.0_det_infer.tar
&&
tar
xf ch_ppocr_mobile_v2.0_rec_infer.tar
&&
tar
xf ch_ppocr_server_v2.0_rec_infer.tar
&&
tar
xf ch_ppocr_server_v2.0_det_infer.tar
&&
cd
../
fi
if
[
${
MODE
}
=
"lite_infer"
]
;
then
# prepare lite nb model and test data
current_dir
=
${
PWD
}
wget
-nc
-P
./models https://paddleocr.bj.bcebos.com/dygraph_v2.0/lite/ch_ppocr_mobile_v2.0_det_opt.nb
wget
-nc
-P
./models https://paddleocr.bj.bcebos.com/dygraph_v2.0/lite/ch_ppocr_mobile_v2.0_det_slim_opt.nb
wget
-nc
-P
./test_data https://paddleocr.bj.bcebos.com/dygraph_v2.0/test/icdar2015_lite.tar
cd
./test_data
&&
tar
-xf
icdar2015_lite.tar
&&
rm
icdar2015_lite.tar
&&
cd
../
# prepare lite env
export
http_proxy
=
http://172.19.57.45:3128
export
https_proxy
=
http://172.19.57.45:3128
paddlelite_url
=
https://github.com/PaddlePaddle/Paddle-Lite/releases/download/v2.9/inference_lite_lib.android.armv8.gcc.c++_shared.with_extra.with_cv.tar.gz
paddlelite_zipfile
=
$(
echo
$paddlelite_url
|
awk
-F
"/"
'{print $NF}'
)
paddlelite_file
=
inference_lite_lib.android.armv8.gcc.c++_shared.with_extra.with_cv
wget
${
paddlelite_url
}
tar
-xf
${
paddlelite_zipfile
}
mkdir
-p
${
paddlelite_file
}
/demo/cxx/ocr/test_lite
mv
models test_data
${
paddlelite_file
}
/demo/cxx/ocr/test_lite
cp
ppocr/utils/ppocr_keys_v1.txt deploy/lite/config.txt
${
paddlelite_file
}
/demo/cxx/ocr/test_lite
cp
./deploy/lite/
*
${
paddlelite_file
}
/demo/cxx/ocr/
cp
${
paddlelite_file
}
/cxx/lib/libpaddle_light_api_shared.so
${
paddlelite_file
}
/demo/cxx/ocr/test_lite
cp
PTDN/configs/ppocr_det_mobile_params.txt PTDN/test_lite.sh PTDN/common_func.sh
${
paddlelite_file
}
/demo/cxx/ocr/test_lite
cd
${
paddlelite_file
}
/demo/cxx/ocr/
git clone https://github.com/LDOUBLEV/AutoLog.git
unset
http_proxy
unset
https_proxy
make
-j
sleep
1
make
-j
cp
ocr_db_crnn test_lite
&&
cp
test_lite/libpaddle_light_api_shared.so test_lite/libc++_shared.so
tar
-cf
test_lite.tar ./test_lite
&&
cp
test_lite.tar
${
current_dir
}
&&
cd
${
current_dir
}
fi
test_tipc/readme.md
浏览文件 @
9be9fe8d
#
推理部署导航
#
飞桨训推一体认证
## 1. 简介
飞桨除了基本的模型训练和预测,还提供了支持多端多平台的高性能推理部署工具。本文档提供了PaddleOCR中所有模型的
推理部署导航PTDN(Paddle Train Deploy Navigation),方便用户查阅每种模型的
推理部署打通情况,并可以进行一键测试。
飞桨除了基本的模型训练和预测,还提供了支持多端多平台的高性能推理部署工具。本文档提供了PaddleOCR中所有模型的
飞桨训推一体认证 (Training and Inference Pipeline Certification(TIPC)) 信息和测试工具,方便用户查阅每种模型的训练
推理部署打通情况,并可以进行一键测试。
<div
align=
"center"
>
<img
src=
"docs/guide.png"
width=
"1000"
>
...
...
@@ -58,7 +58,7 @@
### 目录介绍
```
shell
PTDN
/
test_tipc
/
├── configs/
# 配置文件目录
├── det_mv3_db.yml
# 测试mobile版ppocr检测模型训练的yml文件
├── det_r50_vd_db.yml
# 测试server版ppocr检测模型训练的yml文件
...
...
test_tipc/test_lite.sh
0 → 100644
浏览文件 @
9be9fe8d
#!/bin/bash
source
./common_func.sh
export
LD_LIBRARY_PATH
=
${
PWD
}
:
$LD_LIBRARY_PATH
FILENAME
=
$1
dataline
=
$(
awk
'NR==101, NR==110{print}'
$FILENAME
)
echo
$dataline
# parser params
IFS
=
$'
\n
'
lines
=(
${
dataline
}
)
# parser lite inference
lite_inference_cmd
=
$(
func_parser_value
"
${
lines
[1]
}
"
)
lite_model_dir_list
=
$(
func_parser_value
"
${
lines
[2]
}
"
)
lite_cpu_threads_list
=
$(
func_parser_value
"
${
lines
[3]
}
"
)
lite_batch_size_list
=
$(
func_parser_value
"
${
lines
[4]
}
"
)
lite_power_mode_list
=
$(
func_parser_value
"
${
lines
[5]
}
"
)
lite_infer_img_dir_list
=
$(
func_parser_value
"
${
lines
[6]
}
"
)
lite_config_dir
=
$(
func_parser_value
"
${
lines
[7]
}
"
)
lite_rec_dict_dir
=
$(
func_parser_value
"
${
lines
[8]
}
"
)
lite_benchmark_value
=
$(
func_parser_value
"
${
lines
[9]
}
"
)
LOG_PATH
=
"./output"
mkdir
-p
${
LOG_PATH
}
status_log
=
"
${
LOG_PATH
}
/results.log"
function
func_lite
(){
IFS
=
'|'
_script
=
$1
_lite_model
=
$2
_log_path
=
$3
_img_dir
=
$4
_config
=
$5
if
[[
$lite_model
=
~
"slim"
]]
;
then
precision
=
"INT8"
else
precision
=
"FP32"
fi
is_single_img
=
$(
echo
$_img_dir
|
grep
-E
".jpg|.jpeg|.png|.JPEG|.JPG"
)
if
[[
"
$is_single_img
"
!=
""
]]
;
then
single_img
=
"True"
else
single_img
=
"False"
fi
# lite inference
for
num_threads
in
${
lite_cpu_threads_list
[*]
}
;
do
for
power_mode
in
${
lite_power_mode_list
[*]
}
;
do
for
batchsize
in
${
lite_batch_size_list
[*]
}
;
do
model_name
=
$(
echo
$lite_model
|
awk
-F
"/"
'{print $NF}'
)
_save_log_path
=
"
${
_log_path
}
/lite_
${
model_name
}
_precision_
${
precision
}
_batchsize_
${
batchsize
}
_threads_
${
num_threads
}
_powermode_
${
power_mode
}
_singleimg_
${
single_img
}
.log"
command
=
"
${
_script
}
${
lite_model
}
${
precision
}
${
num_threads
}
${
batchsize
}
${
power_mode
}
${
_img_dir
}
${
_config
}
${
lite_benchmark_value
}
>
${
_save_log_path
}
2>&1"
eval
${
command
}
status_check
$?
"
${
command
}
"
"
${
status_log
}
"
done
done
done
}
echo
"################### run test ###################"
IFS
=
"|"
for
lite_model
in
${
lite_model_dir_list
[*]
}
;
do
#run lite inference
for
img_dir
in
${
lite_infer_img_dir_list
[*]
}
;
do
func_lite
"
${
lite_inference_cmd
}
"
"
${
lite_model
}
"
"
${
LOG_PATH
}
"
"
${
img_dir
}
"
"
${
lite_config_dir
}
"
done
done
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录