Skip to content

EmbedLayerNormalization fusion#2452

Merged
liuziyue merged 24 commits intomasterfrom
ziyl/embedLayerNormFusion
Nov 28, 2019
Merged

EmbedLayerNormalization fusion#2452
liuziyue merged 24 commits intomasterfrom
ziyl/embedLayerNormFusion

Conversation

@liuziyue
Copy link
Contributor

@liuziyue liuziyue commented Nov 21, 2019

Description:

  • Add EmbedLayerNormalization Fusion Transformer to fuse EmbedLayerNormalization subgraph to one node.

Motivation and Context

  • Why is this change required? What problem does it solve?
  • If it fixes an open issue, please link to the issue here.

It is used to optimize Bert model performance.

@liuziyue liuziyue requested a review from a team as a code owner November 21, 2019 20:03
namespace onnxruntime {

// EmbedLayerNorm supports limited data types.
static std::vector<std::string> supported_data_types{"tensor(float16)", "tensor(float)", "tensor(int32)"};
Copy link
Contributor

Choose a reason for hiding this comment

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

Array is enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

Array can be initialized at compile time but vector can't.

@snnn snnn requested a review from a team November 21, 2019 20:20
// Get input "input_ids" from node.
NodeArg* input_ids = nullptr;
if (!graph_utils::NodeArgIsConstant(graph, *(word_gather_node.MutableInputDefs()[1])) &&
!graph_utils::IsGraphInput(graph, word_gather_node.MutableInputDefs()[1])) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shall we add check of first input for 3 Gather nodes? For example, the input has the initializer of 2D tensor.

continue;
}
Node& reduce_sum_node = *graph.GetNode(edges[0]->GetNode().Index());
if (reduce_sum_node.GetOutputEdgesCount() != 1) {
Copy link
Contributor

@tianleiwu tianleiwu Nov 21, 2019

Choose a reason for hiding this comment

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

Reduce_sum could have multiple output edges. For Bert model with 12 layers, there are 12 Attention nodes so output edge count could be 12. I think it is fine to remove the check of output edge count since those edges will linked to the mask index output of embed layer when fusion is done.

continue;
}

std::vector<graph_utils::EdgeEndToMatch> position_embedding_path_symbolic{
Copy link
Contributor

Choose a reason for hiding this comment

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

If second input of position gather is constant initializer, it is better to add code the check that the const like like [1, 2, 3, ...].

Copy link
Contributor

Choose a reason for hiding this comment

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

How about using logic like:

If gather input is (constant) initializer {
check initializer
}
else {
match two paths:
expand -- shape --input_ids
expand -- ... --shape--input_ids
if not matched return.
}

{0, 0, "Unsqueeze", {1, 11}, kOnnxDomain},
{0, 0, "Gather", {1, 11}, kOnnxDomain},
{0, 0, "Shape", {1}, kOnnxDomain},
};
Copy link
Contributor

@tianleiwu tianleiwu Nov 27, 2019

Choose a reason for hiding this comment

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

Also check that shape's parent is input_ids. The edges of ? has not been checked in your code:
input_ids -?- Shape -?- Expand -- Gather
|?
+-Shape--(this Path to Expand)

tianleiwu
tianleiwu previously approved these changes Nov 28, 2019
Copy link
Contributor

@tianleiwu tianleiwu left a comment

Choose a reason for hiding this comment

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

The improvements can be in another PR. Approve it to check in so that other changes depending on it could continue.

Copy link
Contributor

@tianleiwu tianleiwu left a comment

Choose a reason for hiding this comment

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

Add logic to check the shapes of three inputs (input_ids, segment_ids and mask): dimenion 1 is known and all have same value.

@liuziyue liuziyue deleted the ziyl/embedLayerNormFusion branch February 24, 2021 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants