Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Paddle
提交
1ee237c1
P
Paddle
项目概览
PaddlePaddle
/
Paddle
大约 1 年 前同步成功
通知
2299
Star
20931
Fork
5422
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1423
列表
看板
标记
里程碑
合并请求
543
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1,423
Issue
1,423
列表
看板
标记
里程碑
合并请求
543
合并请求
543
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
1ee237c1
编写于
9月 13, 2021
作者:
L
lidanqing
提交者:
GitHub
9月 12, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add lstm qat models scales (#35382)
上级
4e233712
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
131 addition
and
1 deletion
+131
-1
paddle/fluid/framework/ir/fc_gru_fuse_pass.cc
paddle/fluid/framework/ir/fc_gru_fuse_pass.cc
+4
-1
paddle/fluid/framework/ir/fc_lstm_fuse_pass.cc
paddle/fluid/framework/ir/fc_lstm_fuse_pass.cc
+4
-0
paddle/fluid/framework/ir/mkldnn/cpu_quantize_pass_tester.cc
paddle/fluid/framework/ir/mkldnn/cpu_quantize_pass_tester.cc
+85
-0
python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py
...luid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py
+29
-0
python/paddle/fluid/contrib/slim/tests/CMakeLists.txt
python/paddle/fluid/contrib/slim/tests/CMakeLists.txt
+9
-0
未找到文件。
paddle/fluid/framework/ir/fc_gru_fuse_pass.cc
浏览文件 @
1ee237c1
...
...
@@ -17,7 +17,7 @@
#include <string>
#include "paddle/fluid/framework/op_version_registry.h"
#include "paddle/fluid/string/pretty_log.h"
namespace
paddle
{
namespace
framework
{
class
Scope
;
...
...
@@ -335,6 +335,9 @@ void FCGRUFusePass::ApplyImpl(ir::Graph* graph) const {
graph
,
name_scope_
,
param_scope
(),
true
/*with_fc_bias*/
);
AddStatis
(
fusion_count
);
string
::
PrettyLogDetail
(
"--- fused %d pairs of fc gru patterns"
,
fusion_count
);
}
}
// namespace ir
...
...
paddle/fluid/framework/ir/fc_lstm_fuse_pass.cc
浏览文件 @
1ee237c1
...
...
@@ -16,6 +16,7 @@
#include <string>
#include "paddle/fluid/framework/op_version_registry.h"
#include "paddle/fluid/string/pretty_log.h"
namespace
paddle
{
namespace
framework
{
...
...
@@ -348,6 +349,9 @@ void FCLstmFusePass::ApplyImpl(ir::Graph* graph) const {
BuildFusion
(
graph
,
name_scope_
,
param_scope
(),
true
/*with_fc_bias*/
);
AddStatis
(
fusion_count
);
string
::
PrettyLogDetail
(
"--- fused %d pairs of fc lstm patterns"
,
fusion_count
);
}
}
// namespace ir
...
...
paddle/fluid/framework/ir/mkldnn/cpu_quantize_pass_tester.cc
浏览文件 @
1ee237c1
...
...
@@ -97,6 +97,19 @@ void SetOp(ProgramDesc* prog, const std::string& type, const std::string& name,
op
->
SetInput
(
"WeightX"
,
{
inputs
[
2
]});
op
->
SetInput
(
"WeightH"
,
{
inputs
[
3
]});
op
->
SetOutput
(
"Hidden"
,
{
outputs
[
0
]});
op
->
SetAttr
(
"mkldnn_data_type"
,
mkldnn_data_type
);
op
->
SetAttr
(
"Scale_data"
,
1.0
f
);
op
->
SetAttr
(
"Shift_data"
,
0.0
f
);
op
->
SetAttr
(
"Weight_scale"
,
std
::
vector
<
float
>
{
1.0
f
});
}
else
if
(
type
==
"fusion_lstm"
)
{
op
->
SetInput
(
"X"
,
{
inputs
[
0
]});
op
->
SetInput
(
"Bias"
,
{
inputs
[
1
]});
op
->
SetInput
(
"WeightX"
,
{
inputs
[
2
]});
op
->
SetInput
(
"WeightH"
,
{
inputs
[
3
]});
op
->
SetOutput
(
"Hidden"
,
{
outputs
[
0
]});
op
->
SetOutput
(
"Cell"
,
{
outputs
[
1
]});
op
->
SetAttr
(
"mkldnn_data_type"
,
mkldnn_data_type
);
op
->
SetAttr
(
"Scale_data"
,
1.0
f
);
op
->
SetAttr
(
"Shift_data"
,
0.0
f
);
...
...
@@ -418,6 +431,25 @@ ProgramDesc BuildProgramDescFusionGru() {
return
prog
;
}
static
const
std
::
initializer_list
<
std
::
string
>
variable_names_fusion_lstm
=
{
"x"
,
"wx"
,
"wh"
,
"b"
,
"h"
,
"c"
};
// (x, wx, wh, b)->Fusion_lstm_1->h
ProgramDesc
BuildProgramDescFusionLSTM
()
{
ProgramDesc
prog
;
for
(
auto
&
v
:
variable_names_transpose
)
{
auto
*
var
=
prog
.
MutableBlock
(
0
)
->
Var
(
v
);
if
(
v
.
find
(
"wx"
)
==
0
||
v
.
find
(
"wh"
)
||
v
.
find
(
"b"
))
{
var
->
SetPersistable
(
true
);
}
}
SetOp
(
&
prog
,
"fusion_lstm"
,
"Fusion_lstm_1"
,
{
"x"
,
"wx"
,
"wh"
,
"b"
},
{
"h"
,
"c"
},
true
,
"int8"
);
return
prog
;
}
void
MainTestFusionGru
(
const
ProgramDesc
&
prog
,
int
gru_count
,
int
quant_count
,
int
dequant_count
,
int
added_nodes_count
,
float
scale
,
float
shift
)
{
...
...
@@ -470,6 +502,59 @@ TEST(CpuQuantizePass, fusion_gru) {
dequant_count
,
added_nodes_count
,
2.
*
127
,
128.
);
}
void
MainTestFusionLSTM
(
const
ProgramDesc
&
prog
,
int
expect_lstm_count
,
int
quant_count
,
int
dequant_count
,
int
added_nodes_count
,
float
scale
,
float
shift
)
{
std
::
unique_ptr
<
ir
::
Graph
>
graph
(
new
ir
::
Graph
(
prog
));
int
original_nodes_num
,
current_nodes_num
;
PreparePass
(
&
graph
,
prog
,
variable_names_fusion_lstm
,
&
original_nodes_num
,
&
current_nodes_num
);
int
quantize_nodes_count
=
0
;
int
dequantize_nodes_count
=
0
;
int
lstm_nodes_count
=
0
;
for
(
auto
*
node
:
graph
->
Nodes
())
{
if
(
node
->
IsOp
())
{
auto
*
op
=
node
->
Op
();
if
(
op
->
Type
()
==
"fusion_lstm"
)
{
lstm_nodes_count
++
;
auto
op_name
=
BOOST_GET_CONST
(
std
::
string
,
op
->
GetAttr
(
"name"
));
EXPECT_EQ
(
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"Scale_data"
)),
scale
)
<<
"Scale_data for node '"
+
op_name
+
"'."
;
EXPECT_EQ
(
BOOST_GET_CONST
(
float
,
op
->
GetAttr
(
"Shift_data"
)),
shift
)
<<
"Shift_data for node '"
+
op_name
+
"'."
;
EXPECT_EQ
(
BOOST_GET_CONST
(
std
::
vector
<
float
>
,
op
->
GetAttr
(
"Scale_weights"
))[
0
],
scale
)
<<
"Scale_weights for node '"
+
op_name
+
"'."
;
EXPECT_EQ
(
BOOST_GET_CONST
(
bool
,
op
->
GetAttr
(
"force_fp32_output"
)),
true
)
<<
"force_fp32_output for node '"
+
op_name
+
"'."
;
}
else
if
(
op
->
Type
()
==
"quantize"
)
{
quantize_nodes_count
++
;
}
else
if
(
op
->
Type
()
==
"dequantize"
)
{
dequantize_nodes_count
++
;
}
}
}
EXPECT_EQ
(
lstm_nodes_count
,
expect_lstm_count
);
EXPECT_EQ
(
quantize_nodes_count
,
quant_count
);
EXPECT_EQ
(
dequantize_nodes_count
,
dequant_count
);
EXPECT_EQ
(
original_nodes_num
+
added_nodes_count
,
current_nodes_num
);
}
TEST
(
CpuQuantizePass
,
fusion_lstm
)
{
// (x, wx, wh, b)->Fusion_lstm->h
int
expect_lstm_count
=
1
;
int
expect_quant_count
=
1
;
int
dequant_count
=
0
;
// 1 Quant + 1 IN + 0 DeQuant + 0 OUT
int
added_nodes_count
=
1
+
1
+
0
+
0
;
MainTestFusionLSTM
(
BuildProgramDescFusionLSTM
(),
expect_lstm_count
,
expect_quant_count
,
dequant_count
,
added_nodes_count
,
2.
*
127
,
128.
);
}
const
std
::
vector
<
std
::
string
>
churn_out_vars
(
ProgramDesc
*
prog
,
const
std
::
string
&
prefix
,
int
number
)
{
...
...
python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py
浏览文件 @
1ee237c1
...
...
@@ -71,6 +71,7 @@ class Quant2Int8MkldnnPass(object):
self
.
_relu_ops
=
[
'relu'
,
'relu6'
]
self
.
_matmul_ops
=
[
'matmul'
]
self
.
_gru_ops
=
[
'fusion_gru'
,
'multi_gru'
]
self
.
_lstm_ops
=
[
'fusion_lstm'
]
self
.
_weight_thresholds
=
{}
# Collect the Input and Output sclaes from Fake quant models
self
.
_var_quant_scales
=
{}
...
...
@@ -535,10 +536,38 @@ class Quant2Int8MkldnnPass(object):
self
.
_var_quant_scales
[
wx_var_name
]
=
(
use_unsigned_int
,
lod_tensor
)
def
_compute_single_lstm_weight_scales
(
wx_var_name
,
wh_var_name
):
wx
=
np
.
array
(
self
.
_load_param
(
self
.
_scope
,
wx_var_name
))
wh
=
np
.
array
(
self
.
_load_param
(
self
.
_scope
,
wh_var_name
))
lstm_weights_scale
=
1.0
/
np
.
max
(
np
.
abs
(
np
.
concatenate
(
[
wx
[:,
:],
wh
[:,
:]],
axis
=
0
)),
axis
=
0
)
lstm_weights_scale
=
lstm_weights_scale
.
astype
(
'float'
)
return
self
.
_convert_scale2tensor
(
lstm_weights_scale
)
def
_compute_lstm_weight_scales
(
wx_name
,
wh_name
):
for
op
in
graph
.
all_op_nodes
():
if
op
.
op
().
type
()
in
self
.
_lstm_ops
:
assert
len
(
op
.
input
(
wx_name
))
==
len
(
op
.
input
(
wh_name
)
),
'Mismatch in number of weights inputs ({} for WeightX vs. {} for WeightH).'
.
format
(
len
(
op
.
input
(
wx_name
)),
len
(
op
.
input
(
wh_name
)))
for
i
,
wx_var_name
in
enumerate
(
op
.
input
(
wx_name
)):
wh_var_name
=
op
.
input
(
wh_name
)[
i
]
use_unsigned_int
=
False
lod_tensor
=
_compute_single_lstm_weight_scales
(
wx_var_name
,
wh_var_name
)
self
.
_var_quant_scales
[
wx_var_name
]
=
(
use_unsigned_int
,
lod_tensor
)
_compute_var_scales
(
self
.
_conv_ops
,
"Filter"
,
axis
=
1
)
_compute_var_scales
(
self
.
_fc_ops
,
"W"
,
axis
=
0
)
_compute_var_scales
(
self
.
_gru_ops
,
"WeightH"
,
axis
=
0
)
_compute_var_scales
(
self
.
_lstm_ops
,
"WeightH"
,
axis
=
0
)
_compute_gru_weight_scales
(
"WeightX"
,
"WeightH"
)
_compute_lstm_weight_scales
(
"WeightX"
,
"WeightH"
)
return
graph
def
_find_avg_pooling_ids
(
self
,
graph
):
...
...
python/paddle/fluid/contrib/slim/tests/CMakeLists.txt
浏览文件 @
1ee237c1
...
...
@@ -265,6 +265,12 @@ if(LINUX AND WITH_MKLDNN)
download_quant_model
(
${
QUANT2_GRU_MODEL_DIR
}
${
QUANT2_GRU_MODEL_ARCHIVE
}
cf207f8076dcfb8b74d8b6bdddf9090c
)
set
(
QUANT2_GRU_OPS_TO_QUANTIZE
"multi_gru"
)
# Quant2 LSTM
set
(
QUANT2_LSTM_MODEL_ARCHIVE
"lstm_quant.tar.gz"
)
set
(
QUANT2_LSTM_MODEL_DIR
"
${
QUANT_INSTALL_DIR
}
/lstm_quant_test"
)
download_quant_model
(
${
QUANT2_LSTM_MODEL_DIR
}
${
QUANT2_LSTM_MODEL_ARCHIVE
}
40a693803b12ee9e251258f32559abcb
)
set
(
QUANT2_LSTM_OPS_TO_QUANTIZE
"fusion_lstm"
)
### Save FP32 model or INT8 model from Quant model
set
(
QUANT2_INT8_RESNET50_SAVE_PATH
"
${
QUANT_INSTALL_DIR
}
/ResNet50_quant2_int8"
)
...
...
@@ -276,6 +282,9 @@ if(LINUX AND WITH_MKLDNN)
set
(
QUANT2_INT8_GRU_SAVE_PATH
"
${
QUANT_INSTALL_DIR
}
/GRU_quant2_int8"
)
save_quant_nlp_model_test
(
save_quant2_model_gru
${
QUANT2_GRU_MODEL_DIR
}
/GRU_quant_acc
${
QUANT2_INT8_GRU_SAVE_PATH
}
${
QUANT2_GRU_OPS_TO_QUANTIZE
}
)
set
(
QUANT2_INT8_LSTM_SAVE_PATH
"
${
QUANT_INSTALL_DIR
}
/lstm_quant2_int8"
)
save_quant_nlp_model_test
(
save_quant2_model_lstm
${
QUANT2_LSTM_MODEL_DIR
}
/lstm_quant
${
QUANT2_INT8_LSTM_SAVE_PATH
}
${
QUANT2_LSTM_OPS_TO_QUANTIZE
}
)
# Convert Quant2 model to dot and pdf files
set
(
QUANT2_INT8_ERNIE_DOT_SAVE_PATH
"
${
QUANT_INSTALL_DIR
}
/Ernie_quant2_int8_dot_file"
)
convert_model2dot_test
(
convert_model2dot_ernie
${
QUANT2_ERNIE_MODEL_DIR
}
/Ernie_qat/float
${
QUANT2_INT8_ERNIE_DOT_SAVE_PATH
}
"Ernie_quant2_int8"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录