Do not fuse skiplayernorm if any output of add in graph output (#3981)

This commit is contained in:
Yufeng Li 2020-05-18 19:46:51 -07:00 committed by GitHub
parent a75a83b41a
commit b253f0b0f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 9 deletions

View file

@ -172,7 +172,9 @@ Status SkipLayerNormFusion::ApplyImpl(Graph& graph, bool& modified, int graph_le
p_add2 = const_cast<Node*>(&edges[1]->GetNode());
if (CheckFirstAdd(*p_add1, ln_node.GetExecutionProviderType()) &&
CheckSecondAdd(graph, *p_add2, ln_node.GetExecutionProviderType())) {
CheckSecondAdd(graph, *p_add2, ln_node.GetExecutionProviderType()) &&
graph.GetNodeOutputsInGraphOutputs(*p_add1).empty() &&
graph.GetNodeOutputsInGraphOutputs(*p_add2).empty()) {
matched_format = Format::Format1;
}
}
@ -188,7 +190,9 @@ Status SkipLayerNormFusion::ApplyImpl(Graph& graph, bool& modified, int graph_le
p_add2 = const_cast<Node*>(&edges[1]->GetNode());
if (CheckFirstAdd(*p_add1, ln_node.GetExecutionProviderType()) &&
CheckSecondAdd(graph, *p_add2, ln_node.GetExecutionProviderType())) {
CheckSecondAdd(graph, *p_add2, ln_node.GetExecutionProviderType()) &&
graph.GetNodeOutputsInGraphOutputs(*p_add1).empty() &&
graph.GetNodeOutputsInGraphOutputs(*p_add2).empty()) {
matched_format = Format::Format2;
}
}
@ -202,7 +206,8 @@ Status SkipLayerNormFusion::ApplyImpl(Graph& graph, bool& modified, int graph_le
if (graph_utils::FindPath(ln_node, true, format3_parent_path, edges, logger)) {
p_add1 = const_cast<Node*>(&edges[0]->GetNode());
if (CheckFirstAdd(*p_add1, ln_node.GetExecutionProviderType())) {
if (CheckFirstAdd(*p_add1, ln_node.GetExecutionProviderType()) &&
graph.GetNodeOutputsInGraphOutputs(*p_add1).empty()) {
matched_format = Format::Format3;
}
}
@ -237,7 +242,7 @@ Status SkipLayerNormFusion::ApplyImpl(Graph& graph, bool& modified, int graph_le
skip_layer_norm_input_defs,
ln_node.MutableOutputDefs(), {}, kMSDomain);
// Get attribute "epsilon" from "LayerNormalization" node if available. Else, default value
// Get attribute "epsilon" from "LayerNormalization" node if available. Else, default value
// will be used.
NodeAttributes ln_attrs = ln_node.GetAttributes();
NodeAttributes::const_iterator epsilon = ln_attrs.find("epsilon");

View file

@ -1199,7 +1199,7 @@ TEST_F(GraphTransformationTests, ReshapeFusionGraphInputsTest) {
ASSERT_EQ(op_to_count["Concat"], 1);
ASSERT_EQ(op_to_count["Reshape"], 1);
}
TEST_F(GraphTransformationTests, ReshapeFusionMultipleValuesInInitializerDoesntApplyTest) {
auto model_uri = MODEL_FOLDER "fusion/reshape_fusion_multiple_values_in_initializer_tensor_1.onnx";
std::shared_ptr<Model> p_model;
@ -1914,9 +1914,14 @@ TEST_F(GraphTransformationTests, SkipLayerNormFusionTest) {
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format1.onnx", 0, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format2.onnx", 0, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format3.onnx", 0, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format1_partial.onnx", 1, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format2_partial.onnx", 1, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format3_no_fusion.onnx", 1, 1, 0, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format1_graph_output.onnx", 1, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format2_graph_output.onnx", 1, 0, 1, logger_.get());
TestSkipLayerNormFusion(MODEL_FOLDER "fusion/skip_layer_norm_format3_graph_output.onnx", 1, 1, 0, logger_.get());
}
TEST_F(GraphTransformationTests, SkipLayerNormFusion_Input_Output_Check) {

View file

@ -10,7 +10,7 @@ class Format(Enum):
Format3 = 3
def GenerateModel(format, model_name, multi_output_add=False):
def GenerateModel(format, model_name, multi_output_add=False, add_output_in_graph_output=False):
nodes = [ # LayerNorm subgraph
helper.make_node("ReduceMean", ["ln_in"], ["rd1_out"], "reduce1", axes=[-1], keepdims=1),
helper.make_node("Sub", ["ln_in", "rd1_out"], ["sb1_out"], "sub1"),
@ -67,6 +67,10 @@ def GenerateModel(format, model_name, multi_output_add=False):
helper.make_tensor_value_info('C', TensorProto.FLOAT, [16, 32, 4]),
],
initializers)
if add_output_in_graph_output:
extra_output = "ln_in" if format is Format.Format3 else "add3_out"
graph.output.extend([helper.make_tensor_value_info(extra_output, TensorProto.FLOAT, [16, 32, 4])])
model = helper.make_model(graph)
onnx.save(model, model_name)
@ -75,6 +79,10 @@ def GenerateModel(format, model_name, multi_output_add=False):
GenerateModel(Format.Format1, 'skip_layer_norm_format1.onnx')
GenerateModel(Format.Format2, 'skip_layer_norm_format2.onnx')
GenerateModel(Format.Format3, 'skip_layer_norm_format3.onnx')
GenerateModel(Format.Format1, 'skip_layer_norm_format1_partial.onnx', True)
GenerateModel(Format.Format2, 'skip_layer_norm_format2_partial.onnx', True)
GenerateModel(Format.Format3, 'skip_layer_norm_format3_no_fusion.onnx', True)
GenerateModel(Format.Format1, 'skip_layer_norm_format1_partial.onnx', multi_output_add = True)
GenerateModel(Format.Format2, 'skip_layer_norm_format2_partial.onnx', multi_output_add = True)
GenerateModel(Format.Format3, 'skip_layer_norm_format3_no_fusion.onnx', multi_output_add = True)
GenerateModel(Format.Format1, 'skip_layer_norm_format1_graph_output.onnx', add_output_in_graph_output = True)
GenerateModel(Format.Format2, 'skip_layer_norm_format2_graph_output.onnx', add_output_in_graph_output = True)
GenerateModel(Format.Format3, 'skip_layer_norm_format3_graph_output.onnx', add_output_in_graph_output = True)